smbus2 write_i2c_block_data: Was ist das "cmd"-Byte für einen ADS1115?
Von English mit KI übersetzt ·
Garten-Node-Projekt: Pi Zero 2 W, ADS1115 unter 0x48, AIN0 ist eine kapazitive Bodenfeuchtesonde und AIN1 die 12-V-Batterie über einen Spannungsteiler. Das Skript sendet beide Werte alle 5 Minuten an Hermetry.Ich wollte die großen Bibliotheken umgehen und selbst mit smbus2 mit dem ADS1115 kommunizieren. Ich habe das aus einem Forumsbeitrag kopiert:
bus.write_i2c_block_data(0x48, 0x01, [0xC3, 0x83])
time.sleep(0.01)
data = bus.read_i2c_block_data(0x48, 0x00, 2)
raw = data[1] << 8 | data[0]
Es läuft, aber die Zahlen sind unsinnig: Der Bodenwert springt zwischen etwa 900 und 52.000, obwohl sich nichts ändert. Die smbus2-Dokumentation beschreibt das zweite Argument als cmd. Welches Kommando ist das? Das ADS1115-Datenblatt erwähnt Kommandos nirgends, nur Register. Ich habe das Gefühl, dass mir etwas Grundlegendes fehlt.
Garden node project: Pi Zero 2 W, ADS1115 at 0x48, AIN0 is a capacitive soil probe and AIN1 the 12 V battery through a divider. The script posts both to Hermetry every 5 minutes.
I wanted to skip the big libraries and talk to the ADS1115 with smbus2 myself. I copied this from a forum post:
bus.write_i2c_block_data(0x48, 0x01, [0xC3, 0x83])
time.sleep(0.01)
data = bus.read_i2c_block_data(0x48, 0x00, 2)
raw = data[1] << 8 | data[0]
It runs, but the numbers are nonsense: the soil value jumps between about 900 and 52,000 when nothing changes. The smbus2 docs describe the second argument as cmd. What command? The ADS1115 datasheet does not mention commands anywhere, only registers. I feel like I’m missing something basic.
Von English mit KI übersetzt ·
Ist cmd nicht ein Code, den der Chip definiert, wie z. B. „Konvertierung starten“?
Isn’t cmd a code the chip defines, like „start conversion“?
Von English mit KI übersetzt ·
+1, dieses Argument habe ich auch nie verstanden.
+1, never understood that argument either.
Von English mit KI übersetzt ·
„cmd“ ist SMBus-Bezeichnung. Bei einem SMBus-Blockschreibzugriff heißt das erste Byte nach der Adresse Command-Byte, und bei registerbasierten Chips wie dem ADS1115 ist dieses Byte der Registerzeiger. Ihre erste Zeile setzt den Zeiger also auf das Config-Register (0x01) und schreibt darin 0xC3 und dann 0x83. Auf dem Bus: Start, 0x90, 0x01, 0xC3, 0x83, Stopp.0xC383 bedeutet: eine Einzelwandlung starten, AIN0 gegen GND, Messbereich ±4,096 V, Einzelschussmodus, 128 Samples/s. Das Lesen setzt den Zeiger auf 0x00 (Conversion-Register) und liest zwei Bytes.Ihr Fehler liegt in der Byte-Reihenfolge. Der ADS1115 sendet zuerst das höchstwertige Byte, und das Ergebnis ist vorzeichenbehaftet:
data = bus.read_i2c_block_data(0x48, 0x00, 2)
raw = (data[0] << 8) | data[1]
if raw > 0x7FFF:
raw -= 0x10000
volts = raw * 4.096 / 32768
Bei vertauschten Bytes wird eine kleine Änderung im niederwertigen Byte zu einem riesigen Sprung, und genau das ist Ihr 900 gegenüber 52.000. Für AIN1 ändern Sie die MUX-Bits: [0xD3, 0x83]. Und 10 ms reichen bei 128 SPS aus (eine Wandlung dauert etwa 8 ms), die Wartezeit ist also in Ordnung.
„cmd“ is SMBus naming. In an SMBus block write the first byte after the address is called the command byte, and for register-based chips like the ADS1115 that byte is the register pointer. So your first line puts the pointer on the Config register (0x01) and writes 0xC3 then 0x83 into it. On the wire: start, 0x90, 0x01, 0xC3, 0x83, stop.
0xC383 means: start a single conversion, AIN0 against GND, ±4.096 V range, single-shot mode, 128 samples/s. The read sets the pointer to 0x00 (Conversion register) and reads two bytes.
Your bug is the byte order. The ADS1115 sends the most significant byte first, and the result is signed:
data = bus.read_i2c_block_data(0x48, 0x00, 2)
raw = (data[0] << 8) | data[1]
if raw > 0x7FFF:
raw -= 0x10000
volts = raw * 4.096 / 32768
With the bytes swapped, a small change in the low byte becomes a huge jump, which is your 900 vs 52,000. For AIN1 change the MUX bits: [0xD3, 0x83]. And 10 ms is enough at 128 SPS (one conversion is about 8 ms), so the sleep is fine.
Von English mit KI übersetzt ·
Tipp von den Inbetriebnahme-Skids: Notieren Sie während der Tests den Rohwert neben der Spannung. Wenn ein Messwert in drei Monaten falsch aussieht, erkennen Sie anhand des Diagramms sofort, ob ein Verstärkungsfehler (Gain) oder ein Sensorproblem vorliegt.
Tip from commissioning skids: while you’re testing, send the raw count next to the volts. When a reading looks wrong in three months you can tell a gain mistake from a sensor problem straight from the chart.
Von English mit KI übersetzt ·
Es war die Byte-Reihenfolge. Nachdem ich sie vertauscht habe, liegt der Bodenwert stabil bei 1.62 V. Wie Keisha vorgeschlagen hat, habe ich soil.raw neben soil.v hinzugefügt, und die Batterie an AIN1 zeigt nach der Teilerrechnung 12.7 V. Außerdem verstehe ich jetzt, was dieses Argument bedeutet, danke Aoife.
Byte order it was. Swapped them and the soil value sits at 1.62 V, steady. I added soil.raw next to soil.v like Keisha said, and the battery on AIN1 reads 12.7 V after the divider maths. Also understand now what that argument is, thanks Aoife.
- Du musst angemeldet sein, um auf dieses Thema antworten zu können.
Mitdiskutieren
Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

