Hay una biblioteca Arduino para el HIH-6130 que tiene exactamente el mismo protocolo I2C que el sensor que estoy usando, que es el HIH-6120. Estoy usando las mismas dos líneas de código para decirle al sensor que tome una lectura:
Wire.beginTransmission(0x27);
ret = Wire.endTransmission();
ret es 2, lo que significa que el maestro recibió NACK al transmitir la dirección. Mirando esto en mi alcance analógico, parece que el sensor intenta dejar que SDA aumente a 1, pero llega tarde y es demasiado débil: (alrededor de 10us por div, 2v por div, sincronización al caer SDA) A retrasado por B da
(1us por div) Las resistencias pullup son 2k. La dirección del sensor es 0x27 según HP. La frecuencia de reloj mínima es de 100 KHz, que es lo que está dando Arduino.
¿Qué diablos está mal?
Parece que está ACK bien para mí, pero tal vez o el código lo está interpretando mal.
Veo el 0x27 (datos bloqueados en el borde ascendente del reloj), y luego el bit de lectura/escritura es 0, lo que significa que está escribiendo, luego el esclavo conduce SDA bajo para indicar un ACK. Puede ver justo cuando sucede que hay un pequeño paso hacia abajo exactamente a 0 voltios.
Luego, en el flanco descendente del reloj, el esclavo libera la línea SDA (como debería) para que la SDA suba, luego el maestro toma el control del bus y reduce la línea SDA. Es por eso que ves esa señal estrecha.
Entonces se ve bien. ¿De alguna manera el HW lo está interpretando mal o su comprensión de la API podría ser incorrecta?
Vea mi comentario anterior: la transacción en sí se ve bien.
Sin embargo, todo lo que hace su código es enviar la dirección y luego enviar inmediatamente un STOP. En realidad no estás leyendo nada. Esta primera lectura es solo un comando de activación ficticio (gracias, Janka).
De acuerdo con la hoja de datos , luego debe enviar la dirección en modo LEER y luego leer dos bytes si solo desea humedad, o cuatro bytes si desea humedad más temperatura. Entonces envías una parada.
Creo que el código debe parecerse más a esto:
Wire.beginTransmission(0x27); // write to wake-up
Wire.endTransmission(); // ignore this
delay(100);
Wire.begin(); // optional for read
Wire.requestFrom(0x27, 4); // request 4 bytes from slave device
while (Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
ret = Wire.endTransmission();
Si este código se estropea (es decir, si todavía ve NAK donde no hay ninguno), tal vez haya algo sospechoso con la biblioteca.
adam lorenzo