smbus2 write_i2c_block_data : quel est l'octet "cmd" pour un ADS1115 ?
Traduit de English par IA ·
Projet de nœud de jardin : Pi Zero 2 W, ADS1115 à 0x48, AIN0 est une sonde d’humidité du sol capacitive et AIN1 la batterie 12 V via un diviseur de tension. Le script envoie les deux valeurs à Hermetry toutes les 5 minutes.Je voulais éviter les grosses bibliothèques et communiquer moi-même avec l’ADS1115 via smbus2. J’ai copié ceci depuis un message de forum :
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]
Ça tourne, mais les valeurs sont absurdes : la valeur du sol passe d’environ 900 à 52 000 alors que rien ne change. La documentation de smbus2 décrit le second argument comme cmd. Quelle est cette commande ? La fiche technique de l’ADS1115 ne mentionne nulle part de commandes, uniquement des registres. J’ai l’impression de passer à côté de quelque chose de basique.
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.
Traduit de English par IA ·
cmd n’est-il pas un code défini par la puce, comme « démarrer la conversion » ?
Isn’t cmd a code the chip defines, like « start conversion »?
Traduit de English par IA ·
+1, je n’ai jamais compris cet argument non plus.
+1, never understood that argument either.
Traduit de English par IA ·
« cmd » est une appellation SMBus. Dans une écriture par blocs SMBus, le premier octet après l’adresse s’appelle l’octet de commande, et pour les circuits basés sur des registres comme l’ADS1115, cet octet est le pointeur de registre. Votre première ligne place donc le pointeur sur le registre Config (0x01) et y écrit 0xC3 puis 0x83. Sur le bus : start, 0x90, 0x01, 0xC3, 0x83, stop.0xC383 signifie : lancer une conversion unique, AIN0 par rapport à GND, plage ±4,096 V, mode single-shot, 128 échantillons/s. La lecture place le pointeur sur 0x00 (registre de conversion) et lit deux octets.Votre bug vient de l’ordre des octets. L’ADS1115 envoie d’abord l’octet de poids fort, et le résultat est signé :
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
Avec les octets inversés, une petite variation dans l’octet de poids faible devient un énorme saut, ce qui explique vos 900 contre 52 000. Pour AIN1, modifiez les bits MUX : [0xD3, 0x83]. Et 10 ms suffisent à 128 SPS (une conversion dure environ 8 ms), donc la temporisation convient.
« 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.
Traduit de English par IA ·
Astuce tirée de la mise en service des skids : pendant vos tests, enregistrez la valeur brute à côté de la tension. Quand une mesure paraîtra fausse dans trois mois, vous pourrez distinguer un défaut de gain d’un problème de capteur directement sur la courbe.
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.
Traduit de English par IA ·
C’était l’ordre des octets. Après les avoir inversés, la valeur du capteur de sol se stabilise à 1.62 V. J’ai ajouté soil.raw à côté de soil.v comme l’a dit Keisha, et la batterie sur AIN1 affiche 12.7 V après le calcul du diviseur. Je comprends aussi maintenant ce que représente cet argument, merci 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.
- Vous devez être connecté pour répondre à ce sujet.
Rejoignez la discussion
Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

