// To install from the Library Manager: // "LiquidCrystal I2C" #include #include // The analog pin the voltage comes in on const int INPUT_PIN = A0; // The Arduino's 5V: with a multimeter, // write what its 5V pin really measures const float VREF = 5.00; // How many readings are averaged const int SAMPLES = 16; // Time between measurements (ms) const unsigned long READ_EVERY = 300; // I2C address: mostly 0x27, some 0x3F LiquidCrystal_I2C lcd(0x27, 16, 2); // The bar's five pieces: boxes with 1-5 // columns filled, as custom LCD chars void makeBars() { for (int level = 0; level < 5; level++) { // A row, level+1 columns from left byte row = 0; for (int col = 0; col <= level; col++) { row |= 0x10 >> col; } byte shape[8]; for (int y = 0; y < 8; y++) shape[y] = row; lcd.createChar(level, shape); } } // The average reading: steadier numbers int readAverage() { long sum = 0; for (int i = 0; i < SAMPLES; i++) { sum += analogRead(INPUT_PIN); } return sum / SAMPLES; } // Bottom row: 0-5 V as a 16-box bar; // 5 steps a box, 80 steps in all void showBar(int raw) { int steps = (long)raw * 80 / 1023; lcd.setCursor(0, 1); for (int cell = 0; cell < 16; cell++) { int fill = steps - cell * 5; if (fill >= 5) { lcd.write(byte(4)); } else if (fill > 0) { lcd.write(byte(fill - 1)); } else { lcd.print(' '); } } } void setup() { lcd.init(); lcd.backlight(); makeBars(); Serial.begin(9600); } void loop() { int raw = readAverage(); // A 0-1023 reading, turned into volts float volts = raw * VREF / 1023.0; lcd.setCursor(0, 0); lcd.print("Voltage: "); lcd.print(volts, 2); // The trailing space clears old text lcd.print(" V "); showBar(raw); Serial.print("Voltage: "); Serial.print(volts, 2); Serial.print(" V (A0 = "); Serial.print(raw); Serial.println(")"); delay(READ_EVERY); }