ESP8266MOD & LCDproc (hd44780-ethlcd )

Hello all,

I dont know for of all if it’s a good idea in the first place since I can’t find any wifi lcdproc projects. Anywais here it goes.

I’m trying desperately to get this to work with various levels of succes. I’ve triggered about every error from LCDproc server side and i can establish a telnet connection and send data directly to the display. The trouble is i’m trying to port a code on a new coding platform. it’s painful since i’m an eternal noob when it comes to coding to be honest but anywais i usually get some results with my stubbornness. The code i’m try to port to the chip is also a port (picanlcd) but it’s pretty much ready. Ive changed the serial references, added ESP8266WiFi libs. Maybe someone with more experience than me can guide me on this?

I’m using ethlcd driver on lcdproc side

When i restart my lcdproc server on linux side currently this is what i’m getting from serial output:

WiFi connected
IP address:
192.168.121.158
Starting server on port: 2425
Client Connected
Incoming string: 1
Incoming string: 40
Client disconnected

My ino file looks like this currently:

In attachment

On the LCD itself lcdproc never really got to write more than a couple chars or print the char character in a loop.

There are some checks which arent’ necessary i think but i’m pretty sure i’m close anywais.

IF i can’t post this code publicly i’ll remove it.

I need to get the agreement of the original coder but the person who ported picanlcd to arduino should be here somewhere… If there no objections i’ll post the working code.

DemoCode.ino (10.9 KB)

You may want to look at using the hd44780 library instead of the LiquidCrystal library.
The LiquidCrystal does not properly honor the correct timing for the raw command interface using the command() api call.
That means it is possible to overrun the LCD interface by attempting to send a command before the previous command finishes.
This will happen if you ever send the code for clear screen, or home cursor followed by an other command.
In 4 bit mode LCD nibble synchronization can be lost. If so, the LCD will see garbage command until re-initialized.

The hd44780 library does not have this issue.
The hd44780 library also supports backlight control as part of the API using backlight(), noBacklight(), and setBacklight(dimlevel) api functions.

The hd44780 also includes a lcdproc example, using a simplified mode, that might be of some benefit to look at.

The i/o class for controlling the the LCD using Arduino pins is hd44780_pinIO

The nice thing about using the hd4480 library is that if you want to switch to a LCD controlled by a i2c backpack, you only have to change an include file and your constructor. No other changes to the sketch should be necessary.

--- bill

I've looked into the hd44780 library but since i'm using an esp8266 by itself* (with a couple resistors) and the lcd i wanted the esp to handle all the code since it's wifi. Not interfacing another controller and talking to the esp via uart. The library you linked me would work right away if the esp was interfaced with and rs232 to usb chip.

It's maybe a bit more complex than I tought in the first place. Since what i've got is working trough telnet i'm pretty close. My goal was to try and adapt on the esp side whatever is coming out from lcdproc without having to compile a new client for it.

I think you have a misunderstanding of what the hd44780 library is and how it works.
The library does not use use the serial port.
The library provides a LiquidCrystal type API that can talk to LCDs over a variety of h/w interfaces.

Sketches that use the library can do whatever they want on top of the library API.
In the case of the lcdproc example that comes with the hd44780 library, it is a sketch that use a serial port to run the lcdproc protocol and then uses the hd44780 library to control the LCD.
i.e. the sketch pulls in lcdproce messages then translates it to use the hd44780 API to control the LCD.
The h/e interface to the LCD could be an i2c backpack, direct pin control, or could be one of several VFD devices that uses pin control, or SPI.

You are using a network interface to get the lcdproc messages/data instead of a serial port which is why I said:

The hd44780 library also includes a lcdproc example, using a simplified mode, that might be of some benefit to look at.

i.e. it isn't to use directly but may be useful to see how it it was done using the hd44780 library and a serial port.

As I said, one issue you may have using LiquidCrystal library with your sketch vs the hd44780 library is that the LiquidCrystal does not properly honor the hd44780 instruction set timing for the clear and home instructions when using the command() API call.

That is why I suggested you may want to switch over to using the hd44780 library as it does properly honor all the timing and will not let the sketch overrun the LCD command interface.

--- bill

Thanks for the information. Don’t worry i got what you told me the first time. I will definitly use the proper hd44780 library but I must sort what is coming out of the server first.

It seems the first thing client.read() is getting is some kind of init string. I was able to print it to the LCD, it’s a first step but I must decode what data i’m suppose to print and not the entire TCP paquet. I tought the ESP8266WIFI library was handling all the TCP stuff and returning the raw data but i was wrong.

The LCD prints;

HD44780 16X2
TCP b1

It seems I need to send back some data to the lcdproc client.

When i write back with client.write(0x01) etc i get some response from the linux driver and more data.

Here is my slimmed down code if anywais is interesested in helping me try to debug this I would greatly appreciate.

//#include <avr/io.h>
//#include <util/delay.h>
#include <Arduino.h>
// vim: ts=4 ai
// based on info got from here:
// http://lcdproc.cvs.sourceforge.net/viewvc/lcdproc/lcdproc/server/drivers/hd44780-serial.h?content-type=text%2Fplain

#define LED_PIN 15    // This is the pin the backlight is controlled by, it must be a PWM pin
#define STARTUP_BRIGHTNESS 128  // What backlight brightness to start up with (50% by default).

# define BAUDRATE 9600  // What baudrate to use for the serial port

// There was a reason I did not use these as defines, but I can't
// remember it :-/
const int LCDW = 16;
const int LCDH = 2;

// include the LCD library code:
#include <LiquidCrystal.h>

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//#include <WiFi.h>
#include <ESP8266WebServer.h>

#ifndef STASSID
#define STASSID "ssid"
#define STAPSK  "passw"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

//const char* host = "test.net";
//const uint16_t port = 17;

#define LCD_PORT 2425
WiFiServer server(LCD_PORT);

// And this is ths Hardware serial port (which is also bound to the UART->USB chip)
//#include <HardwareSerial.cpp>

// initialize the library with the numbers of the interface pins
/*  Note, while all the ardu documentation and schematics show 4-bit operation.
  It seems the library actually supports both 8-bit and 4-bit mode. It attempts
  8-bit, then falls back to 4-bit */
//LiquidCrystal lcd(12, 11, 2, 3, 4, 5, 6, 7, 8, 9);
const int rs = 16, en = 5, d4 = 4, d5 = 13, d6 = 12, d7 = 14;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void set_backlight(int value) {
  // We can control the backlight via PWM here, range from 0 to 255 values
  // 0 is "off", 255 is "on" (max brightness).
  analogWrite(LED_PIN, value);  // pin 10 is PWM, so we can vary brightness this way
}

void setup() {
  pinMode(LED_PIN, OUTPUT);           // set pin to output
  // We first set the backlight to 50% brightness
  set_backlight(STARTUP_BRIGHTNESS);
  // set up the LCD's number of columns and rows:
  lcd.begin(LCDW, LCDH);
  // set up serial
  lcd.display();
  lcd.clear();
  lcd.write("Ready");

  Serial.begin(BAUDRATE);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.begin();
  Serial.println(String("Starting server on port: ") + LCD_PORT);
}

void loop() {
//    server.handleClient();

  // Todo: Investigate how to to interrupt driven serial I/O, like on PICs.
  // sitting in a tight loop like this is quite wasteful.
  int x = 0;
  //char cmd; //will hold our sent command
//  int cmd; //will hold our sent command
  int cursor = 0; //current cursor position (emulated)
  int scursor = 0;
  char data[5]; //data buffer for (un)signed int printing
  WiFiClient client = server.available();

  /*
    if (!client) {
    Serial.println("connection failed");
    delay(5000);
    return;
    }
  */
  if (client) { // if we have a connection

    if (client.connected())
    {
      Serial.println("Client Connected");
    }

    while (client.connected()) { // keep the client open

      while (client.available() > 0) { // while client is available

        int8_t cmd = client.read(); // store the incoming char
        //char cmd = client.read(); // store the incoming char
        Serial.println(String("Incoming string: ") + cmd);
        client.flush();
        switch (cmd) { // switch it
          case 0x01:
            // set cursor position, next byte is pos
            while (client.available() == 0) {
              delay(1);
            }
            cmd = client.read();
            Serial.println(String("LCD_SETDDRAMADDR: ") + cmd);
            Serial.println(cmd, HEX);
            lcd.command(LCD_SETCGRAMADDR | cmd);
            
            client.write(1);
            cursor = cmd;
            break;
          case 0x02:
            
            cmd = client.read();
            Serial.println(String("case 0x02: ") + cmd);
            Serial.println(cmd, HEX);
            lcd.write(cmd);
            client.write(0x02);
            //cursor = cmd;

            break;
            case 0x06:
            
            cmd = client.read();
            Serial.println(String("case ETHLCD_GET_FIRMWARE_VERSION 0x06: ") + cmd);
            Serial.println(cmd, HEX);
            //lcd.write(cmd);
            client.write(0x06);
            //cursor = cmd;

            break;
          default:
          while (1) {
            
            Serial.println(String("Default case: ") + cmd);
            Serial.println(cmd, HEX);
            if (cmd != -1) {
                break;
              }
            break;
          }
        } // end switch cmd
      } //end while client available
    } // end whie client connected
   // client.stop();
    Serial.println("Client disconnected");
  } // end if client

}// end main loop

Basically this comes to how can i store the raw data coming from the server? I’m guessing this will envolve storing into an array etc but I need some guidance on how to proceed.

Thanks again.

  Welcome to
   LCDproc!

server side:

dany@dany-desktop:~$ sudo service lcdproc status
● lcdproc.service - LCD display daemon
     Loaded: loaded (/lib/systemd/system/lcdproc.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2021-03-07 16:35:38 EST; 1min 44s ago
       Docs: man:LCDd(8)
             http://www.lcdproc.org/
   Main PID: 605372 (LCDd)
      Tasks: 1 (limit: 4149)
     CGroup: /system.slice/lcdproc.service
             └─605372 /usr/sbin/LCDd -s 1 -f -c /etc/LCDd.conf

Mar 07 16:35:38 dany-desktop LCDd[605372]: modify it under the terms of the GNU General Public License
Mar 07 16:35:38 dany-desktop LCDd[605372]: as published by the Free Software Foundation; either version 2
Mar 07 16:35:38 dany-desktop LCDd[605372]: of the License, or (at your option) any later version.
Mar 07 16:35:38 dany-desktop LCDd[605372]: This program is distributed in the hope that it will be useful,
Mar 07 16:35:38 dany-desktop LCDd[605372]: but WITHOUT ANY WARRANTY; without even the implied warranty of
Mar 07 16:35:38 dany-desktop LCDd[605372]: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Mar 07 16:35:38 dany-desktop LCDd[605372]: GNU General Public License for more details.
Mar 07 16:35:38 dany-desktop LCDd[605372]: You should have received a copy of the GNU General Public License
Mar 07 16:35:38 dany-desktop LCDd[605372]: along with this program; if not, write to the Free Software Foundation,
Mar 07 16:35:38 dany-desktop LCDd[605372]: Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

I think i got it to work. I needed to set the same parameters that i received from the driver first.

I need to reboot the server to validate.

edit: Ok server starts and stop, LCD is printing both welcome and goog bye strings, i get no data in between tho.

Nevermind I guess this thread can be closed. I need to sort the backlight situation but i got the basic setup to work. lcdproc sends and the esp8266 prints the raw data to lcd. I'll use the hd44780 libs and post something on my git but everything that was needed to make this code work was in my third post.

Anyone interested here is the cleaned up version. Backlight is harcoded for now. I,ll look into the hd44780 version once i learn how to code :). It's far from perfect but it's a start and it could be handy. I,ll work on it but for now it seems to do what it need it to do.

This topic was automatically closed after 58 days. New replies are no longer allowed.