London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« on: August 24, 2010, 05:12:36 pm » |
I am new to this and need some guidance where to start. I am doing a project for an exhbition where I want to use 4 digit 7 segments LED displays to display time. The time is supposed to be running too fast (double or triple normal time or so) until someone interacts and normal time (and speed) is shown.
I have found some resources how to display time but how do I plan the project so that I get the normal time displayed with the input?
I have an Arduino Duemilanove..
Thankful for any advice.
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX
Offline
Faraday Member
Karma: 41
Posts: 5166
CMiYC
|
 |
« Reply #1 on: August 24, 2010, 05:35:33 pm » |
Reading an input and changing the speed which the time is displayed/counted is easy.
Most of the effort here will be interfacing with the LEDs and counting time properly. Figure this much out and the rest will be obvious.
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6817
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #2 on: August 24, 2010, 06:00:14 pm » |
We need to know a bit more...
Do you need to show the correct time?
What will the speeded up time show, and will the time go back to "correct" when someone interacts?
Do you need the time to be accurate?
Does the Arduino need to automatically know the time at power up, or are you happy to set it every time you turn it on?
What speed are you showing?
|
|
|
|
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #3 on: August 24, 2010, 06:13:32 pm » |
Correct time needs to be shown (when in normal speed). When the time is speeded up you need to notice that it is going too fast so I guess maybe 120 times quicker than normal is okay. On a second thought, maybe I need 6 digits to include seconds. That way it is easier to see that the clock is going too fast.
Yes, the time needs to go back to correct time when someone interacts.
The time can be reset once a day if needed at startup.
Thanks.
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6817
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #4 on: August 24, 2010, 08:20:04 pm » |
So pretty simple then, you don't need an RTC, just roll your own,
I would organize a 1/nth-second timer and two counters that count modulo 60/60/24. Then every 1/nth of a second update one counter (this is you fast counter) and every n interrupts update the other one (the real time counter).
So now we have two counters running counting H:M:S but one is n times faster than the other.
When someone interacts with the device set a flag (and possibly reset the fast counter with the value from the real time counter, depends on what you want to show)
Write a routine to display a "time", it gets called every nth of a second, it tests the flag and either displays the fast or slow counter.
That's pretty much it I think, plus of course you have to be able to set the time so that will need a few buttons, dip switches or something.
|
|
|
|
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #5 on: August 25, 2010, 06:08:59 am » |
Feels great that you are saying its pretty simple  I'll give it a try and see how far I manage... Thanks
|
|
|
|
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #6 on: September 18, 2010, 09:18:43 am » |
This is what I have now. Probably not the best way of making it but it works with the counting... I tried to follow graynomad's advice but now this is what I have. I want it to count slower (speed = 1000) when a button is pressed. I have tried to change the code so it would just change the delay to 1000 and also just made a copy of the whole loop more or less with a longer delay but nothing works. Can somebody help how I can make it work? */ int latchpin3 = 8; // connect to pin 12 on the second'595 int clockpin3 = 12; // connect to pin 11 on the second'595 int datapin3 = 11; // connect to pin 14 on the second'595 int latchpin2 = 5; // connect to pin 12 on the minute'595 int clockpin2 = 7; // connect to pin 11 on the minute'595 int datapin2 = 6; // connect to pin 14 on the minute'595 int latchpin1 = 3; // connect to pin 12 on the hour'595 int clockpin1 = 9; // connect to pin 11 on the hour'595 int datapin1 = 4; // connect to pin 14 on the hour'595 float b = 0; int c = 0; float d = 0; int e = 0; int speed = 10; // used to control speed of counting
int segdisp[10] = { 63,6,91,79,102,109,125,7,127,111 }; void setup() { pinMode(latchpin1, OUTPUT); pinMode(clockpin1, OUTPUT); pinMode(datapin1, OUTPUT); pinMode(latchpin2, OUTPUT); pinMode(clockpin2, OUTPUT); pinMode(datapin2, OUTPUT); pinMode(latchpin3, OUTPUT); pinMode(clockpin3, OUTPUT); pinMode(datapin3, OUTPUT); }
void loop() { for (int z=0; z<24; z++) // count to 24 hours for (int x=0; x<60; x++) // count to 60 minutes for (int y=0; y<60; y++) // count to 60 seconds
// Count
{ digitalWrite(latchpin1, LOW); shiftOut(datapin1, clockpin1, MSBFIRST, 0); // clears the right display shiftOut(datapin1, clockpin1, MSBFIRST, 0); // clears the left display digitalWrite(latchpin2, LOW); shiftOut(datapin2, clockpin2, MSBFIRST, 0); // clears the right display shiftOut(datapin2, clockpin2, MSBFIRST, 0); // clears the left display digitalWrite(latchpin3, LOW); shiftOut(datapin3, clockpin3, MSBFIRST, 0); // clears the right display shiftOut(datapin3, clockpin3, MSBFIRST, 0); // clears the left display { digitalWrite(latchpin1, HIGH); if (z<10) { digitalWrite(latchpin1, LOW); shiftOut(datapin1, clockpin1, MSBFIRST, segdisp[z]); // sends the digit down the serial path of hours shiftOut(datapin1, clockpin1, MSBFIRST, 63); // sends the digit down the serial path of hours digitalWrite(latchpin1, HIGH); } else if (z>=10) { d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digit c=int(d); // make it an integer, c is the right hand digit b=z/10; // divide z by 10 - the whole number value will be the left-hand digit e = int(b); // e is the left hand digit digitalWrite(latchpin1, LOW); // send the digits down to the shift registers! shiftOut(datapin1, clockpin1, MSBFIRST, segdisp[c]); shiftOut(datapin1, clockpin1, MSBFIRST, segdisp[e]); digitalWrite(latchpin1, HIGH); } } if (x<10) { digitalWrite(latchpin2, LOW); shiftOut(datapin2, clockpin2, MSBFIRST, segdisp[x]); // sends the digit down the serial path of minutes shiftOut(datapin2, clockpin2, MSBFIRST, 63); // sends the digit down the serial path of minutes digitalWrite(latchpin2, HIGH); }
else if (x>=10) { d=x%10; // find the remainder of dividing x by 10, this will be the right-hand digit, minutes c=int(d); // make it an integer, c is the right hand digit b=x/10; // divide x by 10 - the whole number value will be the left-hand digit, minutes e = int(b); // e is the left hand digit
digitalWrite(latchpin2, LOW); // send the digits down to the shift registers! shiftOut(datapin2, clockpin2, MSBFIRST, segdisp[c]); shiftOut(datapin2, clockpin2, MSBFIRST, segdisp[e]); digitalWrite(latchpin2, HIGH); } digitalWrite(latchpin3, HIGH); if (y<10) { digitalWrite(latchpin3, LOW); shiftOut(datapin3, clockpin3, MSBFIRST, segdisp[y]); // sends the digit down the serial path shiftOut(datapin3, clockpin3, MSBFIRST, 63); // sends the digit down the serial path digitalWrite(latchpin3, HIGH); } else if (y>=10) { d=y%10; // find the remainder of dividing y by 10, this will be the right-hand digit c=int(d); // make it an integer, c is the right hand digit b=y/10; // divide y by 10 - the whole number value will be the left-hand digit e = int(b); // e is the left hand digit digitalWrite(latchpin3, LOW); // send the digits down to the shift registers! shiftOut(datapin3, clockpin3, MSBFIRST, segdisp[c]); shiftOut(datapin3, clockpin3, MSBFIRST, segdisp[e]); digitalWrite(latchpin3, HIGH); } { delay (speed); } } }
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6817
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #7 on: September 18, 2010, 10:12:16 am » |
Hi sinuslinus, I'm having trouble following the masses of code but some things to do first I think, You don't need all those latch/clock/data pins, you can connect all 3 shift registers in series and only have a single latch, clock and data pin. Then for example your clearing code would be something as simple as this. digitalWrite(latchpin, LOW); // clear all displays for (int x=0, x < 3; x++) shiftOut(datapin, clockpin, MSBFIRST, 0); digitalWrite(latchpin, HIGH);
Which will write 3 null bytes into the 3 SRs thus clearing them. Not that you need to clear them every loop, the new values will be written over the old values, clearing as you have will only cause flicker. Next thing, for (int z=0; z<24; z++) // count to 24 hours for (int x=0; x<60; x++) // count to 60 minutes for (int y=0; y<60; y++) // count to 60 seconds Firstly, what does this do? From what I can see z = 23; x = 59; y = 59; Would do the same thing, so you don't actually have any counters. Also use meaningful variable names (yes I know I didn't above but that was a tight loop that could viewed all at once, your x,y,z get used elsewhere, for example what does "if (z<10)" do, rather "if (hours<10)". Next thing, you are mixing up the calculations with the IO, do one then the other. loop() { int digits[3];
// calc_all_digits_and_put_in_digits_array
digitalWrite(latchpin, LOW); for (int x=0, x < 3; x++) shiftOut(datapin, clockpin, MSBFIRST, digits[x]); digitalWrite(latchpin, HIGH);
float b = 0; int c = 0; float d = 0;
Why do you need floats to calc the time? Then you have to change them back to ints anyway. It's late here, but if you can clean up some of that we can have another look at it. Rob
|
|
|
|
« Last Edit: September 18, 2010, 10:37:29 am by graynomad »
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6817
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #8 on: September 18, 2010, 10:36:56 am » |
It's way after my bed time but I thought I'd give you a start. I think something like this will have a chance of working. #define SECONDS 0; #define MINUTES 2; #define HOURS 4;
uint_8 latchpin = 8; // connect to pin 12 on the '595 uint_8 clockpin = 12; // connect to pin 11 on the '595 uint_8 datapin = 11; // connect to pin 14 on the '595
uint_8 speed = 10; // used to control speed of counting
uint_8 seconds = 0; uint_8 minutes = 0; uint_8 hours = 0; uint_8 digits[6];
uint_8 segdisp[10] = {63,6,91,79,102,109,125,7,127,111};
void setup() {
pinMode(latchpin, OUTPUT); pinMode(clockpin, OUTPUT); pinMode(datapin, OUTPUT); }
void loop() {
if (++seconds > 59) { seconds = 0; minutes++; } if (minutes > 59) { minutes = 0; hours++; } if (hours > 23) { hours = 0; }
digits[SECONDS] = seconds / 10; digits[SECONDS+1] = seconds % 10; digits[MINUTES] = minutes / 10; digits[MINUTES+1] = minutes % 10; digits[HOURS] = hours / 10; digits[HOURS+1] = hours % 10;
digitalWrite(latchpin, LOW); for (int x=0, x < 6; x++) shiftOut(datapin, clockpin, MSBFIRST, segdisp(digits[x])); digitalWrite(latchpin, HIGH); delay (speed); }
It's still doesn't handle your original problem of a fast and slow clock, and I think the digits will be reversed, but it's a start. Rob
|
|
|
|
« Last Edit: September 18, 2010, 10:43:14 am by graynomad »
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #9 on: September 18, 2010, 11:04:19 am » |
I based it on this: http://tronixstuff.wordpress.com/2010/05/06/getting-started-with-arduino-chapter-five/and to be honest I don't really now how this works, it just works :-). First I just used 3 pins and all shift registers in series but I didn't manage to get all the displays working properly and just seconds counting. And I have no answer why I am using floats. I have 6 SRs in pairs, thats the way I got all displays working. I have a look at this and see what happens. Thanks a lot. / Linus
|
|
|
|
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #10 on: September 18, 2010, 07:58:41 pm » |
I understand the idea of simplifying the code but I don't get everything. Is uint_8 unsigned int ? Arduino doesn't compile uint_8 It didn't want to compile several other things but this works: #define SECONDS 0 #define MINUTES 2 #define HOURS 4
unsigned int latchpin = 8; // connect to pin 12 on the '595 unsigned int clockpin = 12; // connect to pin 11 on the '595 unsigned int datapin = 11; // connect to pin 14 on the '595
unsigned int speed = 10; // used to control speed of counting unsigned int seconds = 0; unsigned int minutes = 0; unsigned int hours = 0; unsigned int digits[6];
unsigned int segdisp[10] = {63,6,91,79,102,109,125,7,127,111};
void setup() {
pinMode(latchpin, OUTPUT); pinMode(clockpin, OUTPUT); pinMode(datapin, OUTPUT);
}
void loop() {
if (++seconds > 59) { seconds = 0; minutes++; } if (minutes > 59) { minutes = 0; hours++; } if (hours > 23) { hours = 0; } { digits[SECONDS] = seconds / 1 ; digits[SECONDS+1] = seconds % 10; digits[MINUTES] = minutes / 10; digits[MINUTES+1] = minutes % 10; digits[HOURS] = hours / 10; digits[HOURS+1] = hours % 10; } digitalWrite(latchpin, LOW); for (int x = 0; x < 6; x++) shiftOut(datapin, clockpin, MSBFIRST, digits[x]); digitalWrite(latchpin, HIGH);
delay (speed); }
I'll wire it up and see what happens.. But how can I get the change of speed and preferably a way to set the start "time"? O yes, when you press the button it should go back to the fast speed again after 10 seconds. Okay really, I realized today that want all six displays to just flicker in the fast mode. Hmm that is, like the are all just rolling numbers quickly. And at best show normal time for 10 seconds when the button is pressed. Otherwise it looks like a bomb and not a spinning clock...
|
|
|
|
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #11 on: September 18, 2010, 08:45:29 pm » |
I did a quick wiring but the segments are all wrong. Number 1 is shown as the top horizontal segment for instance. And it doesn't shift down to the next display either. It starts counting on two displays (if I set speed to 1000 it shows seconds on two displays) but when reaches 10 they show differently.
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Offline
Tesla Member
Karma: 71
Posts: 6817
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #12 on: September 18, 2010, 09:04:19 pm » |
I did a quick wiring but the segments are all wrong. Number 1 is shown as the top horizontal segment for instance.
That implies that either your wiring is wrong OR the values in segdisp are wrong, like this FWIW I find with these type of bit pattern lookup tables it's better to use hex or binary and lay it out to be easy to read. short LED_data [] = { // abcdefg. 0xfc, // 0 %11111100 0x60, // 1 %01100000 0xda, // 2 %11011010 0xf2, // 3 %11110010 0x66, // 4 %01100110 0xb6, // 5 %10110110 0xbe, // 6 %10111110 0xe0, // 7 %11100000 0xfe, // 8 %11111110 0xf6, // 9 %11110110 0xee, // A %11101110 0x3e, // b %00111110 0x9c, // C %10011100 0x7a, // d %01111010 0x9e, // E %10011110 0x8e // F %10001110 }; And it doesn't shift down to the next display either.
It starts counting on two displays (if I set speed to 1000 it shows seconds on two displays) but when reaches 10 they show differently. That all points to wiring, can you post the exact circuit you have? It starts counting on two displays Do you have all 6 SRs wired in series? uint_8 Sorry about that, it was late after all, firstly it should have been uint8_t, and secondly your unsigned int is the same.
|
|
|
|
« Last Edit: September 19, 2010, 04:43:03 am by graynomad »
|
Logged
|
|
|
|
|
London, UK
Offline
Newbie
Karma: 0
Posts: 34
Arduino rocks
|
 |
« Reply #13 on: September 19, 2010, 05:45:04 am » |
The values are correct. It has been working with the old code. I went back a step and this is what you wrote: shiftOut(datapin, clockpin, MSBFIRST, segdisplay(digits[x]));
Arduino wont accept this: "In function 'void loop()': error: 'segdisplay' cannot be used as a function" I changed that part to be able to compile it last night as posted but I think this is where the problem is, since your original code didn't. Can you have a look at this? All 6 SRs are daisychained.
|
|
|
|
« Last Edit: September 19, 2010, 06:13:20 am by sinuslinus »
|
Logged
|
|
|
|
|
|
|
|