cat > ads_scope.py <<'PY' import time import smbus from collections import deque import matplotlib.pyplot as plt BUS=1 ADDR=0x48 REG_CONV=0x00 REG_CONFIG=0x01 bus = smbus.SMBus(BUS) # Continuous mode, AIN0, PGA ±4.096V, 860 SPS (chip-side) config = 0x8000 | 0x4000 | 0x0200 | 0x0000 | 0x00E0 | 0x0003 bus.write_i2c_block_data(ADDR, REG_CONFIG, [(config>>8)&0xFF, config&0xFF]) FS=4.096 def read_v(): raw = bus.read_word_data(ADDR, REG_CONV) raw = ((raw & 0xFF) << 8) | (raw >> 8) if raw & 0x8000: raw -= 1<<16 return raw * FS / 32768.0 # ---- Tuning knobs ---- WINDOW_SECONDS = 0.5 # how much time you want visible ASSUMED_SPS = 860 # ADS max conversion rate DRAW_FPS = 25 # how often we redraw (UI) DECIM = 4 # show 1 in N samples (reduces "cramped" look + speeds UI) # Display buffer size: window * (sps/decim) disp_sps = ASSUMED_SPS // DECIM N = int(WINDOW_SECONDS * disp_sps) ys = deque([0.0]*N, maxlen=N) plt.ion() fig, ax = plt.subplots() xs = [i / disp_sps for i in range(N)] line, = ax.plot(xs, list(ys)) ax.set_title(f"ADS1115 AIN0 scope ({WINDOW_SECONDS}s window, ~{disp_sps} pts/s shown)") ax.set_xlabel("Time (s)") ax.set_ylabel("Volts") ax.set_xlim(0, WINDOW_SECONDS) ax.set_ylim(-0.5, 3.5) # Make redraw cheap fig.canvas.draw() bg = fig.canvas.copy_from_bbox(ax.bbox) draw_interval = 1.0 / DRAW_FPS last_draw = time.perf_counter() # Rate meters last_rate_t = time.perf_counter() read_count = 0 append_count = 0 decim_counter = 0 while True: v = read_v() read_count += 1 decim_counter += 1 # keep only 1 out of DECIM reads for display if decim_counter >= DECIM: ys.append(v) append_count += 1 decim_counter = 0 now = time.perf_counter() # Print rates once per second if now - last_rate_t >= 1.0: dt = now - last_rate_t print(f"reads/sec={read_count/dt:.0f} plotted_points/sec={append_count/dt:.0f}") last_rate_t = now read_count = 0 append_count = 0 # Redraw at DRAW_FPS if now - last_draw >= draw_interval: line.set_ydata(list(ys)) fig.canvas.restore_region(bg) ax.draw_artist(line) fig.canvas.blit(ax.bbox) fig.canvas.flush_events() last_draw = now PY python3 ads_scope.py