Skip to content

Fix/ads1x15 pin constants - #16

Open
LeifYKlasson wants to merge 3 commits into
openplotter:masterfrom
LeifYKlasson:fix/ads1x15-pin-constants
Open

Fix/ads1x15 pin constants#16
LeifYKlasson wants to merge 3 commits into
openplotter:masterfrom
LeifYKlasson:fix/ads1x15-pin-constants

Conversation

@LeifYKlasson

Copy link
Copy Markdown

Fix ADS1115/ADS1015 support for adafruit-circuitpython-ads1x15 v3.x

Problem

Two bugs broke ADS1115 (and ADS1015) support after upgrading to adafruit-circuitpython-ads1x15 v3.0.2.

Bug 1 — API change: v3.x removed the P0–P3 pin constants from the ADS1115/ADS1015 classes. Accessing ADS1115.P0 raised:
Error processing ADS1115: type object 'ADS1115' has no attribute 'P0'

Bug 2 — Channels disappearing from UI after editing: After assigning a Signal K path to a channel and saving, all four channels disappeared from the UI (though data continued flowing to Signal K). The read service
adds runtime-only keys (object, ranges) directly into the shared sensor data dict and then writes str(i2c_sensors) back to openplotter.conf. The object key serializes as <AnalogIn object at 0x...> — not valid
Python. When the UI later calls eval() on that string it fails, falls back to {}, and shows an empty list.

Changes

openplotterI2cRead.py

  • Import Pin from adafruit_ads1x15.ads1x15 and replace all ADS1115.P0–P3 / ADS1015.P0–P3 references with Pin.A0–A3 (covers both ADS1115 and ADS1015).
  • Before writing sensors back to openplotter.conf, build a clean serializable copy that strips the runtime-only keys object and ranges from each data entry. The error key is preserved so the UI can still highlight
    failing sensors in red.

For users upgrading from a previous version

If you already configured an ADS1115/ADS1015 sensor and your channels have disappeared, your openplotter.conf may contain the corrupted entry. Run this once to clean it:

python3 << 'EOF'
import configparser

conf = configparser.ConfigParser()
conf.read('/home/pi/.openplotter/openplotter.conf')
try:
sensors = eval(conf.get('I2C', 'sensors'))
for sensor in sensors.values():
for d in sensor.get('data', []):
d.pop('object', None)
d.pop('ranges', None)
conf.set('I2C', 'sensors', str(sensors))
with open('/home/pi/.openplotter/openplotter.conf', 'w') as f:
conf.write(f)
print('Done — restart the OpenPlotter i2c service.')
except Exception as e:
print('Could not parse config:', e)
EOF

Then restart the i2c service (or reboot). Your channels and Signal K paths will reappear.
The cleanup script covers any user who hit the same corrupted config.

@msallin

msallin commented May 24, 2026

Copy link
Copy Markdown

Hi @LeifYKlasson — really appreciate this fix, the channel-disappearance bug was painful and the save-time sanitiser you added is the right call.

Heads-up that we hit the pin-constants part of the fix on a Pi where adafruit_ads1x15.ads1x15.Pin exists but doesn't have an A0 attribute (the library has shipped at least three incompatible APIs over the years and older Pi installs are stuck on an earlier one). The symptom on that hardware after applying this PR is type object 'Pin' has no attribute 'A0' and the whole ADS1115 sensor goes red.

Opened #17 with a backwards-compatible alternative that tries Pin.A0..A3 first and falls back to the older module-level P0..P3 forms. The save-time sanitiser from this PR is preserved verbatim there (with Co-Authored-By credit). We also tacked on two unrelated follow-ups that surfaced while diagnosing: a getPaths2 null-on-0.0 bug and optional differential-mode support for the ADS1x15 via a sensorSettings['diff'] setting.

Happy to fold things differently if you'd prefer — e.g. land this PR's sanitiser standalone and rebase #17 on top, or close #17 once you've taken what's useful from it. Either way is fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants