Awaiting same. Kinda curious as to how anything can go wrong short of some unpublished timing requirement for your display. Especially on lines 1&2.Belial88:
Uploading video.
https://www.youtube.com/watch?v=mSWI6N3 … e=youtu.be
going to do more testing.
my lcd shows a buggy character with the degree symbol (*). Not sure how to fix that
edit. I think… the problem is only with the voltage reading. It doesnt muck up unless I use one of the voltage read characters. If I use one on the bottom line, the first 4-5 chars on the top line gets erased, and if I use it on the 3rd line, there’s some extension effect where it goes off and pushes into the 2nd line, like if I type “GPU VAXG: asdf " it’ll say GPU VAXG: asdf 1.6” and then continue up on line 2 …“19v line2stuff”
edit: no… somethings wrong, im just not sure what it is… there’s definitely some wrong with the voltmetering, but with ‘normal’ lcd stuff it’s mostly fine but there are issues… the first character of the 3rd line seems to dissapear if I go into the setup menu. that’s not a big deal, just restart smartie… im just confused now.
edit2: I think the lcd is just fine, there’s some weird issues like the 1st character of 3rd line goes away if I go into the menu but that is easily ‘fixed’ by having 2 screens or just restarting smartie. I think that the 3rd line is somehow wrapping into the 2nd line, but if i just dont use lines that go over it won’t be an issue, seems to only happen with scrolling lines too so its a non-issue.
The code does a simple display of Line 1 on line1, Line 2 on line2, etc, etc one time, when setup() executes. After every reset you did in the vid, that was AFU. That’s simple stuff, nothing to do w/Smartie or the USB buffering. I double checked that code, found a few mistakes. Double check that your wiring from Micro to LCD is per the pin definition (I believe it has to be but check anyway) in the code. Then run this test code below and see that initial Line 1, Line 2, line 3 and Line 4 all “print” out on their proper lines now. I’ve added some huge delays in a few places just to be sure. No need for any ‘fancy’ Smartie testing (leave it turned off). Just do some resets and observe that very 1’st display.
added delay test code
#include <VarSpeedServo.h> //variable speed servo library
#include <LiquidCrystal.h>
//declare the constants to be used
#define LEDPIN 13 //pin attached to LED
#define servoPIN 9 //Servo control line
#define SWitchPIN 2 //input from N.O. momentary switch
#define redPIN 11 //PWM pin for red LED backlight
#define greenPIN 10 //PWM pin for green LED backlight
#define bluePIN 12 //PWM pin for blue LED backlight
#define rsPIN 8 //reset pin for LCD
#define enablePIN 7 //enable pin for LCD
#define d4PIN 4 //data pin4 for LCD
#define d5PIN 5 //data pin5 for LCD
#define d6PIN 6 //data pin6 for LCD
#define d7PIN 3 //data pin7 for LCD
// these constants won't change. But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;
#define posOpenCMD 1900 //Define Clockwise Servo position in usec
#define posCloseCMD 600 //Define CounterClockwise Servo position in usec
#define DBdelay 2000 //Min time needed btw any 2 button presses, in msec
#define fastSPD 100 //speed setting; 1 = slowest, 255 is fastest (???)
#define slowSPD 15 //Speed Servo/Door opens and closes (15 is good average)
#define DIV_1 1.0 //gain correction for A0 channel
#define DIV_2 1.0 //note it's 1.0, not 1, to get full floating point accuracy
#define V_REF 2.54 //use the measured Aref voltage
//declare the variables used
volatile boolean doorOPEN = false; //desired door state set to closed
byte rxbyte = 0; //rxbyte is the received byte from Smartie
byte temp = 0;
volatile unsigned long SWtime = 0; //holds the time of the last valid switch push
float voltage1 = 0.0; // calculated voltage for A0
float voltage2 = 0.0; // calculated voltage for A1
LiquidCrystal lcd(rsPIN, enablePIN, d4PIN, d5PIN, d6PIN, d7PIN);
VarSpeedServo myServo; //create a servo object
void setup() {
//set the pins to be ins or outs
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW); //turn LED off
pinMode(servoPIN, OUTPUT);
pinMode(SWitchPIN, INPUT_PULLUP);
pinMode(redPIN, OUTPUT);
pinMode(greenPIN, OUTPUT);
pinMode(bluePIN, OUTPUT);
attachInterrupt(1, SW_ISR, FALLING);
Serial.begin(9600);
lcd.begin(numCols, numRows);
//add in test delays
delay(50);
lcd.clear();
delay(5);
analogWrite(bluePIN,0); //Blue brightness 255-0
analogWrite(redPIN,255); //Red brightness 255-0
analogWrite(greenPIN,255); //Green brightness 255-0
analogReference(INTERNAL); //use the internal 2.56v ADC reference
//CMD the servo to close the door
myServo.attach(servoPIN); // Attach the servo
myServo.slowmove(posCloseCMD, fastSPD); // Tell servo to go to closed position
//put a hello world on the LCD
//got rid of home cmd
lcd.print("Line 1");
lcd.setCursor(3, 1);
lcd.print("Line 2");
lcd.setCursor(8, 2);
lcd.print("Line 3");
lcd.setCursor(13, 3);
lcd.print("Line 4");
delay(2000);
}
//the following function is the ISR that responds to the push button switch
//it commands the door to open or close at slow speed
void SW_ISR(){
//debounce the switch by ignoring any interrupt that occurs too soon after the prior one
unsigned long Time = millis();
if(Time - SWtime > DBdelay){ //enough time has elapsed, not a switch bounce
SWtime = Time; //save new time of switch push
doorOPEN = !doorOPEN; //reverse desired door state
if(doorOPEN == true){
digitalWrite(LEDPIN, HIGH); //turn LED on
myServo.slowmove(posOpenCMD, slowSPD); //tell servo to go to open position
}
else {
digitalWrite(LEDPIN, LOW); //turn LED off
myServo.slowmove(posCloseCMD, slowSPD); //tell servo to go to closed position
}
}
}
//this function is used by the smartie code to get data from the PC
byte serial_getch(){
int incoming;
while (Serial.available()==0){
}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
//the main loop is now just the hacked version of the Arduino Smartie code
void loop(){
rxbyte = serial_getch(); //this calls the 'function' serial_getch(), stores result in rxbyte
if (rxbyte == 254) //Matrix uses 254 for commands, if rxbyte = 254 the the code below runs
{
switch (serial_getch()) //calls serial_getch() to get the next byte from the PC
{
case 66: //former backlight on command
break;
case 70: //former backlight off command
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.command(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.command(2);
break;
case 74: //show underline cursor
lcd.command(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.command(0b00001100);
break;
case 76: //move cursor left
lcd.command(16);
break;
case 77: //move cursor right
lcd.command(20);
break;
case 78: //define custom char
lcd.command(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.command(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.command(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
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 0x5B: //Formerly [, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
break;
case 0x5D: //Formerly ], now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
break;
case 0x7B: //Formerly left brace, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
break;
case 0x7D: //Formerly right brace, now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
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.write(rxbyte); //otherwise a plain char so we print it to lcd
}
If this doesn’t work, show this code and a vid of the display after reset (a few tries) to the Adafruit support people and ask for a return. If a simple lcd.setCursor() and lcd.print() direct from the MCU won’t work, Smartie won’t either.
If Line1, etc display proper, repeat a test where Smartie shows up wrong.
OK, I think I figured it out, thanks to my screw up in trying to get Line1, Line2, etc to display and seeing the results in your vid. Do the simple reset test above and hopefully that’s all working. Meanwhile I’ll figure out how to fix the missing character problem.
The problem stems from Smartie sending all 20 characters/line. When a special character ([,],{,}) is sent, it results in 6 characters being sent to the LCD, direct from the Micro, that Smartie doesn’t account for. That means there will be 5 “extra” characters when Smartie gets done w/that line. I figured that line 3 might rollover onto line 4, and line 4 onto line 1 but I didn’t see that exactly, and couldn’t figure on line 2 ever being affected. Plus it sounded like the problem happened even when Smartie didn’t send a special character. So I dismissed the obvious cause initially, but seeing the vid revised my thinking on ‘wrapover’.
That initial screen of Line 1 on line1, etc, etc showed me the extra spaces go someplace odd instead of being dropped. They don’t just wrapover into the next line. So the revised baseline code below ignores the next 5 chars after any special character. Let’s see if this solves the problem. I think it will !
revised baseline code, ignores 5 chars as needed
#include <VarSpeedServo.h> //variable speed servo library
#include <LiquidCrystal.h>
//declare the constants to be used
#define LEDPIN 13 //pin attached to LED
#define servoPIN 9 //Servo control line
#define SWitchPIN 2 //input from N.O. momentary switch
#define redPIN 11 //PWM pin for red LED backlight
#define greenPIN 10 //PWM pin for green LED backlight
#define bluePIN 12 //PWM pin for blue LED backlight
#define rsPIN 8 //reset pin for LCD
#define enablePIN 7 //enable pin for LCD
#define d4PIN 4 //data pin4 for LCD
#define d5PIN 5 //data pin5 for LCD
#define d6PIN 6 //data pin6 for LCD
#define d7PIN 3 //data pin7 for LCD
// these constants won't change. But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;
#define posOpenCMD 1900 //Define Clockwise Servo position in usec
#define posCloseCMD 600 //Define CounterClockwise Servo position in usec
#define DBdelay 2000 //Min time needed btw any 2 button presses, in msec
#define fastSPD 100 //speed setting; 1 = slowest, 255 is fastest (???)
#define slowSPD 15 //Speed Servo/Door opens and closes (15 is good average)
#define DIV_1 1.0 //gain correction for A0 channel
#define DIV_2 1.0 //note it's 1.0, not 1, to get full floating point accuracy
#define V_REF 2.54 //use the measured Aref voltage
//declare the variables used
volatile boolean doorOPEN = false; //desired door state set to closed
byte rxbyte = 0; //rxbyte is the received byte from Smartie
byte temp = 0;
int ignoreCNT = 0;
volatile unsigned long SWtime = 0; //holds the time of the last valid switch push
float voltage1 = 0.0; // calculated voltage for A0
float voltage2 = 0.0; // calculated voltage for A1
LiquidCrystal lcd(rsPIN, enablePIN, d4PIN, d5PIN, d6PIN, d7PIN);
VarSpeedServo myServo; //create a servo object
void setup() {
//set the pins to be ins or outs
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW); //turn LED off
pinMode(servoPIN, OUTPUT);
pinMode(SWitchPIN, INPUT_PULLUP);
pinMode(redPIN, OUTPUT);
pinMode(greenPIN, OUTPUT);
pinMode(bluePIN, OUTPUT);
attachInterrupt(1, SW_ISR, FALLING);
Serial.begin(9600);
lcd.begin(numCols, numRows);
delay(50);
lcd.clear();
delay(5);
analogWrite(bluePIN,0); //Blue brightness 255-0
analogWrite(redPIN,255); //Red brightness 255-0
analogWrite(greenPIN,255); //Green brightness 255-0
analogReference(INTERNAL); //use the internal 2.56v ADC reference
//CMD the servo to close the door
myServo.attach(servoPIN); // Attach the servo
myServo.slowmove(posCloseCMD, fastSPD); // Tell servo to go to closed position
//put a hello world on the LCD
lcd.print("Line 1");
lcd.setCursor(3, 1);
lcd.print("Line 2");
lcd.setCursor(8, 2);
lcd.print("Line 3");
lcd.setCursor(13, 3);
lcd.print("Line 4");
delay(2000);
}
//the following function is the ISR that responds to the push button switch
//it commands the door to open or close at slow speed
void SW_ISR(){
//debounce the switch by ignoring any interrupt that occurs too soon after the prior one
unsigned long Time = millis();
if(Time - SWtime > DBdelay){ //enough time has elapsed, not a switch bounce
SWtime = Time; //save new time of switch push
doorOPEN = !doorOPEN; //reverse desired door state
if(doorOPEN == true){
digitalWrite(LEDPIN, HIGH); //turn LED on
myServo.slowmove(posOpenCMD, slowSPD); //tell servo to go to open position
}
else {
digitalWrite(LEDPIN, LOW); //turn LED off
myServo.slowmove(posCloseCMD, slowSPD); //tell servo to go to closed position
}
}
}
//this function is used by the smartie code to get data from the PC
byte serial_getch(){
int incoming;
while (Serial.available()==0){
}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
//the main loop is now just the hacked version of the Arduino Smartie code
void loop(){
rxbyte = serial_getch(); //this calls the 'function' serial_getch(), stores result in rxbyte
if (rxbyte == 254) //Matrix uses 254 for commands, if rxbyte = 254 the the code below runs
{
ignoreCNT == 0; //turn off character ignoring whenever a command is sent
switch (serial_getch()) //calls serial_getch() to get the next byte from the PC
{
case 66: //former backlight on command
break;
case 70: //former backlight off command
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.command(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.command(2);
break;
case 74: //show underline cursor
lcd.command(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.command(0b00001100);
break;
case 76: //move cursor left
lcd.command(16);
break;
case 77: //move cursor right
lcd.command(20);
break;
case 78: //define custom char
lcd.command(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.command(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.command(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
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 0x5B: //Formerly [, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = 5;
break;
case 0x5D: //Formerly ], now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = 5;
break;
case 0x7B: //Formerly left brace, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = 5;
break;
case 0x7D: //Formerly right brace, now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = 5;
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;
}
if(ignoreCNT > 0){
ignoreCNT--;
}
if(ignoreCNT == 0){
lcd.write(rxbyte); //otherwise a plain char so we print it to lcd
}
}
If you haven’t run the ‘reset tests’ w/the earlier test code, don’t bother to now. Just use this revised code and see if everything works, including that initial screen.
The code does a simple display of Line 1 on line1, Line 2 on line2, etc, etc one time, when setup() executes. After every reset you did in the vid, that was AFU. That’s simple stuff, nothing to do w/Smartie or the USB buffering. I double checked that code, found a few mistakes. Double check that your wiring from Micro to LCD is per the pin definition (I believe it has to be but check anyway) in the code. Then run this test code below and see that initial Line 1, Line 2, line 3 and Line 4 all “print” out on their proper lines now. I’ve added some huge delays in a few places just to be sure. No need for any ‘fancy’ Smartie testing (leave it turned off). Just do some resets and observe that very 1’st display.
Yes, I know your code was odd. Everytime I posted code, your code, etc, I always corrected it, but you never used it. It’s kinda annoying but I wasnt going to say anything lol. You had the color pins mixed up, and you have Enable and d7 mixed up. Of course I always changed this to match my pin-out. As for the text Line1/Line2, I mean it’s not a big deal, you just add a digit to the first part (ie 10,1/20,2/30,3) should be (0,1/0,2/0,3/0,4).
Here’s the ‘new baseline code’ as it should be, as I used it for the youtube video. I didn’t change the text line1/line2 because i mean it’s not imporatnt.
#include <VarSpeedServo.h> //variable speed servo library
#include <LiquidCrystal.h>
//declare the constants to be used
#define LEDPIN 13 //pin attached to LED
#define servoPIN 9 //Servo control line
#define SWitchPIN 2 //input from N.O. momentary switch
#define redPIN 12 //PWM pin for red LED backlight
#define greenPIN 11 //PWM pin for green LED backlight
#define bluePIN 10 //PWM pin for blue LED backlight
#define rsPIN 8 //reset pin for LCD
#define enablePIN 3 //enable pin for LCD
#define d4PIN 4 //data pin4 for LCD
#define d5PIN 5 //data pin5 for LCD
#define d6PIN 6 //data pin6 for LCD
#define d7PIN 7 //data pin7 for LCD
;
When you first posted the code it was like this (well color pins were different, i made it so the wiring was less tied up as the pines on the lcd are, left to right, Blue/Red/Green). Your new code shows Line1/2/3/4 cascaded down each consecutive line:
Line1
…Line2
…Line3
…Line4
Anyways that first code you posted, I don’t know what you changed, but all the LCD issues on it’s own seem to have gone away. Can’t really get anything to dissapear, so that’s cool. However still Voltage issue, with changing between 2 screens the first 5 chars on the top 2 lines will not display, sometimes flash.
Okay using the second code, I’ve noticed that it’s just the 1st space that’s messed up on the top 2 lines.
OK, that's fixed ... so are lines 1/2 still bugged out ?Belial88:
When you first posted the code it was like this (well color pins were different, i made it so the wiring was less tied up as the pines on the lcd are, left to right, Blue/Red/Green). Your new code shows Line1/2/3/4 cascaded down each consecutive line:Line1
…Line2
…Line3
…Line4
Okay so this is what i got. Using your newer code, it’s only the first space of the top 2 lines that’s buggy (wont show, sometimes flashes). I checked the older, err the 1st of the 2 codes you posted, and that one is definitely buggier - it’s the first 5 and 6 (for lines 1 and 2) spaces that are buggy like that. Like before, I believe.
I dont know what the differences are, but the newer code you posted, yea if I just put a single space on lines 1 and 2it’s all good. So we’ve got an acceptable solution now! Yay, as in it’s satisfactory to install, hardwire, etc.
edit: okay the differences is ignorecnts. yea you should.
on an odd note, if I slide the brightness or contrast sliders in the lcd smartie GUI, it bugs out. Like, all these odd cahracters take up most of the spaces, and when I slide the contrast or brightness bar either way, they all ‘slide’ rightwards on various lines and interconnected between the lines, etc. Not sure if relevant, just odd. It ‘resets’ itself to what it’s supposed to display after I close the setup menu after a few seconds.
edit: degree symbol was fixed
I increased the # of chars ignored by 1 so there shouldn't be any more corruption.Belial88:
I dont know what the differences are, but the newer code you posted, yea if I just put a single space on lines 1 and 2it’s all good. So we’ve got an acceptable solution now! Yay, as in it’s satisfactory to install, hardwire, etc.
Not sure what to say about the brightness, etc commands. My guess is that Smartie is sending a command code that is unrecognized and thus triggers this snippet of code. It, for some reason, reads the next byte and tosses it away. Perhaps loosing a character and shifting a line left ?
default:
//all other commands ignored and parameter byte discarded
temp = serial_getch(); //dump the command code
break;
}
return;
} //END OF COMMAND HANDLER
So here’s the new baseline code
#include <VarSpeedServo.h> //variable speed servo library
#include <LiquidCrystal.h>
//declare the constants to be used
#define LEDPIN 13 //pin attached to LED
#define servoPIN 9 //Servo control line
#define SWitchPIN 2 //input from N.O. momentary switch
#define redPIN 12 //PWM pin for red LED backlight
#define greenPIN 11 //PWM pin for green LED backlight
#define bluePIN 10 //PWM pin for blue LED backlight
#define rsPIN 8 //reset pin for LCD
#define enablePIN 3 //enable pin for LCD
#define d4PIN 4 //data pin4 for LCD
#define d5PIN 5 //data pin5 for LCD
#define d6PIN 6 //data pin6 for LCD
#define d7PIN 7 //data pin7 for LCD
// these constants won't change. But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;
const int ignoreMAX = 6;
#define posOpenCMD 1900 //Define Clockwise Servo position in usec
#define posCloseCMD 600 //Define CounterClockwise Servo position in usec
#define DBdelay 2000 //Min time needed btw any 2 button presses, in msec
#define fastSPD 100 //speed setting; 1 = slowest, 255 is fastest (???)
#define slowSPD 15 //Speed Servo/Door opens and closes (15 is good average)
#define DIV_1 1.0 //gain correction for A0 channel
#define DIV_2 1.0 //note it's 1.0, not 1, to get full floating point accuracy
#define V_REF 2.54 //use the measured Aref voltage
//declare the variables used
volatile boolean doorOPEN = false; //desired door state set to closed
byte rxbyte = 0; //rxbyte is the received byte from Smartie
byte temp = 0;
int ignoreCNT = 0;
volatile unsigned long SWtime = 0; //holds the time of the last valid switch push
float voltage1 = 0.0; // calculated voltage for A0
float voltage2 = 0.0; // calculated voltage for A1
LiquidCrystal lcd(rsPIN, enablePIN, d4PIN, d5PIN, d6PIN, d7PIN);
VarSpeedServo myServo; //create a servo object
void setup() {
//set the pins to be ins or outs
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW); //turn LED off
pinMode(servoPIN, OUTPUT);
pinMode(SWitchPIN, INPUT_PULLUP);
pinMode(redPIN, OUTPUT);
pinMode(greenPIN, OUTPUT);
pinMode(bluePIN, OUTPUT);
attachInterrupt(1, SW_ISR, FALLING);
Serial.begin(9600);
lcd.begin(numCols, numRows);
delay(50);
lcd.clear();
delay(5);
analogWrite(bluePIN,0); //Blue brightness 255-0
analogWrite(redPIN,255); //Red brightness 255-0
analogWrite(greenPIN,255); //Green brightness 255-0
analogReference(INTERNAL); //use the internal 2.56v ADC reference
//CMD the servo to close the door
myServo.attach(servoPIN); // Attach the servo
myServo.slowmove(posCloseCMD, fastSPD); // Tell servo to go to closed position
//put a hello world on the LCD
lcd.print("Line 1");
lcd.setCursor(3, 1);
lcd.print("Line 2");
lcd.setCursor(8, 2);
lcd.print("Line 3");
lcd.setCursor(13, 3);
lcd.print("Line 4");
delay(2000);
}
//the following function is the ISR that responds to the push button switch
//it commands the door to open or close at slow speed
void SW_ISR(){
//debounce the switch by ignoring any interrupt that occurs too soon after the prior one
unsigned long Time = millis();
if(Time - SWtime > DBdelay){ //enough time has elapsed, not a switch bounce
SWtime = Time; //save new time of switch push
doorOPEN = !doorOPEN; //reverse desired door state
if(doorOPEN == true){
digitalWrite(LEDPIN, HIGH); //turn LED on
myServo.slowmove(posOpenCMD, slowSPD); //tell servo to go to open position
}
else {
digitalWrite(LEDPIN, LOW); //turn LED off
myServo.slowmove(posCloseCMD, slowSPD); //tell servo to go to closed position
}
}
}
//this function is used by the smartie code to get data from the PC
byte serial_getch(){
int incoming;
while (Serial.available()==0){
}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
//the main loop is now just the hacked version of the Arduino Smartie code
void loop(){
rxbyte = serial_getch(); //this calls the 'function' serial_getch(), stores result in rxbyte
if (rxbyte == 254) //Matrix uses 254 for commands, if rxbyte = 254 the the code below runs
{
ignoreCNT == 0; //turn off character ignoring whenever a command is sent
switch (serial_getch()) //calls serial_getch() to get the next byte from the PC
{
case 66: //former backlight on command
break;
case 70: //former backlight off command
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.command(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.command(2);
break;
case 74: //show underline cursor
lcd.command(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.command(0b00001100);
break;
case 76: //move cursor left
lcd.command(16);
break;
case 77: //move cursor right
lcd.command(20);
break;
case 78: //define custom char
lcd.command(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.command(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.command(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
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 0x5B: //Formerly [, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX;
break;
case 0x5D: //Formerly ], now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX;
break;
case 0x7B: //Formerly left brace, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX;
break;
case 0x7D: //Formerly right brace, now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX;
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;
}
if(ignoreCNT > 0){
ignoreCNT--;
}
if(ignoreCNT == 0){
lcd.write(rxbyte); //otherwise a plain char so we print it to lcd
}
}
It works! I need my wire to come in so I can install of this, but yay!
It’s fairly functional. It does 2 of the 3 things that I’d consider ‘needed’ to be ‘done’. You can control, via Smartie set-up alone, where on any line and when (if) the ADC readings display. You can place any text ahead of the readings, again determined by Smartie. Where it misses is that you can’t specify (right now) the refresh rate/timing. You have to do this goofy 2 screen deal. So I’m going to let some fix for that percolate in my mind.
Are you always going to have 1 line changing, being updated ? If so I believe it would be possible to trigger the ADC reading(s) to update at that same time. No need for swapping btw 2 screens. Perhaps have a timeout as well, refresh the readings every XXX msec even if no screen changes. I’d consider that to be good enough to be done.
https://www.youtube.com/watch?v=9K0unPHVsNA
Sorry it took a while, I cant install this until I get another big mod done… man i never use my pc. to think i once played like, video games or got on reddit.
Are you always going to have 1 line changing, being updated ? If so I believe it would be possible to trigger the ADC reading(s) to update at that same time. No need for swapping btw 2 screens. Perhaps have a timeout as well, refresh the readings every XXX msec even if no screen changes. I’d consider that to be good enough to be done.
I’m not sure what you mean. I’ll have the screen set-up something like in the video and how I’ve discussed so far, ie top 2 lines hwinfo, bottom lines voltage.
It’s highly acceptable now, meaning it’s good enough that I can get to soldering, sleeving, braiding, and drilling holes and installation. Just a few weeks ago it was a considered option to buy a different MCU or just run software crap on the lcd, or buy some dedicated LED 7-seg voltmeters (like I was originally intending).
What I mean is that swappping btw 2 screens to trick Smartie into sending the special characters is a bit goofy. Plus it ties your refresh rate on the ADC stuff to 1/sec, the min screen display time.Belial88:
Are you always going to have 1 line changing, being updated ? If so I believe it would be possible to trigger the ADC reading(s) to update at that same time. No need for swapping btw 2 screens. Perhaps have a timeout as well, refresh the readings every XXX msec even if no screen changes. I’d consider that to be good enough to be done.
I’m not sure what you mean. I’ll have the screen set-up something like in the video and how I’ve discussed so far, ie top 2 lines hwinfo, bottom lines voltage.
What could be done is to have the Arduino log the ‘time’ it receives a cursor position command, which we know Smartie sends before each LCD update. Then, perhaps 50 msec, later the Arduino could do it’s ADC stuff and update the LCD. This way the ADC data is updated whenever any other data is, but on a time-shared, non-interfering basis. The trick to making this work is to have the Arduino memorize the row and column position of the special characters, the one time Smartie sends them.
Here’s that code. It seems to work so far as I can test. With it you just use the [ and ] to get the A0 and A1 voltages. No need to switch btw screens (that no longer works). The voltages should update with the other info displayed. See if it works for you.
non-swapping baseline ver 0.0
#include <VarSpeedServo.h> //variable speed servo library
#include <LiquidCrystal.h>
//declare the constants to be used
#define LEDPIN 13 //pin attached to LED
#define servoPIN 9 //Servo control line
#define SWitchPIN 2 //input from N.O. momentary switch
#define redPIN 12 //PWM pin for red LED backlight
#define greenPIN 11 //PWM pin for green LED backlight
#define bluePIN 10 //PWM pin for blue LED backlight
#define rsPIN 8 //reset pin for LCD
#define enablePIN 3 //enable pin for LCD
#define d4PIN 4 //data pin4 for LCD
#define d5PIN 5 //data pin5 for LCD
#define d6PIN 6 //data pin6 for LCD
#define d7PIN 7 //data pin7 for LCD
// these constants won't change. But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;
const int ignoreMAX = 6; //ignore this many characters
const unsigned long wait = 50;//wait time for ADC update after last Smartie cmd
#define posOpenCMD 1900 //Define Clockwise Servo position in usec
#define posCloseCMD 600 //Define CounterClockwise Servo position in usec
#define DBdelay 2000 //Min time needed btw any 2 button presses, in msec
#define fastSPD 100 //speed setting; 1 = slowest, 255 is fastest (???)
#define slowSPD 15 //Speed Servo/Door opens and closes (15 is good average)
#define DIV_1 1.0 //gain correction for A0 channel
#define DIV_2 1.0 //note it's 1.0, not 1, to get full floating point accuracy
#define V_REF 2.54 //use the measured Aref voltage
//declare the variables used
boolean updateFlag = false; //flag to refresh ADC readings
volatile boolean doorOPEN = false; //desired door state set to closed
byte rxbyte = 0; //rxbyte is the received byte from Smartie
byte temp = 0;
int ignoreCNT = 0; //count of characters to ignore
int row = 0; //index of last row position
int col = 0; //index of last col position
int rowA0 = 0; //index of A0 row position
int colA0 = 0; //index of A0 col position
int rowA1 = 0; //index of A1 row position
int colA1 = 0; //index of A1 col position
unsigned long MSGtime = 0; //holds the time of the last cursor cmd
volatile unsigned long SWtime = 0; //holds the time of the last valid switch push
float voltage1 = 0.0; // calculated voltage for A0
float voltage2 = 0.0; // calculated voltage for A1
LiquidCrystal lcd(rsPIN, enablePIN, d4PIN, d5PIN, d6PIN, d7PIN);
VarSpeedServo myServo; //create a servo object
void setup() {
//set the pins to be ins or outs
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, LOW); //turn LED off
pinMode(servoPIN, OUTPUT);
pinMode(SWitchPIN, INPUT_PULLUP);
pinMode(redPIN, OUTPUT);
pinMode(greenPIN, OUTPUT);
pinMode(bluePIN, OUTPUT);
attachInterrupt(1, SW_ISR, FALLING);
Serial.begin(9600);
lcd.begin(numCols, numRows);
delay(50);
lcd.clear();
delay(5);
analogWrite(bluePIN,0); //Blue brightness 255-0
analogWrite(redPIN,255); //Red brightness 255-0
analogWrite(greenPIN,255); //Green brightness 255-0
analogReference(INTERNAL); //use the internal 2.56v ADC reference
//CMD the servo to close the door
myServo.attach(servoPIN); // Attach the servo
myServo.slowmove(posCloseCMD, fastSPD); // Tell servo to go to closed position
//put a hello world on the LCD
lcd.print("Line 1");
lcd.setCursor(3, 1);
lcd.print("Line 2");
lcd.setCursor(8, 2);
lcd.print("Line 3");
lcd.setCursor(13, 3);
lcd.print("Line 4");
delay(2000);
}
//the following function is the ISR that responds to the push button switch
//it commands the door to open or close at slow speed
void SW_ISR(){
//debounce the switch by ignoring any interrupt that occurs too soon after the prior one
unsigned long Time = millis();
if((Time - SWtime > DBdelay) && (Time > SWtime)){//enough time has elapsed, not a bounce
SWtime = Time; //save new time of switch push
doorOPEN = !doorOPEN; //reverse desired door state
if(doorOPEN == true){
digitalWrite(LEDPIN, HIGH); //turn LED on
myServo.slowmove(posOpenCMD, slowSPD); //tell servo to go to open position
}
else {
digitalWrite(LEDPIN, LOW); //turn LED off
myServo.slowmove(posCloseCMD, slowSPD); //tell servo to go to closed position
}
}
}
//this function is used by the smartie code to get data from the PC
byte serial_getch(){
int incoming;
while (Serial.available()==0){
//check to see if enough time has passed since last message from PC
if((millis() - MSGtime > wait) && (updateFlag == true)){
updateADC();
}
}
// read the incoming byte:
incoming = Serial.read();
return (byte) (incoming &0xff);
}
//this function will update the ADC readings if the [ or ] have been sent
void updateADC(){
updateFlag = false;
if(colA0 > 0){
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.setCursor(colA0, rowA0);
lcd.print(voltage1, 3);
}
if(colA1 > 0){
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.setCursor(colA1, rowA1);
lcd.print(voltage2, 3);
}
}
//the main loop is now just the hacked version of the Arduino Smartie code
void loop(){
rxbyte = serial_getch(); //this calls the 'function' serial_getch(), stores result in rxbyte
if (rxbyte == 254) //Matrix uses 254 for commands, if rxbyte = 254 the the code below runs
{
ignoreCNT == 0; //turn off character ignoring whenever a command is sent
switch (serial_getch()) //calls serial_getch() to get the next byte from the PC
{
case 66: //former backlight on command
break;
case 70: //former backlight off command
break;
case 71: //set cursor position
MSGtime = millis(); //remember time that cursor cmd was sent
updateFlag = true; //set flag to update ADC readings
row = 0;
col = 0;
temp = (serial_getch() - 1); //get column byte
switch (serial_getch()) //get row byte
{
//line 1 is already set up
case 2:
row = 1;
temp += 0x40;
break;
case 3:
row = 2;
temp += 0x14;
break;
case 4:
row = 3;
temp += 0x54;
break;
default:
break;
}
lcd.command(0b10000000 + temp);
break;
case 72: //cursor home (reset display position)
lcd.command(2);
break;
case 74: //show underline cursor
lcd.command(0b00001110);
break;
case 75: //underline cursor off
case 84: //block cursor off
lcd.command(0b00001100);
break;
case 76: //move cursor left
lcd.command(16);
break;
case 77: //move cursor right
lcd.command(20);
break;
case 78: //define custom char
lcd.command(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.command(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.command(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
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 0x5B: //Formerly [, now does A0 ADC
voltage1 = DIV_1 * float(analogRead(A0)) * V_REF/1023.0;
lcd.print(voltage1, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX; //ignore characters replaced by ADC reading
updateFlag = false; //reset ADC update flag
rowA0 = row; //store row of A0 reading
colA0 = col; //store col of A0 reading
break;
case 0x5D: //Formerly ], now does A1 ADC
voltage2 = DIV_2 * float(analogRead(A1)) * V_REF/1023.0;
lcd.print(voltage2, 3);
rxbyte = 0x76; //will cause v to be displayed
ignoreCNT = ignoreMAX; //ignore characters replaced by ADC reading
updateFlag = false; //reset ADC update flag
rowA1 = row; //store row of A1 reading
colA1 = col; //store col of A1 reading
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;
}
if(ignoreCNT > 0){
ignoreCNT--;
}
if(ignoreCNT == 0){
col++; //increment column position counter
lcd.write(rxbyte); //otherwise a plain char so we print it to lcd
}
}
Does it blend … errr, work ?
I haven’t tested it yet, I’ll try it tonight.
There’s something I never got figured out - with how you can scale the 1024 up for higher voltages (and reduced accuracy), can I reduce the ~2.56VREF down, so I have a max voltage read of ~1.5 but increased accuracy? So just add a divider to the voltage lines for like x.6DIV? I don’t remember what we decided on that.
Argggg ... I'll try one more time to 'splain it. You need to understand the voltage divider concept and the basic, ideal, concept of how any ADC works. Without those, any explanation I'd put up wont 'take'.Belial88:
There’s something I never got figured out - with how you can scale the 1024 up for higher voltages (and reduced accuracy), can I reduce the ~2.56VREF down, so I have a max voltage read of ~1.5 but increased accuracy? So just add a divider to the voltage lines for like x.6DIV? I don’t remember what we decided on that.
http://en.wikipedia.org/wiki/Voltage_divider
http://www.facstaff.bucknell.edu/mastas … onvAD.html
The important concept being any ADC compares it’s input voltage to it’s reference voltage, and outputs a count proportional to the ratio btw that and it’s bit width. If the input is 2.5v compared to a 5v reference, then you get an output of 50% {2.5v/5v} of 1024 (for a 10 bit ADC) = 512. If the ADC reference voltage is 2.56v then the ratio changes even if the input voltage doesn’t. 2.5/2.56 = 1008 ADC counts. So by reducing the ADC ref voltage from 5v to 2.56v, you’ve increased the sensitivity, the ADC count/V input, by an inversely proportional amount.
okay so you need a resistor to bring down that super high voltage. But the opposite of a resistor does not exist. So I could… use a divider, but it wouldn’t increase accuracy, only change the range of the voltage measured. and I can’t reduce the voltage reference further because the arduino doesnt go any lower. got it.
can you seriously not edit posts?
Can this same mod be done with a TFT?