I'm just starting out but here's an Arduino connected to a 4x20 HD44780 display, enclosed in 8"x4 1/2" Lexan.
I used a modified version of the LCD arduino library and hacked the LCD Smartie Sketch using Orbital Matrix commands.
LCD Smartie is running the BigNum plugins. It shows Facebook news feeds, BBC Headlines, a Clock, local Weather and my Folding at home status (team 144824) among other things.
I tried to be as neat as possible. This was a fun project, not too much soldering and had a high reward vs time invested.
Nice work! I just got my 20X4 lcd from sparkfun this week and was thinking about a display like this. Would a shot from the back and sides be too much to ask?
Don't really get how you get LCD Samrtie to talk to Arduino. Purely becuase i don't understand the type of commands that it's sending? Could you please explain this?
Nuelectronics sell a shield that does this but I figured I would learn more by building my own. Theirs has a keypad and some other features but the screen is rather small.
Long story short, LCD Smartie is configured to send output using "matrix orbital" commands, which the nuelectronics folks have written a sketch for. I just took the sketch they provided and hacked it to work with a 4x20 LCD (the shield's is only 2x16)
I was pleasantly surprised, Lexan was not that hard to work with. It doesn't seem to shatter and I was able to cut it on my table saw with a standard blade. It was also pretty cheap and available at home depot. It scratches pretty easy though so I kept the protective covering on until the last second. Filed the edges with a hand rasp.
I used some standard stand offs that I had lying around from a motherboard and screwed them directly into the lexan (after pre-drilling of course). For the corners I got some stainless steel cap screws with wingnuts and nylon spacers from the hardware aisle.
Total cost for the case was about $6.
It's sitting on my desk and pretty much everyone who comes in my office comments on it. Most folks ask if it came from a kit which I guess is a good thing.
anny change you could post this modified PDE ?
I have a 4 bit 2x16 connected to my arduino nano for the exact same goal but I don't have the skills to make it work
please help
Upload this to your Arduino, make sure the pins are correct. (RW is NOT required, if you don't use it, make sure to ground the RW pin on the LCD.)
Then open LCD smartie, set it for the speed in the sketch. (19200, can change to whichever you'd like) make sure the COM port is the same as your Arduino, and that should be it! If it doesn't work, you may have to restart the LCDSmartie program, or the Arduino.
This also works for making your Arduino a 1-wire LCD. (well 3.. TX, GND, 5v) and I added some extra code, so if you use the RX as well, you can read the analog pins on the LCD-arduino.
/* Serial LCD, using Matrix Orbital command set*/
// These must be changed in LCD4Bit_mod.cpp, this is just for reference
// RS, RW and Enable can be set to whatever you like
// int RS = 4;
// int RW = 13;
// int Enable = 3;
// DB should be an unseparated group of pins - because of lazy coding in pushNibble()
// int DB[] = {5, 6, 7, 8}; //wire these to DB4~7 on LCD.
#include "LCD4Bit_mod.h"
#include <EEPROM.h>
//#include <Streaming.h>
const byte backLight = 13;
//create object to control an LCD.
//number of lines in display=1
LCD4Bit_mod lcd = LCD4Bit_mod(2);
void setup() {
pinMode(backLight, OUTPUT); //makes the backLight an output
digitalWrite(backLight,HIGH);//turns the backLight on
Serial.begin(19200);
lcd.init();
lcd.clear();
lcd.printIn(" LCD Ready: ");
}
byte serial_getch(){
int incoming;
while (Serial.available()==0){
}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
void loop(){
byte rxbyte;
byte temp;
byte addr;
byte pin;
int myVal;
int val;
rxbyte = serial_getch();
if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands
{
switch (serial_getch())
{
case 50: // Read analog pin, then send value back
pin = serial_getch();
myVal = analogRead(pin)/4;
delay(10);
Serial.print(myVal, BYTE);
break;
case 64: // EEPROM Write (address, value)
addr = serial_getch();
delay(10);
val = serial_getch();
EEPROM.write(addr, val);
break;
case 65: // EEPROM Read (address)
addr = serial_getch(); // EEPROM address
val = EEPROM.read(addr); //
Serial.print(val, BYTE);
break;
case 69: //backlight on (at previously set brightness)
// not implemented
digitalWrite(backLight, HIGH);
break;
case 70: //backlight off
// not implemented
digitalWrite(backLight, LOW);
break;
case 71: //set cursor position
temp = (serial_getch() - 1); //get column byte
switch (serial_getch()) //get row byte
{
//line 1 is already set up
case 2:
temp += 0x40;
break;
case 3:
temp += 0x14;
break;
case 4:
temp += 0x54;
break;
default:
break;
}
lcd.commandWrite(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.commandWrite(2);
break;
case 74: //show underline cursor
lcd.commandWrite(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.commandWrite(0b00001100);
break;
case 76: //move cursor left
lcd.commandWrite(16);
break;
case 77: //move cursor right
lcd.commandWrite(20);
break;
case 78: //define custom char
lcd.commandWrite(64 + (serial_getch() * 8)); //get+set char address
for (temp = 7; temp != 0; temp--)
{
lcd.print(serial_getch()); //get each pattern byte
}
break;
case 83: //show blinking block cursor
lcd.commandWrite(0b00001111);
break;
case 86: //GPO OFF
//implement later
break;
case 87: //GPO ON
/*temp = serial_getch();
if (temp == 1)
{
GPO1 = GPO_ON;
}*/
break;
case 88: //clear display, cursor home
lcd.commandWrite(1);
break;
/*###############################################################
case 152: //set and remember (doesn't save value, though)
case 153: //set backlight brightness
//not implemented
break;
//these commands ignored (no parameters)
//case 35: //read serial number //USING FOR EEPROM//
//case 36: //read version number
case 55: //read module type
case 59: //exit flow-control mode
//case 65: //auto transmit keypresses
case 96: //auto-repeat mode off (keypad)
case 67: //auto line-wrap on
case 68: //auto line-wrap off
case 81: //auto scroll on
case 82: //auto scroll off
case 104: //init horiz bar graph
case 109: //init med size digits
case 115: //init narrow vert bar graph
case 118: //init wide vert bar graph
break;
###############################################################*/
default:
//all other commands ignored and parameter byte discarded
temp = serial_getch(); //dump the command code
break;
}
return;
} //END OF COMMAND HANDLER
//change accented char to plain, detect and change descenders
//NB descenders only work on 5x10 displays. This lookup table works
// with my DEM-20845 (Display Elektronik GmbH) LCD using KS0066 chip.
switch (rxbyte)
{
//chars that have direct equivalent in LCD charmap
/* case 0x67: //g
rxbyte = 0xE7;
break;
case 0x6A: //j
rxbyte = 0xEA;
break;
case 0x70: //p
rxbyte = 0xF0;
break;
case 0x71: //q
rxbyte = 0xF1;
break;
case 0x79: //y
rxbyte = 0xF9;
break;
*/ case 0xE4: //ASCII "a" umlaut
rxbyte = 0xE1;
break;
case 0xF1: //ASCII "n" tilde
rxbyte = 0xEE;
break;
case 0xF6: //ASCII "o" umlaut
rxbyte = 0xEF; //was wrong in v0.86
break;
case 0xFC: //ASCII "u" umlaut
rxbyte = 0xF5;
break;
//accented -> plain equivalent
//and misc symbol translation
case 0xA3: //sterling (pounds)
rxbyte = 0xED;
break;
/* case 0xB0: //degrees symbol
rxbyte = 0xDF;
break;
*/ case 0xB5: //mu
rxbyte = 0xE4;
break;
case 0xC0: //"A" variants
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
rxbyte = 0x41;
break;
case 0xC8: //"E" variants
case 0xC9:
case 0xCA:
case 0xCB:
rxbyte = 0x45;
break;
case 0xCC: //"I" variants
case 0xCD:
case 0xCE:
case 0xCF:
rxbyte = 0x49;
break;
case 0xD1: //"N" tilde -> plain "N"
rxbyte = 0x43;
break;
case 0xD2: //"O" variants
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD8:
rxbyte = 0x4F;
break;
case 0xD9: //"U" variants
case 0xDA:
case 0xDB:
case 0xDC:
rxbyte = 0x55;
break;
case 0xDD: //"Y" acute -> "Y"
rxbyte = 0x59;
break;
/* case 0xDF: //beta //mucks up LCDSmartie's degree symbol??
rxbyte = 0xE2;
break;
*/ case 0xE0: //"a" variants except umlaut
case 0xE1:
case 0xE2:
case 0xE3:
case 0xE5:
rxbyte = 0x61;
break;
case 0xE7: //"c" cedilla -> "c"
rxbyte = 0x63;
break;
case 0xE8: //"e" variants
case 0xE9:
case 0xEA:
case 0xEB:
rxbyte = 0x65;
break;
case 0xEC: //"i" variants
case 0xED:
case 0xEE:
case 0xEF:
rxbyte = 0x69;
break;
case 0xF2: //"o" variants except umlaut
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF8:
rxbyte = 0x6F;
break;
case 0xF7: //division symbol
rxbyte = 0xFD;
break;
case 0xF9: //"u" variants except umlaut
case 0xFA:
case 0xFB:
rxbyte = 0x75;
break;
default:
break;
}
lcd.print(rxbyte); //otherwise a plain char so we print it to lcd
return;
}
I am having trouble with this. I got it to work kinda but I have a 20x4 display. I am getting sticky characters and areas that don't update as they should. then after a while, everything looks like giberish on the lcd...
I am having trouble with this. I got it to work kinda but I have a 20x4 display. I am getting sticky characters and areas that don't update as they should. then after a while, everything looks like giberish on the lcd...
Try changing the baud rates, slower would probably be better. Using it with LCDSmartie it does okay, but when I try use it as a regular serial, I can do all the normal stuff for a while.. but then it does what you say, and prints all the extra crap.
I haven't played with it for a while, so you may want to do some experimenting.. but you could try add a small delay after the Serial.getch() or serial.read, whichever. It's possible it's just sending the information too fast so it get's garbled.
You could also try to remove some of the un-used code.. such as the functions I added for reading eeprom/writing to it if you're not using it.
Still not really sure how it's done.. but with LCD-Smartie, it works like a champ, scrolls fine and such.
This is my second project for Arduino using 2x16 LCD...
I've managed to get the LCD Smartie winamp plugins to work with 2x16 LCD ( WinXP on vmware fusion on a Mac ) to send winamp spectrum analyser to the LCD...
Thanks to the code from CaptionObvious ( instead of using nuelectronics with the extra buttons and other interrupts ) , it works fine without any code modifications...
I also have garbage characters on most of the winamp graphs except for tinygraph..
Anyone found a solution to this yet ??
Does adjusting the baud rate or refresh interval (from LCD Smartie) help or some method to synchronize the display refresh with the data received from the serial port ?