Bonjour à tous,
Pour un projet aquarium (Raspberry/home assistant)
Je rencontre des difficultés pour lire correctement les valeurs d’une sonde TDS Keyestudio V1.0 connectée à un Raspberry Pi via un convertisseur ADC Texas Instruments ADS8688.
La tension varie bien en fonction de la conductivité de l’eau, mais les valeurs lues par le Raspberry Pi ne correspondent pas à celles obtenues avec un multimètre.
Matériel utilisé :
Raspberry Pi X** (précisez le modèle, ex. Pi 4, Pi Zero, etc.)
Convertisseur ADC** : Texas Instruments ADS8688
Mode SPI** : Mode 1 (CPOL=0, CPHA=1)
Fréquence SPI** : 500 kHz
Sonde TDS** : Keyestudio V1.0
Alimentation de la sonde** : 5V
Sortie analogique attendue** : 0V à 2.3V selon la conductivité
Problèmes rencontrés :
La tension lue varie avec la salinité, mais les valeurs ne sont pas cohérentes avec celles obtenues avec un multimètre.
Les valeurs SPI brutes sont bien reçues et varient**, mais la conversion ne semble pas correcte.
Les tensions affichées par le script sont bien plus basses que celles mesurées en réel.
Tests effectués:
Changement du mode SPI
Mode 0: Aucune lecture correcte
Mode 1: Variations observées, mais écart significatif avec la réalité
Lecture brute SPI et traitement des données
Exclusion des 2 bits inutiles du registre ADC
Test de conversion sur 14 bits et 16 bits
Aucun mode ne donne une tension réaliste
*Facteur de conversion utilisé :
tension = (raw_value / 16384) * 5.0 # ADC sur 14 bits
Le facteur est-il correct ?** Dois-je appliquer un gain ADC ?
Consultation de la documentation de l’ADS8688
Lecture ADC sur 16 bits → Donne les mêmes valeurs
Vérification du facteur de conversion
Recherche d’un facteur de gain éventuel
Datasheet ADC ADS8688
Documentation sonde TDS
Documentation sonde TDS 2
Questions:
Mon facteur de conversion est-il correct ou dois-je ajuster le gain de l’ADC ?
Dois-je modifier le mode SPI ou la fréquence pour améliorer la lecture ?
Pourquoi l’ADC ne restitue pas une tension correcte malgré la variation des données SPI brutes ?
Faut-il appliquer un filtrage logiciel sur les valeurs SPI pour éviter des erreurs ?
Merci d’avance pour votre aide je suis bloqué depuis une bonne semaine
import pigpio
import time
# Initialisation du SPI (Mode 3, 500 kHz)
pi = pigpio.pi()
spi = pi.spi_open(0, 500000, 3) # SPI0, 500 kHz, Mode 3 (CPOL=1, CPHA=1)
if spi >= 0:
print("\nSPI ouvert avec succes\n")
# Lecture du registre Device ID
cmd_device_id = [0b10101100, 0x00, 0x00] # Commande pour lire le Device ID
count, response = pi.spi_xfer(spi, cmd_device_id)
print("Reponse du registre Device ID:", response)
# Configuration du CH1 en mode unipolaire 5V
cmd_config_ch1 = [0b10101100, 0x02, 0b00000110] # Config CH1
pi.spi_xfer(spi, cmd_config_ch1)
time.sleep(0.5) # Pause stabilisation
# Verification apres configuration
cmd_read_config_ch1 = [0b10101100, 0x02, 0x00] # Lire config CH1
count, response_config = pi.spi_xfer(spi, cmd_read_config_ch1)
print("Configuration CH1 apres ecriture:", response_config)
while True: # Boucle infinie avec lecture toutes les 10s
print("\n*** Nouvelle lecture SPI ***")
# Lecture de la valeur brute ADC sur CH1
cmd_read_ch1 = [0b10101100, 0x00, 0x00] # Lecture valeur CH1
count, response = pi.spi_xfer(spi, cmd_read_ch1)
# Affichage des donnees SPI brutes
print("Donnees brutes SPI (HEX) :", [hex(x) for x in response])
print("Donnees brutes SPI (BIN) :", [bin(x) for x in response])
print("Longueur du tableau recu :", len(response))
print("Tableau SPI complet :", response)
# Decomposition des octets recus
if len(response) >= 3:
print("Octet 0 :", bin(response[0]))
print("Octet 1 :", bin(response[1]))
print("Octet 2 :", bin(response[2]))
# Extraction en 14 bits (on ignore les 2 bits inutiles)
raw_value_14b = ((response[1] & 0x3F) << 8) | response[2]
print("Valeur ADC brute (14 bits) :", raw_value_14b)
# Extraction en 16 bits (verif si necessaire)
raw_value_16b = (response[1] << 8) | response[2]
print("Valeur ADC brute (16 bits) :", raw_value_16b)
# Conversion en tension (Plage 0-5V)
resolution = 16384 # Pour 14 bits
# resolution = 65536 # Pour 16 bits
tension_14b = (raw_value_14b / resolution) * 5.0
tension_16b = (raw_value_16b / 65536) * 5.0
print("Tension mesuree (14 bits) :", round(tension_14b, 4), "V")
print("Tension mesuree (16 bits) :", round(tension_16b, 4), "V")
# Compensation de temperature
temperature = 25.0 # Temperature par defaut
compensation_coeff = 1.0 + 0.02 * (temperature - 25.0)
tension_compensee = tension_14b * compensation_coeff
print("Tension compensee (T=25C) :", round(tension_compensee, 4), "V")
# Conversion en TDS (ppm) - Formule standard pour sonde TDS
tds_value = (133.42 * tension_compensee**3
- 255.86 * tension_compensee**2
+ 857.39 * tension_compensee)
print("Valeur TDS estimee :", round(tds_value, 2), "ppm")
else:
print("Erreur : Donnees SPI incorrectes")
time.sleep(10) # Pause de 10 secondes entre chaque lecture
else:
print("Erreur d'ouverture du SPI !")