Go Down

Topic: It's 9:45 PM . . (Read 828 times) previous topic - next topic

ill_switch

. . . and I just finished soldering together a RBBB kit, my first ever Arduino (or microcontroller of any kind, really.) It's running blink right now.

Wife and kids are in bed.

I have a pile of LEDs, a pile of resistors, and a big solderless breadboard in front of me. My goal: build and program a binary clock by midnight.

Wish me luck. Here goes!  :)

ill_switch

Done, with half an hour to spare!



Though, there's something weird going on. It never gets past 3 minutes. I'm guessing I have a typo in my code, so I'll start troubleshooting it.

Code: [Select]
/* A basic, brute force binary clock.
  Future versions should be more elegant, using something
  more refined than a series of if statements to set
  LED states.

Circuit is an LED and resistor on digital pins 2 through 12.

Each time a minute passes, iterate through if statements to
 set the state flags for each binary place in hrs and mins,
 incrementing counters as appropriate to "turn over" hours
 and minutes as time passes.
 
At the end of each loop, write to LED pins as appropriate.

*/

// set pin numbers:
int secPin =  2;    // LED for seconds
int min1 = 8;       // LED for minutes 1 place
int min2 = 7;       // LED for minutes 2 place
int min4 = 6;       // LED for minutes 4 place
int min8 = 5;       // LED for minutes 8 place
int min16 = 4;       // LED for minutes 16 place
int min32 = 3;       // LED for minutes 32 place
int hr1 = 9;       // LED for hours 1 place
int hr2 = 10;       // LED for hours 2 place
int hr4 = 11;       // LED for hours 4 place
int hr8 = 12;       // LED for hours 8 place

//set these state variables to program the time at which
//  the sketch is uploaded
int min1State = LOW;       // LED for minutes 1 place
int min2State = LOW;       // LED for minutes 2 place
int min4State = LOW;       // LED for minutes 4 place
int min8State = LOW;       // LED for minutes 8 place
int min16State = LOW;       // LED for minutes 16 place
int min32State = LOW;       // LED for minutes 32 place
int hr1State = LOW;       // LED for hours 1 place
int hr2State = LOW;       // LED for hours 2 place
int hr4State = LOW;       // LED for hours 4 place
int hr8State = LOW;       // LED for hours 8 place

int secs = 0;       // counter for seconds
int mins = 0;       // counter for minutes
int hrs = 0;        // counter for hours

// Variables will change:
int secState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
 // set the digital pin as output:
 pinMode(secPin, OUTPUT);
 pinMode(min1, OUTPUT);
 pinMode(min2, OUTPUT);
 pinMode(min4, OUTPUT);
 pinMode(min8, OUTPUT);
 pinMode(min16, OUTPUT);
 pinMode(min32, OUTPUT);
 pinMode(hr1, OUTPUT);
 pinMode(hr2, OUTPUT);      
 pinMode(hr4, OUTPUT);      
 pinMode(hr8, OUTPUT);            
}

void loop()
{
 // here is where you'd put code that needs to be running all the time.

 // check to see if it's time to blink the LED; that is, is the difference
 // between the current time and last time we blinked the LED bigger than
 // the interval at which we want to blink the LED.
 if (millis() - previousMillis > interval) {
   // save the last time you blinked the LED
   previousMillis = millis();  
   
   //increment counters and set states
   secs = secs + 1;
   if (secs == 60)
   {
     secs = 0;  //reset the seconds counter
     mins = mins + 1; //increment minutes counter
     //then, set the LED states for minutes
     //check the state of a particular place in minutes
     //  if it is low, flip it to high
     //  if it is high, flip it to low, then check next place
     if (min1State == LOW)
     {
       min1State = HIGH;
     }
     else
     {
       min1State = LOW;
       if (min2State == LOW)
       {
         min2State = HIGH;
       }
       else
       {
         min2State = LOW;
         if (min4State == LOW)
         {
           min4State == HIGH;
         }
         else
         {
           min4State == LOW;
           if (min8State == LOW)
           {
             min8State == HIGH;
           }
           else
           {
             min8State == LOW;
             if (min16State == LOW)
             {
               min16State == HIGH;
             }
             else
             {
               min16State == LOW;
               if (min32State == LOW)
               {
                 min32State == HIGH;
               }
               else
               {
                 min32State == LOW;
               }
             }
           }
         }
       }
     }
     
     if (mins == 60)
     {
       mins = 0;  //reset minutes counter
       hrs = hrs + 1;  //increment hours counter
       //set the LED states for hours, same as minutes
       if (hr1State == LOW)
       {
         hr1State = HIGH;
       }
       else
       {
         hr1State = LOW;
         if (hr2State == LOW)
         {
           hr2State = HIGH;
         }
         else
         {
           hr2State = LOW;
           if (hr4State == LOW)
           {
             hr4State = HIGH;
           }
           else
           {
             hr4State = LOW;
             if (hr8State == LOW)
             {
               hr8State = HIGH;
             }
             else
             {
               hr8State = LOW;
             }
           }
         }
       }
       
       if (hrs == 13)
       {
         hrs = 1;  //reset hours counter
       }
     }
   }
   
   // if the LED is off turn it on and vice-versa:
   if (secState == LOW)
     secState = HIGH;
   else
     secState = LOW;
     
   // set the LED with the ledState of the variable:
   digitalWrite(secPin, secState);
   digitalWrite(min1, min1State);
   digitalWrite(min2, min2State);
   digitalWrite(min4, min4State);
   digitalWrite(min8, min8State);
   digitalWrite(min16, min16State);
   digitalWrite(min32, min32State);
   digitalWrite(hr1, hr1State);
   digitalWrite(hr2, hr2State);
   digitalWrite(hr4, hr4State);
   digitalWrite(hr8, hr8State);
 }
}



ill_switch

Of course! Doh! I had a bunch of == where I should have had =.

Corrected:

Code: [Select]
/* A basic, brute force binary clock.
  Future versions should be more elegant, using something
  more refined than a series of if statements to set
  LED states.

Circuit is an LED and resistor on digital pins 2 through 12.

Each time a minute passes, iterate through if statements to
 set the state flags for each binary place in hrs and mins,
 incrementing counters as appropriate to "turn over" hours
 and minutes as time passes.
 
At the end of each loop, write to LED pins as appropriate.

*/

// set pin numbers:
int secPin =  2;    // LED for seconds
int min1 = 8;       // LED for minutes 1 place
int min2 = 7;       // LED for minutes 2 place
int min4 = 6;       // LED for minutes 4 place
int min8 = 5;       // LED for minutes 8 place
int min16 = 4;       // LED for minutes 16 place
int min32 = 3;       // LED for minutes 32 place
int hr1 = 9;       // LED for hours 1 place
int hr2 = 10;       // LED for hours 2 place
int hr4 = 11;       // LED for hours 4 place
int hr8 = 12;       // LED for hours 8 place

//set these state variables to program the time at which
//  the sketch is uploaded
int min1State = LOW;       // LED for minutes 1 place
int min2State = LOW;       // LED for minutes 2 place
int min4State = LOW;       // LED for minutes 4 place
int min8State = LOW;       // LED for minutes 8 place
int min16State = LOW;       // LED for minutes 16 place
int min32State = LOW;       // LED for minutes 32 place
int hr1State = LOW;       // LED for hours 1 place
int hr2State = LOW;       // LED for hours 2 place
int hr4State = LOW;       // LED for hours 4 place
int hr8State = LOW;       // LED for hours 8 place

int secs = 0;       // counter for seconds
int mins = 0;       // counter for minutes
int hrs = 0;        // counter for hours

// Variables will change:
int secState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
 // set the digital pin as output:
 pinMode(secPin, OUTPUT);
 pinMode(min1, OUTPUT);
 pinMode(min2, OUTPUT);
 pinMode(min4, OUTPUT);
 pinMode(min8, OUTPUT);
 pinMode(min16, OUTPUT);
 pinMode(min32, OUTPUT);
 pinMode(hr1, OUTPUT);
 pinMode(hr2, OUTPUT);      
 pinMode(hr4, OUTPUT);      
 pinMode(hr8, OUTPUT);            
}

void loop()
{
 // here is where you'd put code that needs to be running all the time.

 // check to see if it's time to blink the LED; that is, is the difference
 // between the current time and last time we blinked the LED bigger than
 // the interval at which we want to blink the LED.
 if (millis() - previousMillis > interval) {
   // save the last time you blinked the LED
   previousMillis = millis();  
   
   //increment counters and set states
   secs = secs + 1;
   if (secs == 60)
   {
     secs = 0;  //reset the seconds counter
     mins = mins + 1; //increment minutes counter
     //then, set the LED states for minutes
     //check the state of a particular place in minutes
     //  if it is low, flip it to high
     //  if it is high, flip it to low, then check next place
     if (min1State == LOW)
     {
       min1State = HIGH;
     }
     else
     {
       min1State = LOW;
       if (min2State == LOW)
       {
         min2State = HIGH;
       }
       else
       {
         min2State = LOW;
         if (min4State == LOW)
         {
           min4State = HIGH;
         }
         else
         {
           min4State = LOW;
           if (min8State == LOW)
           {
             min8State = HIGH;
           }
           else
           {
             min8State = LOW;
             if (min16State == LOW)
             {
               min16State = HIGH;
             }
             else
             {
               min16State = LOW;
               if (min32State == LOW)
               {
                 min32State = HIGH;
               }
               else
               {
                 min32State = LOW;
               }
             }
           }
         }
       }
     }
     
     if (mins == 60)
     {
       mins = 0;  //reset minutes counter
       hrs = hrs + 1;  //increment hours counter
       //set the LED states for hours, same as minutes
       if (hr1State == LOW)
       {
         hr1State = HIGH;
       }
       else
       {
         hr1State = LOW;
         if (hr2State == LOW)
         {
           hr2State = HIGH;
         }
         else
         {
           hr2State = LOW;
           if (hr4State == LOW)
           {
             hr4State = HIGH;
           }
           else
           {
             hr4State = LOW;
             if (hr8State == LOW)
             {
               hr8State = HIGH;
             }
             else
             {
               hr8State = LOW;
             }
           }
         }
       }
       
       if (hrs == 13)
       {
         hrs = 1;  //reset hours counter
       }
     }
   }
   
   // if the LED is off turn it on and vice-versa:
   if (secState == LOW)
     secState = HIGH;
   else
     secState = LOW;
     
   // set the LED with the ledState of the variable:
   digitalWrite(secPin, secState);
   digitalWrite(min1, min1State);
   digitalWrite(min2, min2State);
   digitalWrite(min4, min4State);
   digitalWrite(min8, min8State);
   digitalWrite(min16, min16State);
   digitalWrite(min32, min32State);
   digitalWrite(hr1, hr1State);
   digitalWrite(hr2, hr2State);
   digitalWrite(hr4, hr4State);
   digitalWrite(hr8, hr8State);
 }
}


My next attempt will do something more elegant in place of that big ugly if statement. Also, I have a DS1307 RTC that I want to integrate into this project. I figure I'll have it check the RTC once a day or something and "calibrate" against the RTC's time.

I guess I get to post in the exhibition forum now, huh? I posted here expecting this thread to be a generic rumination about this being my first microcontroller project, but lo and behold, I actually accomplished something. Thanks to the Arduino team (and Modern Device, for my RBBB kit) for putting such a great set of tools together.

TBAr

#3
Aug 19, 2009, 05:55 am Last Edit: Aug 19, 2009, 05:57 am by TBAr Reason: 1
Woo Hoo!  Coded and debugged ahead of schedule!

Take the rest of the day off! :)

ill_switch

Doh! again. There are still problems - I don't reset the states correctly when minutes or hours rolls over. Oh well, something to work out tomorrow night.

ill_switch

Quote
Woo Hoo!  Coded and debugged ahead of schedule!


Almost.

Seriously though, it's scary how easy this stuff is. I figured this binary clock project would keep me busy for a week or two, but it only really lasted 3 hours, even accounting for debugging tomorrow!  ;D

retrolefty

Welcome to the hobby, it can be quite fun and a time sink at the same time. There are always new libraries and external devices to explore and each new challenge can lead to another.

Congrads on your first project working, I'm sure future projects will follow and not be so quick to complete.  ;)

Lefty

TBAr

#7
Aug 19, 2009, 06:02 am Last Edit: Aug 19, 2009, 06:14 am by TBAr Reason: 1
Ahhhh, the pressures of development on a schedule.

Don't forget to fill out your TPS Report.   :D

ill_switch

Debugged this morning. I hadn't synchronized the "counters" for each time segment with the LED state variables. So I was getting weird behavior - 13:61 instead of 1:01 AM, for instance.

So, next up, get it working with the RTC. Then, find a more elegant way to encode the time. Right now, I'm basically storing hours and minutes as both base-10 (in the counters) and binary (in the LED state variables). There's gotta be a nicer way to do it. . .

Cabe

TBAr what happens if you get a PC Load Letter error? :p

My current problem its 5:52 am in the UK, I have the Arduino IDE in front of me and no hardware to test it on......hopefully by the weekend, with enough coffee :)

jezuz

Finally an office space reference. +20pts for TBAr

Go Up