Go Down

Topic: Serial Uno not sending data to ESP8266 01 (Read 682 times) previous topic - next topic

Agree8

Hi All

Could have a look on my code and explain why UNO doesn't send sensor data to ESP8266 by Serial (pin 0 and 1)? I've spent last few weeks trying to make it work, learned something but still they don't comunicate.

Both UNO and ESP while connected to my PC work ok (Arduino sends data and responds to feedback, ESP requests time, gets data and send it to ThingSpeak). So when I type what they should get in serial its ok, but when I connect one to another ThingSpeak is not updated...

The Idea:
Both UNO and ESP turn on about every 10 minutes (555 timer + relay - circut ready)
I'm sending 12 variables to ESP, It informs UNO what it already has, when it has everything or time is up it sends the data. Once a day on a hour I choose it asks ESP for NTP time, next time it's on it will get it updated. The LED pin will trigger turning off power.

Connection:
Both UNO and ESP have seperate 5V supplies (both connected to the same extension lead). Arduino gets 5V 1A, ESP 5V 500mA. ESP is plugged into a ESP-01 adapter(4 pins), so it can be powered with 5v and I have it connected to arduino serial directly (RX to TX, TX to RX).

So Far UNO:
  • Gets sensor data
  • Manages SD card (gets time from SD card and saves sensor data)
  • Reads time from RTC and updates it's time
  • Gives fedback in serial

ESP:
  • Connects to Wifi
  • Gets time from NTP Server
  • Collects data from Serial and sends data to ThingSpeak
  • Gives feedback in serial

I've tried today adding "<" and ">" To the char arrays that UNO sends but still nothing. (tutorial https://forum.arduino.cc/index.php?topic=288234.0)

On UNO the liblaries and code take over 95% storage space (below 70% dynamic memory), so ESP has to have it's own script... I tried using SoftwareSerial but it didn't help in finding the issue.

I have one UNO and a few NANO's only, and I'm not planning to buy a MEGA.

I left only two variables in to show what I mean (and not have 18 000 characters).
UNO code:
Code: [Select]


#include <DHT.h>
#include <DHT_U.h>

#include <SmoothThermistor.h>

#include <MS5611.h>
MS5611 baro;
int32_t pressure;

#include "RTClib.h"
RTC_DS1307 rtc;

#include <Wire.h>
#include <SPI.h>
#include <SD.h>

#define DHTPIN_INSIDE 3     // what digital pin we're connected to
#define DHTPIN_OUTSIDE 5      // what digital pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321


DHT dht_in(DHTPIN_INSIDE, DHTTYPE);
DHT dht_out(DHTPIN_OUTSIDE, DHTTYPE);

SmoothThermistor smoothThermistor_up(A1, ADC_SIZE_10_BIT, 10000, 10000, 3470, 25, 10);
SmoothThermistor smoothThermistor_front(A2, ADC_SIZE_10_BIT, 10000, 10000, 3470, 25, 10);
SmoothThermistor smoothThermistor_back(A3, ADC_SIZE_10_BIT, 10000, 10000, 3470, 25, 10);


float light = 0;

float temp_pressure = 0;

// SD Card IS 10

File gFile;
File timeFile;


// SERIAL
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;
unsigned char incomingData = 0;  //unsigned char


String newDate = "";
String this_day = "";
String this_time = "";

int running_time = 0;

int waitABit = 0;

boolean got_light = false;
boolean got_temp_pressure = false;

int oneSec = 0;

void setup() {
  pinMode(PD2, OUTPUT);
  Serial.begin(115200);
  rtc.begin();

  // Pin turning switching 555 therefore turning off power


  baro = MS5611();
  baro.begin();
  dht_in.begin();
  dht_out.begin();

  if (!SD.begin(10)) {
    //Serial.println("initialization failed!");
    while (1);
  }
  //Serial.println("initialization done.");


  if (SD.exists("TIME.txt")) {

    timeFile = SD.open("TIME.txt");

    newDate = timeFile.readString();
    timeFile.close();
    SD.remove("TIME.txt");
    rtc.adjust(DateTime(newDate.substring(0, 4).toInt(), newDate.substring(5, 7).toInt(), newDate.substring(8, 10).toInt(), newDate.substring(11, 13).toInt(), newDate.substring(14, 16).toInt(), newDate.substring(17).toInt()));
  }
  timeFile = SD.open("NTP.txt");
  newDate = timeFile.readString();
  timeFile.close();
  if (newDate.length() > 5) {
    //Serial.println(newDate);
    rtc.adjust(DateTime(newDate.substring(0, 4).toInt(), newDate.substring(5, 7).toInt(), newDate.substring(8, 10).toInt(), (newDate.substring(11, 13).toInt() - 1), newDate.substring(14, 16).toInt(), newDate.substring(17).toInt()));
  }
  else {
    newDate = "";
  }
}

void loop() {
  delay(5000);

  DateTime now = rtc.now();
  int minutess = now.minute();
  int hourss = now.hour();
  int minuteNow = now.minute();
  int hourNow = now.minute();
  while (((minuteNow < minutess + 1) && (hourNow == hourss)) && (hourss == 18) && (minutess < 15)) {
    Serial.write('T'); // get time
    recvWithEndMarker();
    showNewNumber();
    now = rtc.now();
    minuteNow = now.minute();
    hourNow = now.minute();
  }
  running_time = 0;
  if (incomingData == 0) {
    this_day = String(now.year()) + "-" + String(now.month()) + "-" + String(now.day()) + " ";
    newDate = this_day + this_time;
    //Serial.println(newDate);
    timeFile = SD.open("NTP.txt", FILE_WRITE);
    timeFile.print(newDate);
    timeFile.close();
    this_time = "";
  }

  //Serial.println(this_time);


  this_day = String(now.year()) + "-" + String(now.month()) + "-" + String(now.day()) + " ";
  //Serial.println(this_day);
  newDate = this_day + this_time;
  this_time = "";

  light = analogRead(A0);
  // Serial.println(light);
  // Read temperatures as Celsius (the default in DHT22)
 

  //Read thermistors (10 samples)


  // Read pressure [hPa] and temperature
  temp_pressure = baro.getTemperature() / 100;
  pressure = baro.getPressure() / 10; // Should be 100, but I want one more place to delete from substring


  gFile = SD.open("GDATA.txt", FILE_WRITE);
  // ...
  gFile.close();

  String string_light = "A" + String(light);
  String string_temp_pressure = "B" + String(temp_pressure);
// From "A" to "L"

  string_light = "<" + string_light.substring(0, 5) + ">";
  string_temp_pressure = "<" + string_temp_pressure.substring(0, 5) + ">";
// From "A" to "L"

  char array_light[string_light.length() + 1]; // char array_light[string_light.length() + 1];
  string_light.toCharArray(array_light, string_light.length() + 1); // string_light.toCharArray(array_light, string_light.length() + 1);

  char array_temp_pressure[string_temp_pressure.length() + 1];
  string_temp_pressure.toCharArray(array_temp_pressure, string_temp_pressure.length() + 1);

  Serial.println("begin");
  running_time = 0;
  running_time = millis();

  now = rtc.now();
  minutess = now.minute();
  hourss = now.minute();
  minuteNow = now.minute();
  hourNow = now.minute();

  while ((minuteNow < minutess + 1) && (hourNow == hourss)) {
    now = rtc.now();
    minuteNow = now.minute();
    hourNow = now.minute();

    if (got_light == false) {
      Serial.write(array_light);
      recvWithEndMarker();
      showNewNumber();
    }
    if (got_temp_pressure == false) {
      Serial.write(array_temp_pressure);
      recvWithEndMarker();
      showNewNumber();
    }
   
   
    if (running_time > 1000) {
      running_time = 0;
      running_time = millis();
      oneSec++;
      //Serial.println(oneSec);
    }

  }
 
  now = rtc.now();
  minutess = (int)now.minute();
  hourss = (int)now.minute();
  while ((minuteNow < minutess + 1) && (hourNow == hourss)) {
      now = rtc.now();
    minuteNow = (int)now.minute();
    hourNow = (int)now.minute();
    recvWithEndMarker();
    showNewNumber();
    if (incomingData == 'X') {
      digitalWrite(PD2, HIGH);
    }
  }
  digitalWrite(PD2, HIGH);
  delay(5000);
  digitalWrite(PD2, LOW);

}
void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  if (Serial.available() > 0) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewNumber() {
  if (newData == true) {
    incomingData = 0;           
    String chArray(receivedChars);
    incomingData = chArray.charAt(0);
    switch (incomingData) {
      case 'A':
        got_light = true;
        oneSec++;
        break;
      case 'B':
        got_temp_pressure = true;
        oneSec++;
        break;
      case 'T':
        this_time = chArray.substring(1);
        break;
    }

    newData = false;
  }
}



ESP8266  code is below (over 9000)

Agree8

ESP8266:

Code: [Select]
/*
  WriteMultipleFields

  Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds.

  Hardware: ESP8266 based boards

  !!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!!


  ThingSpeak ( https://www.thingspeak.com ) is an analytic IoT platform service that allows you to aggregate, visualize, and
  analyze live data streams in the cloud. Visit https://www.thingspeak.com to sign up for a free account and create a channel.

  Documentation for the ThingSpeak Communication Library for Arduino is in the README.md folder where the library was installed.
  See https://www.mathworks.com/help/thingspeak/index.html for the full ThingSpeak documentation.

  For licensing information, see the accompanying license file.

  Copyright 2018, The MathWorks, Inc.
*/

#include "ThingSpeak.h"
#include "secrets.h"
#include <ESP8266WiFi.h>

#include <NTPClient.h>
#include <WiFiUdp.h>

char ssid[] = SECRET_SSID;   // your network SSID (name)
char pass[] = SECRET_PASS;   // your network password
int keyIndex = 0;            // your network key Index number (needed only for WEP)
WiFiClient  client;

unsigned long myChannelNumber = SECRET_CH_ID;
const char * myWriteAPIKey = APIKEY_GREENHOUSE;
const char * myWriteAPIKey_2 = APIKEY_WEATHER;

// Initialize our values
int light = 0;

float temp_pressure = 0;
float temp_hum_inside = 0;
float temp_hum_outside = 0;
float temp_up = 0;
float temp_front = 0;
float temp_back = 0;

float heat_index_hum_inside = 0;
float heat_index_hum_outside = 0;

float hum_inside = 0;
float hum_outside = 0;

int pressure = 0;

boolean got_light = 0;
boolean got_temp_pressure = 0;
boolean got_temp_hum_inside = 0;
boolean got_temp_hum_outside = 0;
boolean got_temp_up = 0;
boolean got_temp_front = 0;
boolean got_temp_back = 0;

boolean got_heat_index_hum_inside = 0;
boolean got_heat_index_hum_outside = 0;

boolean got_hum_inside = 0;
boolean got_hum_outside = 0;

boolean got_pressure = 0;

String myStatus = "";

// SERIAL
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;
unsigned char incomingData = 0;
float dataNumber = 0;             // new for this version

WiFiUDP ntpUDP;

// You can specify the time server pool and the offset (in seconds, can be
// changed later with setTimeOffset() ). Additionaly you can specify the
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

int dataSoFar = 0;
void setup() {
  Serial.begin(115200);  // Initialize serial

  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);  // Initialize ThingSpeak
  timeClient.begin();
}
void loop() {
  // Connect or reconnect to WiFi
  if (WiFi.status() != WL_CONNECTED) {
    //Serial.print("Attempting to connect to SSID: ");
    //Serial.println(SECRET_SSID);
    while (WiFi.status() != WL_CONNECTED) {
      WiFi.begin(ssid, pass);  // Connect to WPA/WPA2 network. Change this line if using open or WEP network
      //Serial.print(".");
      delay(5000);
    }
    //Serial.println("\nConnected.");
  }

  // Example 4 - Receive a number as text and convert it to an int
  unsigned long time_now = 0;
  time_now = millis();
  while (time_now < 20000) {
    recvWithStartEndMarkers();
    showNewNumber();
    if (dataSoFar == 12) {
      time_now = 20000;
      break;
    }
    switch (incomingData) {
      case 'A':
        if (got_light == 1) {
          break;
        }
        light = (int)dataNumber;
        got_light = 1;
        Serial.write('A');
        //Serial.println(light);
        dataSoFar++;
        break;
      case 'B':
        if (got_temp_pressure == 1) {
          break;
        }
        temp_pressure = dataNumber;
        got_temp_pressure = 1;
        Serial.write('B');
        //Serial.println(temp_pressure);
        dataSoFar++;
        break;
      case 'T':
        timeClient.update();
        String string_time = timeClient.getFormattedTime();
        char time_now[string_time.length() + 1];
        string_time.toCharArray(time_now, string_time.length() + 1);
        Serial.write(time_now);
        incomingData = '0';
        break;
    }
  }
  //Serial.print("Have the data");

  // set the fields with the values
  ThingSpeak.setField(1, light);
  ThingSpeak.setField(2, temp_hum_inside);
  ThingSpeak.setField(3, temp_pressure);
  ThingSpeak.setField(4, temp_up);
  ThingSpeak.setField(5, temp_front);
  ThingSpeak.setField(6, temp_back);
  ThingSpeak.setField(7, hum_inside);
  ThingSpeak.setField(8, heat_index_hum_inside);

  // set the status
  ThingSpeak.setStatus(myStatus);

  // write to the ThingSpeak channel Grrenhouse
  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

  ThingSpeak.setField(1, light);
  ThingSpeak.setField(2, temp_hum_outside);
  ThingSpeak.setField(3, hum_outside);
  ThingSpeak.setField(4, heat_index_hum_outside);
  ThingSpeak.setField(5, pressure);

  // set the status
  ThingSpeak.setStatus(myStatus);
  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey_2);

  Serial.write('X'); // Informs arduino all has been sent
  delay(5000); // Wait 5 seconds to update the channel again
}

void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
 // if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}
void showNewNumber() {
  if (newData == true) {
    dataNumber = 0;             // new for this version
    String chArray(receivedChars);
    dataNumber = chArray.substring(1).toFloat();   // new for this version
    incomingData = chArray.charAt(0);
    newData = false;
  }
}

ieee488

I don't understand why beginners always insist on jumping into the deep end.

Write simple sketch for each where Uno sends "01234" to ESP-01.
Get that working.

.

Agree8

Hi ieee488. Thank you - in simplified version UNO sent the data and ESP received it (LED starts blinking), but then UNO doesn't get feedback from ESP.

With time the project kept growing, and there's a ton of material on the web, so I'll surely find a solution like I had in the past for SD card, 555, LED display, ASCII. Well  this time I didn't.

UNO:
Code: [Select]

// SERIAL
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;
unsigned char incomingData = 0;  //unsigned char

String dataIn = "";
int sendingTime = 0;

void setup() {
  pinMode(PD2, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  // 01234 witb begining and ending char
  String sendedString = "<01234>";

  char sendedChars[sendedString.length() + 1];
  sendedString.toCharArray(sendedChars, sendedString.length() + 1);
  Serial.write(sendedChars); // get time

  sendingTime = millis();
  while (sendingTime < 20000){
  recvWithStartEndMarkers();
  showNewNumber();
  }
  if (incomingData == 'X') {
    digitalWrite(PD2, HIGH);
    delay(100000);
  }
  digitalWrite(PD2, LOW);
sendingTime = 0;
}
void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}
void showNewNumber() {
  if (newData == true) {        // new for this version
    String chArray(receivedChars);
    dataIn = chArray;
   
    newData = false;
  }
}

ESP:
Code: [Select]
/*
  When receives data from UNO turn on the LED and send confirmation

*/

// SERIAL
const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;
unsigned char incomingData = 0;
float dataNumber = 0;             // new for this version

String dataIn = "";
int sendingTime = 0;
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);  // Initialize serial

}
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);// Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)


  //Wait for data
  recvWithStartEndMarkers();
  showNewNumber();

  if (dataIn == "01234") {
    String dataOut = "<X>";
    char sendedChars[dataOut.length() + 1];
    dataOut.toCharArray(sendedChars, dataOut.length() + 1);
digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
    digitalWrite(LED_BUILTIN, HIGH);
     delay(1000);
     digitalWrite(LED_BUILTIN, LOW);
    delay(10000);
    sendingTime = millis();

    //
    while (sendingTime < 20000){
      Serial.write(sendedChars);
    }
   sendingTime = 0;
  }
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  // if (Serial.available() > 0) {
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}
void showNewNumber() {
  if (newData == true) {        // new for this version
    String chArray(receivedChars);
    dataIn = chArray;

    newData = false;
  }
}

ieee488

#4
Nov 17, 2019, 06:07 pm Last Edit: Nov 17, 2019, 06:09 pm by ieee488
Did you replace the firmware in the ESP-01 with Arduino ESP8266 Core library ( https://github.com/esp8266/Arduino ) ?

Also, so that we are on the same page, link to the ESP8266 01 module that you have.

The ESP-01 comes loaded by default with AT firmware, so I have no idea what you are doing.

There are many modules that have ESP8266 IC. The one I have used is the ESP-01.



Agree8

Yes, in prefferences I've used the URL http://arduino.esp8266.com/stable/package_esp8266com_index.json. As the board I'm using "Generic ESP8266" (picture)

The module I'm using is ESP8266 ESP-01. I also have the 5V logic adapter and the USB to ESP8266 adapter with a switch (UART/PROG).

I expected that the problem may be that one device send data when the other doesn't listen, but using while loops to extend listening time hasn't fixed the issue.

The simpler code was able to get data from UNO, so I will still be better off than I was yesterday and I will finally setit up.

If the's no clear reason why It doesn't work I will delete any contact ESP to UNO, and make it so it only receives data. Maybe I need to flash the firmware but when I tried to do it on ESP-12 I got confused with what the software wanted :o




ieee488


Go Up