import time import smbus from collections import deque import RPi.GPIO as GPIO import matplotlib.pyplot as plt BUS = 1 ADDR = 0x48 REG_CONV = 0x00 REG_CONFIG = 0x01 REG_LOTH = 0x02 REG_HITH = 0x03 bus = smbus.SMBus(BUS) # ADS1115 config bits MUX_AIN0 = 0x4000 PGA_4V096 = 0x0200 MODE_CONT = 0x0000 DR_860 = 0x00E0 COMP_QUEUE_1 = 0x0000 # assert after 1 conversion COMP_ACTIVELO = 0x0008 # ALERT pin active low COMP_TRAD = 0x0000 COMP_NONLAT = 0x0000 COMP_POL_LO = 0x0000 FS_VOLTS = 4.096 GPIO_PIN = 17 # ALRT/RDY connected here def write_reg(reg, value): bus.write_i2c_block_data(ADDR, reg, [(value >> 8) & 0xFF, value & 0xFF]) def read_conv(): data = bus.read_i2c_block_data(ADDR, REG_CONV, 2) raw = (data[0] << 8) | data[1] if raw & 0x8000: raw -= 1 << 16 volts = raw * FS_VOLTS / 32768.0 return volts def start_continuous_rdy_ain0(): # Put ALERT into "conversion ready" mode: # Set Hi_thresh = 0x8000, Lo_thresh = 0x0000 (datasheet trick) write_reg(REG_HITH, 0x8000) write_reg(REG_LOTH, 0x0000) # Enable comparator so ALERT/RDY toggles each conversion config = ( 0x8000 | MUX_AIN0 | PGA_4V096 | MODE_CONT | DR_860 | COMP_TRAD | COMP_NONLAT | COMP_ACTIVELO | COMP_QUEUE_1 ) write_reg(REG_CONFIG, config) # ---- Plot setup ---- WINDOW_SECONDS = 0.5 SPS = 860 maxlen = int(WINDOW_SECONDS * SPS) ys = deque([0.0] * maxlen, maxlen=maxlen) xs = [i / SPS for i in range(maxlen)] plt.ion() fig, ax = plt.subplots() line, = ax.plot(xs, list(ys)) ax.set_title("ADS1115 AIN0 live (0.5s window @ 860 SPS)") ax.set_xlabel("Time (s)") ax.set_ylabel("Volts") ax.set_xlim(0, WINDOW_SECONDS) ax.set_ylim(-0.5, 3.5) # GPIO ready pin GPIO.setmode(GPIO.BCM) GPIO.setup(GPIO_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) start_continuous_rdy_ain0() last_draw = time.perf_counter() draw_interval = 1/30 # redraw 30 fps try: while True: # wait for conversion-ready pulse (ALERT goes low) GPIO.wait_for_edge(GPIO_PIN, GPIO.FALLING) v = read_conv() ys.append(v) now = time.perf_counter() if now - last_draw >= draw_interval: line.set_ydata(list(ys)) fig.canvas.draw_idle() plt.pause(0.001) last_draw = now except KeyboardInterrupt: pass finally: GPIO.cleanup()