#!/usr/bin/env python3 import time from smbus2 import SMBus ADDR = 0x48 # change if your i2cdetect shows a different one REG_CONV = 0x00 REG_CFG = 0x01 # PGA gain bits: +/-4.096V gives 0.125mV/LSB (nice for small signals) PGA_4_096 = 0x0200 # 128 SPS is stable; can bump to 250/475 later DR_128SPS = 0x0080 # Single-shot mode MODE_SINGLE = 0x0100 # Comparator disabled COMP_DISABLE = 0x0003 # MUX values (ADS1115) MUX_SE = { 0: 0x4000, # AIN0 vs GND 1: 0x5000, 2: 0x6000, 3: 0x7000, } # Differential pairs we care about when 4 unknown wires go to A0-A3 MUX_DIFF = { "D01": 0x0000, # A0-A1 "D03": 0x1000, # A0-A3 "D13": 0x2000, # A1-A3 "D23": 0x3000, # A2-A3 "D02": 0x4000, # A0-A2 "D12": 0x5000, # A1-A2 } # LSB for PGA +/-4.096V is 125uV LSB_V = 0.000125 def write_u16(bus, reg, value): # ADS expects big-endian bus.write_i2c_block_data(ADDR, reg, [(value >> 8) & 0xFF, value & 0xFF]) def read_u16(bus, reg): data = bus.read_i2c_block_data(ADDR, reg, 2) return (data[0] << 8) | data[1] def read_signed_conv(bus): raw = read_u16(bus, REG_CONV) # Convert to signed 16-bit if raw & 0x8000: raw -= 1 << 16 return raw def read_channel(bus, mux_bits): cfg = mux_bits | PGA_4_096 | MODE_SINGLE | DR_128SPS | COMP_DISABLE # Start conversion by setting OS bit cfg |= 0x8000 write_u16(bus, REG_CFG, cfg) # Wait for conversion: at 128SPS max ~7.8ms; give it 10ms time.sleep(0.010) raw = read_signed_conv(bus) return raw * LSB_V def fmt_mv(v): return f"{v*1000:7.1f}mV" def main(): print("ADS1115 scan - Ctrl+C to stop") print("Tip: floating inputs drift. For clean 'unplug goes near 0 fast', add 470k-1M pulldown from each A0-A3 to GND.") with SMBus(1) as bus: while True: se = {ch: read_channel(bus, MUX_SE[ch]) for ch in range(4)} d = {name: read_channel(bus, mux) for name, mux in MUX_DIFF.items()} line = ( f"SE0:{fmt_mv(se[0])} SE1:{fmt_mv(se[1])} SE2:{fmt_mv(se[2])} SE3:{fmt_mv(se[3])} | " f"D01:{fmt_mv(d['D01'])} D02:{fmt_mv(d['D02'])} D03:{fmt_mv(d['D03'])} " f"D12:{fmt_mv(d['D12'])} D13:{fmt_mv(d['D13'])} D23:{fmt_mv(d['D23'])}" ) print(line) time.sleep(0.05) # 20Hz-ish if __name__ == "__main__": main()