How to use an ESP8266 SoftwareSerial with the LCD keypad shield

I have recently developed a project to implement in a factory, where an ESP8266 (that I programmed through my Arduino UNO) detects a machine activation and sends an HTTP request to a web server. My colleague suggested we try to add a way for the factory employees to select which product is being manufactured. My initial try was to use the Arduino LCD shield with keypad to select the product, and then send that information to the ESP. However, I'm having some troubles establishing the communication between the Arduino and the ESP. This is the code I used for the Arduino:

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

#define ESP_TX 5
#define ESP_RX 6
SoftwareSerial espSerial(ESP_RX, ESP_TX);

const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
LiquidCrystal lcd( pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7 );

const char* ssid = "ssid";
const char* password = "password";

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  espSerial.begin(9600);

  lcd.setCursor(0,0);
  lcd.print("Initializing...");
  pinMode(LED_BUILTIN, OUTPUT);
  delay(2000);
  
  // Send credentials to ESP
  digitalWrite(LED_BUILTIN, HIGH);
  espSerial.print(ssid);
  espSerial.print(",");
  espSerial.println(password);

  // Receive WiFi confirmations
  while (!espSerial.available()) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
  }
  // TODO: Write confirmation to LCD
}

void loop() {
  // TODO
}

And the ESP8266 code:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Esp.h>

const char* ssid;
const char* password;
const char *serverUrl = "http://mocmoc.pt/api/esp/shiftv2";
WiFiClient wifiClient;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  
  // Read WiFi credentials from arduino
  while (!Serial.available()) {
    digitalWrite(LED_BUILTIN, LOW); // turn LED on
    delay(1000);
    digitalWrite(LED_BUILTIN, HIGH); // turn LED off
    delay(1000);
  }
  String data = Serial.readStringUntil('\n');
  int separator = data.indexOf(',');
  ssid = data.substring(0, separator).c_str();
  password = data.substring(separator + 1).c_str();

  // Connect to WiFi
  Serial.println("Connecting to WiFi...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
  }
  Serial.println("WiFi connected");
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {
  while (Serial.available() > 0) {
    Serial.print(Serial.read());
  }
  //if (Serial.available() > 0) {
  //  String command = Serial.readStringUntil('\n');
  //  if (command.startsWith("SELECT_PRODUCT")) {
  //    selectedProduct = command.substring(command.indexOf(":") + 1);

  //    // JSON Payload
  //    String json = "{";
  //    json += "\"id\": \"" + String(machineId) + "\"";
  //    json += "}";

      // Setup HTTP request
  //    HTTPClient http;
  //    http.begin(wifiClient, serverUrl);
  //    http.addHeader("Content-Type", "application/json");

      // Setup HTTP request
  //    int httpResponseCode = http.POST(json);
  //    if (httpResponseCode > 0) {
  //      Serial.print("HTTP Response Code: ");
  //      Serial.println(httpResponseCode);
  //    } else {
  //      Serial.print("HTTP POST request failed. Error code: ");
  //      Serial.println(httpResponseCode);
  //      Serial.println(http.errorToString(httpResponseCode));
  //    }
  //  }
  //}
  //  http.end();
  //}
}

But it doesn't seem to work. I tried removing the LCD shield and Seria.print what I get from the ESP to the Serial Monitor, but all I got was a 0. Any idea what I'm doing wrong? Would you try solving this task in another way?

The rationale behind my code was based on the Arduino sending the Wifi info to the ESP, which then sends confirmation when it connects. It is simpler to program the Arduino than the ESP, so it might make it easier in the long run.

For added context, in terms of wiring, I have the Arduino 3.3V connected to the ESP vcc and EN, Arduino GND connected to ESP GND, Arduino digital pin 6 (SoftwareSerial RX) connected to ESP TX, and Arduino digital pin 5 (SoftwareSerial TX) connected to ESP RX through a voltage divider.
This is the SoftwareSerial library I am trying to use: GitHub - plerup/espsoftwareserial: Implementation of the Arduino software serial for ESP8266
And this is my ESP8266: Módulo WiFi ESP8266 ESP-01 Wireless

5 volt Arduino Tx to 3.3 volt ESP is not good. Level shift that signal.

There is a conflict on pins 5 and 6.

In my experience if you connect a voltage even a tiny bit above the ESP8266's 3V3 you will get strange problems. I found this out after carelessly calculating resistor values for a voltage divider between a ATMega4809 and an ESP8266. Search for voltage divider or any topic using serial on any 3V3 powered devices.

Which pins on the ESP8266 are you using for serial? You code seems to use the same serial port for both the serial monitor and your connection to the Uno.

having to program two microcontrollers plus the overhead of inter module communication does not appear to make the overall system simpler
I would suggest you move the whole project to an ESP32

1 Like

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