Mientras trabajaba en un circuito para registrar el dióxido de carbono con un sensor de CO2 K30 usando un escudo de registro de datos de Adafruit , me encontré con un problema. La dirección I2C del RTC en el escudo tiene una colisión con la dirección del sensor de CO2. La dirección del RTC está integrada en el silicio y no se puede cambiar , pero la dirección del sensor K30 es mutable . De acuerdo con la guía I2C ( consulte el PDF en I2C/I2C_comm_guide , ¡advertencia en PDF comprimido!), la dirección I2C del sensor puede tener cualquier valor:
0x00 a 0x7F
Esto parece ser un problema común. He encontrado varios hilos (ver a , b , c , d , e , f ) que han intentado resolver este desafío. La mayoría fracasa con los resultados positivos o sugiere usar una interfaz diferente. SIN EMBARGO, según la hoja de datos, debería ser posible piratear este cambio en la EEPROM.
0x7F
: según la hoja de datos, debería poder llamar a todos los sensores K30 usando esta dirección, sin embargo, no pude hacer que funcionara en la práctica cuando estaba en el mismo circuito que el RTC.Estoy ejecutando un clon de Arduino Uno conectando el I2C a A4 y A5. Las líneas I2C tienen pullups de 2.2K. El K30 está funcionando a ~9V.
Al ejecutar el código Arduino proporcionado por el fabricante, puedo leer la respuesta del sensor y tiene sentido.
#include <Wire.h>
byte CheckSum(byte * buf, byte count) {
byte sum=0;
while (count>0) {
sum += *buf;
buf++;
count--;
}
return sum;
}
void setup() {
Serial.begin(9600);
Wire.begin();
delay(1000);
byte changebuf[4] = {0x31, 0x00, 0x69, 0x00};
changebuf[3] = CheckSum(changebuf, 3);
Wire.beginTransmission(0x68<<1);
for (size_t i = 0; i<sizeof(changebuf); i++) {
Wire.write(changebuf[i]);
}
Wire.endTransmission();
}
void loop() {}
El mensaje 0xD0, 0x31, 0x00, 0x69, 0x9A
es Los bytes son:
0x68
)Estos valores se basan en la hoja de datos.
Después de ejecutar esto, enciendo y enciendo el dispositivo para que los valores de EEPROM se propaguen a la RAM según la hoja de datos.
Después de ejecutar el código anterior, la dirección no cambia. El dispositivo sigue respondiendo a la dirección predeterminada original 0x68
y no responde a la nueva dirección 0x69
.
¿Por qué está fallando mi intento de ordenar a la EEPROM del K30 que cambie el valor asociado con la dirección I2C del dispositivo? ¿Hay algún problema con la secuencia de bytes que envío?
#include <Wire.h>
byte CheckSum(byte * buf, byte count) {
byte sum=0;
while (count>0) {
sum += *buf;
buf++;
count--;
}
return sum;
}
void setup() {
Serial.begin(9600);
Wire.begin();
delay(1000);
byte changebuf[5] = {0x31, 0x00, 0x00, 0x69, 0x00};
changebuf[4] = CheckSum(changebuf, 4);
Wire.beginTransmission(0x68);
for (size_t i = 0; i<sizeof(changebuf); i++) {
Wire.write(changebuf[i]);
}
Wire.endTransmission();
}
void loop() {}
La dirección de la eeprom es de dos bytes. Usted solo proporcionó uno. La dirección de eeprom que desea es 0x00 0x00
Una cosa, si la dirección predeterminada era 0x68, desplazada por uno es 0xd0, no 0x69.
Sensor de CO2 K30 que cambia la dirección predeterminada de I2C. La referencia con la que estoy trabajando es la guía de comunicaciones I2C 2.15 del sitio Gaslab.com. http://co2meters.com/Documentation/Other/SenseAirCommGuide.zip El ZIP tiene manuales para la operación de UART e I2C. El final de la guía I2C tiene ejemplos de sintaxis.
Suponiendo que está leyendo con éxito la medición de CO2 desde la ubicación de RAM del sensor 0x08, entonces sabemos que tiene I2C operativo. También puede leer la ubicación de RAM 0x20 y la dirección EEPPROM 0x0 para la dirección actual, que debería ser 0x68. Escriba la ubicación de RAM 0x20 en su dirección deseada, verifique que la suma de verificación sea correcta para el mensaje, recuerde no incluir el byte de dirección I2C. ver 9.0 Al cambiar la dirección base, lo que muchos pasan por alto es enviar el comando para escribir RAM en EEPROM antes de apagar y encender el sensor. Use el registro de comando especial SCR 0x60 para escribir RAM en EEPROM, vea 8.7.
El método alternativo que uso es escribir EEPROM directamente. Cambie el comando de escribir RAM a escribir EEPROM. Escriba la dirección 0 de la EEPROM en la dirección deseada y luego apague y encienda.
VBR
0x3_
. Resulta que me faltaba un 0x00
byte en mi mensaje original. Al final del OP, publiqué una versión corregida del código simple para realizar esta tarea para futuros usuarios.
WesH
0xD0, 0x31, 0x00, 0x00, 0x69, 0x9A
hizo el truco. Tenga en cuenta que utilicé la dirección original de0x68
sin cambio de bits. Agregaré el código corregido al OP.