problema con el código para el MH-Z19B [Solucionado]

Hola a todos, estoy trabajando con el MH-Z19B y tras usar un código que encontré y que el usuario que lo subió le funcionaba, a mi me ocurre todo lo contrario. Sólo he cambiado nombres de funciones, variables, etc para manejarme mejor. El código es el siguiente:

#include <SoftwareSerial.h>
#define RX 4 
#define TX 5  
int ppm;
SoftwareSerial sensor(RX, TX);


void setup() 
{
  Serial.begin(9600);
  sensor.begin(9600);
}

void loop() 
{
  ppm = leerco2();
  delay(3000);
  if (ppm > 0) {
    Serial.print("PPM: ");
    Serial.print(ppm);
    Serial.print(" \t");
    Serial.print(" \n");
}}

 int leerco2(){
  byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
  byte response[9]; 
  sensor.write(cmd,9);
  Serial.print("Comando enviado: ");
  Serial.print("0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79");
  Serial.print(" \t");
  Serial.print(" \n");
    
    //Limpiar buffer
      memset(response, 0, 9);
      int i = 0;
      while (sensor.available() == 0) 
      {
        Serial.print("Waiting for response ");
        Serial.print(i);
        Serial.println(" s");
        delay(1000);
        i++;
      }
  if (sensor.available() > 0) 
      {
        sensor.readBytes(response, 9);
      }
      
  // mostramos los valores devueltos por el sensor en hexadecimal
  
  for (int i = 0; i < 9; i++) 
  {
    Serial.print(String(response[i], HEX));
    Serial.print("   ");
  }
  Serial.println("");

  // checksum
  
  byte check = getCheckSum(response);
  if (response[8] != check) {
    Serial.println("Checksum not OK!");
    Serial.print("Received: ");
    Serial.println(response[8]);
    Serial.print("Should be: ");
    Serial.println(check);
  }
  
  // ppm
  int ppm = 256 * response[2] + response[3];
  Serial.print("PPM UART: ");
  Serial.println(ppm);

  //temp
  byte temp = response[4] - 40;
  Serial.print("Temperature? ");
  Serial.println(temp);

  /* status
  byte status = response[5];
  Serial.print("Status? ");
  Serial.println(status); 
  if (status == 0x40) {
    Serial.println("Status OK"); 
  }*/
  
  return ppm;
}

byte getCheckSum(char *packet) {
    char i;
    char checksum=0;
    for (i = 1; i < 8; i++) 
    {
      checksum += packet[i];
    }
    checksum = 0xff - checksum;
    checksum += 1;
    return checksum;
}

El memset borra el puerto serie virtual antes de leer la respuesta y queda todo el rato a la espera, por eso no sé cómo a este usuario le funcionaba. Esto es lo que muestra mi monitor serie.

04:25:03.640 → Waiting for response 842 s
04:25:04.622 → Waiting for response 843 s
04:25:05.638 → Waiting for response 844 s
04:25:06.623 → Waiting for response 845 s
04:25:07.639 → Waiting for response 846 s
04:25:08.619 → Waiting for response 847 s
04:25:09.637 → Waiting for response 848 s
04:25:10.620 → Waiting for response 849 s
04:25:11.636 → Waiting for response 850 s
04:25:12.621 → Waiting for response 851 s
04:25:13.639 → Waiting for response 852 s
04:25:14.622 → Waiting for response 853 s
04:25:15.636 → Waiting for response 854 s
04:25:16.653 → Waiting for response 855 s
04:25:17.635 → Waiting for response 856 s
04:25:18.652 → Waiting for response 857 s
04:25:19.633 → Waiting for response 858 s
04:25:20.650 → Waiting for response 859 s
04:25:21.629 → Waiting for response 860 s
04:25:22.647 → Waiting for response 861 s
04:25:23.662 → Waiting for response 862 s

Si elimino el memset el puerto serie me muestra lo mismo que en el caso anterior, pero si quito el memset y también el bucle de “esperando respuesta” me muestra lo siguiente:

04:33:05.198 → Comando enviado: 0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79
04:33:05.266 → 15 c1 ff 21 2 3 0 11 e5
04:33:05.300 → Checksum not OK!
04:33:05.334 → Received: 229
04:33:05.334 → Should be: 9
04:33:05.368 → PPM UART: 4294967073
04:33:05.368 → Temperature? 218
04:33:08.314 → PPM: -223
04:33:08.348 → Comando enviado: 0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79
04:33:08.416 → 15 c1 ff 21 2 3 0 11 e5
04:33:08.450 → Checksum not OK!
04:33:08.484 → Received: 229
04:33:08.484 → Should be: 9
04:33:08.518 → PPM UART: 4294967073
04:33:08.518 → Temperature? 218
04:33:11.471 → PPM: -223

Según la hoja de datos del sensor la respuesta del sensor debería ser algo así:

ff 86 6 ba 43 0 0 0 77

Y como se ve a mi me sale como desplazados los bytes porque el primero debe ser ff y despues 86.

El enlace al post del usuario que le funciona es esta por si os sirve:

Y la hoja de datos del fabricante esta aquí:

Mis conexiones entres sensor y arduino mega son estas:

sensor Vin → Arduino pin 5V
sensor GND → Arduino pin GND
sensor PWM → Arduino pin 9
sensor RX → Arduino pin 4
sensor TX → Arduino pin 5

Espero podáis ayudarme. Desde ya muchas gracias. Saludos.

Primero el memset no borra el puerto serie, borra los datos o mejor dicho los 9 bytes asignados para ser rellenados por una lectura desde el puerto serie.
Son cosas distintas.

Para mi tienes al reves esto

sensor RX → Arduino pin 4
sensor TX → Arduino pin 5
sensor GND → Arduino pin GND

Debe ser asi

sensor RX → Arduino pin 5 o sea TX Arduino
sensor TX → Arduino pin 4 o sea RX Arduino
sensor GND → Arduino pin GND

Los cambias fisicamente o inviertes aca

#define RX 5
#define TX 4

Hola surbyte:

Primero el memset no borra el puerto serie, borra los datos o mejor dicho los 9 bytes asignados para ser rellenados por una lectura desde el puerto serie.
Son cosas distintas.

Tomo nota.

El problemas estaba en el pin que he usado para enviar y recibir. He usado el pin 11 y 12 del mega y ha empezado a funcionar. Probé también lo que me dijiste y seguía sin funcionar.

Ahora voy a implementar las funciones de calibrado a ver si consigo hacerlo bien. Muchas gracias. Saludos.

Por dios hombre!!!!!!!!!!!
Si usas un MEGA para que usas SoftwareSerial?, si el MEGA tiene 4 puertos Serie.

Tu no dices en ningún momento que arduino estas usando, y yo supuse que era un UNO/NANO/etc de los que solo tienen un puerto serie.

Mira el MEGA lado derrecho desde Serial a Serial3

Serial3 pines 14 y 15
Serial2 pines 16 y 17
Serial1 pines 18 y 19
Serial pines 0 y 1

Disculpa surbyte por no contestar llevo días sin entrar. Tienes toda la razón, no los he usado por pereza cuando realmente es más cómodo, rápido y se ahorra código. Imagino que la lectura, escritura, etc. se hará igual....

Serial2.write()
Serial2.readBytes()

Gracias por tu ayuda siempre.

Un abrazo.