Splitting ESP32 sketch into multiple threads and files

  arduino, c++, esp32, microcontroller, multithreading

I’m working on a quite complex and large sketch for my ESP32 and I’m dividing it into threads and classes, splitting everything in different files. For sake of simplicity I’m gonna show you just the idea of my project setup.

For instance, I’m using a BME280 sensor to read temperature, humidity, and pressure values. Therefore, I created an header file called bme280.h and an associated cpp file called bme280.cpp. Here’s the content of the two files.

bme280.h

#ifndef BME280_H
#define BME280_H

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

typedef struct {
  float temperature;
  float pressure;
  float humidity;
}bmeData;

class BME280_sensor {  
  public:
    BME280_sensor();
    bmeData readBmeData();

  private:
    Adafruit_BME280 bme;
};

#endif

bme280.cpp

#include "bme280.h"

BME280_sensor::BME280_sensor() {
  bool status;
  
  status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    // exit(0);
    while (1);
  }
  Serial.println("BME280 sensor correctly initialized!");
}

bmeData BME280_sensor::readBmeData() {
  bmeData bmeValues;

  bmeValues.temperature = bme.readTemperature();
  bmeValues.pressure = bme.readPressure() / 100.0F;
  bmeValues.humidity = bme.readHumidity();

  return bmeValues;
}

This is basically how I’m using every sensor.

Now, my .ino file is busy doing some other job, so I used the pthread library for creating a different thread in charge of reading sensors values. Hence, my .ino file, before doing its job, starts this thread, which I named mainThread. Here’s an example:

file.ino

#include <pthread.h>
#include "main.h"

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println("Serial initialized");

  pthread_t mainThreadRef;
  int mainValue;

  mainValue = pthread_create(&mainThreadRef, NULL, mainThread, (void*)true);

  if (mainValue) {
     Serial.println("Main thread error occured");
  }
}

void loop() {
  // Some other job
}

The main thread, instead, is implemented using a main.h file and a main.cpp file. Here’s an example:

main.h

#ifndef MAIN_H
#define MAIN_H

#include <Arduino.h>

void *mainThread();

#endif

main.cpp

#include "main.h"
#include "bme280.h"

void *mainThread(void *firstIteration) {
  BME280_sensor bme;
  
  while (1) {
    bmeData bmeValues = bme.readBmeData();
    
    Serial.println(bmeValues.temperature);
    Serial.println(bmeValues.humidity);
    Serial.println(bmeValues.pressure);
    
    delay(3000);
  }
}

Now, I wonder if this whole structure of the project is good, because I’m facing weird values reading, like temperature over 100 or pressure under 0, and some other weird stuff. To be more precise:

  1. Is it "safe" to have a thread acting as the main thread doing all the jobs?
  2. Is it good to have a different class for each sensor that I am using or does it interfere with sensor readings?

Thank you all in advance for you help!

Source: Windows Questions C++

LEAVE A COMMENT