Board: ESP32 TTGO LoRa OLED
Core Installation version: 1.0.1-rc4
IDE name: Arduino IDE 1.8.09
Computer OS: Windows 10
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:
//----------------*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");
}
}
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
@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.