Skip to content

Example for ESP32 #2

@jeroenvermeulen

Description

@jeroenvermeulen

Hi @Jaron0211 ,

After testing with your code, I have written my own from scratch.
My checksum validation works.
As far as I could find only the first chars are always the same: 0x42 0x4D.
I hope my code can help you.

Update: This code is tested on multiple modules.

#include <Arduino.h>

// Configuration for UART and sensor communication
// ESP32
const uint8_t uartPortNr = 0;  // Hardware UART port number, 0 = default hardware serial
const int8_t sensorRxPin = -1; // -1 = Use default RX pin for the hardware UART, this is GPIO20 on ESP32-C3, GPIO3 on NodeMCU-32S
const int8_t sensorTxPin = -1; // -1 = Use default TX pin for the hardware UART, this is GPIO21 on ESP32-C3, GPIO1 on NodeMCU-32S
// ESP-12E, Wemos D1 mini
//const int8_t sensorRxPin = 13; // D7
//const int8_t sensorTxPin = 15; // D8
// ESP-01
//const int8_t sensorRxPin = 0; // GPIO0
//const int8_t sensorTxPin = 2; // GPIO2
// Arduino Nano
//const int8_t sensorRxPin = 4; // GPIO0
//const int8_t sensorTxPin = 5; // GPIO2
// other board?
//const int8_t sensorRxPin = 17;
//const int8_t sensorTxPin = 16;

// Define the frame for packets
const uint8_t frameHeader[2] = {0x42, 0x4D};
const size_t frameHeaderLen = sizeof(frameHeader);  // Automatically determine header length
const int frameLength = 16;

// Global variables
static unsigned long lastCheck = 0; // Timestamp for checking sensor data periodically
#ifdef ESP32
HardwareSerial *sensorSerial = nullptr; // Pointer to the sensor serial interface
#else
#include <SoftwareSerial.h>
SoftwareSerial *sensorSerial = nullptr; // Pointer to the sensor serial interface
#endif
uint8_t buffer[16] = {0}; // Buffer for storing sensor data, initialized all 0.

void setup() {  
  // Initialize Serial (USB) for debugging
  Serial.begin(9600);
  // Short delay to allow Serial monitor to initialize
  delay(500);
  Serial.println("\nInitializing...");

  // Initialize sensor UART communication
  #ifdef ESP32
    sensorSerial = new HardwareSerial(uartPortNr);
    sensorSerial->begin(9600, SERIAL_8N1, sensorRxPin, sensorTxPin);
  #else
    sensorSerial = new SoftwareSerial(sensorRxPin, sensorTxPin);
    sensorSerial->begin(9600);
  #endif

  // Allow some time for sensor UART initialization
  delay(100);
  if (!sensorSerial) {
    Serial.println("Error: sensor serial port not initialized.");
    return;
  }
  Serial.println("Setup done.");
}

// Function to check if the received bytes match the frame header
bool isFrameHeaderMatched() {
  for (size_t i = 0; i < frameHeaderLen; i++) {
    if (buffer[i] != frameHeader[i]) return false;
  }
  return true;
}

// Function to print a buffer as hexadecimal values
void serialHex(uint8_t* buffer, int length) {
  for (int i = 0; i < length; i++) {
    char hexStr[4]; // Space for "FF " and null terminator
    sprintf(hexStr, "%02X ", buffer[i]);
    Serial.print(hexStr);
  }
}

// Function to calculate the checksum of a sensor data buffer
int calcChecksum(uint8_t* buffer)
{
  uint8_t sum = 0;
  for (int i = 0; i < 15; i++) {
    sum += buffer[i];
  }
  return sum;
}

void loop() {
  // Limit checking to every 10 milliseconds to prevent unnecessary CPU usage
  if (millis() - lastCheck < 10) return;
  lastCheck = millis();

  // Safety check
  if (!sensorSerial || sensorSerial->available() <= 0) return;

  // Shift buffer left
  for (size_t i = 0; i < frameHeaderLen - 1; i++) {
    buffer[i] = buffer[i + 1];
  }
  // Read byte from the sensor serial port
  buffer[frameHeaderLen - 1] = sensorSerial->read();

  // Check if frame header matches
  if (!isFrameHeaderMatched()) return;

  // Read the remaining bytes
  int remaining = frameLength - frameHeaderLen;
  if (sensorSerial->readBytes(&buffer[frameHeaderLen], remaining) != remaining) {
    Serial.println("ERROR: Incomplete data received.");
    return;
  }

  // Print received data in hex format
  serialHex(buffer, frameLength);

  // Validate checksum
  if (calcChecksum(buffer) != buffer[15]) {
    Serial.println("ERROR: Checksum mismatch.");
    return;
  }

  // Extract CO2 concentration in PPM from buffer
  int ppm = (buffer[6] << 8) | buffer[7];
  Serial.print("- CO2: ");
  Serial.print(ppm);
  Serial.println(" ppm");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions