Binary Clock

Hi guys,

I'm James :slight_smile:

I decided to make a binary clock - you know how they are.. i based it from my watch and thought i had it sussed. Unfortunately, i did not....... As far as i could tell, it was going to work.. but yeah, help please!!

I've included the code below, its got 2 functions for the display in binary
(hour and minute) and the main loop to count! There are comments to explain it as i go but if anyone needs to ask, go ahead and i'll try explain my thought process! I have a line of LEDs on a breadboard ready as a display. I'd prefer not to look at any examples or anything if i can help it! If anyone can help me rescue this I'd be very appreciative! But otherwise I'll start afresh and work through slower.. Its just puzzling why it doesn't work, that's all :stuck_out_tongue:

Cheers everyone!

James

// James Leyland 27-12-16
//variables - need to be global?
//including attempt of display
//the two functions in theory work for decoding the counter into binary, but not tested yet.
//source of likely error is the IF STATEMENT involving the hourCount and tempHour (i tried to make it so it doesnt have to work out the hour output every minute!)
//WRITTEN WITH NO REFERENCES OR EXAMPLES!!!!!!! (quite proud despite the major defect of it not working -_-)

 int minOne = 4;
 int minTwo = 5;
 int minFour = 6;
 int minEight = 7;
 int minSixteen = 8;
 int minThirtyTwo = 9;

 int hourOne = 0;
 int hourTwo = 1;
 int hourFour = 2;
 int hourEight = 3;

 int AMLED = 10;
 int PMLED = 11;
 int sec = 12;
 //counters
 int secCount = 0;
 int minCount = 0;
 int hourCount = 0;
 int AM = 0;
 int PM = 0;

void setup() {
 pinMode(minOne, OUTPUT);
 pinMode(minTwo, OUTPUT);
 pinMode(minFour, OUTPUT);
 pinMode(minEight, OUTPUT);
 pinMode(minSixteen, OUTPUT);
 pinMode(minThirtyTwo, OUTPUT);

 pinMode(hourOne, OUTPUT);
 pinMode(hourTwo, OUTPUT);
 pinMode(hourFour, OUTPUT);
 pinMode(hourEight, OUTPUT);

 pinMode(AMLED, OUTPUT);
 pinMode(PMLED, OUTPUT);
 pinMode(sec, OUTPUT);
 
}

void loop() {
 while (1);
 {
   int tempHour;           //may be a cause of error if it doesnt work. temphour is to reduce the amount of times that the hour loop is done; only if the hourCount changes
   minutes(minCount);
   if (hourCount =! tempHour)
   {
     hours(hourCount);
   }
   tempHour = hourCount;
   delay(800);
   digitalWrite(sec, HIGH);
   delay(198); //allowing 1ms for the rest of the loop to run
   digitalWrite(sec, LOW);
   secCount = secCount + 1;
   if (secCount = 60)
   {
     secCount = 0;
     minCount = minCount + 1;                      //concern expressed about the nested ifs. will this work? do they need to be after one another?
     if (minCount = 60)
     {
       minCount = 0;
       hourCount = hourCount + 1;
       if (hourCount = 12)
       {
         hourCount = 0;
         if (AM = 1)
         {
           AM = 0;
           PM = 1;
           digitalWrite(AMLED, LOW);
           digitalWrite(PMLED, HIGH);
         }
         else
         {
           AM = 1;
           PM = 0;
           digitalWrite(PMLED, LOW);
           digitalWrite(AMLED, HIGH);
         }
       }
       
     }
     
   }
   
 }

}

void minutes(int count)
{
 digitalWrite(minOne, LOW);
 digitalWrite(minTwo, LOW);
 digitalWrite(minFour, LOW);
 digitalWrite(minEight, LOW);
 digitalWrite(minSixteen, LOW);
 digitalWrite(minThirtyTwo, LOW);
 
 if (count > 32)
 {
   count = count - 32;
   digitalWrite(minThirtyTwo, HIGH);
 }
 if (count > 16)
 {
   count = count - 16;
   digitalWrite(minSixteen, HIGH);
 }
 if (count > 8)
 {
   count = count - 8;
   digitalWrite(minEight, HIGH);
 }
 if (count > 4)
 {
   count = count - 4;
   digitalWrite(minFour, HIGH);
 }
 if (count > 2)
 {
   count = count - 2;
   digitalWrite(minTwo, HIGH);
 }
 if (count = 1)
 {
   count = count - 1;
   digitalWrite(minOne, HIGH);
 }
 if (count != 0)
 {
   //error - outputs 63
   digitalWrite(minOne, HIGH);
   digitalWrite(minTwo, HIGH);
   digitalWrite(minFour, HIGH);
   digitalWrite(minEight, HIGH);
   digitalWrite(minSixteen, HIGH);
   digitalWrite(minThirtyTwo, HIGH);
 }
 return;
}

void hours(int count)
{
 digitalWrite(hourOne, LOW);
 digitalWrite(hourTwo, LOW);
 digitalWrite(hourFour, LOW);
 digitalWrite(hourEight, LOW);
 
 if (count > 8)
 {
   count = count - 8;
   digitalWrite(hourEight, HIGH);
 }
 if (count > 4)
 {
   count = count - 4;
   digitalWrite(hourFour, HIGH);
 }
 if (count > 2)
 {
   count = count - 2;
   digitalWrite(hourTwo, HIGH);
 }
 if (count = 1)
 {
   count = count - 1;
   digitalWrite(hourOne, HIGH);
 }
 if (count != 0)
 {
   //error - outputs 15
   digitalWrite(hourOne, HIGH);
   digitalWrite(hourTwo, HIGH);
   digitalWrite(hourFour, HIGH);
   digitalWrite(hourEight, HIGH);
 }
 return;
}

Let's start by using code tags, the </> button above, to get your code in a box.

:o oops :s thanks for that, didn't even consider that sorry!

Your variables and pin assignments could all be byte vs int, they are never exceeding 255 and will never reach +/- 32767 will they?
You don't need this, you're already in a never ending loop():
while (1);
Go thru and fix all the if's:
if (secCount = 60) << needs == for a comparison

See how it works with those changes to start.

Please post a hand drawn (not Fritzing) wiring diagram, showing how everything is connected.

Then describe what should happen, and what happens instead.

hi,
right, I've patched it up as CrossRoads said (after you pointed the while(1) and "=" instead of"==" i felt like such an idiot) I'm going to test it now.. I changed the 'int's to 'bytes' as you suggested? I've not heard of using 'byte' before what are its restrictions?

As for a wiring diagram, here is one... I know there are no resistors but I've never killed an LED from an arduino before, they're just a bit horrible to look at because they're so bright haha Its very simple though..

///edit, i can't actually upload it because my camera is being aweful and giving corrupt files.
There literally a wire that goes from each output to an LED then ground. It should count up , second LED counting seconds and so on.

It is working much better than before although thre seems to be an issue with the minutes as its not counting in binary 1,2,4,8, 16, it lit up all of them for 2 and now 3 is okay

cheers for the help :slight_smile:
Cheers

No diagram.

I know there are no resistors but I've never killed an LED from an arduino before

You will eventually kill the Arduino, guaranteed.

ah. I'd best stick some in there.. :s is it not okay to breadboard without them?

and i have drawn one haha i just can't get a photo of it -_-

0 -------|>|---,
1 -------|>|---|
2 -------|>|---|
3 -------|>|---|

honestly, as crude as this depiction is, this is literally what is is (mind |>| is an LED) sorry about this!

cheers

Post your updated code.
Add current limit resistors, 220-270-330 up to 1K, in that range. Save your eyesight, your LEDs, and your IO pins,

byte are for values 0 to 255, and use 1 byte of memory. unsigned int are for values 0 to 65535, or int (left-most bit being the sign bit) from -32768 (0b1111111111111111) to 32767 (0b01111111111111111) and use 2 bytes of memory.
A byte is the smallest memory location that is accessible. There 2048 bytes of SRAM where variables are stored in a Uno, get used to using them properly so you have enough for larger programs later on.

Here is the new one. I added the part at the end of the hour and minute functions that lights them all up if the final count doesn't = 0 after having things taken from it.. which apparently happens quite often.. the count worked for 1, 3, and 5 but the ones between that in the test lit everything. its something in the logic isn't it..

will do :slight_smile:

I'm just having a rummage now for resistors.. I hadn't ever thought of the current damaging the chip..

  byte minOne = 4;
  byte minTwo = 5;
  byte minFour = 6;
  byte minEight = 7;
  byte minSixteen = 8;
  byte minThirtyTwo = 9;

  byte hourOne = 0;
  byte hourTwo = 1;
  byte hourFour = 2;
  byte hourEight = 3;

  byte AMLED = 10;
  byte PMLED = 11;
  byte sec = 12;
  //counters 
  byte secCount = 0;
  byte minCount = 0;
  byte hourCount = 0;
  byte AM = 0;
  byte PM = 0;

void setup() {
  pinMode(minOne, OUTPUT);
  pinMode(minTwo, OUTPUT);
  pinMode(minFour, OUTPUT);
  pinMode(minEight, OUTPUT);
  pinMode(minSixteen, OUTPUT);
  pinMode(minThirtyTwo, OUTPUT);

  pinMode(hourOne, OUTPUT);
  pinMode(hourTwo, OUTPUT);
  pinMode(hourFour, OUTPUT);
  pinMode(hourEight, OUTPUT);

  pinMode(AMLED, OUTPUT);
  pinMode(PMLED, OUTPUT);
  pinMode(sec, OUTPUT);
  
}

void loop() {
    int tempHour;           //may be a cause of error if it doesnt work. temphour is to reduce the amount of times that the hour loop is done; only if the hourCount changes 
    minutes(minCount);
    if (hourCount =! tempHour)
    {
      hours(hourCount); 
    }
    tempHour = hourCount;
    delay(800);
    digitalWrite(sec, HIGH);
    delay(198); //allowing 1ms for the rest of the loop to run
    digitalWrite(sec, LOW);
    secCount = secCount + 1;
    if (secCount == 60)
    {
      secCount = 0;
      minCount = minCount + 1;                      //concern expressed about the nested ifs. will this work? do they need to be after one another?
      if (minCount == 60)
      {
        minCount = 0;
        hourCount = hourCount + 1;
        if (hourCount == 12)
        {
          hourCount = 0;
          if (AM == 1)
          {
            AM = 0;
            PM = 1;
            digitalWrite(AMLED, LOW);
            digitalWrite(PMLED, HIGH);
          }
          else
          {
            AM = 1;
            PM = 0;
            digitalWrite(PMLED, LOW);
            digitalWrite(AMLED, HIGH);
          }
        }
        
      }
      
    
  }

}

void minutes(int count)
{
  digitalWrite(minOne, LOW);
  digitalWrite(minTwo, LOW);
  digitalWrite(minFour, LOW);
  digitalWrite(minEight, LOW);
  digitalWrite(minSixteen, LOW);
  digitalWrite(minThirtyTwo, LOW);
  
  if (count > 32)
  {
    count = count - 32;
    digitalWrite(minThirtyTwo, HIGH);
  }
  if (count > 16)
  {
    count = count - 16;
    digitalWrite(minSixteen, HIGH);
  }
  if (count > 8)
  {
    count = count - 8;
    digitalWrite(minEight, HIGH);
  }
  if (count > 4)
  {
    count = count - 4;
    digitalWrite(minFour, HIGH);
  }
  if (count > 2)
  {
    count = count - 2;
    digitalWrite(minTwo, HIGH);
  }
  if (count == 1)
  {
    count = count - 1;
    digitalWrite(minOne, HIGH);
  }
  if (count != 0)
  {
    //error - outputs 63
    digitalWrite(minOne, HIGH);
    digitalWrite(minTwo, HIGH);
    digitalWrite(minFour, HIGH);
    digitalWrite(minEight, HIGH);
    digitalWrite(minSixteen, HIGH);
    digitalWrite(minThirtyTwo, HIGH);
  } 
  return;
}

void hours(int count)
{
  digitalWrite(hourOne, LOW);
  digitalWrite(hourTwo, LOW);
  digitalWrite(hourFour, LOW);
  digitalWrite(hourEight, LOW);
  
  if (count > 8)
  {
    count = count - 8;
    digitalWrite(hourEight, HIGH);
  }
  if (count > 4)
  {
    count = count - 4;
    digitalWrite(hourFour, HIGH);
  }
  if (count > 2)
  {
    count = count - 2;
    digitalWrite(hourTwo, HIGH);
  }
  if (count == 1)
  {
    count = count - 1;
    digitalWrite(hourOne, HIGH);
  }
  if (count != 0)
  {
    //error - outputs 15
    digitalWrite(hourOne, HIGH);
    digitalWrite(hourTwo, HIGH);
    digitalWrite(hourFour, HIGH);
    digitalWrite(hourEight, HIGH);
  }
  return;
}

Here's a simple diagram I crafted using powerpoint and then save-as to .jpg.
Anybody should be able to do the same with any drawing program.

Attach your drawing, then Copy the link and Edit:Modify and paste it in with image tags, or use the Monitor-looking button to create them:

Fritzing is just okay, this makes it a lot clearer what is happening. Most folks never get the schematic capture part of Fritzing worked, so the result is a poor jumble of unclear connections to undefined pins on black boxes.

good shout, was debating doing it in paint but thought it might be considered insulting - i thought that was what fritzing was :s - I'll definitely do that next time. sorry

I wouldn't have done it like that, but that's part of learning.
For example, using Blink without delay is much better for keeping track of seconds going by.
I would also track each time element as its own bit so you can easily update them. Everyone has different style tho.

  byte minOnePin = 4;
  byte minTwoPin = 5;
  byte minFourPin = 6;
  byte minEightPin = 7;
  byte minSixteenPin = 8;
  byte minThirtyTwoPin = 9; // etc for the other pins, then make matching variables, change in setup() also
  byte minOne ; // will initialize as 0
  byte minTwo ;
  byte minFour ;
  byte minEight ;
  byte minSixteen ;
  byte minThirtyTwo ;
// same for other pins
void loop(){
currentMicros = micros(); // add declarations for time elements, make them all unsigned long
elapsedMicros = currentMicros - previousMicros;
if (elapsedMicros >= oneSecond){
previousMicros = previousMicros + oneSecond; // oneSecond = 1000000 microSeconds
oneSecond = oneSecond + 1;
if (oneSecond == 60){
oneSecond = 0;
timeUpdateNeeded = 1; // one second flag
// and toggle oneSecPin or whatever your plan is for it
}
if (timeUpdateNeeded == 1){ // one minute has passed
timeUpdateNeeded = 0;
minOne = minOne +1;
if (minOne ==2){
  minOne = 0;
  minTwo = minTwo +1;
 if (minTwo == 2){
   minTwo = 0;
   minFour =  minFour +1;
   if (minFour == 2){
   minFour =0;
   minEight =  minEight +1;
  if ( minEight ==2){
      minEight = 0;
     minSixteen = minSixteen +1;
      if(minSixteen == 2){
        minSixteen == 0;
        minThirtytwo = minThirtytwo +1;
        // check for 60, 111100
       if (minThirtytwo ==1 && minSixteen ==1 && minEight ==1 && minFour ==1 &&  minTwo ==0 &&  minOne ==0){
        minThirtytwo = 0;
       minSixteen = 0;
       minEight = 0;
      minFour = 0;
      // now do similar as above update the hours, and the AM/PM check
       } 
      }
     }
    }
   }
 }
} // add enough } to close out the if's above

digitalWrite(minOnePin, minOne);
digitalWrite (minTwoPin, minTwo);
// etc. // add enough } to close out the if's above
} // one second time check is done
} // end loop

ohhh, I hadn't thought of that! so using ms to count rather than waiting for seconds...
like
1000ms = 1 second
60s = 1 min
60 min = 1hour
12 hour = 1PM
2PM = 1AM

I'm going to give it a rest for a bit, been at it all day trying to figure out that (==) -_-, just needed fresh eyes :stuck_out_tongue: i might give your method a go, might have less issues than mine hahah

thanks so much for your help!

James