Showing posts with label lcd. Show all posts
Showing posts with label lcd. Show all posts

Sunday, June 10, 2018

Scrolling Text On LCD with Arduino

Introduction

We want to program the Arduino so that it will scroll (possibly very long) text acroos an LCD screen.
The text shall be sent to the Arduino via the serial port
The text transmitted by the PC via the USB link is stored in the Arduino Memory and displayed as a scrolling text on the LCD display.
The major risk is to lose data in case of very long text since the Arduino internal serial port buffer is limited to 64 bytes

The Hardware

The hardware is the classical Interfacing of an Arduino UNO with a 2x16 HD44780 LCD module. Note that for the module I did use did include a current limiting resistor in the circuit backlight. This may not be the case for your module. So be careful. You may destroy the module if you don’t include an external resistance on a module that has no internal limiting resistance.  (see https://electronics.stackexchange.com/questions/212197/is-it-necessary-to-use-resistor-when-connecting-backlight-of-16x2-lcd-display for details).

For the NPN transistor. I did use a BC547 but any similar transistor (BC108, 2N222,…) may be used instead.

The software

The software is made of 2 parts:

The display part

The display part builds a 16 characters string containing the part of the buffer to print (if needed padded with white spaces) and display it with a lcd.print command. This has the advantage of not disturbing the other lines of the display.
Since the Arduino serial port input buffer is very small (64 bytes), the display routine is immediately stopped once bytes are received in the serial port input buffer. (note: the process could probably be optimized using interrupts but tests did show the program was working correctly without using interrupts

The communication Part

This routine simply fills a large (256 bytes) buffer with the data received on the serial port using the method Serial.readBytesUntil('\n',buffer,256);
The handshaking is done via an XON XOFF mechanism.

Full listing

/*
 LCD Serial ScrollPrint

MIT License

Copyright (c) 2018 Pierre Poliakoff

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

 */

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

//declare the hardware
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

int pinBacklight=9;

//const
//=====
const byte XOFF=19;
const byte XON=17;
//variables
//=========
char buffer[256];



void LcdPrintAndScroll(char *buffer,int len)
{
int offset =-16;
String screen="                "; //16 chars buffer string
while(Serial.available()==0)
  {
  lcd.setCursor(0,0);
  offset++;
  if(offset>len)
   {
    offset=-16;
   }
 
  for (int i=0; i <16 && Serial.available()==0 ;i++)
    {
      if((i+offset<len)&&(i+offset>=0)&&buffer[i+offset]>31)
       {
        screen[i]=buffer[i+offset];
       }
      else
      {
        screen[i]=' ';
      }
    }
  lcd.print(screen);
  unsigned long now=millis();
  while(millis()-now<250 && Serial.available()==0)
    {
      //do nothing
    }
  }
}

void setup() {
  // initialize Hardware
  pinMode(pinBacklight,OUTPUT);
  digitalWrite(pinBacklight,HIGH);
  Serial.begin(9600);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  lcd.print("Waiting for Data");
  lcd.setCursor(0,1);
  lcd.print("Scroll Text Demonstration");

}
//===========================================
void loop() {
int len;
// receive data
while (Serial.available()==0)
  {
   //Do nothing 
  }
len=Serial.readBytesUntil('\n',buffer,256);
Serial.write(XOFF); // pause the transmission
Serial.flush();
// insert herre any long computation on Buffer
Serial.write(XON);//reactivate the transmission
//Print Data
if (len>0)
  {
    LcdPrintAndScroll(buffer,len);
  }

}

Sending Data from the PC

We do not want to write a specific software on the PC to send the data. We  simply use the Windows Command line features:
On my PC the Arduino is visible as COM4 (check on you PC for the exact value)
We configure the com port communication via the following command

mode COM4 BAUD=9600 xon=on data=8


Note that each time you upload a new firmware version in the Arduino, you must reconfigure the com port with the above command
Then you can send the data to display via a simple copy command

copy mydata.txt com4:

if you prefer to enter the data directly with the keyboard, you can use

copy con: com4:

Press enter to display the text on the Arduino and CTRL-Z to exit.




The Final Result




Sunday, February 28, 2016

Connecting multiple LCD displays to an Arduino

The LCD Display

The LCD Display based on Hitachi HD (or equivalent) have been around for many years. They are a very popular way to display information on any microcontroller circuit.



They are available from many manufacturer and are in various display size. The usual size is 16x2 characters but you can find variants in 40x2 characters or 16x4 characters.

The display includes the full circuitry to drive the display and interface with the microcontroller.

Interfacing with the Arduino

 Interfacing with the Arduino is very straight forward and very well documented in www.arduino.cc/en/Tutorial/HelloWorld

The schematic is quite simple:


We can limit the number of wires used on the Arduino by using a 4 bits interface instead of 8 bits and hardwiring the R/W pin to VSS since we don't need to read back information for the display.

This means that the interface is reduced to 4 data bits (DB4...DB7) and the 2 control wires: RS and E.
RS is used to select the register where the data shall be written (one register is used to display text and the other one is used to control the display behaviour) . The E wire is used to perform the actual data write operation.

To access the LCD display from the Arduino sketch we use an object of the LiquidCrystal class (for the standard Arduino library LiquidCrystal.h) by creating it with the correct pin assignation:

  lcd(12, 10, 5, 4, 3, 2);

Warning: When wiring the display, check carefully the manufacturer datasheet to find the correct pinout. Every manufacturer agrees that there are 14 pins to control the LCD + 2 pins to control the backlight but the exact pin assignation varies slightly from a manufacturer to another.

Multiple Displays


Now we want to connect one (or more) additional displays to the Arduino

As explained above the LCD display takes the data into account only when the E pin is activated. This means that you can connect all the displays signals in parallel on the Arduino digital outputs as long as you keep the E signals separated.

In the schematics below I have used digital output D10 to control E signal of LCD1  and output D11 to control E signal of LCD2

The Software

The Arduino sketch to control multiple displays is very similar to the one used to control one display.

You simply have to create one object of the LiquidCrystal class for each display. I have found that the easiest way to do it is to store them in array by using the following code:
 
LiquidCrystal lcd[2]={LiquidCrystal(12, 11, 5, 4, 3, 2), LiquidCrystal(12, 10, 5, 4, 3, 2)};


This allows to easily select on which display to print (or to send any command) as shown in the very simple "Hello World" example below.

warning, since arrays begin at index zero, the 2 LCD displays shall be numbered zero and on1 (instead of one and two).

/*
This sketch prints "Hello World!" on 2 LCD displays
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11 for LCD1 pin 10 for LCD 0
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K pot
* ends to +5V and ground
* wiper to LCD VO pin
*/

// Directly based on the Arduino example LiquidCrystal HelloWorld
#include <LiquidCrystal.h>

LiquidCrystal lcd[2] = { LiquidCrystal(12, 11, 5, 4, 3, 2),LiquidCrystal(12, 10, 5, 4, 3, 2) };

void setup() {
// set up the LCD's number of columns and rows:
lcd[0].begin(16, 2);
lcd[1].begin(16, 2);
lcd[0].setCursor(0, 0);

lcd[0].print("Hello");
lcd[1].setCursor(0, 0);
lcd[1].print("World!");
}

void loop() {
}