Arduino-esp32: OLED and RTC DS3231 not working great.

Created on 20 Sep 2019  路  4Comments  路  Source: espressif/arduino-esp32

Hardware:

Board: ESP32 TTGO LoRa OLED
Core Installation version: 1.0.1-rc4
IDE name: Arduino IDE 1.8.09
Computer OS: Windows 10

Description:

I have a communication problem between my ESP device. I am using Wifi, LoRa, OLED, and RTC DS3231. Follows: The device cannot keep OLED or RTC fully operational. Either works either.

Tested:

  1. RTC LIBRARY EXAMPLE, OK
  2. OLED LIBRARY EXAMPLE, OK
  3. WIFI + LORA + RTC, OK
  4. WIFI + LORA + OLED, OK
  5. WIFI + LORA + OLED + RTC, NOT OK.

Sketch:

                         //----------------*Includes of Librarys*----------------\\

    // Load Wi-Fi library.
    #include <WiFi.h>
    // Load SPI library.
    #include <SPI.h>
    //Load LoRa library.
    #include <LoRa.h>
    // Load Wire and 3Wire library.
    #include <Wire.h> 
    // Loard RTC - Clock library .
    #include <RtcDS3231.h> // DS3231 Module -  
    // Load Json utitily library
    #include <ArduinoJson.h>
    // Load SSD1306 Display library.
    #include "SSD1306.h" 
    // Load pack images library .
   // #include "images.h"

                         //----------------*Defines of Pins usage:*----------------\\
                   /*in LoRa module*/
  #define SCK     5    // GPIO5  -- SX1276 SCK.
  #define MISO    19   // GPIO19 -- SX1276 MISnO.
  #define MOSI    27   // GPIO27 -- SX1276 MOSI.
  #define SS      18   // GPIO18 -- SX1276 CS.
  #define RST     14   // GPIO14 -- SX1276 RESET.
  #define DI0     26   // GPIO26 -- SX1276 IRQ(Interruption Requirement).
  // Band bound rate 915x10^6
  #define BAND  915E6
  // Json usage 
  #define countof(a) (sizeof(a) / sizeof(a[0]))

                    /*in Wire module*/
                    /*in RTC - Clock module*/
  RtcDS3231<TwoWire> Rtc(Wire);
                    /*in SSD1306 Display - module*/
  SSD1306 display(0x3c, 4, 15);      

                         //----------------*Defines of variables:*----------------\\

  unsigned int counter = 0;
  String rssi = "RSSI --";      // Start of display mode the RSSI.
  String packSize = "--";       // Start of PackSize values.
  String packet ;               // Create of packet String usage in LoRa events.
  String outgoing;              // Outgoing message usage in LoRa events.
  byte msgCount = 0;            // Count of outgoing messages in LoRa events.


//----------------*IMPORTANT!*----------------\\  
// When use the LoRa communication mode, each devices need to have 
// a destination and localAddress!
// The localAddress is unique for each device.
  byte localAddress = 0xBB;     // Address of this device.
  byte destination = 0xFF;      // destination to send to.
// This Address are define by programmer, so, in this case, for each new device
// will need to add in specific configuration a Local and Destination Adress for
// send mensages by LoRa Protocol. 
//----------------*IMPORTANT!*----------------\\  

  long lastSendTime = 0;        // Last send time for millis() function.
  int interval = 2000;          // interval between sends for millis() function -> The time delay approach.

  RtcDateTime compiled;         // The hour compiled.
  RtcDateTime now;              // The 'now' hour.

  String tempoAtual;            
  String tempoMarcado;          

  // The Wifi connect credentials
//  const char* ssid     = "Os Gnomos est茫o no Bosque"; // Name of network.
//  const char* password = "brancadeneve";   // Password of the network.

    const char* ssid     = "HCNAutomacao";
    const char* password = "Hcn@2019";

  // Set web server port number to 80
  WiFiServer server(80);
  IPAddress local_IP(192, 168, 1, 53);
//  IPAddress gateway(192, 168, 1, 1);
//  IPAddress subnet(255, 255, 255, 0);

  // Variable to store the HTTP request.
  String header;

  // Auxiliar variables to store the current output state.
  String output14State = "off";
  String output27State = "off";

  // Assign output variables to GPIO pins.
  const int output14 = 17;
  const int output27 = 27;

  int Hour;

  TaskHandle_t Task2; // The 2nd core running method for computing the Clock time.

// Setup or Configurations

void setup() {
                         /* ----------- OLED Display Setup ----------- */
    pinMode(16,OUTPUT);
    digitalWrite(16, LOW);  // This setup is necessary because the display needs
    delay(50);              // to come a restart mode for reset trash in memory
    digitalWrite(16, HIGH); // and begin for the operation.

    display.init(); // Display Initialize.
    display.flipScreenVertically();  // A orientation for letter printed.
    display.setFont(ArialMT_Plain_10); // The configuration of font size.  
//    logo(); // Print a LoRa logomark.
    delay(1500);
    display.clear();
                                  /* -----------  ----------- */ 

                         /* ----------- LoRa module SPI setup ----------- */ 
    SPI.begin(SCK,MISO,MOSI,SS);


    Serial.begin(115200);    // After finish configurate, Delete all Serial communication.
    while (!Serial);

    Serial.println();
    Serial.println("LoRa Sender Test");
    LoRa.setPins(SS,RST,DI0);

    if (!LoRa.begin(BAND)) {
      display.drawString(0, 0, "Starting LoRa failed!");
      display.display(); // Show in Display a drawString mesage.
      Serial.println("Starting LoRa failed!");
      while (1);
    }

    display.drawString(0, 0, "LoRa Initial success!");
    display.display(); // Show in Display a drawString mesage.
    delay(1000);
    display.clear();
                                  /* -----------  ----------- */ 

                         /* ----------- WiFi Operation setup ----------- */ 

    // Connect to Wi-Fi network with SSID and password
    Serial.print("Connecting to ");
    Serial.println(ssid);
//    if (!WiFi.config(local_IP, gateway, subnet)) {
//    Serial.println("STA Failed to configure");
//    }

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      display.clear();
      display.drawString(0, 0, "Try to starting a WiFi Connection...");
      display.display(); // Mostra o conte煤do na tela.
      Serial.print(".");
      WiFi.begin(ssid, password);
      delay(500);  // 
    }
    display.clear();
    display.drawString(1, 0, WiFi.localIP().toString());
    display.display();
    delay(2000);
    display.clear();
    // Print local IP address and start web server
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    server.begin();

     xTaskCreatePinnedToCore(
                    Task2code,   /* Task function. */
                    "Task2",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    0,           /* priority of the task */
                    &Task2,      /* Task handle to keep track of created task */
                    0);  

    Serial.print("compiled: ");
    Serial.print(__DATE__);
    Serial.println(__TIME__);

    Wire.begin(21, 13);
    Rtc.Begin();
}

void loop() {
  onReceive(LoRa.parsePacket());
}

String printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    return datestring;
}

// LoRa send mensagens commands
void sendMessage(String outgoing) {
  LoRa.beginPacket();                   // Start packet
  LoRa.write(destination);              // Add destination address
  LoRa.write(localAddress);             // Add sender address
  LoRa.write(msgCount);                 // Add message ID
  LoRa.write(outgoing.length());        // Add payload length
  LoRa.print(outgoing);                 // Add payload
  LoRa.endPacket();                     // Finish packet and send it
  msgCount++;                           // Increment message ID
}

void onReceive(int packetSize) {

  // if there's no packet, in Wifi-Mode
  if (packetSize == 0) {
      onWifi();
  } else{
  // read packet header bytes:
  int recipient = LoRa.read();          // Recipient address
  byte sender = LoRa.read();            // Sender address
  byte incomingMsgId = LoRa.read();     // Incoming msg ID
  byte incomingLength = LoRa.read();    // Incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // Check length for error
    Serial.println("error: message length does not match length");
    return;                             // Skip rest of function
  }

  // If the recipient isn't this device or broadcast,
  if (recipient != localAddress && recipient != 0xFF) {
    Serial.println("This message is not for me.");
    return;                             // Skip rest of function
  }

  // If message is for this device, or broadcast, print details:
  Serial.println("Received from: 0x" + String(sender, HEX));
  Serial.println("Sent to: 0x" + String(recipient, HEX));
  Serial.println("Message ID: " + String(incomingMsgId));
  Serial.println("Message length: " + String(incomingLength));
  Serial.println("Message: " + incoming);
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);

  display.drawString(40, 26, String(incoming)); // Display mesagens received
  display.display();
}
}

void onWifi(){
    WiFiClient client = server.available();   // Listen for incoming clients
    /*
    if(tempoAtual.equals(tempoMarcado)) {

      String status;

      if(output14State.equals("on")) {
        status = "off";
        digitalWrite(output14, LOW);
      } else {
        status = "on";
        digitalWrite(output14, HIGH);
      }

      Serial.println("GPIO 12 " + status);
      output14State = status;
      tempoMarcado = "";
      client.stop();
    }
*/
    delay(1000); // ten milisegundos


  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /14/on") >= 0) {
              Serial.println("GPIO 12 on");
              output14State = "on";
              digitalWrite(output14, HIGH);
              client.print("On LED");
            } else if (header.indexOf("GET /14/off") >= 0) {
              Serial.println("GPIO 12 off");
              output14State = "off";
              digitalWrite(output14, LOW);
              client.print("Off LED");
            } else {
              String MessageJson = header;
              MessageJson.replace("GET /", "");
              MessageJson.replace(" HTTP/1.1", "");
              MessageJson.replace("%7B", "{");
              MessageJson.replace("%22", "\"");
              MessageJson.replace("%7D", "}");

              // Read Json received by http 
              readJson(MessageJson);
              sendMessage(MessageJson);

              display.clear();
              display.drawString(1, 0, "Received and Sent");

              delay(2000); // ten milisegundos

              display.clear();
              display.drawString(1, 0, WiFi.localIP().toString());


            }
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #555555;}</style></head>");

            // Web Page Heading
            client.println("<body><h1>ESP32 Web Server</h1>");

            // Display current state, and ON/OFF buttons for GPIO 14  
            client.println("<p>GPIO 14 - State " + output14State + "</p>");
            // If the output14State is off, it displays the ON button       
            if (output14State=="off") {
              client.println("<p><a href=\"/14/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/14/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 

            // Display current state, and ON/OFF buttons for GPIO 27  
            client.println("<p>GPIO 27 - State " + output27State + "</p>");
            // If the output27State is off, it displays the ON button       
            if (output27State=="off") {
              client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
              break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    delay(1);
    //Serial.println("Client disconnected.");
    Serial.println("");
  }
}

void readJson(String MessageJson){
  StaticJsonDocument<200> doc;

  DeserializationError error = deserializeJson(doc, MessageJson);

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }

  String data_atual = doc["dateAtual"];
  String quantidade_estacao = doc["qtdEstacao"];
  String hora_inicio = doc["startHora"]; 
  String duracao_estacao = doc["duracaoEstacao"];
  String data_nao_irrigacao= doc["dataNaoIrrigacao"];
  String chuva= doc["chuva"];

  /*
  sendMessage("quantidade_estacao:" + quantidade_estacao);
  sendMessage("data_atual:" + data_atual);
  sendMessage("hora_inicio:" + hora_inicio);
  sendMessage("duracao_estacao:" + duracao_estacao);
  sendMessage("data_nao_irrigacao:" + data_nao_irrigacao);
  sendMessage("chuva:" + chuva);
  */

}

void Task2code( void * pvParameters ){
  int cont = 0;
  Serial.print("Task2 running on core ");
  Serial.println(xPortGetCoreID());

  for(;;){
    now = Rtc.GetDateTime();
    tempoAtual = printDateTime(now);
    Serial.println("Tempo Atual: " + tempoAtual);
    Serial.println("Tempo Marcado: " + tempoMarcado);
    RtcTemperature temp = Rtc.GetTemperature();
    temp.Print(Serial);
    // you may also get the temperature as a float and print it
    // Serial.print(temp.AsFloatDegC());
    Serial.println("C");
  }
}

Debug Messages:

In this Code, the OLED Display crash with message in display:  LoRa Initial success!
1. LoRa message sent by other ESP: Received
2. Command by WiFi: Working
3. RTC in other core: Working
4. OLED: Crashed

DS3231_RL.txt
CASA STATION.txt
REMOTE STATION.txt
esp8266-oled-ssd1306-master.zip

All 4 comments

@JoanPedro What value of pullup resistors are you using on SCL and SDA?

Chuck.

@JoanPedro I use a SSD1306, 3 MCP23008 Expanders, 8 24LCxx EEPROMS, a DS1307 RTCC, MMA8452 Accel, SHT25 temp/hum all on the same I2C bus. I use 3.3k pullups on the 3.3v branch and 10k on the 5v (MCP23008's) branch.

Chuck.

You do realize that Wire() is single threaded? and you can't do two different things at the same time with one piece of hardware? If I am understanding your program you are trying to display on a SSD1306 and read from a RTC using the same hardware without any synchronization between two separate tasks? Either interleave your access or use both I2C peripherals (Wire() and Wire1()).
Also, you init the SSD1306 using the Default SDA and SCL pins, then RECONFIGURE Wire() with custom pins at the bottom of your setup? How do you expect the SSD1306 to magically receive communications when you disconnect it?

Chuck.

I want apologize for the inconvenience. Beginner in this world. Thank you @stickbreaker.
Problem solved.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Buffalchill picture Buffalchill  路  60Comments

cyberman54 picture cyberman54  路  102Comments

orcema picture orcema  路  67Comments

PhilColbert picture PhilColbert  路  125Comments

dbachko picture dbachko  路  84Comments