Pages: [1]   Go Down
Author Topic: Volt Meter Clock  (Read 2141 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,
This is indeed my first post. I've had my arduino for a while and have been feel particularly hobbyish lately so I decided to break it out and give a project a go. I have seen some cool things done with analog volt meters and decided to make a clock. I decided to go ahead and make a volt meter clock. I did a bit of searching and there has been some work with them but I wanted to write my own code since I just finished a course in C programming. I did look at some other code but it seemed very complex. So I gave it a go myself.
Basic idea is that there are three voltmeters (hour(0-12), minute(0-60), second(0-60)) that will serve as the dials for my clock. I will use the arduino to control the voltages to each meter in accordance to the time. I am using the analogWrite() function and would really appreciate someone to take a look at my code. I dont have my arduino or the volt meters at the moment but have already written the code. There is a variable for a set button but it is not yet implemented. Anyways, the code:
Code:

int pinSecond = 11; //pins for each voltmeter
int pinMinute = 10;
int pinHour   = 9;
int pinSet    = 8;

double stepHour = 0; //increase for each step
double stepSecond = 0;
double stepMinute = 0;

double voltHour = 0; //"volts" for each setting. Not actually volts
                    //but percentage(?) of 5V.
double voltMinute = 0;
double voltSecond = 0;

void setup()
{
    pinMode(pinSecond, OUTPUT);
    pinMode(pinMinute, OUTPUT);
    pinMode(pinHour, OUTPUT);
    pinMode(pinSet, INPUT);

    stepHour = 12/255;
    stepMinute = 60/255;
    stepSecond = 60/255;
}

void loop()
{
    for (int h=0; h<12; h++)
    {
        analogWrite(pinHour, voltHour);

        for (int m=0; m<60; m++)
        {
            analogWrite(pinMinute, voltMinute);

            for(int s=0; s<60; s++)
            {
                analogWrite(pinSecond, voltSecond);
                voltSecond = voltSecond + stepSecond;
                delay(1000);
            }

            voltMinute=voltMinute+stepMinute;
            voltSecond=0;
        }

        voltHour=voltHour+stepHour;
        voltMinute=0;
    }
    voltHour=0;
}
So that's it. Seems a bit too simple to be correct but perhaps it is. I will eventually go back and try to do a bit of optimization with variables. Seems like I could use some more ints and bytes to make it a bit smaller.
I will also implement some code that upon a button press will progress the time by one minute and perhaps add a second button for hours.
Any suggestions?
My one question is about the analogWrite function. This takes a value between 0 and 255 and I understand a bit of how it works but would a value of 0=0V and a value of 255=5V on the voltmeter?
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 534
Posts: 26969
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The analogWrite controls a PWM signal going out.  You'll probably want to run the output into an RC filter to make smooth(er) DC to into the meters.
Once you get working to your satisfaction, I think you'll want to control the seconds going by by keeping track of the millis() or micros() going by for better accuracey, delay(1000) may give you a lot of drift.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8501
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's usually better (or at least clearer) to seperate the input and calculations from the output. So in that context I would do something like this psuedo code

Code:
#define MAX_PWM_VAL 50 // for example

#define HOURS_PIN 2
#define MINUTES_PIN 3
#define SECONDS_PIN 4


every second
seconds++
if (seconds > 59) {
   seconds = 0;
   minutes++
}

if (minutes > 59) {
   minutes = 0;
   hours++;
}

if (hours > 24) {
   hours = 0;
}

// now we have a set of variables to use
// map the time variables to PWM values that make sense for the dials being used

analogueWrite (SECONDS_PIN, map (seconds, 0, 59, 0, MAX_PWM_VAL));
analogueWrite (MINUTES_PIN, map (minutes, 0, 59, 0, MAX_PWM_VAL));
analogueWrite (HOURS_PIN,   map (hours, 0, 24, 0, MAX_PWM_VAL));


Quote
but would a value of 0=0V and a value of 255=5V on the voltmeter?
Depends on the meter, but 5V may be too high. Hense the mapping above.

______
Rob
« Last Edit: February 02, 2011, 12:32:31 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the way you did the code will make the minute and hour meters move in discrete  steps, rather than smoothly move from one number to the other.  Also you should be able to do all of the calculations with only integers.  Let me know if you need any more help.  I have my own arduino powered meter clock on my front table. (check out Make vol 13)
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey all,

Thank you for the great replies, all very helpful.
Of course, I am left with some(less) questions.
@graynomad.
The psuedo code looks great though at first I didnt catch the psuedo and was like, "Holy crap! When did C++ get so plain language?"
In your code you use #define. How does this compare in memory usage to an int or byte. Seems like one could replace a lot of constants with these but I haven't seen them much.
As far as the gauges? You say that this depends on the gauge. I was thinking of using a 0-5V meter but perhaps there are better ones.
I have seen some 0-5V meters online for cheap, seems like they could work pretty well. I also have some old pyrometers I would like to use. I guess I'll have to get over to a powersupply and see about their specs.
@Crossroads.
RC circut? I have learned of this but will have to go back and refresh myself. The basic idea is this will smooth the power out, yeah?
As far as millis. I have searched around for some clock code (forgot that a clock doesnt need to be a volt clock for the code to be applicable) and found some millis() implementations such as this one:
Code:
if (millis() - lastTick >= 1000) {
lastTick = millis();
serialOutput();
second++;
}
I understand and like this usage but what happens with millis() overflows?
@gradbert
I definitely want the discret steps, at least for now. I have seen your clock and when I started my hunt (inspired by the torrent meter) yours was one of the ones that I saw. I had a bit of a hard time deciphering your code though/wanted to write my own anyways. I think my biggest need for help right now is the electronics end of things.
I will certainly let you all know as the project progresses and let you know how it turns out.
Thanks!
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8501
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
In your code you use #define. How does this compare in memory usage to an int or byte.
#define is a preprocessor directive, it doesn't use any memory, just performs a text substitution before the compiler sees the code.

So

#define CONST_VAL 1

is IMO it's a better option than say

const int CONST_VAL = 1;

for that reason but also in the resultant code, say

if (CONST_VAL == x)

using a variable the processor has to go and get the CONST_VAL value at run time, as a #define it's a load immediate instruction which has to be faster.

I know every man and his dog uses const for this so maybe my reasoning is all wrong, but that's what I've done for years.

Quote
You say that this depends on the gauge.
I was just thinking of doing this with say converted current meters (or maybe those "old pyrometers") that may have a limited full scale voltage. But if you're getting 5v dials then it doesn't matter.

As for the RC filter on the PWM, it may not be required if the meter needles have enough inertia and the PWM frequency is high enough.


______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 534
Posts: 26969
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As long as you define the variables used with millis() as
unsigned long
and do all your math as subtractions (millis_now - millis_before)
the math will work out.
For example, say the time just rolled over and you captured it at 0x0000 0030
and time before was 0xFFFF FF10
then 0000 0030 - FFFF FF10 will yield a correct result of 0x0000 0120

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12858
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I know every man and his dog uses const for this so maybe my reasoning is all wrong

It is.   smiley-wink  "const" is usually free.  "static const" is always free.  With the advantage that "const" is typed...

Code:
#define MILLISPERSECOND (1000)
unsigned long Stop;
Stop = 68 /*seconds*/ * MILLISPERSECOND;  // Oops!

Code:
static const unsigned long MILLISPERSECOND = 1000;
unsigned long Stop;
Stop = 68 /*seconds*/ * MILLISPERSECOND;  // Whew!
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8501
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks CB, so the I assume the typing helps protect against doing the wrong thing, but I can't get the second one to throw an error.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Pages: [1]   Go Up
Jump to: