Author Options:

Arduino Multimeter on 1602LCD? Answered


I am currently in the process of finishing the code for my Arduino controlled PSU with an LCD volt and amp meter. My question was basically, how can I get the volts and the amps to show on the LCD with 3 decimal place digits instead of 2 which i have now.

Also, im having trouble putting 4 measurements all on one display- i currently have watts, amps and volts but i wanted to add resistance, however, for some reason i cant fit them all in one screen and i get weird errors when i try changing the setCursor value. 


P.s here is the code I'm using (a took bits off different websites and examples-will reference them in the final sketch)
#include <LiquidCrystal.h>
const int numRows = 2;
const int numCols = 16;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int analogInputVolts = A0; //voltinput
int analogInputAmps = A1; //ampinput
float vout = 0.00;
float vin = 0.00;
float amps = 0.00;
float watts = 0.00;
float ohms = 0.00;

float VA = 4.970;          // Arduino 5V supply
float R1 = 2995;        //  R1 in ohms
float R2 = 999;        //  R2 in ohms

int readAmpsADC = 0;
int readVoltsADC = 0;

void setup(){
  lcd.begin(16, 2);
   pinMode(analogInputVolts, INPUT);
   pinMode(analogInputAmps, INPUT);

float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

void loop() {
   readVoltsADC = analogRead(analogInputVolts);
   readVoltsADC = readVoltsADC + analogRead(analogInputVolts);
   readVoltsADC = readVoltsADC / 2;
   vout = (readVoltsADC * VA) / 1023.0;
   vin = vout / (R2/(R1+R2)); 
   readAmpsADC = analogRead(analogInputAmps);
   readAmpsADC = readAmpsADC + analogRead(analogInputAmps);
   readAmpsADC = readAmpsADC + analogRead(analogInputAmps);
   readAmpsADC = readAmpsADC / 3 ;      // get average of 3 readings

   amps = fabs(fmap(readAmpsADC, 509.0, 699.0, 0.0, 5.0));

   if (amps < 0.09) amps = 0.00;
   if (amps > 5) digitalWrite(13, HIGH);
   if (vin < 0.5) vin = 0.00;
   watts = vin* amps;
   ohms = vin / amps;
   if (amps = 0.00) Serial.println("Nil");
   lcd.print(" ");
   lcd.setCursor(1, 1);
  lcd.setCursor(0, 0);
   lcd.print(" ");



Why are you floating everything? Use int instead of float. Floating the math could be causing problems.

Why do you need a resistance measurement for a power supply? Dividing the voltage output of the power supply by the amperage output of your power supply doesn't give you any kind of useful info.

You should probably set the cursor position before you print.

What is the advantage of using int instead of float? And how would I set the cursor position before printing, do you mean physically swapping the code lines?

Float will sometimes mess with the math.

Yes move the lines of code. This way you set the cursor where you want the print to start at.

is this the reason why the rows and columns that i set in the setCursor mode dont actually follow the correct layout. i.e. (7,0) doesnt actually go to (7,0) but rather somewhere totally different

Yes. You have to set the cursor in the right place before telling the screen what to display.

The items are being displayed exactly where you have told them to display. On the first pass through the sketch the Voltage is printed in the right place. But then the cursor is set the the start of the 2nd row and it displays your amperage. Then the cursor is set to the start of the first row and displays the wattage. Then you set the cursor to the middle of the first row and it run through the sketch at the beginning again. Since you left the cursor in the middle of the 1st row on the last loop through the sketch the voltage ends up being displayed there.

In ardino I got only two decimal value e.G. 12.02 ,20.45etc for more accurate and precision measurement I need more digital after point like 12.02123; 20.45557; 27.34567

Any solution....

In ardino I got only two decimal value e.G. 12.02 ,20.45etc for more accurate and precision measurement I need more digital after point like 12.02123; 20.45557; 27.34567

Any solution....

Don't recalculate (R2/(R1+R2)); Its a constant for your hardware.,

I just put this in my program, but now for some reason i'm getting watts showing on the LCD but no amp value it just says "A:0.00". So i undid the changes and it keeps on happening, is there a bug in the code i cant work out?

yeah this was something strange- in the serial monitor the ohms readout would say "inf".

That's because anything divided by zero is infinity. You should ALWAYS check for Div/0 before you do a calculation.

Thanks, i'm still getting the error of a random digit appearing on the LCD after i change decimal place locations i.e the last digit on the 3 decimal value moves to the right and when i decrease the voltage less than 10v (so its just 4 digits) the last digit remains unchanged so it seems like i have a 4 decimal place value. Why does this happen, i had a feeling it was because of the setCursor mode but i changed it and the error still remains

lcd.print(" ");
   lcd.print("V: ");
   lcd.setCursor(1, 1);
  lcd.print("A: ");
  lcd.setCursor(0, 0);
   lcd.print(" ");
   lcd.print("W: ");

No, it covers the OLD values with clear space, then writes the new values on top.
WHat I think you're seeing is something like
1.230...but its actually writing
1.23 on the screen, so you still see

With the new code you should see

But put a 100mSec delay in the loop, or only write the LCD when there is a change in the value, or the display will flicker.

I changed the loop delay but it is still covering the values on the LCD. But it is doing what you said, in that the amps value is flickering with values trying to get on screen but they get blocked off. So currently, the only things that i can see on the display are "V:,A: and W:" no values...

Change the lines lcd.print(watts) to
lcd.print (watts,3);

Likewise, amps, Vin

ahh thanks for that, would you by any chance know how accurate the arduinos A/D because i would have thought showing 3 digits would be inaccurate

You have to understand the difference between resolution, precision and accuracy. The RESOLUTION of the arduino ADC is 1024 bits. The accuracy is around 512 bits, the precision is awful. You could improve it by using a real voltage reference to feed the ADC.

In other words, three digits are for show, you can only really read the first 2 decimals.

There's a "Vref" pin on the Arduino board, I think you can cut a link, and put a precision reference in to there