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

Mee_n_Mac:
Aaaah but did them damn ancients ever put in clay their init sequence timing ? :mrgreen:

Mmm, I've never had a problem initializing an LCD, but I've always used the 8 bit interface.

The Hitachi datasheet does tell you how to initialize:

  • - Function set (4/8 bit data, 1/2 line, 8/10 char height)
  • - Display on/off (display on/off, cursor on/off, blink on/off)
  • - Entry mode (cursor move, display shift)
  • - CGRAM load (custom char glyphs)
  • I think that I've seen people using 6 wire interfaces, 4 bit data with no R/W line.

    You can’t read back from the LCD that way.

    The only real reason to read the LCD is to get the busy flag.

    For the fastest reliable operation you need to read the busy flag.

    For robust startup, I always send 3 times 0x38 (Function set) in 8 bit data mode.

    Also note that for 4 bit data the Function set transfer is a single (not a double) because the LCD is in 8 bit mode.

    So this is currently my code. I had to use arduino 1.01 and make it as a leonardo (no micro listed), and I had to change lcd.print(rxbyte) to lcd.write(rxbyte). i really had to dig to find those answers… jesus.

    // include the library code:
    #include <LiquidCrystal.h>
    
    #define REDLITE 7
    #define GREENLITE 8
    #define BLUELITE 9
    
    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(12,6,11,5,4,3,2);
    // 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
    
      }
    

    Now, if I wire it so that just Blue is hooked up to grnd, it’s a blue screen and all is good. But I was trying to like, combine the adafruit RGB lcd tutorial (ie hello world but rgb rotates between colors all prismatically) and thought it’d be cool to have that kind of functionality in the code.

    And is there a way to change brightness? I messed with int brightness (by defines) and brightness = X in setup with no luck.

    Anyways, right now the major hurdles are:

    • How to best display CPU and GPU temps. I’ve found ways to do it, but very suboptimal ways. Only way to display cpu temp is with coretemp plugin, and I have to have coretemp runnign at same time. I have to use system mobnitor plug in for GPu temp, but for some reason it wont display cpu temp (and open hw monitor doesnt have max cpu core temp anyways even if it did work).

    • Still need to work out the ADC voltage display, I assume I’d program the LCD to basically be a 20x2 for LCD Smartie, and then lines 0,2 and 0,3 I’d just have arduino code for lcd.

    As I understand, you need to divide by a voltage, so I guess I’d just divide by like 2.8voltage for more accuracy… or a refernece voltage close to that, i guess. Not exactly sure on all that but hopefully it’ll be easy to figure out.

    Okay so moving onto the ADC stuff:

    /*--------------------------------------------------------------
      Program:      voltmeter_LCD
    
      Description:  4 channel DC voltmeter with voltages displayed
                    on LCD to 1 decimal place
      
      Hardware:     Arduino Uno with voltage dividers on A2 to A5.
                    2 x 16 LCD connected to standard pins used in
                    Arduino example sketches from IDE.
                    
      Software:     Developed using Arduino 1.0.5 software
                    Should be compatible with Arduino 1.0 +
    
      Date:         27 May 2013
     
      Author:       W.A. Smith, http://startingelectronics.com
    --------------------------------------------------------------*/
    #include <LiquidCrystal.h>
    
    // number of analog samples to take per reading, per channel
    #define NUM_SAMPLES 10
    // voltage divider calibration values
    #define DIV_1    11.1346
    #define DIV_2    11.1969
    #define DIV_3    11.0718
    #define DIV_4    11.0718
    // ADC reference voltage / calibration value
    #define V_REF    4.991
    
    #define REDLITE 7
    #define GREENLITE 8
    #define BLUELITE 9
    
    int brightness = 50;
    
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    int sum[4] = {0};                // sums of samples taken
    unsigned char sample_count = 0;  // current sample number
    float voltage[4] = {0.0};        // calculated voltages
    char l_cnt = 0;                  // used in 'for' loops
    
    void setup()
    {
       Serial.begin(9600);
       lcd.begin(20, 4);
      pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
     
      brightness = 50;
    }
    
    void loop()
    {
        // take a number of analog samples and add them up
        while (sample_count < NUM_SAMPLES) {
            // sample each channel A2 to A5
            for (l_cnt = 0; l_cnt < 4; l_cnt++) {
                sum[l_cnt] += analogRead(A2 + l_cnt);
            }
            sample_count++;
            delay(10);
        }
        // calculate the voltage for each channel
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {
            voltage[l_cnt] = ((float)sum[l_cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
        }
        // display voltages on LCD
        // each voltage is multiplied by the resistor network
        // division factor to calculate the actual voltage
        // voltage 1 - A (pin A2)
        lcd.setCursor(0, 0);
        lcd.print("A ");
        lcd.print(voltage[0] * DIV_1, 1);
        lcd.print("V ");
        // voltage 2 - B (pin A3)
        lcd.setCursor(8, 0);
        lcd.print("B ");
        lcd.print(voltage[1] * DIV_2, 1);
        lcd.print("V ");
        // voltge 3 - C (pin A4)
        lcd.setCursor(0, 1);
        lcd.print("C ");
        lcd.print(voltage[2] * DIV_3, 1);
        lcd.print("V ");
        // voltage 4 - D (pin A5)
        lcd.setCursor(8, 1);
        lcd.print("D ");
        lcd.print(voltage[3] * DIV_4, 1);
        lcd.print("V ");
        // reset count and sums
        sample_count = 0;
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {
            sum[l_cnt] = 0;
        }
    }
    

    Again, I don’t understand how to change brightness, or how to select a color from RGB. I could just stick only the blue led pin into 5v and it’s all gravy, but just trying to understand the lcd a bit better, maybe make a shade of blue instead.

    I followed this tutorial:

    http://startingelectronics.com/projects … voltmeter/

    I had to add in setup

    pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
     
      brightness = 50;
    

    and define red/greenblute and in brightness to get the lcd on (maybe i wouldnt have to if i just use only blue pin, but w/e).

    I thought I was smart and showing a greater understanding, but all 4 voltages on the lcd display 3,2.9,2.7,2.6 respectively. Not 0 since nothing is being measured. When I added a ~1.5v lithium AA battery to the leads (a0 pin and ground) nothing changed, but I dont want to test like 6v and end up blowing something.

    I just want to measure 0 to about 2.5-2.8v. I assume I have to compromise and go with ~5v, that’s fine.

    The tutorial says it’s based off some arduino tutorial, but nothing in it’s code has:

    #define DIV_1    11.1346
    #define DIV_2    11.1969
    #define DIV_3    11.0718
    #define DIV_4    11.0718
    // ADC reference voltage / calibration value
    #define V_REF    4.991
    

    Which I assume is the source of the problem. I don’t really want to mess with these and end up blowing something (is this an unfounded fear? Ive shorted many things so uhh i want to avoid that). I see the v_ref is ~5v so i dunno, that sounds right.

    Like they look nothing alike:

    int analogPin = 3;     // potentiometer wiper (middle terminal) connected to analog pin 3
                           // outside leads to ground and +5V
    int val = 0;           // variable to store the value read
    
    void setup()
    {
      Serial.begin(9600);          //  setup serial
    }
    
    void loop()
    {
      val = analogRead(analogPin);    // read the input pin
      Serial.println(val);             // debug value
    }
    

    edit: okay so i looked deeper and saw the DIV values reoccuring in the code, as being multipierrs simply for the simply (ie print = display on lcd voltage x DIV). So I changed it to 1, maybe that makes it 0-5v measuring. I tried to measure a 1.5v aa battery. On first lead, nothing happens. On second lead, suddenly the 4 values are replicated (i have a 20x4 instead of 16x2) on bottom half, with a bit of scrolling and weird characters thrown in too.

    I unplug and replug, looks normal but… yea gonna wait for help now. With DIV at 1 for all leads, the voltages read as .3v,.2v,.2v,.2v. Not zero fyi.

    What number of voltages are you going to measure ? The code waay above measures 4, each through a divider that reduces the input by about a factor of 11 before going into the ADC. Thus to get the input you must multiply by 11. I’ll assume each channel and the ADC reference voltage were individually measured. That code also averaged a number of ADC samples before displaying them.

    If you want to use that code start by setting the DIV_x’s to 1.0. I assume that you don’t have any voltage divider. Short the analog pins to ground and the reading should equal zero (or pretty close). Put the battery btw the input pins and ground and you should ~1.5v. Pins left open will yield odd and semi-random numbers. One thing to be aware of is that the display can only respond so quickly. Sending data to one more often than every 200 - ??? msecs may result in a odd looking display, w/some of the digits washed out or missing.

    As to the backlighting … I’d have to look at that display. IIRC Adafruit had one setup to be PWM’ed for RGB color mix and brightness. Is your display this one ?

    http://www.winstar.com.tw/products_deta … n&ProID=36

    i can tell the above code measures 4, I think I could just delete 2 defines and two of the items in the loop (beginning with setcursor…) so it would just measure 2.

    If you want to use that code start by setting the DIV_x’s to 1.0. I assume that you don’t have any voltage divider. Short the analog pins to ground and the reading should equal zero (or pretty close). Put the battery btw the input pins and ground and you should ~1.5v. Pins left open will yield odd and semi-random numbers. One thing to be aware of is that the display can only respond so quickly. Sending data to one more often than every 200 - ??? msecs may result in a odd looking display, w/some of the digits washed out or missing.

    oh okay, so that’s why it was like .01, .02. They had to be shorted to read .00 voltage. Like they were picking up electrowaves.

    One thing to be aware of is that the display can only respond so quickly. Sending data to one more often than every 200 - ??? msecs may result in a odd looking display, w/some of the digits washed out or missing.

    I’m a bit confused here, is there something in the code that says send data every 200 msec? Does this mean I’m confusing the display if I hold something, like a battery or cpu vcore input voltage read point, or that if i just touch it really quick?

    That seems like my display, not exact i think? It’s this:

    http://www.adafruit.com/products/498#Downloads

    http://www.adafruit.com/datasheets/WH20 … -JT%23.pdf

    i think it’s same base model though, 44780.

    Okay well tried to do it again with a 1.5battery and set to div = 1. I think part of the problem was pinout, i didnt see anywhere inthe code to use A2-a5, not a0/a1. I noticed that because of the comments (my first try was actually changing the values in the comments, until i realized those were comments). So, i just tried the wires on a2-a5.

    Seemed to work, I’ll have to come back, something like you said about yea, they spazz out. It was all 4 values changing to 0 or ~1.7v if it was shorted or on my aa battery respectively. Also a lot of weird characters would flash sometimes, and then it would be out of control. Maybe it’s just supposed to be hardwired to whatever voltage your measuring when it’s on, not like a DMM. Which is fine by me, but just makes debugging weird.

    DMM says battery is 1.744, so that’s cool. I’ll have to spend a bit more time on this, let me see if i can figure this stuff out more before you take a lot of time on this.

    Belial88:
    i can tell the above code measures 4, I think I could just delete 2 defines and two of the items in the loop (beginning with setcursor…) so it would just measure 2.

    Just be sure to delete the last 2 and reduce loop counters to measure and compute the averages for just the 1'st two analog pins. See the un-modified code but w/my comments below.
    void loop()
    {
        // take a number of analog samples and add them up
        while (sample_count < NUM_SAMPLES) {
            // sample each channel A2 to A3
            for (l_cnt = 0; l_cnt < 4; l_cnt++) {       //l_cnt only goes 0 to 1 now.  4 should be 2
                sum[l_cnt] += analogRead(A2 + l_cnt);
            }
            sample_count++;
            delay(10);
        }
        // calculate the voltage for each channel
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {          //l_cnt only goes 0 to 1 now.  4 should be 2
            voltage[l_cnt] = ((float)sum[l_cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
        }
    

    Belial88:

    One thing to be aware of is that the display can only respond so quickly. Sending data to one more often than every 200 - ??? msecs may result in a odd looking display, w/some of the digits washed out or missing.

    I'm a bit confused here, is there something in the code that says send data every 200 msec? Does this mean I'm confusing the display if I hold something, like a battery or cpu vcore input voltage read point, or that if i just touch it really quick?
    There's no timing restriction/delay in that code, that I could see. I would say that it takes long enough to run, that for this controller, it's a non-concern. Note each channel was sampled 10x and averaged, with 10 msec btw each sample. So it takes almost 400 msec to complete just the code above. In your case I'd take a sample of the voltage once per loop of the servo/switch/door code. Take some number (your choice) of samples and when done, compute the average and update the display.

    There’s no restriction on how long or short you apply the voltage. Of course if you take some time taking samples to be averaged and just touch the wire to the battery for shorter than that time, the display will show a funky average. But you can’t hurt anything.

    So have you got the contrast and backlighting working ? According to the docs, apply 5v to pin 15 of the display. Ground pin 18 to turn on (100%) the blue LED. You also use a IO pin from the Arduino to pin 18 and put the brightness under software control via PWM. Same goes for the R and G LEDs.

    http://arduino.cc/en/Reference/AnalogWrite

    http://arduino.cc/en/Tutorial/PWM

    The difference in your case (from the tutorial) is that a analogWrite(pin, 0) (= logic 0 = ground) is full on and a 255 is off.

    I don’t really understand what you did. I’m assuming it makes more sense read as: // 4 as 2, l_cnt only goes 0 to 1 now.

    But i don’t understand how its assigning it as A2+. How do I get it to be pins A0 and A1? Or A0 and A8? I don’t see where they assigned the pins.

    I used a dmm and found v_ref is 4.93 (it was like 5.12 when lcd not hooked up). I’m sure it’ll change with servo added, I can test it later.

    There’s no timing restriction/delay in that code, that I could see. I would say that it takes long enough to run, that for this controller, it’s a non-concern. Note each channel was sampled 10x and averaged, with 10 msec btw each sample. So it takes almost 400 msec to complete just the code above. In your case I’d take a sample of the voltage once per loop of the servo/switch/door code. Take some number (your choice) of samples and when done, compute the average and update the display.

    Ohhh, so Num_samples = number of times voltage is checked for an average. I don’t want an average, I’d prefer a max voltage, averages are specifically why I am doing this isntead of pulling a software value easily from an lcd smartie plugin (the motherboard averages the value, and motherboard companies often will use firmware that averages in a way that makes it seem like the board is using less voltage than it really is, so reviewers will say things like ‘omg the asrock extreme is an awesome motherboard, it can do the same 5ghz overclock at only 1.4v, while the other boards needed 1.6v!’ when in reality it’s just giving a false voltage read.

    Here’s an example of what I’m talking about, and a large part of why this needs to be hardwired rather than software:

    http://www.youtube.com/watch?v=oB0dm2-nfpc

    Also, averaging causes very important information in regards to voltage peaks and offsets to be lost, information that hardwiring gives. I know DMMs and voltmeters also read averages on some level, but they are more accurate and not as biased as motherboard firmware. I dont just want more accurate voltage reads here, I also want to know when and what causes vdroop and vpeak on my chip.

    How did you come up with it taking 400msec to do the voltage reading? So I say, a sample of 1. I’m not sure I really follow what you mean.

    So have you got the contrast and backlighting working ? According to the docs, apply 5v to pin 15 of the display. Ground pin 18 to turn on (100%) the blue LED. You also use a IO pin from the Arduino to pin 18 and put the brightness under software control via PWM. Same goes for the R and G LEDs.

    http://arduino.cc/en/Reference/AnalogWrite

    http://arduino.cc/en/Tutorial/PWM

    The difference in your case (from the tutorial) is that a analogWrite(pin, 0) (= logic 0 = ground) is full on and a 255 is off.

    Yea contrast is straightforward, with a pot on lcdpin3. I think I will put a pot on my computer case to make the contrast easily adjustable coolpoints!!!. It’s the backlighting brightness I’ve never been able to adjust, or to change the color of the LCD via coding. But now thanks to your help, I can!

    I deleted the int brightness and brightness lines, and added analogWrite(XXXXLITE,0-255) and got it working! Super cool!

    It seems if i ever shake the pins a bit, the lcd wigs out a bit and starts displaying crazy chars and stuff, that’s what was going on.

    Anyways, is it possible for me to make the voltmetering more accurate, which I assume I have to do by reducing max voltage read? Like 0-3v? Couldn’t I make the DIVs like .5? So instead of scaling up voltage range to ~11v with div=11, make it .5 to make it to 2.5v? Or 1.78571429 for 2.8v max?

    I’m hoping I can easily figure it out to have it where LCD smartie rules the top 2 lines, and 2x voltmeters for bottom 2 lines. I’m not sure if that means make it so each part of code thinks its a 2x20 display or just say its a 4x20, but i can play with that and figure it out.

    This is my code:

    /*--------------------------------------------------------------
      Program:      Voltmeter LCD
      
      Description:  2 channel DC voltmeter with voltages displayed
                    on LCD to 1 decimal place
      
      Hardware:     Arduino Uno with voltage dividers on A2 to A5.
                    2 x 16 LCD connected to standard pins used in
                    Arduino example sketches from IDE.
                    
      Software:     Developed using Arduino 1.0.5 software
                    Should be compatible with Arduino 1.0 +
    
      Date:         27 May 2013
     
      Author:       W.A. Smith, http://startingelectronics.com
    --------------------------------------------------------------*/
    #include <LiquidCrystal.h>
    
    // number of analog samples to take per reading, per channel
    #define NUM_SAMPLES 1
    // Samples of Voltage to be averaged for each read
    #define DIV_1    1
    #define DIV_2    1
    // ADC reference voltage / calibration value
    #define V_REF    4.93
    
    #define REDLITE 6
    #define GREENLITE 9
    #define BLUELITE 10
    
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    int sum[4] = {0};                // sums of samples taken
    unsigned char sample_count = 0;  // current sample number
    float voltage[4] = {0.000};        // calculated voltages
    char l_cnt = 0;                  // used in 'for' loops
    
    void setup()
    {
       Serial.begin(9600);
       lcd.begin(20, 4);
      pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
     
    }
    
    void loop()
    {
      analogWrite(BLUELITE,0); //Blue brightness 255-0
      analogWrite(REDLITE,255); //Red brightness 255-0
      analogWrite(GREENLITE,255); //Green brightness 255-0
        // take a number of analog samples and add them up
        while (sample_count < NUM_SAMPLES) {
            // sample each channel A2 to A5
            for (l_cnt = 0; l_cnt < 2; l_cnt++) {
                sum[l_cnt] += analogRead(A2 + l_cnt);
            }
            sample_count++;
            delay(10);
        }
        // calculate the voltage for each channel
        for (l_cnt = 0; l_cnt < 2; l_cnt++) {
            voltage[l_cnt] = ((float)sum[l_cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
        }
        // display voltages on LCD
        // each voltage is multiplied by the resistor network
        // division factor to calculate the actual voltage
        // voltage 1 - A (pin A2)
        lcd.setCursor(0, 2);
        lcd.print("CPU VCORE ");
        lcd.print(voltage[0] * DIV_1, 1);
        lcd.print("v");
        // voltage 2 - B (pin A3)
        lcd.setCursor(0, 3);
        lcd.print("CPU VRIN  ");
        lcd.print(voltage[1] * DIV_2, 1);
        lcd.print("v");
        // reset count and sums
        sample_count = 0;
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {
            sum[l_cnt] = 0;
        }
    }
    

    It displays the voltages on the bottom 2 lines of my display, as CPU VCORE X.Xv and CPU VRIN X.Xv. When I measure one voltage, both change (and the 2nd usually off by a points or two), but when I short the other one for 0v it’s straight.

    • I don’t know how to get more decimal places. In definitions I changed to float voltage[4] = {0.000}; but it didn’t do it.

    • dont know how to change pin assignment

    • wondering if i can make it so its more accurate by like doing 0-3v instead.

    This is both codes together:

    /*--------------------------------------------------------------
      Program:      Voltmeter LCD
      
      Description:  2 channel DC voltmeter with voltages displayed
                    on LCD to 1 decimal place
      
      Hardware:     Arduino Uno with voltage dividers on A2 to A5.
                    2 x 16 LCD connected to standard pins used in
                    Arduino example sketches from IDE.
                    
      Software:     Developed using Arduino 1.0.5 software
                    Should be compatible with Arduino 1.0 +
    
      Date:         27 May 2013
     
      Author:       W.A. Smith, http://startingelectronics.com
    --------------------------------------------------------------*/
    #include <LiquidCrystal.h>
    
    // number of analog samples to take per reading, per channel
    #define NUM_SAMPLES 1
    // Samples of Voltage to be averaged for each read
    #define DIV_1    1
    #define DIV_2    1
    // ADC reference voltage / calibration value
    #define V_REF    4.93
    
    #define REDLITE 6
    #define GREENLITE 9
    #define BLUELITE 10
    
    
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    int sum[4] = {0};                // sums of samples taken
    unsigned char sample_count = 0;  // current sample number
    float voltage[4] = {0.000};        // calculated voltages
    char l_cnt = 0;                  // used in 'for' loops
    
    void setup()
    {
       Serial.begin(9600);
       lcd.begin(20, 4);
      pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
      
      lcd.setCursor(0,0);
      lcd.print("Belial's Perfect Z87");//First line of text
      lcd.setCursor(0,1);
      lcd.print("   Intel i7-4770K"); //Second line of text
      
    }
    
    byte serial_getch(){
      
      int incoming;  
      while (Serial.available()==0){}
       // read the incoming byte:
      incoming = Serial.read();
    
      return (byte) (incoming &0xff);
    }
    
    
    void loop()
    {
      analogWrite(BLUELITE,0); //Blue brightness 255-0
      analogWrite(REDLITE,255); //Red brightness 255-0
      analogWrite(GREENLITE,255); //Green brightness 255-0
        // take a number of analog samples and add them up
        while (sample_count < NUM_SAMPLES) {
            // sample each channel A2 to A5
            for (l_cnt = 0; l_cnt < 2; l_cnt++) {
                sum[l_cnt] += analogRead(A2 + l_cnt);
            }
            sample_count++;
            delay(10);
        }
        // calculate the voltage for each channel
        for (l_cnt = 0; l_cnt < 2; l_cnt++) {
            voltage[l_cnt] = ((float)sum[l_cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
        }
        // display voltages on LCD
        // each voltage is multiplied by the resistor network
        // division factor to calculate the actual voltage
        // voltage 1 - A (pin A2)
        lcd.setCursor(0, 2);
        lcd.print("CPU VCORE ");
        lcd.print(voltage[0] * DIV_1, 1);
        lcd.print("v");
        // voltage 2 - B (pin A3)
        lcd.setCursor(0, 3);
        lcd.print("CPU VRIN  ");
        lcd.print(voltage[1] * DIV_2, 1);
        lcd.print("v");
        // reset count and sums
        sample_count = 0;
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {
            sum[l_cnt] = 0;
            
         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
        }
    }
    

    They dont play well. uploads, is just like voltmeter code alone (1st line belials perfect…, 2nd line intel…, 3 and 4th voltmeters). Then when I start lcd smartie, 3rd line is voltmeter, 1st line is /?_?-?<-? and nothing on 2nd and 4th line and i cant change it no matter what i do from there, even if i turn off lcdsmartie.

    On a side note, I think I’d like to incorporate timekeeping to this code (it’s hooked up to pc anyways for lcd stuff). Like 1st line has cpu temps and date, 2nd linje has gpu temps and time, or something. I tried to find code on it, i thought it’d be super simple, but its not. Not sure how to copy the code, like I dont know how to make time= something, and then call ‘time’ for stuff like lcdprint. I dont know what library to use, all the stuff online has so many different libraries and udpates and outdated so i cant make sense at all of how to do it. Like I see a lot of example sketches, but they really confuse me - how do you know you did the example right if you dont have an lcd telling you the time results? How do you know what time it is if the arduino has no display on it? I dont see any lquidcrystal lcd(…) in the codes. Everything i google to try to steal code uses an rtc.

    I did realize, that in order to ‘do’ all this, my arduino will have data+ and data- hooked up to the pc, and then +/- to the powergen battery, and then lcd to +/- of the motherboard. Kinda funny.

    Vcc is going to be all over the place. Don’t use it as an analog reference.

    In “setup”:

    analogReference(INTERNAL);
    

    Now you have 2.56V as your reference.

    If you want to measure any voltages higher than 2.56 you will have to put a voltage divider on that analog in pin.

    Besides a stable reference this gives you twice the resolution as with a Vcc reference.

    Belial88:
    I don’t really understand what you did. I’m assuming it makes more sense read as: // 4 as 2, l_cnt only goes 0 to 1 now.

    But i don’t understand how its assigning it as A2+. How do I get it to be pins A0 and A1? Or A0 and A8? I don’t see where they assigned the pins.

    If you look at the loop it starts with l_cnt = 0 and cylces 4 times w/l_cnt = 0, then l_cnt = 1, l_cnt = 2 and finally l_cnt = 4. Thus analogRead(A2+0) = analogRead(A2), analogRead(A2+1) = analogRead(A3), etc, etc. Given you want to do only 2 channels and no averaging, you can forget the loop and fancy incrementing and just do 2 separate analogReads().
            for (l_cnt = 0; l_cnt < 2; l_cnt++) {
                sum[l_cnt] += analogRead(A2 + l_cnt);
            }
            sample_count++;
            delay(10);
    

    Belial88:
    Ohhh, so Num_samples = number of times voltage is checked for an average. I don’t want an average, I’d prefer a max voltage, averages are specifically why I am doing this isntead of pulling a software value easily from an lcd smartie plugin

    Errr do you want the display to hold (for how long) a max voltage or just be like a DVM, displaying the voltage it reads every ?200? msec ?

    Belial88:
    How did you come up with it taking 400msec to do the voltage reading? So I say, a sample of 1. I’m not sure I really follow what you mean.

    Look at the loop above. There's a delay(10) = a 10 msec delay in between each sample. So the code takes 40 msec to read 1 sample for each of the 4 channels. It does this 10x (10 samples to be averaged) thus (about) 400 msec.

    Belial88:
    Anyways, is it possible for me to make the voltmetering more accurate, which I assume I have to do by reducing max voltage read? Like 0-3v? Couldn’t I make the DIVs like .5? So instead of scaling up voltage range to ~11v with div=11, make it .5 to make it to 2.5v? Or 1.78571429 for 2.8v max?

    Yup, as previously mentioned and as posted by Renate. Much the same idea as used in the tutorial. You use a pot to scale your 2.8v down to 2.5v and then set the ADC ref voltage to 2.56v. Of course you can do a calibration so the display reads the same as your (calibrated) DVM.

    Belial88:
    I’m hoping I can easily figure it out to have it where LCD smartie rules the top 2 lines, and 2x voltmeters for bottom 2 lines. I’m not sure if that means make it so each part of code thinks its a 2x20 display or just say its a 4x20, but i can play with that and figure it out.

    I'll have to look at the Smartie code to see how it works.

    So all the pieces now kinda work by themselves, they need to be melded into 1 program and fine tuned.

    Belial88:
    On a side note, I think I’d like to incorporate timekeeping to this code (it’s hooked up to pc anyways for lcd stuff). Like 1st line has cpu temps and date, 2nd linje has gpu temps and time, or something. I tried to find code on it, i thought it’d be super simple, but its not. Not sure how to copy the code, like I dont know how to make time= something, and then call ‘time’ for stuff like lcdprint. I dont know what library to use, all the stuff online has so many different libraries and udpates and outdated so i cant make sense at all of how to do it. Like I see a lot of example sketches, but they really confuse me - how do you know you did the example right if you dont have an lcd telling you the time results? How do you know what time it is if the arduino has no display on it? I dont see any lquidcrystal lcd(…) in the codes. Everything i google to try to steal code uses an rtc.

    Unless Smartie can pull time from the PC, you'd need to add more hardware (Real Time Clock) and more Arduino code.

    Renate:
    Vcc is going to be all over the place. Don’t use it as an analog reference.

    In “setup”:

    analogReference(INTERNAL);
    

    Now you have 2.56V as your reference.

    If you want to measure any voltages higher than 2.56 you will have to put a voltage divider on that analog in pin.

    Besides a stable reference this gives you twice the resolution as with a Vcc reference.

    So to be clear, you mean vcc = 5v pin = 5v output, is going to be all over the place due to giving power to multiple things? I mean going from 4.9-5.3v really doesnt hurt accuracy that much, does it? I mean i want accuracy, but just trying to understand exactly what you mean.

    But setting a max voltage read of 2.56v is great, I’d much rather have that be my max voltage so as for more accuracy! And that’s great, if I want to do like 3v, I just do 1.171875 on the divider right? Why I could even use ~2 as a divider for 5v reference!

    I tapped RF line (AREF) and ground with my DVM and found it to be 2.54v.

    Anyways, so I include your line into setup, and then make define V_REF INTERNAL in definitions.

    If you look at the loop it starts with l_cnt = 0 and cylces 4 times w/l_cnt = 0, then l_cnt = 1, l_cnt = 2 and finally l_cnt = 4. Thus analogRead(A2+0) = analogRead(A2), analogRead(A2+1) = analogRead(A3), etc, etc. Given you want to do only 2 channels and no averaging, you can forget the loop and fancy incrementing and just do 2 separate analogReads().

    oh… i see the analogRead(A2+1_cnt) now. yea i wasnt understanding all of that stuff.

    Errr do you want the display to hold (for how long) a max voltage or just be like a DVM, displaying the voltage it reads every ?200? msec ?

    I’m not exactly sure. What’s the difference really? Like what’s the difference between a display holding a max voltage for 200msec and a DVM reading every 200 msec?

    I mean the analog reads are going to be soldered to my motherboard on the voltage read points it has (specially built to tap with a DVM to see true voltages) for constant voltage reads.

    Yup, as previously mentioned and as posted by Renate. Much the same idea as used in the tutorial. You use a pot to scale your 2.8v down to 2.5v and then set the ADC ref voltage to 2.56v. Of course you can do a calibration so the display reads the same as your (calibrated) DVM.

    I’m am little confused what you mean. The tutorial used 5v. What 2.8v are you referring to?

    Unless Smartie can pull time from the PC, you’d need to add more hardware (Real Time Clock) and more Arduino code.

    I thought I could pull time from the computer, I saw some people saying they did code for that. Well doing it via lcd smartie took about 2 minutes to figure out and works.

    Anyways this is my code now:

    /*--------------------------------------------------------------
      Program:      Voltmeter LCD
      
      Description:  2 channel DC voltmeter with voltages displayed
                    on LCD to 1 decimal place
      
      Hardware:     Arduino Uno with voltage dividers on A2 to A5.
                    2 x 16 LCD connected to standard pins used in
                    Arduino example sketches from IDE.
                    
      Software:     Developed using Arduino 1.0.5 software
                    Should be compatible with Arduino 1.0 +
    
      Date:         27 May 2013
     
      Author:       W.A. Smith, http://startingelectronics.com
    --------------------------------------------------------------*/
    #include <LiquidCrystal.h>
    
    // number of analog samples to take per reading, per channel
    #define NUM_SAMPLES 1
    // Samples of Voltage to be averaged for each read
    #define DIV_1    1
    #define DIV_2    1
    // ADC reference voltage / calibration value
    #define V_REF    INTERNAL
    
    #define REDLITE 6
    #define GREENLITE 9
    #define BLUELITE 10
    
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    int sum[4] = {0};                // sums of samples taken
    unsigned char sample_count = 0;  // current sample number
    float voltage[4] = {0.000};        // calculated voltages
    char l_cnt = 0;                  // used in 'for' loops
    
    void setup()
    {
       Serial.begin(9600);
       lcd.begin(20, 4);
      pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
      
     analogReference(INTERNAL);
    }
    
    void loop()
    {
      analogWrite(BLUELITE,0); //Blue brightness 255-0
      analogWrite(REDLITE,255); //Red brightness 255-0
      analogWrite(GREENLITE,255); //Green brightness 255-0
        // take a number of analog samples and add them up
        while (sample_count < NUM_SAMPLES) {
            // sample each channel A2 to A5
                  analogRead(A0);
                  analogRead(A1);
        }
        // calculate the voltage for each channel
        for (l_cnt = 0; l_cnt < 2; l_cnt++) {
            voltage[l_cnt] = ((float)sum[l_cnt] / (float)NUM_SAMPLES * V_REF) / 1024.0;
        }
        // display voltages on LCD
        // each voltage is multiplied by the resistor network
        // division factor to calculate the actual voltage
        // voltage 1 - A (pin A2)
        lcd.setCursor(0, 2);
        lcd.print("CPU VCORE ");
        lcd.print(voltage[0] * DIV_1, 1);
        lcd.print("v");
        // voltage 2 - B (pin A3)
        lcd.setCursor(0, 3);
        lcd.print("CPU VRIN  ");
        lcd.print(voltage[1] * DIV_2, 1);
        lcd.print("v");
        // reset count and sums
        sample_count = 0;
        for (l_cnt = 0; l_cnt < 4; l_cnt++) {
            sum[l_cnt] = 0;
        }
    }
    

    and nothing displays.

    Unless I put back in like this:

    for (l_cnt = 0; l_cnt < 2; l_cnt++) {

    sum[l_cnt] += analogRead(A0 + l_cnt);

    }

    sample_count++;

    delay(10);

    }

    The values wig out when not connected/shorted, but whatever, but when I put it to that same 1.7v AA battery it reads as 2.0v. So how do i get that accurate and how do I get it to read 1.743v.

    Belial88:

    Yup, as previously mentioned and as posted by Renate. Much the same idea as used in the tutorial. You use a pot to scale your 2.8v down to 2.5v and then set the ADC ref voltage to 2.56v. Of course you can do a calibration so the display reads the same as your (calibrated) DVM.

    I’m am little confused what you mean. The tutorial used 5v. What 2.8v are you referring to?

    You've previously mentioned that the max voltage you intend to read off the mobo was 2.8v. The tutorial used a voltage divider of 100k and 1000k to reduce (up to) 55v down to the 5v range (that's why there was an 11x multiply). You can use a voltage divider (a 10k pot) to do the same type of thing. Then you **[u]also use[/u]** the internal AREF voltage of 2.56v.

    If your other mobo voltage is > 2.8v, you can use a different voltage divider.

    http://en.wikipedia.org/wiki/Voltage_divider

    I simplified your code since you’re not averaging. I’m a little unsure of how to lcd.print a floating point number. If the code below doesn’t work right, I have an idea. Do NOT input voltages >2.54v !!

    #include <LiquidCrystal.h>
    
    #define DIV_1    1.0           //note it's 1.0, not 1, to get full floating point accuracy
    #define DIV_2    1.0
    // ADC reference voltage / calibration value
    #define V_REF    2.54         //use the measured Aref voltage
    #define LOOPdelay 200       //measure the voltages and update the LCD every xxx msec
    #define REDLITE 6
    #define GREENLITE 9
    #define BLUELITE 10
    
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    
    //declare the variables used
    float voltage1 = 0.0;        // calculated voltages
    float voltage2 = 0.0;        // calculated voltages
    
    void setup()
    {
      Serial.begin(9600);
      lcd.begin(20, 4);
      lcd.clear();
      delay(LOOPdelay);
      pinMode(REDLITE, OUTPUT);
      pinMode(GREENLITE, OUTPUT);
      pinMode(BLUELITE, OUTPUT);
      
     analogReference(INTERNAL);
    }
    
    void loop(){
      analogWrite(BLUELITE,0); //Blue brightness 255-0
      analogWrite(REDLITE,255); //Red brightness 255-0
      analogWrite(GREENLITE,255); //Green brightness 255-0
      // sample each channel A0 and A1
      voltage1 = DIV_1 * float((analogRead(A0)) * V_REF/1024.0);
      voltage2 = DIV_2 * float((analogRead(A1)) * V_REF/1024.0);
    
      // display voltages on LCD
      // each voltage is multiplied by the resistor network
      // division factor to calculate the actual voltage
      // voltage 1 - A (pin A0)
      lcd.setCursor(0, 2);
      lcd.print("CPU VCORE ");
      lcd.print(voltage1, 3);
      lcd.print("v");
      // voltage 2 - B (pin A1)
      lcd.setCursor(0, 3);
      lcd.print("CPU VRIN  ");
      lcd.print(voltage2, 3);
      lcd.print("v");
      delay(LOOPdelay);         //give LCD time to process data
    }
    

    Belial88:
    The values wig out when not connected/shorted, but whatever, but when I put it to that same 1.7v AA battery it reads as 2.0v. So how do i get that accurate and how do I get it to read 1.743v.

    You had mis-set a constant in the defines. I'm surprised it displayed anything close to reality. You may need to increase the value for LOOPdelay to make things readable. Indeed you can play with that value to see how low it can go before your LCD stops working.

    ( Off-topic, just happened to glance upon this line in the forum feed, the below is a generic reminder;

    #define DIV_1 1.0 //note it's 1.0, not 1, to get full floating point accuracy
    ```Instead of define, consider using 'static const' - in this case, 'static const float DIV_1 = 1.0<B>**<COLOR color="#ff0000">;</COLOR>**</B>'. Even if you did type '1' instead of '1.0', the float type would ensure that any operations with it are done in float. The space within these parentheses is not large enough to contain the pro/con arguments, google 'define vs const' for lots more information (some of which may not apply to Arduino - reader beware). )

    For the purpose on a future discussion on how to meld the servo, DVM, and Smartie code, here’s my take on how Smartie, running on the Arduino, does it’s job. Here’s a snippet of Smartie code ;

    void loop(){
      byte rxbyte;  //this tells the 'compiler' to allocate some memory for a variable called rxbyte
      byte temp;    //this tells the 'compiler' to allocate some memory for a variable called temp
      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
                                // 'switches' based on that byte
        {
        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;
    

    So what does serial_getch() do ?

    byte serial_getch(){
      int incoming;  
      while (Serial.available()==0){}
    	// read the incoming byte:
      incoming = Serial.read();
    
      return (byte) (incoming &0xff);
    }
    

    The big picture foir serial_getch() is that the Arduino sits polling the serial port (USB in your case) waiting for a character to come in from the PC. While it’s doing this, it’s not doing anything else … like running your servo or DVM code. When a byte does come in, it’s stored in rxbyte (eventually) for use by the rest of the Smartie code.

    That value of rxbyte then determines what Smartie does. It may move the cursor to some position, it may cause a character to be ‘printed’ on the LCD or it may even do nothing … allowing you to use that rxbyte value to cause the code to do something “custom” to your code (like an analogRead(A0) perhaps …). Each value of rxbyte corresponds to one of the ‘cases’ to be run.

    So there’s one problem to be solved, how to get the other code to run while not crippling Smartie. Afterall if that other code runs and the serial_getch() misses a byte or 2, your display will be AFU until the next refresh (from the PC) cycle. That’s less than good. And yet the existing servo code wants to poll the door open/close switch … a conflict with the Smartie code. That all said I believe there’s a good solution.

    To understand the Smartie switch … case code, read this.

    http://arduino.cc/en/Reference/SwitchCase

    Kamiquasi:
    ( Off-topic, just happened to glance upon this line in the forum feed, the below is a generic reminder;

    #define DIV_1 1.0 //note it's 1.0, not 1, to get full floating point accuracy
    ```Instead of define, consider using 'static const' - in this case, 'static const float DIV_1 = 1.0<B>**<COLOR color="#ff0000">;</COLOR>**</B>'. Even if you did type '1' instead of '1.0', the float type would ensure that any operations with it are done in float. The space within these parentheses is not large enough to contain the pro/con arguments, google 'define vs const' for lots more information (some of which may not apply to Arduino - reader beware). )
    
    Agreed Kami ... but this (coding, electronics) is so new to the OP, and the code he started with used #define, that I wanted to keep the new stuff I'd introduce to the min needed, to avoid the TMI, tl;dr condition.

    I’ve been training myself to be ‘Arduino proper’ so I was fighting myself re: the above but … whatcha gonna do. I didn’t learn General Relativity in a day … or a week … or :mrgreen:

    There are lots of problems with this merge of voltage reading and Smartie display.

    First of all, while you are waiting for an analog reading the Arduino is doing nothing.

    Second of all, while you are waiting for the Smartie to kick out a byte the Arduino is doing nothing.

    Then there are more complicated problems.

    Arduino is fine but it tries to sugar-coat reality.

    It’s fine to learn on, but the truth is that the world is a nasty and dangerous places with races and deadlocks.

    Consider if you were trying to do two things at once.

    Are you sure that you wouldn’t ever get confused no matter when the requests came in?

    That’s why all the programs that I have written for Atmel chips have as the main code:

       /* loop */
       for(;;)
          __asm__ ("sleep");
    

    I handle most everything in Interrupt Service Routines.

    That’s something that they try to hide from you in Arduino 1.01

    Also:

    The Smartie is trying to speak to a dumb LCD.

    It sets the cursor, spits out a few characters.

    Consider this: what if in your loop it picks up a cursor control command and goes to that position,

    then your voltage sampler comes in with a number, does its own cursor control to get to a position,

    and prints some voltage reading.

    The cursor is left at a strange place. When the loop gets back to the Smartie input part and wants to print “1234”,

    guess where it goes? Yup, the wrong place!

    If it were me, the first thing that I would do would be to dump the Smartie LCD interface, it’s too stupid.

    What the Arduino should require from the PC is data, not something formatted already.

    Instead of making it a serial port, make it an HID device taking reports from the PC.

    I don’t know what values you could get/use. Let’s presume some temps.

    So have an HID report that contains a temperature or two.

    Might as well have it send the PC time too.

    There no reason to have your device be running a RTC.

    Once you get that data you can integrate it with the display of voltages.

    Yes, this stuff is a bit hairy and complicated.

    That’s the way real life is especially when trying to do two unrelated things simultaneously.

    Mee_n_Mac:

    Belial88:

    Yup, as previously mentioned and as posted by Renate. Much the same idea as used in the tutorial. You use a pot to scale your 2.8v down to 2.5v and then set the ADC ref voltage to 2.56v. Of course you can do a calibration so the display reads the same as your (calibrated) DVM.

    I’m am little confused what you mean. The tutorial used 5v. What 2.8v are you referring to?

    You've previously mentioned that the max voltage you intend to read off the mobo was 2.8v. The tutorial used a voltage divider of 100k and 1000k to reduce (up to) 55v down to the 5v range (that's why there was an 11x multiply). You can use a voltage divider (a 10k pot) to do the same type of thing. Then you **[u]also use[/u]** the internal AREF voltage of 2.56v.

    If your other mobo voltage is > 2.8v, you can use a different voltage divider.

    http://en.wikipedia.org/wiki/Voltage_divider

    I’m sorry, I’m a little confused what you mean, and I know I’ve been confusing too.

    One of my voltage ranges needs to max out at around 2.8v, but I’d be totally okay with it being 2.5v, especially for increased accuracy. Even maybe 2.4v would be okay. I say 2.8v as a good max voltage that leaves a ton of headroom (note, I am at ~2vrin and that’s after an extreme overclock, so much more than ~2.3vrin is really not necessary, but haswell’s die at around 2.6v and sometimes things like vPeaks can hit that high on certain boards or certain situations, which is why I wanted a bit more headroom. So, a max of 3v is okay, to keep things simple, I’d be totally okay with a max of 3v.

    I guess the perfect max value would be like… 2.6v, but I really don’t mind it being between 2.5-3v.

    So the max voltage I’ll read, for me, will likely be about 2.06v, maybe it spikes to 2.1v sometimes, but I wanted to make sure it could read up to about 2.5-3v. So what do you mean exactly, I use both the 5v and the 2.56 (or 2.4 in my case)v AREF so the voltage is doubly-calibrated? I just include both in the code? I’m a little confused where the pot comes in. Don’t I just write in a divider of .5?