Uno/Nano I2C and RX/TX at same time

Dear all,

I am trying to have an Uno and/or a Nano controller to capture sensor data and send it with a ESP01S to a webserver.

Generally I have tested the separate components and generally they all work. The problem that I face is that I am not sure if I considered everything correctly from a communication point of view.
The ESP01S is connected to RX/TX, the arduino is serial printing at BAUD 115200, the ESP captures that and sends it further to the webserver. Conceptually all good here.

The sensors (so far I am used to simple digital or rather analog inputs) are 2 components, an MQ135 that is connected to A0 to capture analog input and a BME280 that I connected to the Arduino's SCA/SDL (saw this in some youtube video). Running just the sensors, everything works.

The problem I now face is that it seems that when the ESP is connected, it is not capturing the sensor data, it is just empty and sending therefore empty values to the webserver.
Is it possible that I am not able to run with an Uno or a Nano RX/TX and SCL/SDA at the same time? It is the first time I connected SCL/SDA and therefore lack knowledge, also could not find anything online for orientation/explanation.

Appreciate if you could give me general guidance on above!

As above understanding is the primary focus, I also have CSB/SDO pins on my BME280, not sure if I am right, but I believe that I have read somewhere that these are digital pins, could they be used instead of SCL/SDA and therefore have correct sensor data captuing while the RX/TX being occupied with the ESP?

Thanks for any advise, clarification or pointing in the right direction!

An Uno or nano can only do one thing at a time, but because it does things quickly, it can give the impression (to a human) that it is doing several things at a time.

There is no reason why I2C should interfere with Serial or vice versa. The problem is almost certainly in the program you did not post.

I2C uses interrupts and you should not try to send data using Serial from within an Interrupt Service Routine because Serial needs interrupts and they are turned off within an ISR.

...R

Thanks, Robin.

There is no reason why I2C should interfere with Serial or vice versa.

This sounds very good. Sorry for not posting the code, it is a bit of a mess at the moment as I mixed different sources and examples to my need. I will clean it up and post it later on today to have a better orientation moving forward on my case.

Not sure if I understood the interrupt part, maybe we can further elaborate once the code is posted by me.

Cheers,
Alex

Alright, here is the Arduino code, still a bit messy, sorry:

//Includes and defines for BME280
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

//Includes and define for MQ135
#define anInput     A0                        //analog feed from MQ135
#define digTrigger   2                        //digital feed from MQ135
#define co2Zero      0                        //calibrated CO2 0 level

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

unsigned long delayTime;

String postmessage = "";

float value01 = 0;
float value02 = 0;
float value03 = 0;
float value04 = 0;
float value05 = 0;


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

    pinMode(anInput,INPUT);                     //MQ135 analog feed set for input
    pinMode(digTrigger,INPUT);                  //MQ135 digital feed set for input
    
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));

    unsigned status;
    
    // default settings
    status = bme.begin(0x76);  
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    Serial.println("-- Default Test --");
    delayTime = 10000;

    Serial.println();
}


void loop() { 

  int co2now[10];                               //int array for co2 readings
  int co2raw = 0;                               //int for raw value of co2
  int co2comp = 0;                              //int for compensated co2 
  int co2ppm = 0;                               //int for calculated ppm
  int zzz = 0;                                  //int for averaging
  
  for (int x = 0;x<10;x++){                   //samplpe co2 10x over 2 seconds
    co2now[x]=analogRead(A0);
    delay(200);
    }

  for (int x = 0;x<10;x++){                     //add samples together
    zzz=zzz + co2now[x];
    }
    
  co2raw = zzz/10;                            //divide samples by 10
  co2comp = co2raw - co2Zero;                 //get compensated value

  value01 = 0;
  value02 = 0;
  value03 = 0;
  value04 = 0;
  value05 = 0;
  
  value01 = value01 + bme.readTemperature();
  value02 = value02 + (bme.readPressure() / 100.0F);
  value03 = value03 + (bme.readAltitude(SEALEVELPRESSURE_HPA));
  value04 = value04 + (bme.readHumidity());
  value05 = value05 + co2comp;

    /// Serial & PHP Communication ///
  
  postmessage = "value01=";
  //postmessage += bme.readTemperature();

  postmessage += value01;
  
  postmessage += "&value02=";
  //postmessage += "AA";

  postmessage += value02;
  
  // postmessage += bme.readPressure() / 100.0F;
  postmessage += "&value03=";
  //postmessage += bme.readAltitude(SEALEVELPRESSURE_HPA);

  postmessage += value03;
  
  postmessage += "&value04=";
  //postmessage += bme.readHumidity();

  postmessage += value04;
  
  postmessage += "&value05=";
  //postmessage += co2comp;

  postmessage += value05;
  
  // printValues();
  // Serial.print("CO2 = ");
  // Serial.print(co2comp);
  // Serial.println(" PPM");
  // Serial.println();
  Serial.println(postmessage);
  // Serial.println();
  delay(10000);

}

As described before, it captures sensor data and creates a string "postmessage", this string goes on the serial and I get the following at BAUD 115200 every 10 seconds:
BME280 test
-- Default Test --

value01=22.99&value02=984.58&value03=241.50&value04=51.90&value05=263.00
value01=22.99&value02=984.53&value03=241.89&value04=52.07&value05=261.00
value01=23.05&value02=984.53&value03=241.90&value04=51.88&value05=258.00
value01=23.03&value02=984.53&value03=241.91&value04=51.73&value05=256.00
value01=23.08&value02=984.53&value03=241.91&value04=51.84&value05=256.00
value01=23.06&value02=984.52&value03=242.03&value04=51.70&value05=256.00
value01=23.10&value02=984.56&value03=241.65&value04=52.01&value05=257.00

This string is supposed to be added to the code of the ESP for php and sent per POST to a webserver.

As above looks great, I need to read it with the ESP, the used code is (just the important reading part of the code):

void loop() {

 if (Serial.available() > 0) {

//  postmessage = Serial.read(); // read the incoming byte:
  postmessage = Serial.readString();
//  postmessage = "value01=10&value02=20&value03=30&value04=40&value05=50";
}

A simple Serial.readString(); I use this in a different project with a Mega+WiFi board and it is working. But in this project I get for some reason no good reading.

Reading Serial at BAUD 115200 for the ESP, I get:
httpRequestData: api_key=ARAYA&⸮⸮
HTTP Response code: 200
httpRequestData: api_key=ARAYA&⸮⸮
HTTP Response code: 200

The wrong-sided question marks are supposed to be the Arduino serial "postmessage", as if the BAUD is wrong but it is set everywhere to 115200.

Appreciate any feedback.

First off, you are using SPI and not I2C - so it's not surprising that you were confused by my reference to interrupts.

Second, from what you say here

But in this project I get for some reason no good reading.

Reading Serial at BAUD 115200 for the ESP, I get:
httpRequestData: api_key=ARAYA&⸮⸮

it seems that the problem is in your ESP program and not in the program you posted in Reply #3

...R

Thanks, Robin.

I need to get my head around this SPI and I2C stuff, as mentioned I am using it for the first time and apologies for the confusion.

I had in the past with the Mega+WiFi also issues with reading serial into the ESP, I suspected formats causing issues but never got really to the root cause. I think, I will start from scratch with some very basic code to see how it behaves and step up the complexity on this project. Once I have more conclusions to share, I will reply.

In case there is more feedback/guidance, be it from you Robin or other users, just let me know, anything could help steer in the right direction.

Cheers

I just tried the following.

Arduino:

String postmessage;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  postmessage = "lalala";
  Serial.println(postmessage);
  delay(3000);
}

and ESP-01S:

String postmessage;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  while (Serial.available() > 0) {
    postmessage = Serial.readString();
    }
    Serial.println(postmessage);
    delay(3000);
}

I still just get two reverse question marks. I read some forum entries which mention issues with the BAUD rate but in my case the bAUD is identical.

I don't have any experience with the ESP8266. Have you allowed for the fact that the Uno operates at 5v and the ESP8266 operates at 3.3v?

Have you tried a lower baud rate - say 9600?

...R

Yes, the voltage is not the issue, the ESP-01S is powered with 3.3V. When I create some static output with the ESP, it is showing it correctly in the serial, just the reading is garbage.

I did try also 9600 on the arduino and ESP and it didnt help, actually I think the ESP is no good to work with something else but 115200. As I have more ESPs laying around, I took another one with freshly update firmware and loaded above simple code, ending up with exactly the same behaviour - two reverse question marks from reading the serial.

For completeness, that is how I wired it, not my picture but the same wiring (GPIO0 and RST on ground only for programming mode or for reset of course):

I did not use any resistors for RX/TX. I saw people using them in other examples to protect the ESP from the Arduino's 5V on RX/TX, I will check this out and add some resistors to the wiring to see if it makes any difference.

b9m:
Yes, the voltage is not the issue, the ESP-01S is powered with 3.3V.

I was not referring to the power supply but to the connection between the 5v Tx of the Uno and the 3.3v Rx of the ESP 8266.

You should have a circuit that drops the voltage - for example a pair of resistors wired as a voltage divider.

The 3.3v Tx from the ESP8266 to the 5v Rx of the Arduino will probably work.

...R

The strange aspect of the ESP is that RX needs to be connected to RX and TX to TX. As mentioned, there are multiple wiring examples where resistors are added and examples without.

I just tried both, with resistors between RX and RX, but also then with TX and TX. Doing it on TX does not do anything, I am not able to receive the reversed question marks, I am actually not getting anything on the serial from the ESP. Adding the resistors to RX will make the reversed question marks occur again just like without the resistors. I used 1k ohm and 2.2k ohm per this example (the resistance I took from the comments of the example and the wiring is per the breadboard example):

Sorry. I've run out of ideas.

...R

No worries, thanks for looking into it, Robin!

The initial question related to the headline got answered, I think, I will open a new topic with a headline dedicated to the ESP issue as with the current headline it might not attract folks who are specialized in the ESP.

Cheers

RX to RX TX to TX applies if you want to connect the esp8266 with the USB chip on Uno (which is wired to ATmega RX to TX).
is your Uno an original with ATmega16u2 as USB chip? because clones with FTDI or CH340 usually supply 3.3 V from the USB chip which doesn't provide enough current for the esp8266

Hi Juraj, Thanks for checking this out.

The Uno is an original and that is what I am currently testing the ESP8266 with. Once I get it to work with the Uno, I also plan to give it a try with a 3rd party Nano.

Are you saying that if I want to use the Uno with ESP8266 and the "sophisticated" sensor/php code, I should do it RX to TX, and TX to RX? If so then I did not know that, thanks for highlighting that RX to RX / TX to TX is just for the USB connection / sketch upload to ESP8266.
I will check it out and report back.

Juraj, thanks a lot, it works! This is what I get with the "sophisticated" code on the Uno and on the ESP when I check my webserver database query:

ID Timestamp temp *C pressure hPa approx. alt. m humidity % co2 PPM
670 2021-02-02 13:56:14 24.07 986.70 223.44 52.13 237.00
669 2021-02-02 13:56:03 24.02 986.70 223.26 50.55 249.00
668 2021-02-02 13:55:52 23.98 986.74 223.09 50.61 270.00
667 2021-02-02 13:55:41 986.74 223.06 51.49 123.00
666 2021-02-02 13:55:30 986.74 223.06 51.49 123.00
665 2021-02-02 13:55:09
664 2021-02-02 13:54:59

Exactly what I was looking for! Many thanks.

Concluding that TX to TX and RX to RX is just for the USB connection via Uno, for the communication TX has to be connected to RX and RX to TX.

Nano 3.3 V pin can't power esp8266 with WiFi active

Thanks Juraj, 5v to 3.3v stepper are already on their way to me from China

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