Posted on

Arduino Based Voltage Meter

Arduino Uno R3 Main Board Front/Top View A000066

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.

Posted on

Concept to Product – Our USBTINY Programmer

Here at Proto-PIC we are always thinking about new products we can bring to the market. Sometimes the ideas ‘just come to us’, other times, it’s a customer comment, review, or passing remark that inspires the idea.  We had a customer who had a USBTINY programmer, and called for support on programming a couple of chips she had. The chips in question were the ATTINY 85, and the ATMEGA 328. While both of these chips are through-hole and easy to mount to a breadboard, our customer could not get the chips to program consistently.

Thus, the idea of our USBTINY ISP ZIF programmer was born.  The main idea was to produce a programmer with a ZIF socket that could program ATTINY25/45/85 as well as the ATMEGA 328 (As used in the Arduino). I also wanted to have an ICSP header to program chips ‘off board’.

Proof of concept.

The USBTINY firmware was downloaded from the internet, expecting this to require an ATTINY 84 Chip, I was happy to find the firmware could be compiled for an ATTINY 45, not a chip we normally have in stock, but if it works on a 45, it will work on an 85. Uploaded the compiled firmware to an ATTINY 85, and building the breadboard below, I tested the circuit by uploading firmware to another ATTINY 85.

We like RED at Proto-PIC

Seeing this program a chip for the first time gave me that ‘happy’ feeling inside. Now, I asked myself, do I make this a kit or do I create a PCB? Thinking that a finished product is more likely to be of use to the general tinkering community, I opted to create a PCB. I wanted to test this design with an ICSP setup, so I ‘frankensteined’ a board on a piece of matrix PCB board, and created :

FrankenProgrammer

He might be scary to look at, with his ‘barely hanging on resistors’ and you don’t want to see the wiring on the back. But this programmer works ‘It’s ALIVE . . . . . ALIVE’ , programming ATTINY 85s, ATMEGA 328s, and uploading the bootloader to the Arduino UNO. Now that I have a working prototype, time to layout & create a PCB.

To lay out the schematic, I referred to the breadboard prototype as this was easier to follow than FrankenProgrammer’s wiring. I used EAGLE to layout the schematic & design the PCB, Knowing I wanted to use a ZIF socket, I laid out the circuit to allow me to use the same socket for the ATTINY 25/45/85 as well as the ATMEGA 8/168/328 chips. I find these the most popular chips to use in projects. I have also included an ICSP header, to program chips installed in boards with an ICSP header. Sending the design off to our PCB Fabricator, waiting for a week or so, for the PCBs to be made and delivered, and then finding out I had NO ZIF sockets left. No problem, I’ll just install a swiss pin socket for testing.

A thing of beauty

Now that is a nice board – does need a small modification to the layout (The USB connector needs moved 1MM as it JUST clips the edge of the PCB), and as you can see, I added a place to add ZENER diodes if required, as well as a resonator to allow the programming of chips that have the fuses set to use an external oscillator. I did socket the ATTINY Chip that has the firmware, the reason for this was to allow me to remove for reprogramming if required. I think this is a good idea for the final release. I tested this board with an ATMEGA328, an ATTINY85, as well as programming a bootloader to an Arduino UNO. This programmer is now in my collection, and has a small upgrade of a ZIF socket (Mounted on Swiss Turned Pins).

In all her finery

Concept -> final design, around 3 weeks. Things went well for this design, It can take months, and take a few iterations to get a final design.