Circuito para controlar um LCD usando um Shift Register 74HC595 e um Arduino.
Vamos utilizar a biblioteca New LiquidCrystal (https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home), que tanto dá para o SR 74HC595 como para o HEF4094B (basta adaptar utilizando o respetivo esquema para cada um).
Download: LiquidCrystal_V1.2.1
Nota: Verificar se existe uma outra biblioteca mais antiga na directoria do IDE que possa gerar conflito com esta.
Esquema:
Temos assim que ligar os pinos do LCD de acordo com o esquema:
// +--------------------------------------------+
// | MCU |
// | IO1 IO2 IO3 |
// +----+-------------+-------------+-----------+
// | | |
// | | |
// +----+-------------+-------------+-----------+
// | Strobe Data Clock |
// | 8-bit shift/latch register | 74HC595N
// | Qa0 Qb1 Qc2 Qd3 Qe4 Qf5 Qg6 Qh7 |
// +----+----+----+----+----+----+----+----+----+
// | | | | | | |
// |11 |12 |13 |14 |6 |5 |4 (LCD pins)
// +----+----+----+----+----+----+----+----+----+
// | DB4 DB5 DB6 DB7 E Rw RS |
// | LCD Module |
Fazer as ligações aos Q's correctos do 74HC595 e podemos ainda utilizar o Q7 (que sobra) para controlar outra coisa.
Os pinos do 74HC595 podem ser consultados na datasheet:
Para o Arduino, neste exemplo, usámos os seguintes pinos:
LATCH (STCP) => pino 12 do Arduino
DS (DATA) => pino 11 do Arduino
SHCP (CLOCK) => pino 10 do Arduino
Pino MR do 74HC595 tem de se ligar ao VCC (+5v), para que não esteja a fazer RESET e inicie sem problemas.
Pino OE do 74HC595 tem de se ligar ao GND, para termos o Output Enable.
Podemos comparar os pinos do 74HC595 com os do HEF4094B, desde que se utilizem os correctos podemos usar ambos os SR:
Na segunda imagem tempos um exemplo prático para cada um dos SR e da respectiva diferença nos pinos.
Resumo das ligações do LCD ao SR74HC595 (usando a biblioteca acima indicada):
Nota: Ficamos assim com o Output do SR Q7 disponível, podemos usar o mesmo para controlar o backlight do LCD ou qualquer outro dispositivo (usando um transístor caso se exceda a corrente máxima permitida por cada pino do SR: 40mA).
Código de teste:
HelloWorld
include <Wire.h>
#include <LiquidCrystal_SR3W.h>
const int PIN_LCD_STROBE = 12; // Out: LCD IC4094 shift-register strobe LACH PIN - STCP
const int PIN_LCD_DATA = 11; // Out: LCD IC4094 shift-register data DATA PIN - DS
const int PIN_LCD_CLOCK = 10; // Out: LCD IC4094 shift-register clock CLOCK PIN - SHCP
LiquidCrystal_SR3W lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE); // srdata / srclock / strobe
// Creat a set of new characters
byte armsUp[8] = {0b00100,0b01010,0b00100,0b10101,0b01110,0b00100,0b00100,0b01010};
byte armsDown[8] = {0b00100,0b01010,0b00100,0b00100,0b01110,0b10101,0b00100,0b01010};
const int BACKLIGHT_PIN = 5;
void setup(){
lcd.begin(16,2); // initialize the lcd
lcd.createChar (0, armsUp); // load character to the LCD
lcd.createChar (1, armsDown); // load character to the LCD
lcd.home (); // go home
lcd.print("LiquidCrystal_SR");
}
void loop(){
// Do a little animation
for(int i = 0; i <= 15; i++) showHappyGuy(i);
for(int i = 15; i >= 0; i--) showHappyGuy(i);
}
void showHappyGuy(int pos){
lcd.setCursor ( pos, 1 ); // go to position
lcd.print(char(random(0,2))); // show one of the two custom characters
delay(550); // wait so it can be seen
lcd.setCursor ( pos, 1 ); // go to position again
lcd.print(" "); // delete character
}
Teste Completo:
//http://arduino-info.wikispaces.com/LCD-Blue-I2C
#include <Wire.h>
#include <LiquidCrystal_SR3W.h>
const int PIN_LCD_STROBE = 12; // Out: LCD IC4094 shift-register strobe LACH PIN - STCP
const int PIN_LCD_DATA = 11; // Out: LCD IC4094 shift-register data DATA PIN - DS
const int PIN_LCD_CLOCK = 10; // Out: LCD IC4094 shift-register clock CLOCK PIN - SHCP
// srdata / srclock / strobe / bl pin on SR / blpol (positive\negative)
LiquidCrystal_SR3W lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE, 7, POSITIVE); // 7 e POSITIVE definem estão associados ao output Q7
// Creat a set of new characters
byte heart[8] = {
0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000
};
byte smiley[8] = {
0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000
};
byte frownie[8] = {
0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b00000, 0b01110, 0b10001
};
byte armsDown[8] = {
0b00100, 0b01010, 0b00100, 0b00100, 0b01110, 0b10101, 0b00100, 0b01010
};
byte armsUp[8] = {
0b00100, 0b01010, 0b00100, 0b10101, 0b01110, 0b00100, 0b00100, 0b01010
};
void setup() {
// put your setup code here, to run once:
lcd.begin(16, 2); // initialize the lcd for 16 chars 2 lines, turn on backlight
// load characters to the LCD
lcd.createChar(0, smiley);
lcd.createChar(1, frownie);
lcd.createChar(2, armsDown);
lcd.createChar(3, armsUp);
lcd.createChar(4, heart);
lcd.clear();
lcd.home (); //go home
lcd.setCursor (0, 0); //XY
lcd.print(F("LiquidCrystalSR3"));
lcd.setCursor (0, 1);
lcd.print(F("World "));
lcd.print(char(4));
lcd.print(char(2));
lcd.print(char(3));
delay(2000);
// ------- Quick 3 blinks of backlight -------------
for (int i = 0; i < 3; i++)
{
lcd.backlight();
delay(450);
lcd.noBacklight();
delay(450);
}
lcd.backlight(); // finish with backlight on
}
void loop() {
lcd.clear();
for (int i = 5; i <= 15; i++) {
lcd.setCursor ( i, 1 );
lcd.print(char(random(0, 2)));
delay(100);
lcd.setCursor ( i, 1 );
lcd.print(F(" "));
}
for (int i = 15; i >= 5; i--) {
lcd.setCursor ( i, 1 );
lcd.print(char(random(0, 2)));
delay(100);
lcd.setCursor ( i, 1 );
lcd.print(F(" "));
}
// Turn the display on/off
lcd.setCursor ( 5, 1 );
lcd.print(F("screen off"));
delay(1000);
lcd.noDisplay();
delay(1000);
lcd.display();
lcd.clear();
lcd.setCursor ( 5, 1 );
lcd.print(F("CURSOR"));
delay(1000);
lcd.setCursor ( 5, 1 );
lcd.cursor();
delay(2000);
lcd.noCursor();
lcd.clear();
lcd.setCursor ( 5, 1 );
lcd.print(F("BLINK"));
lcd.setCursor ( 5, 1 );
lcd.blink();
delay(2000);
lcd.noBlink();
lcd.clear();
lcd.setCursor ( 5, 1 );
lcd.print(F("SCROLL"));
delay(1000);
//SCROLL TEST
for (uint8_t positionCounter = 0; positionCounter < 10; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(50);
}
// scroll 16 positions (display length + string length) to the left
// to move it back to center:
for (uint8_t positionCounter = 0; positionCounter < 10; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(50);
}
lcd.setCursor ( 0, 1 );
lcd.print(F(" "));
}
Testando a saída Q7 (podemos colocar um LED ligado a este pino (com uma resistência de 220R ao negativo)):
//http://arduino-info.wikispaces.com/LCD-Blue-I2C
#include <Wire.h>
#include <LiquidCrystal_SR3W.h>
const int PIN_LCD_STROBE = 12; // Out: LCD IC4094 shift-register strobe LACH PIN - STCP
const int PIN_LCD_DATA = 11; // Out: LCD IC4094 shift-register data DATA PIN - DS
const int PIN_LCD_CLOCK = 10; // Out: LCD IC4094 shift-register clock CLOCK PIN - SHCP
// srdata / srclock / strobe / bl pin on SR / blpol (positive\negative)
LiquidCrystal_SR3W lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE, 7, POSITIVE);
void setup() {
// put your setup code here, to run once:
lcd.begin(16,2); // initialize the lcd for 16 chars 2 lines, turn on backlight
lcd.clear();
lcd.setCursor(0,0); //Start at character 0 on line 0
lcd.print("LCD DISPLAY");
lcd.setCursor(0,1);
lcd.print("TEST");
// ------- Quick 3 blinks of backlight -------------
for(int i = 0; i< 3; i++)
{
lcd.backlight();
delay(450);
lcd.noBacklight();
delay(450);
}
lcd.backlight(); // finish with backlight on
}
void loop() {
// put your main code here, to run repeatedly:
}
Vídeo final: