Why does Serial2.read() break the code?

Hello,

I am making a project where I have an Arduino Mega (Elegoo MEGA 2560 R3) reading data from sensors and then sending this data over UART to an ESP32. From the ESP, the data is then sent to Influxdb (an open-source time series database). I am following a tutorial that uses a BME280 with just the ESP (not arduino) to read and send the data. I am using an arduino to read the sensors because I will be using multiple sensors and there isnt much space left on the ESP for the rest of the code.

So, on the site, they read the data from the BME sensor and store it in a variable "temperature".

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

#if defined(ESP32)
  #include <WiFiMulti.h>
  WiFiMulti wifiMulti;
  #define DEVICE "ESP32"
#elif defined(ESP8266)
  #include <ESP8266WiFiMulti.h>
  ESP8266WiFiMulti wifiMulti;
  #define DEVICE "ESP8266"
  #define WIFI_AUTH_OPEN ENC_TYPE_NONE
#endif

#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>

// WiFi AP SSID
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
// WiFi password
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
// InfluxDB v2 server url, e.g. https://eu-central-1-1.aws.cloud2.influxdata.com (Use: InfluxDB UI -> Load Data -> Client Libraries)
#define INFLUXDB_URL "REPLACE_WITH_YOUR_DATABASE_URL"
// InfluxDB v2 server or cloud API authentication token (Use: InfluxDB UI -> Load Data -> Tokens -> <select token>)
#define INFLUXDB_TOKEN "REPLACE_WITH_YOUR_TOKEN"
// InfluxDB v2 organization id (Use: InfluxDB UI -> Settings -> Profile -> <name under tile> )
#define INFLUXDB_ORG "REPLACE_WITH_YOUR_ORG"
// InfluxDB v2 bucket name (Use: InfluxDB UI -> Load Data -> Buckets)
#define INFLUXDB_BUCKET "SENSOR"
// Set timezone string according to https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
// Examples:
//  Pacific Time:   "PST8PDT"
//  Eastern:        "EST5EDT"
//  Japanesse:      "JST-9"
//  Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
#define TZ_INFO "WET0WEST,M3.5.0/1,M10.5.0"

// InfluxDB client instance with preconfigured InfluxCloud certificate
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
// InfluxDB client instance without preconfigured InfluxCloud certificate for insecure connection 
//InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN);

// Data point
Point sensorReadings("measurements");

//BME280
Adafruit_BME280 bme; // I2C

float temperature;
float humidity;
float pressure;

// Initialize BME280
void initBME(){
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void setup() {
  Serial.begin(115200);

  // Setup wifi
  WiFi.mode(WIFI_STA);
  wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to wifi");
  while (wifiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  
  //Init BME280 sensor
  initBME();
  
  // Add tags
  sensorReadings.addTag("device", DEVICE);
  sensorReadings.addTag("location", "office");
  sensorReadings.addTag("sensor", "bme280");

  // Accurate time is necessary for certificate validation and writing in batches
  // For the fastest time sync find NTP servers in your area: https://www.pool.ntp.org/zone/
  // Syncing progress and the time will be printed to Serial.
  timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");

  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
  }
}

void loop() {
  // Get latest sensor readings
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure()/100.0F;

  // Add readings as fields to point
  sensorReadings.addField("temperature", temperature);
  sensorReadings.addField("humidity", humidity);
  sensorReadings.addField("pressure", pressure);

  // Print what are we exactly writing
  Serial.print("Writing: ");
  Serial.println(client.pointToLineProtocol(sensorReadings));
  
  // Write point into buffer
  client.writePoint(sensorReadings);

  // Clear fields for next usage. Tags remain the same.
  sensorReadings.clearFields();

  // If no Wifi signal, try to reconnect it
  if (wifiMulti.run() != WL_CONNECTED) {
    Serial.println("Wifi connection lost");
  }

  // Wait 10s
  Serial.println("Wait 10s");
  delay(10000);
}

This part in particular is what I am refering too:

void loop() {
  // Get latest sensor readings
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure()/100.0F;

  // Add readings as fields to point
  sensorReadings.addField("temperature", temperature);
  sensorReadings.addField("humidity", humidity);
  sensorReadings.addField("pressure", pressure);

And the code works fine but...

Since the data is coming over the serial port, I changed the code so that the serial data is being stored in the temperature variable (Using a GY-906 sensor btw).

void loop() {

 // Get latest sensor readings
  temperature = Serial2.read();

  // Add readings as fields to point
  sensorReadings.addField("TemperatureTwo", temperature);

But when I do this, the serial monitor keeps showing me this


When the actual temperature readings are around 20C (I had the serial monitor from the arduino open to cross check the data going through).

Can someone please explain why this doesnt work? Thanks.

EDIT: Forgot to mention that when I printed Serial2.read(), the data shows up correctly on the ESP but its when I put it into a variable that it breaks.

EDIT2: Arduino Code

#include <Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

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

void loop() { 
  Serial.println(mlx.readObjectTempC());
  delay(10000);
}

please show the code for Arduino Mega - how do you send temperature value to Serial

I find that difficult to believe given the resources available on an ESP32.

with @gfvalvo on the matter of program size, but have you even initialized 'Serial2' ? at 9600bps as you have with the Mega (why so slow ? ) and how have you connected your 3.3v device to the 5v Mega ?

not to mention that you read without checking if there is anything in the buffer

temperature = Serial2.read();

which most likely there isn't.

Printing to serial converts the value to ascii characters, you likely need to convert that back to a numeric value. The values you are seeing are the individual ascii codes for numbers and a decimal point.

It says its taken 67% of program space and 12% of dynamic memory. Would adding 6 other sensors not fill the program space up?

void setup() {
  Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);

I chose 9600 because thats what the tutorials on how to send data from the arduino to esp was saying to use. I have a voltage divider circuit between the tx pin of the arduino to the rx pin of the esp. Could you explain more about how to check if there is anything in the buffer?

are you talking about esp32? - I think that adding 6 sensors will not change these numbers by more than 1-2%

checking to see if the buffer has stuff.

void fReceiveSerial_LIDAR( void * parameters  )
{
  char OneChar;
  char *str;
  str = (char *)ps_calloc(300, sizeof(char) ); // put str buffer into PSRAM
  bool BeginSentence = false;
  sSerial.reserve ( StringBufferSize300 );
  for ( ;; )
  {
    EventBits_t xbit = xEventGroupWaitBits (eg, evtReceiveSerial_LIDAR, pdTRUE, pdTRUE, portMAX_DELAY);
    if ( LIDARSerial.available() >= 1 )
    {
      while ( LIDARSerial.available() )
      {
        OneChar = LIDARSerial.read();
        if ( BeginSentence )
        {
          if ( OneChar == ‘>’)
          {
            if ( xSemaphoreTake( sema_ParseLIDAR_ReceivedSerial, xSemaphoreTicksToWait10 ) == pdTRUE )
            {
              xQueueOverwrite( xQ_LIDAR_Display_INFO, ( void * ) &sSerial );
              xEventGroupSetBits( eg, evtParseLIDAR_ReceivedSerial );
              //
            }
            BeginSentence = false;
            break;
          }
          sSerial.concat ( OneChar );
        }
        else
        {
          if ( OneChar == ‘<’ )
          {
            sSerial = “”; // clear string buffer
            BeginSentence = true; // found begining of sentence
          }
        }
      } //  while ( LIDARSerial.available() )
    } //if ( LIDARSerial.available() >= 1 )
    xSemaphoreGive( sema_ReceiveSerial_LIDAR );
  }
  vTaskDelete( NULL );
} //void fReceiveSerial_LIDAR( void * parameters  )
//////////////////////////////////////////////////////////////////////////////////////////

if it has stuff then get the stuff otherwise do something else.

This if ( LIDARSerial.available() >= 1 ) checks to thingy for stuff.

Yes, the esp. Ok, good to know. This is my first time using esp so I'm pretty clueless atm with it

Use a different partition scheme with the ESP32 for more ram.

49 57 46 54 55 is ASCII for "19.67"

Use Serial2.parseFloat() instead of Serial2.read() to read your numbers instead of individual characters.

Perfect! That fixed. Thank you and everyone for helping me.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.