How to Use a Screen to Display CPU Temp (not thermistor)?

Belial88:
ohh okay… so you really just need a resistor in the line… but a resistor might not always exist for what you want, so you just use a pot. And so you turn the max voltage you want into 2.56v (or 2.54 in my case if aref = 2.54). But since having a 2.8v thing isnt always on hand, you can just make, like, 1.8v x (AREF / Max Voltage Wanted, or .89 for 2.8v) = 1.602…

so really, for 2.8v, you just put a 89% Resistor on the line and then put the divider to whatever. I googled 89% resistors but couldnt find any. Maybe i could use like a 90% resistor or whatever is commonly sold and settle for like 2.81v… or just use a pot.

Actually in this case you want to use the pot in it's 3 terminal mode so it looks like the 2 resistors in the voltage divider wiki link. Varying the wiper simultaneously changes the values of both the 'top' and 'bottom' resistors. You could just use 2 resistors that give you the desired ratio but you'll have to measure that ratio since all resistors have some tolerance and so aren't guaranteed to exactly be their nominal value. I just figured a pot would be simpler.

Belial88:
It doesnt ever send brightness commands because… we set the lcd to just be on in setup.

okay so i see what you are getting at, if I go into lcd smartie and hit ‘backlight on’ one of the lines comes up, then backlight off and the other one comes up. But I dont see any commands in the arduino code that i understand dont do anything.

OK, there isn't any command line control, just a GUI control, at the PC Smartie setup screen. So there's no way to send those commands as I had envisioned.

Well I have another way. I noticed from this page there should be inline commands to use ‘special characters’. That code didn’t exist at the Arduino end so I created it. A command to use special character 3 does the A0 conversion stuff. A command to use special character 4 does the A1 conversion stuff.

http://lcdsmartie.sourceforge.net/commands.html

On the Smartie setup GUI, on line 3, put CPU VCORE $Chr(131)

On the Smartie setup GUI, on line 4, put CPU VRIN $Chr(132)

So lines 3 and 4 look like this;

(click on to open)

See how that works. You can add spaces and change the characters above to make it look good.

revised 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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


//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 0x83: //Formerly special char 3, 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 0x84: //Formerly special char 4, 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
}

Mee_n_Mac:
I just figured a pot would be simpler.

A pot would just be another source of instability.

Whether resistor divider or pot you are still going to have to calibrate whatever you have.

The ratio of 89.whatever is not sacred, that is the maximum you could use.

You could use, 50%, you just start losing resolution of the digital value.

Use a 1.2K resistor on the top and a 10K resistor on the bottom.

That happens to give you 89.2857%

(Not that that’s really important.)

By top and bottom, you mean like Arduino Analog pin - wire - 10k resistor - 12k resistor - wire - item to be measured?

The new code, it says:

CPU VCORE |3 (some weird character like that kinda)

CPU VR (sometimes it’ll be CPU VRIN |3 weird character that’s slightly different looking)

In smartie’s gui it says CPU VCORE (black box)

CPU VRIN (black box)

I also tried it like how you pictured, where it’s spaced out a bit and the 2nd line (VRIN) has a | at the start of it, it just makes it start further out. No response to voltage reads.

Belial88:
The new code, it says:

CPU VCORE |3 (some weird character like that kinda)

CPU VR (sometimes it’ll be CPU VRIN |3 weird character that’s slightly different looking)

In smartie’s gui it says CPU VCORE (black box)

CPU VRIN (black box)

I also tried it like how you pictured, where it’s spaced out a bit and the 2nd line (VRIN) has a | at the start of it, it just makes it start further out. No response to voltage reads.

Hmmmm let's see if Smartie sends the ASCII code I think it's supposed to be sending. I've commented out the ADC stuff. The prior line 3 and 4 commands should now display this on the LCD lines 3 and 4;

CPU VCORE v

CPU VRIN v

The | in the pic above was a mistake. The Smartie screen that shows what the LCD is supposed to look like wont match the LCD because the Arduino code is altered. Mine shows the same thing.

new 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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


//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 0x83: //Formerly special char 3, 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 0x84: //Formerly special char 4, 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
}

FWIW the last 2 cases (0x83, 0x84) in the code snippet below is what I added to the Arduino Smartie code above. You’ll note the ADC portions are commented out. I’m curious to see if there’s a timing problem.

  //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 0x83: //Formerly special char 3, 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 0x84: //Formerly special char 4, 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;

Same thing with new code ;/

Belial88:
Same thing with new code ;/

OK that's kinda good. Let's do 2 tests to show if my understanding of how Smartie works is correct. The test code below sacrifices the [ and ] characters to do the stuff you want. Using the code presently in the Arduino tell Smartie to send the following on lines 3 and 4.

CPU VCORE [

CPU VRIN ]

Hopefully the LCD displays exactly the above. Then install this new test code and tell Smartie to send the same again. Hopefully you get the desired ADC voltages.

new 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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


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

The portion in the above that was changed.

  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;

Okay so I just found a weird issue. The 4th line of the LCD never fully displays when I start up LCD Smartie, it seems to only display to 6 characters when I launch it, regardless of what is written for it to display on the display. It only displays all of it if I edit the line. This happens with all the code, even the original/tutorial lcd smartie only.

The voltmetering, it doesnt update, like with the backlight on/off thing. It only updates if I remove the [ or ], then reapply it, in GUI.

OK making some progress. The PC Smartie sends ASCII characters as I thought. It seems to to something unexpected with any extended ASCII characters. The last line seems to be some timing issue, almost apart from the hacked Arduino code as it doesn’t even complete the CPU VRIN.

What happened with the 1’st test ?

Are you saying that if you make the last line CPU VRIN x, where x is anything except a [ or ], that it always displays CPU VRIN x correctly ?

In the Smartie setup GUI what do you have for the refresh interval and startup parameters ? I assume any scrolling is disabled.

More info: So LCD smartie will, on launch, on the 4th line, only show up to 5-6 characters, it seems to change, and only the first 5 will change dynamically. After running for a min or so sometimes a character or few will add on. Once launched, it’ll show the 4th line if I edit it - however, if it’s a changing line, like dynamic values or switching screens, the line will be frozen after 5 characters. Like only the first 5 will change. If I just program the lcd, it’s fine. In general it’s kinda buggy, like if I have scrolling screens, it’ll often freeze stuff at the end of the line.

So with the last code on last page, the 1st test, with special char

#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;

#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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


//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 0x83: //Formerly special char 3, 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 0x84: //Formerly special char 4, 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
}

sending:

CPU VCORE [

CPU VRIN ]

already in smartie… it cuts off so it’s CPU VR when I launch smartie so it’s CPU VCORE [ // CPU VR . I believe this is a problem with the smartie or lcd code as it was, always was, i just realize this problem. Then I go to edit it in smartie, i gotta edit that 4th line (can’t just hit apply again), and it’ll show CPU VCORE [ // CPU VRIN ] . A space doesn’t work, i have to like add a character, or delete, apply, undo so it’s back to CPU VRIN ], to show it correctly like that.

So I could have 1234567890 as the last line, and it doesnt matter which code I use, it’ll cut off so it’s 123456. If I use CPU VRIN ] with the new code, it’ll still cut off at the 6th character. It always displays incorrectly when i launch smartie. When I edit it, with the new code, it’ll show it as CPU VRIN ] = CPU VRIN VOLTAGE, but there’s the issue where it isn’t always updating voltage, it only samples that voltage when i initially send that character as voltage… so CPU VRIN ] with the new code, will show only the voltage on it when I launch smartie and it’s already in the GUI like that, or if I edit the line.

Using the new code for [ and ]:

#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;

#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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


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

It’s all good after I edit the lines, just voltage only samples when I edit the line. So if i launch smartie with nothing, then add those CPU VCORE [ / CPU VRIN ] in smartie, it’ll show the voltage only for the time I hit ‘apply’ and never change.

Refresh Interval, Scroll intervals are at the default 500. Otherwise it’s exact same except I changed transition to none.

I tried to do something really neat actually - I made it so the lcd smartie swaps between 2 screens at 1 second on each (fastest i could do it). Wasn’t changing voltages. So I added a character so it was bCPU VCORE [ / bCPU VRIN ] to see if that’d work. Well, it works with the 3rd line, both [ and ], but the 4th line just has issue, like it’ll switch between CPU VRIN x.xxx and CPU VRRIN x.xxx.

It’s just that 4th line is goobered up. I even messed with 300/300 like in your pic. I guess start from the beginning right, what is going on.

This is the original code for just smartie:

// include the library code:
#include <LiquidCrystal.h>

#define REDLITE 12
#define GREENLITE 11
#define BLUELITE 10

int brightness = 50;

// these constants won't change.  But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8,3,4,5,6,7);
// RS, RW, Enable, 4,5,6,7 (Refer to the back of your LCD for details)

void setup() { 
  Serial.begin(9600);
  // set up the LCD's number of rows and columns: 
  lcd.begin(numRows, numCols);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("**LCD  SMARTIE**");
  lcd.setCursor(0,1);
  lcd.print("on Arduino");
   lcd.setCursor(0,2);
  lcd.print("*<3*");
  lcd.setCursor(0,3);
  lcd.print("Jeri");
  
  pinMode(REDLITE, OUTPUT);
  pinMode(GREENLITE, OUTPUT);
  pinMode(BLUELITE, OUTPUT);
 
  brightness = 50;
}

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;

  rxbyte = serial_getch();

  if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands
  {
    switch (serial_getch())
    {
    case 66: //backlight on (at previously set brightness)
      // not implemented            

      break;
    case 70: //backlight off
      // not implemented            
      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 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

  }

Seems like there’s 2 problems;

  • line4 gets cutoff and this happens w/the unhacked Smartie code

  • the LCD doesn’t update every 500 msec

Let’s solve 1 at a time. The last may be some normal operation of Smartie. That is, if nothing on the PC side changes, the Smartie PC software doesn’t bother to update the LCD. If true we’ll have to come up with a different approach to doing the ADC stuff. To test this idea put cpu usage on line 1, fan speed on line 2 and CPU VRIN ] on line 3. Leave line 4 empty. Set the refresh time to 500 msec. Use the last test code so that the ADC stuff will run if the [ or ] is sent. The “simulated” LCD on my PC shows that it’s updating. Let’s see what the real one does.

Can I assume you’re using the matrix.dll plugin and comX, 9600 baud ?

Doing your 3 line test, no, the CPU VRIN ] will only update if I edit the line. Like even if i have it flash between 2 screens, it will only update if the 2nd screen has the line edited, changed. So like if 1st screen CPU VRIN ], then CPU VRIN ]a , the voltage actually gets updated every screen flash, but obviously that character is obnoxious, even more obnoxious with the flashing…

Refresh set to 500/500. Display Plugin: matrix.dll, Startup parameters: COMX,9600

I keep it on usb 2.0 front case header, usually com 7 or 9.

Is it possibly the lcd?

Belial88:
Doing your 3 line test, no, the CPU VRIN ] will only update if I edit the line. Like even if i have it flash between 2 screens, it will only update if the 2nd screen has the line edited, changed. So like if 1st screen CPU VRIN ], then CPU VRIN ]a , the voltage actually gets updated every screen flash, but obviously that character is obnoxious, even more obnoxious with the flashing…

Refresh set to 500/500. Display Plugin: matrix.dll, Startup parameters: COMX,9600

I keep it on usb 2.0 front case header, usually com 7 or 9.

Is it possibly the lcd?

I doubt it's the LCD. It's Smartie not doing what I infer from looking at the Arduino-end code. Did the CPU usage or fan speed update every 500 msec while the voltage did not ? Does it appear that Smartie isn't sending the whole LCD every 500 msec, but instead, only the parts that changed ?

To test the idea above I’ve repurposed the { and } to do the same thing as [ and ]. So use the test code below and;

Screen 1

line1 = cpu usage

line2 = fan speed

line3 = VCORE [

and;

Screen 2

line1 = cpu usage

line2 = fan speed

line3 = VCORE {

And see if the A0 voltage updates. And the cpu and fan data too.

new 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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


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

Have you used the serial monitor to send text from the Arduino to the PC ?

Have you used the serial monitor to send text from the Arduino to the PC ?

If I type in ‘12345567890’ x2, it fills up 20 characters, 1 line. I fill up 3 lines, all good. If I fill up 4 lines, it only goes to the 3rd character on that 4th line.

:X

To test the idea above I’ve repurposed the { and } to do the same thing as [ and ]. So use the test code below and;

Screen 1

line1 = cpu usage

line2 = fan speed

line3 = VCORE [

and;

Screen 2

line1 = cpu usage

line2 = fan speed

line3 = VCORE {

And see if the A0 voltage updates. And the cpu and fan data too.

First and 2nd line are glitchy, they aren’t appearing sometimes… most of the time. Sometimes it’l just be line 1, or line 2… hard to understand exactly what’s going on. Voltage is updating fine though.

Belial88:
First and 2nd line are glitchy, they aren’t appearing sometimes… most of the time. Sometimes it’l just be line 1, or line 2… hard to understand exactly what’s going on. Voltage is updating fine though.

That would seem to confirm Smartie is too smart, only updating the LCD when the display has data that's changed.

If you repeat the same experiment w/only lines 1 and 2 having ‘data’ to be displayed, leaving lines 3 and 4 empty … are they (lines 1 and 2) still glitchy ?

It might be time to post some questions on the Smartie forum ?

I have a guess as to what’s happening w/line4 and it relates to the speed of the USB and your 32U4 based Micro.

Here’s the test;

Screen 1

line1 = anything

line2 = anything

line3 =

line4 =

and;

Screen 2

line1 =

line2 =

line3 = anything

line4 = anything

That is put any characters you want on the anything lines but leave the other 2 lines blank.

If line4 shows up OK, I’ll explain my guess.

Another informative test is;

Screen 1

line1 = 1

line2 = 2

line3 = 3

line4 = 12345678901234567890

no Screen 2

Use any version of Smartie code.

OK one last test, this one to see how many characters Smartie @PC end sends. For example if you setup the following;

Screen 1

line1 = a

line2 = b

line3 = c

line4 = d

Screen 2

line1 = A

line2 = B

line3 = C

line4 = D

I would hope Smartie sends 2 - 4 bytes to move the cursor from line to line plus 1 for the single character. Resulting in LCD displays of (w/new test code below);

Screen 1

line1 = 5a

line2 = 3b

line3 = 5c

line4 = 5d

Screen 2

line1 = 5A

line2 = 3B

line3 = 5C

line4 = 5D

OTOH if the GUI fills in spaces after the character you place on each line, the it’s 20 characters per line all the time, giving a display of;

Screen 1

line1 = 25a

line2 = 23b

line3 = 25c

line4 = 25d

Screen 2

line1 = 25A

line2 = 23B

line3 = 25C

line4 = 25D

So here’s the test code to do that test.

#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
int bctr = 0;

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);
  lcd.clear();

  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.home();
  lcd.print("Line 1");
  lcd.setCursor(10, 1);
  lcd.print("Line 2");
  lcd.setCursor(20, 2);
  lcd.print("Line 3");
  lcd.setCursor(30, 3);
  lcd.print("Line 4");
}


//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();
  bctr++ ;
  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);
      lcd.print(bctr);  //display byte count for prior line
      bctr = 0;
      break;
    case 72:  //cursor home (reset display position)
      lcd.command(2);
      lcd.print(bctr);  //display byte count for prior line
      bctr = 0;
      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
}

FYI I think your Micro implements a 64 byte incoming buffer on the USB. If the data comes in too fast from the PC, the buffer will be overrun and data to the Arduino will be lost … like parts of line4 ??? This can’t happen if the baud rate is really 9600 but I’ve learned that isn’t true at the Arduino end, despite the code saying

Serial.begin(9600); //this has no meaning on Leonardo/Micro/Yun

and so I suspect the setup at the PC end is equally ficticious. Real data rates of 10x to 40x that 9600 have been posted. So depending on how many characters are really sent, I can see the buffer getting overrun.

I found a bug report complaining about USB-CDC buffer overruns w/the note that it had been fixed. I found this on the release notes page;

ARDUINO 1.5.3 BETA 2013.08.30
[ide]
* Removed useless baud rates from serial monitor
* Fixed some minor IDE UI bugs (Shigeru Kanemoto)
* Added support for new 1.5 Library format (https://github.com/arduino/Arduino/wiki … cification)
* Pass board type from boards.txt (https://github.com/arduino/Arduino/issues/308)
* Display estimated RAM usage after compile (Loren M. Lang)
* Import library menu is now scrollable
* Scrollable menus can now be scrolled with the mouse wheel
[arduino core]
* sam: Fixed delayMicrosecond() when interrupts are disabled
* sam: Upgraded libsam, and added missing modules (CAN, ETH, etc.) (Thibaut Viard)
* sam: Added compatibility for avr/pgmspace.h (Paul Stoffregen)
* sam: Added serialEvent*() support
* sam: Fixed micros() to work with inside interrupts. (stimmer)
* avr: Added support for Flash strings on String class (Jantje)
* Added support for floating point numbers in String class (Tevin Zhang, SebiTimeWaster)
* sam: Fixed String buffer overflows (Paul Stoffregen)
* avr: Added recipe for assembly files (C. A. Church)
* avr: Use analogPinToChannel if it’s defined (Kristian Sloth Lauszus)
* avr: Optimized HardwareSerial buffer (Matthijs Kooijman)
* removed unused flags from String (free 1 byte of SRAM)

Notice the highlited line above. So perhaps downloading the latest beta release of the Arduino IDE and recompiling your code using it may fix the oveerrun and line4 problem.

Mee_n_Mac:

Belial88:
First and 2nd line are glitchy, they aren’t appearing sometimes… most of the time. Sometimes it’l just be line 1, or line 2… hard to understand exactly what’s going on. Voltage is updating fine though.

That would seem to confirm Smartie is too smart, only updating the LCD when the display has data that's changed.

If you repeat the same experiment w/only lines 1 and 2 having ‘data’ to be displayed, leaving lines 3 and 4 empty … are they (lines 1 and 2) still glitchy ?

It might be time to post some questions on the Smartie forum ?

No. It appears with just using first 2 lines, it’s okay… Even with CPU Vcore and vrin, using the swapping 2 screens method, works fine. I could live with a 1 second refresh. I’d prefer a quicker one, but this is doable.

I have a guess as to what’s happening w/line4 and it relates to the speed of the USB and your 32U4 based Micro.

Here’s the test;

Screen 1

line1 = anything

line2 = anything

line3 =

line4 =

and;

Screen 2

line1 =

line2 =

line3 = anything

line4 = anything

That is put any characters you want on the anything lines but leave the other 2 lines blank.

If line4 shows up OK, I’ll explain my guess.

Another informative test is;

Screen 1

line1 = 1

line2 = 2

line3 = 3

line4 = 12345678901234567890

no Screen 2

Use any version of Smartie code.

It goofs up. After a few seconds, line 1 will like freeze, and then the 4th line, it’ll do something like characters 6-onwards will freeze, and only character 2-3 OR 1-3 OR 1-2 will show (or basically, 2 of the first 5 characters will not be there when it’s time to display on that line).

So like it’ll turn into:

VCORE 1.718v // VCORE 1.718v

VRIN 0.000v // XXXXXXXXXXXXXXXXX

XXXXXXXXXXXXX // VCORE 1.777v

0.000v // IN 0.000v

Seems like voltage is reading fine though.

Using only line 4 with a static or dynamic value, 1 screen or switching screens, seems to work perfectly fine.

I would hope Smartie sends 2 - 4 bytes to move the cursor from line to line plus 1 for the single character. Resulting in LCD displays of (w/new test code below); OTOH if the GUI fills in spaces after the character you place on each line, the it’s 20 characters per line all the time, giving a display of;So here’s the test code to do that test

No. What I got was… not consistent. I guess:

1st line - it’d be 8a/8A/8a/8A/8a/8A then a 24/24/8a/8A/8a/8A… i dont know if it’s a cycle, I think a 7a (or 7A?) and 10a (10A maybe?) sometimes showed up too. It mostly goes 8a/8A for a couple times then 24. Usually the other random character would precede this 24.

2nd line - 24B/24b, but the 24 flashes super fast so it basically looks like it’s just xxB/xxb. Like right when screen changes, the 24 flashes for a split second, just barely.

3rd line - 24C/24c, normal operation I presume.

4th line - 24D/24d, but sometimes the 24 wouldn’t be there, and eventually a 24 got all the way at the end (spaces 15-16, so 24xxx|End of screen).

Notice the highlited line above. So perhaps downloading the latest beta release of the Arduino IDE and recompiling your code using it may fix the oveerrun and line4 problem.

nooooooo. LCD Smartie doesn’t work on newer IDEs. That was my huge hang-up earlier that took FOREVER to figure out on why I couldn’t get LCD smartie to work (made really confusing and harder because the tutorial had 3 different pinouts pictured and none used the right code even though he says ‘this is my pinout’):

http://waihung.net/lcd-smartie-through-arduino/

At bottom you can see comments:

Dude: I also get the random numbers, but then I upload the same skecth using Arduino IDE v23. Once uploaded with ide v23 eveything works perfectly.

OP: Sorry for the late reply. And yes as stated by Mario, I’ve used the old Arduino IDE back then.

So I can’t use the old IDE. What I want to do is just impossible!

Maybe I’ll look into buying discrete voltmete panels again and just use the temps info or something. Maybe just pull the software reported voltages, as much as I’d dislike that…

it also has to uninstall my 1.0.5 ;/

oh, the beta seemed to work. But not perfectly. Repeating the above tests…

I have a guess as to what’s happening w/line4 and it relates to the speed of the USB and your 32U4 based Micro.

Here’s the test;

Screen 1

line1 = anything

line2 = anything

line3 =

line4 =

and;

Screen 2

line1 =

line2 =

line3 = anything

Works.

Another informative test is;

Screen 1

line1 = 1

line2 = 2

line3 = 3

line4 = 12345678901234567890

no Screen 2

Works

Mee_n_Mac:
OK one last test, this one to see how many characters Smartie @PC end sends. For example if you setup the following;

Screen 1

line1 = a

line2 = b

line3 = c

line4 = d

Screen 2

line1 = A

line2 = B

line3 = C

line4 = D

I would hope Smartie sends 2 - 4 bytes to move the cursor from line to line plus 1 for the single character. Resulting in LCD displays of (w/new test code below);

Screen 1

line1 = 5a

line2 = 3b

line3 = 5c

line4 = 5d

Screen 2

line1 = 5A

line2 = 3B

line3 = 5C

line4 = 5D

OTOH if the GUI fills in spaces after the character you place on each line, the it’s 20 characters per line all the time, giving a display of;

Screen 1

line1 = 25a

line2 = 23b

line3 = 25c

line4 = 25d

Screen 2

line1 = 25A

line2 = 23B

line3 = 25C

line4 = 25D

So here’s the test code to do that test.

#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
int bctr = 0;

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);
lcd.clear();

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.home();
lcd.print(“Line 1”);
lcd.setCursor(10, 1);
lcd.print(“Line 2”);
lcd.setCursor(20, 2);
lcd.print(“Line 3”);
lcd.setCursor(30, 3);
lcd.print(“Line 4”);
}

//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();
bctr++ ;
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);
lcd.print(bctr); //display byte count for prior line
bctr = 0;
break;
case 72: //cursor home (reset display position)
lcd.command(2);
lcd.print(bctr); //display byte count for prior line
bctr = 0;
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
}




FYI I think your Micro implements a 64 byte incoming buffer on the USB. If the data comes in too fast from the PC, the buffer will be overrun and data to the Arduino will be lost ... like parts of line4 ??? This can't happen if the baud rate is really 9600 but I've learned that isn't true at the Arduino end, despite the code saying 

Serial.begin(9600); //this has no meaning on Leonardo/Micro/Yun

and so I suspect the setup at the PC end is equally ficticious. Real data rates of 10x to 40x that 9600 have been posted. So depending on how many characters are really sent, I can see the buffer getting overrun.

24A/24a, but 24 flashes super fast, so it’s like nothing displays at all there (just a/A).

24B/24b, again the flashing number

24C/24c normal operation i presume

24D/24d normal operation i presume.

so… the new beta is better but still doesn’t work, seeing as we got 2 fully working lines instead of 1. Doesn’t seem as FUBAR’d as the other time i guess…

I tried to see if I could just do exactly what I originally wanted and get away (cpu temp via software/gpu temp via softwware, had to use some random voltage since gpu not plugged in atm/volt1/volt2) and first 2 lines just were bugged out ;/