markbennettuk
Published © CC BY-NC-SA

Voltmeter Clock

A clock that shows the time on 3 panel mount voltmeters.

IntermediateFull instructions provided4,253
Voltmeter Clock

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
85C1-V 5 volt panel meter
×3
DS3231MPMB1 Peripheral Module
Maxim Integrated DS3231MPMB1 Peripheral Module
×1
Jumper wires (generic)
Jumper wires (generic)
×4
Wire, Hook Up
Wire, Hook Up
×1
Rubber feet
×6

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Laser cutter (generic)
Laser cutter (generic)
3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Custom parts and enclosures

Front face

Base plate

End Bracket

Arduino Holder

Clock board holder

Schematics

Volt Meter Clock circuit

Dial overlays

Code

Code

Arduino
// Volt Meter Clock
// by Mark Bennett 2020

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68

// clock module connections
// pin A5 => SCL
// pin A4 => SDA
// VCC and GND connected to 5V and GND

int mode = 0; // 0 = run, 1 = set, 2 = show minimum, 3 = show maximum

int hoursPin = 5;     // pin for hours meter
int minutesPin = 6;   // pin for minutes pin
int secondsPin = 9;   // pin for seconds meter

float hoursValue = 0; // variable to store current hours 
float minutesValue = 0; // variable to store current minutes 
float secondsValue = 0; // variable to store current seconds 

float hoursMinimum = 14;   // 0-255 value to set zero position of meter
float minutesMinimum = 14; // 0-255 value to set zero position of meter
float secondsMinimum = 22; // 0-255 value to set zero position of meter

float hoursMaximum = 230;   // 0-255 value to set maximum position of meter
float minutesMaximum = 230; // 0-255 value to set maximum position of meter
float secondsMaximum = 236; // 0-255 value to set maximum position of meter

void setup() {
  pinMode(hoursPin, OUTPUT);
  pinMode(minutesPin, OUTPUT);
  pinMode(secondsPin, OUTPUT);
  
  Wire.begin();
  Serial.begin(9600);

  if(mode == 1){
    // do not use leading zero on the numbers, they will be read as octal numbers
    //             s   m   h  day   d   m   y
    setDS3231time(30, 46, 16,   7, 12,  9, 20);
  }
}

void loop() {
  byte second, minute, hour, weekday, day, month, year;

  switch(mode){
    case 0:
    case 1:
      readDS3231time(&second, &minute, &hour, &weekday, &day, &month, &year);
      secondsValue = second;
      minutesValue = minute;
      hoursValue = hour;
  
      if(hoursValue > 11){
        hoursValue -= 12;
      }

      analogWrite(secondsPin, secondsMinimum + (((secondsMaximum - secondsMinimum) / 60) * secondsValue));
      analogWrite(minutesPin, minutesMinimum + (((minutesMaximum - minutesMinimum) / 60) * minutesValue));
      analogWrite(hoursPin, hoursMinimum + (((hoursMaximum - hoursMinimum) / 12) * hoursValue));
      break;
    case 2:
      // these lines are for setting the maximum and minimum level for the meters when you first set up your clock
      analogWrite(secondsPin, secondsMinimum);
      analogWrite(minutesPin, minutesMinimum);
      analogWrite(hoursPin, hoursMinimum);
      break;
    case 3:
      analogWrite(secondsPin, secondsMaximum);
      analogWrite(minutesPin, minutesMaximum);
      analogWrite(hoursPin, hoursMaximum);
      break;
  }
  
  delay(100);
}

byte decToBcd(byte val){
  return((val / 10 * 16) + (val % 10));
}

byte bcdToDec(byte val){
  return ((val / 16 * 10) + (val % 16));
}

void setDS3231time(byte second, byte minute, byte hour, byte weekday, byte day, byte month, byte year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekday));
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void readDS3231time(byte *second, byte *minute, byte *hour, byte *weekday, byte *day, byte *month, byte *year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *weekday = bcdToDec(Wire.read());
  *day = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

Credits

markbennettuk

markbennettuk

4 projects • 19 followers

Comments