smbus2 write_i2c_block_data: ADS1115 için "cmd" baytı nedir?
Yapay zekâ tarafından English dilinden çevrildi ·
Bahçe düğümü projesi: Pi Zero 2 W, 0x48 adresinde ADS1115, AIN0 kapasitif toprak nem sensörü, AIN1 ise bölücü üzerinden 12 V akü. Script her 5 dakikada bir ikisini de Hermetry’ye gönderiyor.Büyük kütüphaneleri kullanmadan ADS1115 ile smbus2 üzerinden doğrudan konuşmak istedim. Bir forum gönderisinden şunu kopyaladım:
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]
Çalışıyor ama sayılar saçma: hiçbir şey değişmediği halde toprak değeri yaklaşık 900 ile 52.000 arasında zıplıyor. smbus2 belgeleri ikinci argümanı cmd olarak tanımlıyor. Bu hangi komut? ADS1115 veri sayfası hiçbir yerde komuttan bahsetmiyor, yalnızca registerlardan söz ediyor. Galiba çok temel bir şeyi kaçırıyorum.
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.
Yapay zekâ tarafından English dilinden çevrildi ·
cmd, çipin tanımladığı bir kod değil mi, örneğin “dönüşümü başlat” gibi?
Isn’t cmd a code the chip defines, like “start conversion”?
Yapay zekâ tarafından English dilinden çevrildi ·
+1, bu argümanı ben de hiç anlayamadım.
+1, never understood that argument either.
Yapay zekâ tarafından English dilinden çevrildi ·
“cmd” SMBus adlandırmasıdır. Bir SMBus blok yazmada adresten sonraki ilk bayta komut baytı denir ve ADS1115 gibi register tabanlı çiplerde bu bayt register işaretçisidir. Yani ilk satırınız işaretçiyi Config registerına (0x01) yönlendirir ve buraya 0xC3, ardından 0x83 yazar. Hatta: start, 0x90, 0x01, 0xC3, 0x83, stop.0xC383 şu anlama gelir: tek bir dönüşüm başlat, AIN0’ı GND’ye karşı ölç, ±4.096 V aralığı, tek atımlı mod, 128 örnek/s. Okuma işlemi işaretçiyi 0x00 (Conversion registerı) olarak ayarlar ve iki bayt okur.Hatanız bayt sırasındadır. ADS1115 önce en anlamlı baytı gönderir ve sonuç işaretlidir:
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
Baytlar ters olduğunda, düşük bayttaki küçük bir değişim büyük bir sıçramaya dönüşür; bu da sizin 900 ile 52.000 farkınızdır. AIN1 için MUX bitlerini değiştirin: [0xD3, 0x83]. 128 SPS’de 10 ms yeterlidir (bir dönüşüm yaklaşık 8 ms sürer), dolayısıyla bekleme süresi uygundur.
“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.
Yapay zekâ tarafından English dilinden çevrildi ·
Devreye alma sırasında edindiğim bir ipucu: testleri yaparken ham sayıyı voltajın yanında da kaydedin. Üç ay sonra bir okuma yanlış göründüğünde, grafiğe bakarak kazanç (gain) hatası ile sensör sorununu hemen ayırt edebilirsiniz.
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.
Yapay zekâ tarafından English dilinden çevrildi ·
Bayt sırasıymış. Onları değiştirince toprak değeri 1.62 V’ta sabit kaldı. Keisha’nın dediği gibi soil.v yanına soil.raw ekledim ve bölücü hesabından sonra AIN1’deki akü 12.7 V gösteriyor. Ayrıca o argümanın ne olduğunu artık anladım, teşekkürler 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.
- Bu konuyu yanıtlamak için giriş yapmış olmalısınız.
Sohbete katılın
Soru sormak ve yanıtlamak, yararlı gönderileri beğenmek ve sorununuzu çözen yanıtı işaretlemek için oturum açın. Her katkı puan ve seviye kazandırır.

