/*
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;
}