Go Down

Topic: Display shows ▇OoOo_ ? (Read 1 time) previous topic - next topic

BitSeeker

May 23, 2020, 05:00 pm Last Edit: May 25, 2020, 04:22 pm by BitSeeker
I have set up a project on a breadboard using an ESP8266 and  one of those two row blue 1602 Arduino LCD displays without I2C daughterboard. The code on the back says RG1602A v2.

Initially I used the built the project on a Uno board using the LCD connections diagram here:

https://www.arduino.cc/en/uploads/Tutorial/LCD_Base_bb_Fritz.png

I then transferred this to the ESP8266, using the same pins as shown in the second wiring diagram for my NodeMCUv 3 board here under the heading "Interface LCD with ESP12 without using Shift Register":

https://circuitdigest.com/microcontroller-projects/interfacing-lcd-with-nodemcu

I stuck with using a fixed resistor instead of using two potentiometers.

I also have connected a DHT11 temperature/humidity sensor with sensing pin connected to D4(GPIO0) and a button on D4 (GPIO2). The project code runs fine, but after a few minutes, the display suddenly stops and displays OoOo preceded by a single character block and followed by a flashing cursor. The project does use some timing using millis(), but the problem was already happening before I added that. Otherwise ist a display, sensor and button. I am using the Adafruit DHT library as its the only one that I have found to work with the ESP8266 so far. I suspect that its a problem with the display unit itself.

Has anyone seen this or can suggest what the problem may be?
I will post code if required.

bperrybap

#1
May 23, 2020, 08:55 pm Last Edit: May 23, 2020, 08:56 pm by bperrybap
The page you linked to describes two different ways to control the LCD, pins vs a 595 shift register.
Which way did you use?
If the 595, the 595 is very subject to voltages and clock signal glitches which can cause the LCD and the MCU to lose sync which will corrupt the display.
What can help for that is to add a bit of decoupling between power and ground (like a .1uf cap) very close to the 595 chip like directly at pins 8 and 16 of the chip.


If you wired up things like the photo with the long loopy power & ground signal paths, you could have ground bounce issues.
This could cause the LCD to see the incorrect signal levels which will also cause the MCU and the LCD to lose sync which will corrupt the display.
I have seen that happen when wiring things using the two rails as shown in those figures.
I would wire the power and ground signals from the ESP board directly to the same power rails and on the same side of the rail to ensure shorter wire lengths for the power signals rather than using the other rails and runing wires between them.
You should be able to move things around to be able to plug the ESP module into the boardboard.

--- bill

BitSeeker

#2
May 23, 2020, 10:51 pm Last Edit: May 23, 2020, 10:55 pm by BitSeeker
Sorry, yes it does describe both methods. To clarify, I am using the first method with the 6x GPIO pins and separate external components and wiring. There is no 595 shift register. However, since I will be needing more GPIO pins for my project, I will be either getting a display with the necessary shift register built-in, or a PCF8574 add on board to my existing display. Given the price difference, it is almost not worth bothering with the add on board.

However, as mentioned my project is on a breadboard at this stage, the display is running at 3.3V and the NodeMCU board is plugged into the breadboard. However, the display does have maybe 8in of ribbon cable attached. I soldered a row of Dupont connectors on the end so that i could plug it into the breadboard.  What seems odd though is that its always the same pattern ▇OoOo_ rather than something random. However, I do have another new display I might be able to use and eliminate the ribbon cable altogether.




bperrybap

Can you post a photo of what you are actually using/running.
And the code you are running?

--- bill

Paul__B

OK, so the code running is not the example code from that "tutorial", but your own.

Did you by any chance attempt - unwisely - to use a "String" (capital "S") variable or function of any sort?

Interesting but apparently not fatal if you managed to follow the theme if not the exact form of the Fritzing diagram, foul-up in the table:


BitSeeker

#5
May 24, 2020, 05:46 pm Last Edit: May 24, 2020, 06:10 pm by BitSeeker
Attached is a photo of my project breadboard. Code shown below.

OK, so the code running is not the example code from that "tutorial", but your own.
Correct. I referenced the drawing to determine how to connect the LCD without the I2C adapater/shift register IC. Code for reading the sensor and writing to the LCD is based on the online examples but modified accordingly to suit the pins being used and the LCD output desired. I have also added an fan "override" button and experimented (unsuccessfully so far) with using PWM to control fan speed.

Did you by any chance attempt - unwisely - to use a "String" (capital "S") variable or function of any sort?
Not explicitly in my code and I don't see any String variables used in the LiquidrCrystal or Adafruit DHT sensor library, although LiquidCrystal uses std::string (lower case "s").

Code: [Select]
#include <LiquidCrystal.h>

#ifdef __AVR__
  #include "dht11.h"
  #define DHT11PIN 13
  dht11 dhtSensor;
  LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#endif

#if defined(ESP32) || defined(ESP8266)
  // Using Adafruit DHT library
  #include <DHT.h>
  #define DHT11PIN 0
  DHT dhtSensor(DHT11PIN, DHT11);
  #define FANPIN 16
//  #define FANSPEEDPIN A0
  #define FANOVERRIDE 2
  LiquidCrystal lcd(5, 4, 14, 12, 13, 15);
#endif

//uint8_t pos = 0;
  bool turnFanOn = false;
  bool fanOverride = false;
  int fanSpeed = 0;
  uint16_t fanOnInterval= 60; // Seconds (1 - 32000)
  unsigned long fanTimeout = 0;

void setup()
{
  Serial.begin(115200);
#ifdef ESP8266
  dhtSensor.begin();
#endif  
  pinMode(FANPIN, OUTPUT);
  digitalWrite(FANPIN, LOW);
  pinMode(FANOVERRIDE, INPUT_PULLUP);
//  analogWriteFreq(1000);
  lcd.begin(16, 2);

}


void loop()
{
  Serial.println();

#ifdef __AVR__
  int chk = dhtSensor.read(DHT11PIN);
  float temperature = (float)dhtSensor.temperature;
  float humidity = (float)dhtSensor.humidity;
#endif

#if defined(ESP32) || defined(ESP8266)
  float temperature = dhtSensor.readTemperature();
  float humidity = dhtSensor.readHumidity();
#endif

  outputSerial(temperature, humidity);

/*
  lcd.setCursor(0,0);
  lcd.print("Hello, world!");
  if (pos>0) lcd.setCursor(pos-1,1);
  lcd.print(" ");
  lcd.setCursor(pos,1);
  lcd.print(">");
  if (pos==0) lcd.setCursor(15,1);
  lcd.print(" ");
  pos<15 ? pos += 1 : pos = 0;
*/

  updateDisplay(temperature, humidity);

  // Turn fan on/off
//  fanSpeed = analogRead(FANSPEEDPIN);
//  analogWriteRange(fanSpeed);
  turnFanOn ? digitalWrite(FANPIN, HIGH) : digitalWrite(FANPIN, LOW);
//  turnFanOn ? analogWrite(FANPIN, HIGH) : analogWrite(FANPIN, LOW);

Serial.print(F("Fan override pin: "));
Serial.println(digitalRead(FANOVERRIDE));


  // Fan Override
  if (digitalRead(FANOVERRIDE)==LOW && !fanOverride) {
    fanOverride = true;
    fanTimeout = millis() + fanOnInterval * 1000;
  }
  if (fanOverride && fanTimeout<millis()){
    fanOverride = false;
    fanTimeout = 0;
  }

  delay(2000);

}


void outputSerial(float temp, float humid){
  Serial.print("Temp (°C): ");
  Serial.print(temp, 2);
  Serial.print("\t");
  Serial.print("Humidity (%): ");
  Serial.print(humid, 2);
  Serial.print("\t");
  Serial.print("Fan status: ");
  Serial.print(turnFanOn);
  Serial.print("\t");
//  Serial.print("Fan speed: ");
//  Serial.print(fanSpeed);
//  Serial.print("\t");
  Serial.print("Fan override: ");
  Serial.print(fanOverride);
  Serial.println();
}


void updateDisplay(float temp, float humid){

  // Header
  lcd.setCursor(0,0);
  lcd.print("Tmp | Hum | Fan");
  
  //Temperature
  lcd.setCursor(0,1);
  lcd.print(temp,0);
  lcd.print((char)223);
  
  lcd.setCursor(4,1);
  lcd.print("|");

  // Humidity
  lcd.setCursor(6,1);
  lcd.print(humid,0);
  lcd.print("%");

  lcd.setCursor(10,1);
  lcd.print("|");

  // Fan status
  lcd.setCursor(12,1);
  // Update fan status
  turnFanOn = fanOn(humid);
  turnFanOn ? lcd.print("ON ") : lcd.print("OFF");
}


bool fanOn(float humid){
  if (fanOverride) return true;
  if (humid>50) return true;
  return false;
}

Paul__B

#6
May 24, 2020, 11:34 pm Last Edit: May 25, 2020, 01:20 am by Paul__B Reason: Image added - was pressed for time earlier!


Not explicitly in my code and I don't see any String variables used in the LiquidrCrystal or Adafruit DHT sensor library, although
OK, I cannot see any so that is not the problem.

The use of "String"s is a common cause of a (fairly) repeatable crash after a period of operation.  It is presumably significant that you get the same error display each time.

bperrybap

#7
May 25, 2020, 01:02 am Last Edit: May 25, 2020, 01:03 am by bperrybap
First, not that it is related to this issue, but I'm curious why you would use raw GPIO bit numbers rather than the Dn symbol names that match up with the labels on the board?
Seems odd (and a bit painful) to add a bit of extra work and unnecessary confusion to have to constantly do the mappings.

That code and what you have wired up that you have now shown us is VERY different from what you said you had wired up and what you were doing.
You never mentioned controlling a fan and that isn't part of the circuits shown on the page you linked to.
Details really matter, and this difference is a very big detail.


In the photo I see a what looks like a red wire hooked up to Arduino digital pin 0 (D0 on the PCB), which in the Wemos variant is mapped to GPIO 16 (which is the number your code is using for FANPIN).
and the red wire may also be going through a resistor to the 4 pin component (hard to tell in the photo).

Lets start over.
Can you provide more information about what you are really doing, a full schematic of what you have wired up,  the exact code that you are running that is having the issue, and if you have some insight as to when the issue is occurring.

--- bill




BitSeeker

#8
May 25, 2020, 11:47 am Last Edit: May 25, 2020, 05:38 pm by BitSeeker
My apologies, it seems I confused things with my opening post. I initially wired the Uno using this diagram:

https://www.arduino.cc/en/uploads/Tutorial/LCD_Base_bb_Fritz.png

I then adapted that wiring to the ESP8266 using the diagram under the heading"Interface LCD with ESP12 without using Shift Register". It is almost identical except that the latter has two potentiometers.

https://circuitdigest.com/microcontroller-projects/interfacing-lcd-with-nodemcu

I only used one and a fixed resistor as per the Uno drawing, but adapted to the ESP8266 using the pins shown in the NodeMCU drawing. I have now corrected my first post.

Using GPIO references seems to be the only way to address the pins. I did initially try using the D references (e.g. D0, D1, D2, etc) but this would not compile:

Code: [Select]
'D4' was not declared in this scope
This is why I used the GPIO numbers instead. I am using the generic ESP8266 board profile.

The 4-pin component that the red wire from GPIO16 runs from goes to an opto-coupler. The two wires on the opposite side connect to the fan controller board. That aspect of the project was added since the first post was created. I had intended to draw up a circuit diagram for my own reference anyway, but will be adding an I2C module to reduce the number of required pins. Nevertheless, I attach a drawing as requested. Please not that the second potentiometer on the breadboard connected to A0 can be ignored for now. The code has been commented out and the link to the wiper disconnected.

bperrybap

thank you, that clears up lots of things.

Using GPIO references seems to be the only way to address the pins. I did initially try using the D references (e.g. D0, D1, D2, etc) but this would not compile:

Code: [Select]
'D4' was not declared in this scope
This is why I used the GPIO numbers instead. I am using the generic ESP8266 board profile.
You should be able to use the "LOLIN(WEMOS)...." boards.
They have the same pin mapping as the board you have.

I'm assuming this issue happens while things are just sitting there and with no fan control happening or even any fans wired up?

I have seen the exact same display corruption you are seeing before.
I can't remember what was causing it.
Usually that kind of stuff happens when there are voltage issues, or signal noise/corruption issues.

It could also be that that processor has crashed or watchdog timed out.
Does the display ever change from the pattern you see?
Are you still seeing serial messages after the display corrupts?

Also, if you are not aware gpio pins 15, 2, and 0 are special.
They control how the ESP module boots. You have be careful if you use them.
You can google around for things like "esp8266 special pins" and get more information.
Here is a note from one my projects that I did to remind myself of the issues:
Code: [Select]
* Note:
 * GPIO2 is used to control the built in LED.
 * It is recommended to avoid using GPIO0, GPIO2, & GPIO15 for inputs (see below)
 * GPIO0, GPIO2, and GPIO15 are special inputs used at reset and power up.
 * They control the boot mode:
 *  GPIO15    GPIO0    GPIO2    MODE       Description
 *    L         L        H      UART    Download Code from Uart
 *    L         H        H      FLASH   Boot from SPI flash (normal)
 *    H         x        x      SDIO    Boot from SD card
 *
 * Programing flash using uart0 requires a boot mode of "boot from uart0"
 * with boot_sel=b001, that is, it must make sure
 * GPIO15=0, GPIO0=0, and GPIO2=1 during reset
 * Because of this, GPIO15 has an external pulldown.
 * This makes these GPIO pins unsuitable for simple grounding switches
 * especially when switches can be pressed at powerup to set modes.
 * GPIO15 and GPIO0 do appear to work correctly after boot and GPIO0 does
 * not appear to have a pull down on it.
 * more docs here:
 * http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html
 * https://github.com/CHERTS/esp8266-devkit/tree/master/Espressif/docs/ESP8266



--- bill




BitSeeker

#10
May 25, 2020, 08:33 pm Last Edit: May 25, 2020, 08:45 pm by BitSeeker
thank you, that clears up lots of things.
You should be able to use the "LOLIN(WEMOS)...." boards.
They have the same pin mapping as the board you have.
Ah, yes, selecting one of the named Wemos boards does indeed allow using 'D' designations for the pins. I wonder whether there is a way to detect when the '"Generic" profile is selected and engage a map, i.e.:

Code: [Select]
#ifdef __GENERIC__
#define D2 GPIO4
....
#endif


I'm assuming this issue happens while things are just sitting there and with no fan control happening or even any fans wired up?

I have seen the exact same display corruption you are seeing before.
I can't remember what was causing it.
Usually that kind of stuff happens when there are voltage issues, or signal noise/corruption issues.
Yes, it happens while the setup is just sitting there. I am at the present using a 40W lightbulb instead of the 45W fan, but even with the bulb off (which it will be by default unless I breathe into the sensor) it will just display that pattern after a period of time with no intervention. The controller board and bulb is at least 1.5m away from the project breadboard.

It could also be that that processor has crashed or watchdog timed out.
Does the display ever change from the pattern you see?
Are you still seeing serial messages after the display corrupts?
That was my first thought, but, output is still being generated to the serial port and scrolling up the terminal window when the display corrupts which happens maybe 2 or 3 minutes after boot-up. The pattern does not seem to change once it gets displayed although I'm not sure whether I have left it long enough for another interval to occur. It did generate another random pattern a couple of times, but I was prodding things at the time.

Also, if you are not aware gpio pins 15, 2, and 0 are special.
They control how the ESP module boots. You have be careful if you use them.
You can google around for things like "esp8266 special pins" and get more information.
No, I wasn't aware of that so thank you for your project notes. I had some reservations about using  16, 2 and 0 due to their descriptions but didn't find any specific information about them. As it is, I ran out of pins and ended up having to use them. I did find certain things didn't work on specific pins so it was a bit of trial and error to find an arrangement that worked. Your search phrase yeilds a number of results so I will do my research.

I'm curious about pin 15 since I thought that the upload was via RX0/TX0 rather than TX2/TX2. However, pin 15 (GPIO15) is TX so if the ESP module happens to transmit something on that pin (perhaps a heartbeat between the ESP module and the UART on the dev board), then I can see how the display might get upset since as per the tutorial it uses that pin for data.

I can't do anything on S2 and S3 (GPIO 9 and 10) as connecting anything stops the board from booting up so GPIO pins are in rather short supply. In reality it looks like there may only be 5 or possibly 6 useable pins plus the analog A0. That's one of the reasons I have now purchased an I2C adapter board.
I figure I will need four buttons for my project and two sensors so even with the display connected to the I2C bus, that does not leave me with a lot of leeway, but it should be manageable.

BitSeeker

Regarding the original display problem, I think the problem was an intermittent connection on the breadboard. I reseated the display connector as I found that one of the pins pushed back up through the black plastic. So far it seems to have worked without problems.

Added WiFi to the project today and it looks like in this configuration, the display clashes with WiFi. WiFi still works but the display is no longer showing anything. When reverting back to to the non-WiFi version the display works normally again. I am hoping that the I2C adapter resolves this issue. I wonder whether its TX2/RX2, i.e. pin 15 related?

BitSeeker

I got the I2C module with PCF8574 chip today and this seems to work fine and the display is a bit brighter and more readable. However, following an online tutorial, it still uses two GPIO pins - D1 + D2, GPIO4 and GPIO5:

https://randomnerdtutorials.com/esp32-esp8266-i2c-lcd-arduino-ide/

I had hoped that it would use the SD and SC pins on the other side of the board? Is there any reason why it doesn't and can I configure it to do so? I guess that still leaves me with D4 and D5 (GPIO2 and GPIO5) available, but is there any way to configure the GPIO pins that it uses?

groundFungus

The ESP8266 Wire library allows one to specify the SDA and SCL pins.
Code: [Select]
Wire(int SDA,int SCL);

See this page (scroll down).

BitSeeker

#14
May 28, 2020, 08:21 pm Last Edit: May 28, 2020, 09:11 pm by BitSeeker
The ESP8266 Wire library allows one to specify the SDA and SCL pins.
Code: [Select]
Wire(int SDA,int SCL);

See this page (scroll down).
Thanks for the link. It contains a summary of very useful information and was very helpful. Wire.begin() does seem change pins so long as I use those on the same side of the board. For example D5/D6 works as does D9/10 (Rx/Tx) although that pair makes the serial port unavailable over USB. Using D7/D8 blocks sketch uploads. Not quite sure how that works since USB seems to use Rx/Tx but GPIO15 (D8) A.K.A TXD2 was already mentioned as a "special pin" so I was expecting trouble using that one.

Unfortunately, Wifi.begin() doesn't seem to work for the pins GPIO6 - GPIO11 on the other side of the board. I am not sure why. On tracing out the mapping of pins 9-14 of the ESP8266 module to the pins on the RESET/A0 side of the dev board I discovered that they are ordered slightly differently than the wiring diagrams suggest, but even taking that into account, I couldn't get I2C to work on any of the pins on that side.

In short, yes I can use different pins, but only from among those that I have already freed up by switching to using I2C.

For reference, that side of  my board seems to be wired as follows:

Code: [Select]
Analogue       - A0
Ground         - G
Reserved?      - VU
SPIHD [GPIO9]  - S3
CLK   [GPIO6]  - S2
MOSI  [GPIO8]  - S1
CSO   [GPIO11] - SC
MISO  [GPIO7]  - SD
SPIWP [SPIO10] - SK
Ground         - G
3.3V           - 3V
Enable         - EN
Reset          - RST
Ground         - G
Vinput         - VIN



Go Up