Project Objective: In this project we will use the Arduino to emulate the PH
Anderson #117 serial text display minus big numbers. The layout of a piggyback pcb
will complete the project.
Introduction: See
the discussion in the "Controlling a Serial Display" project which
covers several of the serial LCD displays on the market. Most of these products
have a similar command set and the sketch presented here could be modified to
emulate many of these.
Serial LCD displays are available in both text and graphic
versions. This project covers text displays with one to four lines and up to 40
columns. Initially, the displays will be limited to 80 total characters, a
limitation of the Arduino standard LCD library.
Since the serial LCD is a one wire device, all control of the LCD terminal must use command sequences. Here are the commands used in this project:
Arduino Serial LCD Rev. A: Command Set (as of 9/16/12)
Command
?a home cursor
?b destructive backspace
?c# set cursor style, 0= none 2= blinking 3=underline
?f clear screen
?g Beep
?h Backup Cursor (Non-destructive backspace)
?i Forward cursor
?j Up cursor
?k Down cursor
?l Clear cursor line
?m Carriage Return
?n CRLF, cursor at start of next line, line cleared
?p### Position cursor x = ##, y = #
?x## Position cursor on x column, (two characters are required), first column is column 0,
?y# Position cursor at y row, first row is row 0 (one character only)
?? display a "?"
?! Send direct command to LCD
?B Backlight Intensity – sets PWM value, two hex digits req. (00 to FF)
?D# Define custom character. See text.
?# Print a custom character
?H High output on auxiliary digital pins: valid numbers are 1,2,3,4
?L Low output on auxiliary digital pins: valid numbers are 1,2,3,4
?G Configure for LCD geometry. Supported formats: 2X16, 2X20, 2X24, 2X40, 4X16 and 4X20.
Except for the ?p### command they are identical to the PH Anderson, #117 chip. The start character for a command sequence is a '?', but this can be easily changed in the sketch, say to a '!'. The sketch below compiles, but some commands are missing.
One of the nice features of the #117 command set is that control can be accomplished using a PC termial program. In fact, using the Arduino IDE to update the code the built in terminal can be opened to test changes.The piggyback pcb can be modified and updated the same way.
Note: As of 10/08/12 the code was updated, as well as the schematic.The schematic changes were made to simplify the piggyback pcb layout. Because of this there were also changes to code. Several additional commands have been added and we will continue to add more.
Since the serial LCD is a one wire device, all control of the LCD terminal must use command sequences. Here are the commands used in this project:
Arduino Serial LCD Rev. A: Command Set (as of 9/16/12)
Command
?a home cursor
?b destructive backspace
?c# set cursor style, 0= none 2= blinking 3=underline
?f clear screen
?g Beep
?h Backup Cursor (Non-destructive backspace)
?i Forward cursor
?j Up cursor
?k Down cursor
?l Clear cursor line
?m Carriage Return
?n CRLF, cursor at start of next line, line cleared
?p### Position cursor x = ##, y = #
?x## Position cursor on x column, (two characters are required), first column is column 0,
?y# Position cursor at y row, first row is row 0 (one character only)
?? display a "?"
?! Send direct command to LCD
?B Backlight Intensity – sets PWM value, two hex digits req. (00 to FF)
?D# Define custom character. See text.
?# Print a custom character
?H High output on auxiliary digital pins: valid numbers are 1,2,3,4
?L Low output on auxiliary digital pins: valid numbers are 1,2,3,4
?G Configure for LCD geometry. Supported formats: 2X16, 2X20, 2X24, 2X40, 4X16 and 4X20.
Except for the ?p### command they are identical to the PH Anderson, #117 chip. The start character for a command sequence is a '?', but this can be easily changed in the sketch, say to a '!'. The sketch below compiles, but some commands are missing.
One of the nice features of the #117 command set is that control can be accomplished using a PC termial program. In fact, using the Arduino IDE to update the code the built in terminal can be opened to test changes.The piggyback pcb can be modified and updated the same way.
Note: As of 10/08/12 the code was updated, as well as the schematic.The schematic changes were made to simplify the piggyback pcb layout. Because of this there were also changes to code. Several additional commands have been added and we will continue to add more.
Schematic Used with Solderless Breadboard:
The schematic above shows the parts which need to be added to the solderless breadboard for this project. The headers in the schematic are the the headers on the Arduino board. The piggyback board will require a different schematic and include the atmega328, as well as, serial interface circuits and jumpers.
The image below shows the Arduino Serial LCD connected to an
Arduino sending serial data at 9600 baude. The text being sent is
"Temperature" and "76.8" or "77.6", where the
word Temperature is sent once and the numbers sent alternately in the loop section of the sketch. Before
the numbers are sent the cursor is positioned at character column 14. The small
round object is a piezo speaker.
Sketch:Version 0.6 /* Arduino_PHAnderson #117 Serial LCD emulator Date: 10/08/12 Author: R. LaSalle */ #include <LiquidCrystal.h> #include <EEPROM.h> /* LCD pin assignments RS 8 RW 9 E 10 D4 4 D5 5 D6 6 D7 7 */ #define BP 3 #define BL 11 #define Bd0 14 #define Bd1 15 #define maxrowloc 0 #define maxcolloc 1 #define bootscrloc 2 #define curtypeloc 3 #define ledblloc 4 #define tabloc 5 #define user0 10 #define user1 30 #define user2 50 #define user3 70 #define commchr '?' //#define VER .5 uint16_t bauderate = 9600; uint8_t maxrow = 4; uint8_t maxcol = 20; uint8_t bootscr = 1; uint8_t ledbl = 0x7f; uint8_t nrow =0; uint8_t ncol =0; int8_t temp =0; int8_t temp1 =0; int8_t temp2 =0; int8_t temp3 =0; LiquidCrystal lcd(8,9,10,4,5,6,7); void setup() { // EEPROM.write(maxrowloc,0); // EEPROM.write(maxcolloc,0); temp=EEPROM.read(maxrowloc); temp1=EEPROM.read(maxcolloc); if(temp==0 && temp1==0){ //Is EEPROM empty? If yes load defaults. maxrow=4; maxcol=20; EEPROM.write(maxrowloc,maxrow); EEPROM.write(maxcolloc,maxcol); } maxrow=EEPROM.read(maxrowloc); maxcol=EEPROM.read(maxcolloc); lcd.begin(maxcol,maxrow); // Change this for other screen sizes. pinMode(Bd0,INPUT); //bauderate set bit 0 pinMode(Bd1,INPUT); //bauderate set bit 1 digitalWrite(Bd0,HIGH); //pullup digitalWrite(Bd1,HIGH); //pullup if(digitalRead(Bd0)==LOW && digitalRead(Bd1)==LOW){bauderate=2400;} if(digitalRead(Bd0)==HIGH && digitalRead(Bd1)==LOW){bauderate=9600;} if(digitalRead(Bd0)==LOW && digitalRead(Bd1)==HIGH){bauderate=19200;} if(digitalRead(Bd0)==HIGH && digitalRead(Bd1)==HIGH){bauderate=38400;} Serial.begin(bauderate); // Default baudrate. pinMode(BL,OUTPUT); pinMode(BP,OUTPUT); analogWrite(BL, ledbl); // Set maximum brightness. // Boot Screens if(bootscr==1){ //Config screen ncol=0; nrow=0; lcd.setCursor(ncol,nrow); //home cursor lcd.print("Arduino_PHA117"); lcd.setCursor(0, 1); lcd.print("G:");lcd.print(maxrow);lcd.print("x"); lcd.print(maxcol/10);lcd.print(maxcol%10); lcd.print(" B:");lcd.print(bauderate); lcd.setCursor(0,0); //home cursor } } void loop() { byte rxbyte = getc(); // Command //byte temp; // Parameter if (rxbyte == commchr) { switch (getc()) { case 'p': // Set cursor position (2 parameters, column, row) temp=getn(); temp1=getn(); temp2=getn(); if(temp=='e'||temp1=='e'){ error(); break; } temp=temp*10+temp1; if(temp>maxcol-1){ error(); break; } ncol=temp; if(temp2=='e'){ error(); break; } if(temp2>maxrow-1){ error(); break; } nrow=temp2; lcd.setCursor(ncol, nrow); break; case 'a': // Cursor home (doesn't clear the screen!) lcd.home(); ncol=0; nrow=0; break; case 'b': //Destructive backspace lcd.command(16); //cursor back lcd.write(' '); // write space lcd.command(16); //cursor back ncol=ncol-1; break; case 'c': // Set Cursor type switch (getc()){ case '0': lcd.noCursor(); lcd.noBlink(); break; case '2': lcd.cursor(); lcd.noBlink(); break; case '3': lcd.cursor(); lcd.blink(); break; default: break; } break; case 'f': // Clear screen lcd.clear(); ncol=0; nrow=0; break; case 'g': //beep tone(BP,4000,250); break; case 'h': // Move cursor back if(ncol>0){ lcd.command(16); ncol=ncol-1; } break; case 'i': // Move cursor forward if(ncol<maxcol){ lcd.command(20); ncol=ncol+1; } break; case 'j': //Cursor up if(nrow>0){ nrow=nrow-1; lcd.setCursor(ncol,nrow); } break; case 'k': //Cursor down if(nrow<maxrow){ nrow=nrow+1; lcd.setCursor(ncol,nrow); } break; case 'l': //clear cursor line ncol=0; // maxcol=20; lcd.setCursor(ncol,nrow); for(byte i=0;i<=maxcol-1;i++){lcd.write(' ');} ncol=0; lcd.setCursor(ncol,nrow); break; case 'm': //CR ncol=0; lcd.setCursor(ncol,nrow); break; case 'n': //CRLF ncol=0; if(nrow<maxrow-1){nrow=nrow+1;} lcd.setCursor(ncol,nrow); break; case 'x': temp=getn(); temp1=getn(); if(temp=='e'||temp1=='e'){ error(); break; } temp=temp*10+temp1; if(temp>maxcol-1){ error(); break; } ncol=temp; lcd.setCursor(ncol,nrow); break; case 'y': temp=getn(); if(temp=='e'){ error(); break; } if(temp>maxrow-1){ error(); break; } nrow=temp; lcd.setCursor(ncol,nrow); break; case 'B': temp=geth(); temp1=geth(); if(temp==0xff || temp1==0xff){break;} temp=temp<<4; ledbl=temp+temp1; EEPROM.write(ledblloc,ledbl); analogWrite(BL,ledbl); break; case 'G': //enter R,C temp=getn(); temp1=getn(); temp2=getn(); if(temp=='e' || temp1=='e' || temp2=='e'){error();break;} maxcol=temp1*10+temp2; maxrow=temp; EEPROM.write(maxcolloc,maxcol); EEPROM.write(maxrowloc,maxrow); break; } } else{ // Otherwise its a plain char so we print it to the LCD. lcd.write(rxbyte); ncol=ncol+1; } } /* * Waits for a byte to be available, reads and returns it. */ byte getc() { //get character while (Serial.available() == 0); return Serial.read(); } byte getn() { //get decimal digit byte temp; while (Serial.available() ==0); temp=Serial.read()-48; if(0>temp>9){ return 'e'; } else{ return temp; } } byte geth(){ //get hex digit byte temp=getc(); if(temp>=0x30 && temp<=0x39){ temp=temp-0x30; return temp; } if(temp>=0x61 && temp<=0x66){ temp=temp-0x57; return temp; } return 0xff; } void error(){ tone(6,4000,250); return; }
.
To Be Continued
|
No comments:
Post a Comment