I used this schematic and code to create a voltmeter using an Arduino Nano (thank you T.K. Hareendran):
https://www.electroschematics.com/arduino-digital-voltmeter/. I used two resistors, 7100 and 33000 for the voltage divider. I also measured the voltage between 5 volts and ground. It measures 7.74 volts. I edited the code for both resistors, voltage reading of the Nano, and I used a SSD1306 oled display. Here is the code:
/*
DC Voltmeter
An Arduino DVM based on voltage divider concept
T.K.Hareendran
*/
#include <Wire.h>
#include <Adafruit_GFX.h> // Include core graphics library for the display
#include <Adafruit_SSD1306.h> // Include Adafruit_SSD1306 library to drive the display
Adafruit_SSD1306 display(128, 64); // Create display
#include <Fonts/FreeMonoBold12pt7b.h> // Add a custom font
#include <Fonts/FreeMono9pt7b.h> // Add a custom font
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
//This is the original code
float R1 = 33190;// resistance of R1 -see text!
float R2 = 7120; // resistance of R2 - see text!
//float R1 = 30080;// resistance of R1 -see text!
//float R2 = 7500; // resistance of R2 - see text!
int value = 0;
void setup() {
pinMode(analogInput, INPUT);
delay(500 ); // This delay is needed to let the display to initialize
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize display with the I2C address of 0x3C
display.clearDisplay(); // Clear the buffer
display.setTextColor(WHITE); // Set color of the text
display.setRotation(0); // Set orientation. Goes from 0, 1, 2 or 3
display.setTextWrap(false); // By default, long lines of text are set to automatically “wrap” back to the leftmost column.
// To override this behavior (so text will run off the right side of the display - useful for
// scrolling marquee effects), use setTextWrap(false). The normal wrapping behavior is restored
// with setTextWrap(true).
display.dim(0); //Set brightness (0 is maximun and 1 is a little dim)
}
void loop() {
// read the value at analog input
value = analogRead(analogInput);
vout = (value * 4.74) / 1023.0; // see text
vin = vout / (R2/(R1+R2));
if (vin<0.09) {
vin=0.0;//statement to quash undesired reading !
}
display.clearDisplay(); // Clear the display so we can refresh
display.setFont(&FreeMono9pt7b); // Set a custom font
display.setTextSize(1); // Set text size. We are using a custom font so you should always use the text size of 0
// Print text:
display.setCursor(0,10); // (x,y)
display.println("Voltmeter: "); // Text or value to print
display.setCursor(0,27); // (x,y)
display.println("Volts: "); // Text or value to print
display.setCursor(70,27); // (x,y)
display.println(vin); // Text or value to print
// Print variable with left alignment:
display.display(); // Print everything we set previously
delay(1000 );
}
This is the first attempt. The voltage is very close to what my variable power supply reads and I have checked it with another voltmeter for accuracy which matches. The display on the SSD1306 bounces about 6 hundredths but sometimes goes as much as 1/10th of a volt low to 1/10th of a volt high compared to my voltmeter.
Then I tried a voltage sensor that uses a voltage divider with smd resistors. I measured the resistors and R1 which should have read 30K ohms measured 30,080 ohms and R2 was right on the money at 7.5K ohms. I wired the sensor and changed the values for R1 and R2 in the code. I uploaded the code. This time the variable meter read 8.11 volts and my display bounced between 8.01 volts to 8.24 volts.
Here is my dilemma. Looking at youtube videos using a Hitachi 16X2 display, the voltage values appear to be rock steady but on my SSD1306, the values bounce between 2/10ths of a volt. Am I being too picky? Should the SSD1306 be more stable? I could measure 10ths instead of hundredths. BTW, the voltmeter I use on my variable power supply also measures in hundredths and appears to be more stable.
Any suggestions?
Thanks.
