Pages: [1]   Go Down
Author Topic: Tick Tock Another Binary Clock  (Read 921 times)
0 Members and 1 Guest are viewing this topic.
South Uk
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello world. Right i have been slowly teaching my self through different projects and have hit a bit of a mental break down on the best way to achieve what i want from my project.

I am building a Binary clock using an atmega328p on a breadboard for now, then the hope is to move it forward to a full working pocket watch once i am happy with the prototype.

*Now the problem is power consumption of the LEDS and the watch lasting for a reasonable time.*

I Know this can be done by making the 328 carry on counting time but to switch off the LEDS say 30 seconds after a switch is activated like a push button or when i open the watch case.

Now my problem is with the best way to go about this with out using 'if' statements too much and slowing the clock down and losing time.

This is the code so far.... and any suggestions would be more than appreciated in solving my problem and even if code is the right way to do this and if not maybe a better hardware solution is out there?

Code:
// CSM
// binary clock code V1.2, on atmega328p-pu breadboard.

#include <Time.h> // Using the basic Time library

int hourLEDs[] = {1, 2, 3, 4}; // Hours LED 
int minuteLEDs[] = {10, 9, 8, 7, 6, 5}; // Minutes LED
int secondLEDs[] = {16, 15, 14, 13, 12, 11}; // Seconds LED

int loopLEDs[] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // The order in which to spin the LEDS

int switchPin = 17 ; // Used for setting the time, hold to advance time

void setup()       
{
  for (int i = 0; i < 4; i++)
  {
     pinMode(hourLEDs[i], OUTPUT);
  }
  for (int i = 0; i < 6; i++)
  {
     pinMode(minuteLEDs[i], OUTPUT);
  }
  for (int i = 0; i < 6; i++)
  {
     pinMode(secondLEDs[i], OUTPUT);
  }
  setTime(0);
}

void loop()                     
{
  if (digitalRead(switchPin))
  {
     adjustTime(1);
  }
  else if (minute() == 0 && second() == 0)
  {
    spin(hour());
  }
  updateDisplay();
  delay(1);
}

void updateDisplay()
{
  time_t t = now();
  setOutput(hourLEDs, 4, hourFormat12(t));
  setOutput(minuteLEDs, 6, minute(t));
  setOutput(secondLEDs, 6, second(t));
}


void setOutput(int *ledArray, int numLEDs, int value)
{
    for (int i = 0; i < numLEDs; i++)
    {
     digitalWrite(ledArray[i], bitRead(value, i));
    }
}


void spin(int count)
{
  for (int i = 0; i < count; i++)
  {
      for (int j = 0; j < 16; j++)
      {
         digitalWrite(loopLEDs[j], HIGH);
         delay(50);
         digitalWrite(loopLEDs[j], LOW);
      }
  }
}








Many Thanks
Logged

Help Help Help

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6133
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Now my problem is with the best way to go about this with out using 'if' statements too much and slowing the clock down and losing time.
The time library keeps track of the time using an interrupt.  Your code will have very little impact on it losing track of time.   You might miss updating the seconds display by a few hundred miliseconds, but us slow humans won't notice.

The most power efficient and accurate way to keep track of time is to use a RTC like the DS1307 or DS3231 (more expensive but much more accurate).  That way you can put your 328 to sleep and wake it up every so often.

Using delay() does not save you any power.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Offline Offline
Edison Member
*
Karma: 64
Posts: 2488
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Supply the current with external hardware.


* LEDs.jpg (241.02 KB, 843x500 - viewed 25 times.)
Logged

South Uk
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Now my problem is with the best way to go about this with out using 'if' statements too much and slowing the clock down and losing time.
The time library keeps track of the time using an interrupt.  Your code will have very little impact on it losing track of time.   You might miss updating the seconds display by a few hundred miliseconds, but us slow humans won't notice.

The most power efficient and accurate way to keep track of time is to use a RTC like the DS1307 or DS3231 (more expensive but much more accurate).  That way you can put your 328 to sleep and wake it up every so often.

Using delay() does not save you any power.


Thanks for your quick reply, im looking into the RTC method and putting the 328 to sleep my only problem now is i only have Digital pin 0 (RX) Free after using the last to analog inputs 4-5 for the RTC. Would i be able to make an interrupt to wake with this pin or by moving others around? any suggestions welcome?
Logged

Help Help Help

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

According to the datasheets, Pin change interrupts can be used to wake from sleep, which means you can use Digital Pin 0 to wake from power down and sleep modes.
Digital0 is PCINT16 (pin change interrupt source 16). Which means its interrupt can be enabled with:
Code:
 PCMSK2 = _BV(0); //set PCINT16 as enabled, others disabled
  PCICR |= _BV(2); //enable pin change interrupt source 2.

And disabled with:
Code:
 PCICR &= ~_BV(2); //disable pin change interrupt source 2.

And if needed, the corresponding interrupt routine is:
Code:
ISR(PCINT2_vect){
  //code executed on pin change.
}
« Last Edit: January 06, 2013, 09:09:16 am by Tom Carpenter » Logged

~Tom~

South Uk
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cheers Tom for the quick reply and fast response i have a RTC on order now and going to give the sleep on Digital pin 0 a go later tonight. is it just a matter of pulling the pin to GND or do i need to do a bit more research and reading on how to wire up an interrupter on a digital pin?

Thanks again
Logged

Help Help Help

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Basically to trigger the uC to wake up, you have to cause an interrupt. To make a pin change interrupt occur, you need to simply toggle the logic state of the pin.
You can do that in a number of ways:
(1) add an external pullup resistor, then to wake up, simply pull the pin to ground with a switch.
(2) add an external pulldown resistor, then to wake up, simply connect the pin to +5v with a switch.
(3) If you went for a DS1307 based RTC, then you could connect its SQW output to Digital 0, and configure the DS1307 to output 1Hz. That way the microcontroller gets woken up once every second.

The third method would seem to me to be an ideal solution. You can put the arduino to sleep. Then when it is woken back up by the DS1307, you can read in the current time, output it to the clock display, then put the arduino back to sleep.
That way the arduino would sleep saving power for most of the time, but the clock would update once every second. You could probably accomplish reading in the time and updating the clock within a few milliseconds, meaning the arduino would sleep for about 99% of the time.
« Last Edit: January 06, 2013, 12:51:13 pm by Tom Carpenter » Logged

~Tom~

Leeds, UK
Offline Offline
Edison Member
*
Karma: 78
Posts: 1719
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Edit:

I have just noticed you are trying to have the clock automatically turn off the display, then turn it back on when the user presses a switch or something. In which case use method (1) or (2) of those i mentioned in the last post. If you make the external resistor something like 10k to 100k.
Logged

~Tom~

South Uk
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great i will have a go with ether method one or two and see how it plays out. Thanks again for your help tom, hope i can get this all togethere and running this is my 3-4th project now and would like to get it portable and battery powered maybe so thats the next step after getting this section of it working and i think you have set me in the right direction.

Cheers
Logged

Help Help Help

Pages: [1]   Go Up
Jump to: