Arduino Based Voltage Meter

Arduino Based Voltage Meter

I was looking at making some videos on Arduino development, and while planning the recording sessions, I thought about using a web-cam to show a multi-meter screen to show readings on a circuit. While this would not be too difficult to arrange, I thought 'What if I could read the voltage and display it on my PC screen!'.  This lead to a mini project . .


      The first step was to read the voltage using an analog input on the Arduino, and scale this to the actual voltage, As I am using a USB connection to power the Arduino (and my final project) - I read the voltage using my multi-meter and took a note of this (5.14 Volts), to use later in my code. I then wrote code to print the voltage reading to the Serial Monitor :


VoltMeter1.ino      int myVoltageReading = 5.14;      unsigned int analogIn = 0;      void setup()      {              Serial.begin(115200);      }       void loop()      {              analogIn = analogRead(A0);              analogIn = map(a, 0, 1023, 0, myVoltageReading * 1000);                if (analogIn < 10) Serial.print("0");               if (analogIn < 100) Serial.print("0");              if (analogIn < 1000) Serial.print("0");              if (analogIn < 10000) Serial.print("0");              Serial.println(a, DEC);              delay(150);      }


This is reading the analog port every 150mS and sending the voltage to the serial monitor in micro Volts. A good start. Now to write a C# application to get this info and display it on screen. Using Visual Studio, I started a new application, and designed a form with a nice big font displaying '00:000 V'.  This was going to be my canvas. I then needed a way to select the COM port that the Arduino would be connected to, I had used a similar piece of code in an earlier project, so I just cut and pasted that into my new project. I also added a drop down box, label and a button. I then wrote the serial data handler part of the application. The application would open the serial port, and when it received some data, it would call a function that took this data and updated the display. Unfortunately this did not go as I had hoped due to the data structure (or lack of structure) as the application would often show random values. I then decided to update the Arduino sketch to send a header, and footer to the data. This would allow the C# application to parse the data in a controlled manor. Here is the update :

VoltMeter2.ino

      int myVoltageReading = 5.14;
      unsigned int analogIn = 0;
      void setup()
      {
              Serial.begin(115200);
      }

      void loop()
      {
              analogIn = analogRead(A0);
              analogIn = map(analogIn, 0, 1023, 0, myVoltageReading * 1000);
              Serial.print("@");
              if (analogIn < 10) Serial.print("0");
              if (analogIn < 100) Serial.print("0");
              if (analogIn < 1000) Serial.print("0");
              if (analogIn < 10000) Serial.print("0");
              Serial.print(analogIn, DEC);
              Serial.print("#");
              delay(150);
      }

      This is now good for reading voltages up to myVoltageReading, but some of the circuits may require up to 9 Volts (or higher). This can be arranged using 2 resistors, and a small change to the code. I am using 2 x 8.2K matched resistors (I matched them using my multi-meter), though you could use 2 resistors of the same unmatched value if you just wanted approximate voltage. I connected the resistors in series, one end to GROUND on the Arduino, the intersection of the resistors to the A0 pin, and my input probe to the free end of the resistor pair. Updating the code to the code below, I could now read up to 10V and I also stabilized the reading by taking an average of 10 reads. I used my meter and a 9V battery to give a reference so I could 'trim' the top end. I decided to do this rather than use a voltage reference as I wanted this to be as cheap as possible.

VoltMeterFinal.ino

      unsigned int analogIn = 0;
      void setup()
      {
              Serial.begin(115200);
      }

      void loop()
      {
              for (int loopy = 0; loopy < 10; loopy++)
        {
               analogIn = analogIn + analogRead(A0);
               delay(10);
        }
              analogIn = analogIn / 10;
              analogIn = map(analogIn, 0, 1023, 0, 10190); // The last value here has been trimmed - 9.2V on Milti-meter matches
              Serial.print("@");
              if (analogIn < 10) Serial.print("0");
              if (analogIn < 100) Serial.print("0");
              if (analogIn < 1000) Serial.print("0");
              if (analogIn < 10000) Serial.print("0");
              Serial.print(analogIn, DEC);
              Serial.print("#");
              delay(50);
              analogIn = 0;
      }


      Now that I have this up and running, I wanted to make the project as small as I could. I got a 5V pro-mini and an FTDI based USB to Serial board (Though any USB -> Serial adapter would be OK) and soldered them together, one on top of the other.  I had an old muti-meter, and using the leads from this, I made my probes, and then secured them with hot glue (After soldering them to Ground and the Resistors), finally wrapping the electronics in heat tubing. This is now sitting in my tools drawer, ready to go. I have built one of these for myself, for using at home.

Click here for the code for this project.

5th Sep 2019

Recent Posts