LiquidCrystal.h clashing with something on ESP8266..

Hi - I’m on a WeMos D1 R1 here and I’ve been able to work with a 16x2 LCD screen just fine for simple projects, but I found that when I combined my LCD code with a more complex project, it just crapped out random characters on the screen or refused to display anything at all (the characters came when I used an SN74HC595N, there were no characters when wired direct).

Anyway…I did a bunch of A/Bing, trying bits of code at a time with it to see what works, and I narrowed it down to a set of Millis() functions I was using to create a key engage/disengage switch.

I’ll just paste the code here - I’ve highlighted the stuff I think is conflicting somehow in red (e: ok apparently you can’t highlight stuff in red in the code tags…basically, everything that’s in arm() is suspect).

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.h>
#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

// blynk
char auth[] = "4c2e86a099324e8c851b530f98c7e61a";
char ssid[] = "INFINITUMD17B";
char pass[] = "3377073136";

// hardware
int sensor = D7;
int val = 0;

[color=red]unsigned long periodStartMillis;
unsigned long currentMillis;
const byte buttonPin1 = D2;    // Key Switch
byte currentButtonState;
byte previousButtonState;
boolean printFinalMessage = true;
unsigned long debounceStartMillis;
unsigned long debouncePeriod = 2000;
boolean debouncing = false;[/color]

int armState = false;
int alarmState = false;

int ledGrn = D8;
int ledRed = D9;
int siren = D13;
int sound = true;
int userLen = 30;
int Len = userLen;
int blinker = true;
BlynkTimer timer;
  
BLYNK_WRITE(V0)
{
int soundButton = param.asInt();
  if (soundButton == 1) {
    sound = true;
    Serial.println("Sound: On");
  } else {
    sound = false;
    Serial.println("Sound: Off");
  }
}

BLYNK_WRITE(V1)
{
  int pinValue = param.asInt();
  Len = pinValue;
  int seconds = pinValue/10;
  Serial.print("Alarm Timer Set: ");
  Serial.print(seconds);
  Serial.println("s");
}
BLYNK_WRITE(V2)
{
int armButton = param.asInt();
  if (armButton == 1) {
    armState = true;
    confirmGrn();
    Serial.println("ARMED");
  } else {
    armState = false;
    confirmRed();
    Serial.println("DISARMED");
  }
}

BLYNK_WRITE(V3)
{
int runningLights = param.asInt();
  if (runningLights == 1) {
    blinker = true;
    Serial.println("Running Lights: On");
  } else {
    blinker = false;
    Serial.println("Running Lights: Off");
  }
}

void updates() {
  Blynk.virtualWrite(V0,int(sound));
  Blynk.virtualWrite(V1,Len);
  Blynk.virtualWrite(V2,int(armState));
  Blynk.virtualWrite(V3,int(blinker));

  if (armState == false) {
    Blynk.virtualWrite(V4,"(Not Armed)");
    }

  }

  
void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
[color=red]  periodStartMillis = millis();
[/color]  armState = false;
  sound = true;
  Len = 30;
  [color=red]pinMode(buttonPin1, INPUT_PULLUP);[/color]
  pinMode(sensor, INPUT);
  pinMode(ledGrn, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(siren, OUTPUT);
  digitalWrite(ledGrn, LOW);
  digitalWrite(ledRed, LOW);
  digitalWrite(siren, LOW);
  Serial.println("\n Power On");
  timer.setInterval(2000L, updates);
  delay(2000);
  ArduinoOTA.setHostname("Fuck-Face-3000");  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA
}

void loop()
{
Blynk.run();
timer.run();
ArduinoOTA.handle();  // For OTA
arm();

if (armState == true){
  if (blinker == true){
          digitalWrite(ledGrn, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);}
          motion();
          delay(1000);
    } else {
      if (blinker == true) {
          digitalWrite(ledRed, HIGH);
          delay(50);
          digitalWrite(ledRed, LOW);}
          delay(1000);
    }
} //LOOP END


[color=red]void arm() {
      currentMillis = millis();
    previousButtonState = currentButtonState;    //save the previous button state
    currentButtonState = digitalRead(buttonPin1);  //read the current state of the input
    if (currentButtonState != previousButtonState) //if the button state has changed
    { 
      debounceStartMillis = currentMillis;  //save the time that the state change occured
      debouncing = true;  //flag that debouncing in progress
    }    //end state change check
    
    if (currentMillis - debounceStartMillis >= debouncePeriod)  //if the debounce period has elapsed
    {
      if (debouncing == true)    //debouncing taking place
      {
        if (currentButtonState == HIGH)  //if the button is currently pressed
        {
          if (armState == false) {
          debouncing = false;
          Serial.println("ARMED");
          armState = true;
          confirmGrn();
            } else {
          debouncing = false;
          Serial.println("DISARMED");
          armState = false;
          confirmRed();
            }
        }
      }
      delay(200);
    } else {
      // Do nothing
      }
  }[/color]



  void motion() {
      val = digitalRead(sensor);
      if (val == HIGH) {
      alarmState == true;
      Blynk.virtualWrite(V4,"Active");
      Blynk.setProperty(V4, "color", "#F00F00");
      Serial.println("MOTION DETECTED");
          do {
        if (sound == true) {
          beep();
          Len = Len - 1;
        } else {
          flash();
          Len = Len - 1;
          }
        } while (Len > 0);
        Len = userLen;
      } else {
        Blynk.virtualWrite(V4,"Clear");
        Blynk.setProperty(V4, "color", "#23C48E");
        alarmState == false;
        // Do nothing in LOW state
      }
      
    }


void beep() {
          digitalWrite(ledRed, HIGH);
          digitalWrite(siren, HIGH);
          delay(50);
          digitalWrite(ledRed, LOW);
          digitalWrite(siren, LOW);
          delay(50);
  }

void flash() {
          digitalWrite(ledRed, HIGH);
          delay(50);
          digitalWrite(ledRed, LOW);
          delay(50);
  }

void confirmGrn() {
  if (sound == true) {
          digitalWrite(ledGrn, HIGH);
          digitalWrite(siren, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
          digitalWrite(siren, LOW);
          delay(50);
          digitalWrite(ledGrn, HIGH);
          digitalWrite(siren, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
          digitalWrite(siren, LOW);
          delay(50);
          digitalWrite(ledGrn, HIGH);
          digitalWrite(siren, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
          digitalWrite(siren, LOW);
    } else {
          digitalWrite(ledGrn, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
          delay(50);
          digitalWrite(ledGrn, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
          delay(50);
          digitalWrite(ledGrn, HIGH);
          delay(50);
          digitalWrite(ledGrn, LOW);
      }
  }

void confirmRed() {
  if (sound == true) {
          digitalWrite(ledRed, HIGH);
          digitalWrite(siren, HIGH);
          delay(400);
          digitalWrite(ledRed, LOW);
          digitalWrite(siren, LOW);
    } else {
          digitalWrite(ledRed, HIGH);
          delay(400);
          digitalWrite(ledRed, LOW);
      }
  }

And the LCD code is just generic stuff like this:

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("test");
    lcd.setCursor(0, 1);
  lcd.print("line 2");
}

void loop() {
}

So…has anyone else had this problem on an ESP8266 or anything really? It’s very frustrating, I spent a lot of time messing around with it

e: removed foul language

e: also, I’d like to point out to the mod(s) that the images on this tutorial have gone offline some time in the past couple days: https://www.arduino.cc/en/Tutorial/LiquidCrystalDisplay

jtbennett:
e: also, I'd like to point out to the mod(s) that the images on this tutorial have gone offline some time in the past couple days: https://www.arduino.cc/en/Tutorial/LiquidCrystalDisplay

It's quite unfortunate. The issue actually affects many pages on this website. It has already been reported to Arduino here:

Hopefully it will be fixed soon.

OK - those fritzing fools need to stop diddling their filepaths around.

Regarding the LCD issue, I think I've actually fried the board somehow since it's not working on a plain Uno with nothing else attached and a super basic test code...so I suppose we can just ignore this issue :expressionless:

I would recommend you try my hd44780 library with the hd44780_pinIO class.
It has many tweaks for various processors, has more features and is faster than the bundled LiquidCrystal library.
I don't use the LiquidCrystal library anymore but I just tried it on my Wemos D1 R1 board with a LCD keypad shield.
I doesn't work, but my hd44780 library does.
In fact, I went took a look as to see what could be a difference and noticed that I have a specific tweak for the ESP8266 processors.

The hd44780 library is available in the library manager so it is easy to install, and includes lots of documentation that can be accessed through the "Documentation" sketch.
You can read more about it on the hd44780 github page: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library
I'd recommend first running the included hd44780_pinIO examples.
If you use the pins 8,9,4,5,6,7 the examples will work out the box.

The changes to use it are minimal. Change the headers and the name of the constructor used for the lcd object.

--- bill