simple countdown timer

There are so many previous posts on timers, and so many different examples, I am not sure which is best for me.

I need to make a 4 digit timer for a sports scoreboard, it only has to countdown from max 99 minutes, so the accuracy I have been reading about of less than a second a day using the normal xtal will be fine.

I am using the shiftout method of driving the LEDs with TPIC6B595 shift registers using the code you guys helped me with on a previous project.

I am not at the moment using any intrrupts, and the only time the chip has to do anything apart from refresh the display every second, is to change the scores every now and then, so am I correct that the millis will keep a fairly accurate time ?

I was thinking of using

if ( (TimeNow-1000) > LastTimeBlinked ) ...

idea that I saw for checking the seconds by reading millis?

Does this sound logical? or as the RTCs are quite cheap now is it worth the extra coding and board space to use one of them?

You could go this route - I am only setup to count from from 10:00, but you could change that easy enough. This code runs on a 5V 16 MHz promini.

I have this at the start of my loop. After this, I look for timer control buttons (start/stop), score updates, and then have a section that writes the time & score digits out to a MAX7221 8 x 7-segment display driver if they changed.

I use time_running = 0 to show timer is stopped, and =1 & =2 to show time is running (1 allows time to stop if some actions occur, and 2 to not stop if the same actions occur).
I have colon on/off twice a second, that's what the quarter interval is for.
Define all the variables prior to setup, add some stuff to set the start time you want - I have a section after this code that monitors a wireless remote control I built to start & stop time and set it to 1:00, 3:00, 10:00 (and quarter_interval to 0 - important) if time is stopped. You could do same by reading some discrete buttons or similar. If no button presses are seen and update_time=1, then the max7221 is updated with the new values.

Just update the 10:00 area to count down from 60:00 instead.

void loop()
{
  // check if time needs updating
  if ((time_running == 1) || (time_running == 2))  // fencing time is counting down or delay time is counting down
  {
    unsigned long currentMillis = millis();  // see how long its been

    if (currentMillis - previousMillis > interval) // more than our quarter second interval?
    {
      // save the last time we okayed time updates 
      previousMillis = currentMillis; 
      quarter_interval = quarter_interval+1;
      // cycle the colon state
      if (colon == 0x80)
      {
        colon = 0x00;
      }
      else
      {
        colon = 0x80;
      }
      update_time = 1;   //  enable time display to be updated

      if (quarter_interval == 4) // we hit the one second update time
      {
        quarter_interval = 0;
        // update the time digits
        // cases: 
        // 0:01, final second - stop time, disable touch lights, sound buzzer
        // Tens of seconds rollover: time = x:50, x:40, x:30, x:20, x:10: decrement tens of seconds, rollover seconds to 9
        // Minutes rollover: time = 9:00, 8:00, etc. 2:00, 1:00: decrement ones of minutes, rollover tens of seconds to 5, ones of seconds to
        9
          // 10:00: Roll all the digits over
        // otherwise: just roll over the seconds

        // Case: Final Second
        if ((minutes_ones == 0) && (seconds_tens == 0) && (seconds_ones == 1)) // don't need minutes_tens, can't have 10:01
        {
          time_running = 0;  // stop time running
          seconds_ones = 0;  // clear the last second
          updated = 1;  // fake a Case complete flag
          buzzer = 1;                     // add a buzzer for this: end of time buzzer sounds       

          }
        }  // end of  if final second

        // Case: x:50, x:40, x:30, x:20, x:10
        if ((seconds_tens >0) && (seconds_ones == 0))  // case for the last tens of seconds 
        {
          seconds_tens = seconds_tens - 1;  // decrement the tens
          seconds_ones = 9;  // rollover the ones
          updated = 1;
        }  // end of if 10 of seconds rollover

        // Case: 9:00, 8:00, etc 2:00, 1:00
        if ((minutes_ones > 0) && (seconds_tens == 0) && (seconds_ones == 0)) // case for the last ones of minutes
        { 
          minutes_tens = 0x00;  //
          minutes_ones = minutes_ones - 1;  // decrement the minutes
          seconds_tens = 5;  // rollover the tens of seconds;
          seconds_ones = 9;  // rollover the ones of seconds;
          updated = 1;
        } // end of if minutes rollover

        // Case: starting from 10:00
        if (minutes_tens == 0x01)  // roll over all digits
        {
          minutes_tens = 0x00;  // rollover the tens of minutes
          minutes_ones = 9;  // rollover the ones of mints;
          seconds_tens = 5;  // rollover the tens of seconds;
          seconds_ones = 9;  // rollover the ones of seconds; 
          updated = 1;
        } // end of if 10:00 rollover

        // General Case: just decrement the seconds
        if (updated == 0)  // nothing else updated - but don't decrement if = 0.
        {
          seconds_ones = seconds_ones - 1;
        }
        updated = 0;  // reset for next pass thru
      } // end of if quarter_interval
    } // end of reaching our interval
  } // end of if time_running
  else
  {
    update_time = 0;   // no time update this time around - probably don't need this
  }
// next sections: look for control button presses to start/stop time, reset the time digits if time is stopped, update the score digits if time is stopped, set off the buzzer for a few seconds ...
    if (currentMillis - previousMillis > interval) // more than our quarter second interval?

...actually exceeds interval. Generally, you would want to use greater-than-or-equals...

    if (currentMillis - previousMillis >[glow]=[/glow] interval)

Thanks Crossroads,
I can modify that nicely for my use I think, I have a rf link that sends a bcd code for the preset minutes, and a jam pulse to set the start time ( and pauses the clock on my cmos version )
There is also a run and pause button on the remote.
My present timer has 12 chips on it including the ULN2003 drivers, but it would be nice to get it down to an arduino and 4 serial reg /driver chips, I could fit it on the board with the scores then ( which I also want to upgrade to Arduino when I am brave enough to try the virtualwire library )

Coding,
Okay, I can accept the logic behind that & have changed my code. Should make the time a little more accurate not having to make one more pass thru the rest of the code after getting to a quarter second.

That comparison was from Blink without Delay, by the way. I guess copying from there one should use a little scrutiny.

Boffin,
Why 4 chips? Can do the digits with just the one MAX7221. Go check the datasheet, get a sample from Maxim. Very easy to use. Each digit just needs the code below for an update.
I have an address mapped for each digit (seconds_tens_address in this example), I have a variable for each digits data (seconds_tens), and a variable for each decimal point (which I am using to indicatge other stuff, in this case a light called right_priority). Just before writing to the MAX7221, I combine them using a temp variable called number_to_display.
In cases where I want to blank leading digits, I test if the value of, say seconds_tens in this case, is 0x00, and then set number_to_display to 0x0F instead, and continue with ORing in the decimal point (0x00, off, or 0x80 for on).

Then you're down to just 2 chips and the RF receiver - the arduino (pro mini, 24 pin x 0.6") and the 24pin x 0.3" Max7221 in a DIP.
You can set the MAX7221 to drive from 3 to 8 digits.
Sounds like you have separate boxes for Time & score?

I copied a different digit here to show the blanking.

  // *****************************************************************************
  // Time digits display update section
  // *****************************************************************************

  if (update_time == 1) // if = 1, a change was made and we are updating time in here
  {
    update_time = 0;  // reset for the next pass thru

    //combine minutes_tens with Decimal point: colon
    if (minutes_tens == 0) {
      number_to_display = 0x0F;
    }  // for blanking
    else {
      number_to_display = minutes_tens;
    }
    number_to_display = number_to_display | colon; // OR in the decimal point
    digitalWrite(SS,LOW);  // take the SS pin low to select the chip
    SPI.transfer(minutes_tens_address);  // select the Address,
    SPI.transfer(number_to_display);      // select the data
    digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

and continue for the other digits, close out the section with a final }.

One reason I want to use 4 of the TPIC6B595s is that I get them for less than 50 cents US, whereas the MAX7221 is over $12 there , so probably over $20 by the time I got it here.
I am also using 4 chips because I want to avoid multiplexing the displays, ( I latch them )
This is a hangover from my existing scoreboards, where I get incredible range on the Radiometrix 433 Mhz link.
The link is as near to perfect as you can get, line of sight, across a field, to a receiver with an antenna mounted high, and nowhere near any interference or buildings.
I did experiment with adding a multiplexed text display and it severely reduced the range that the remote would work, so its no sweat latching the displays.
There are some practical reasons too, but I might try it again when I get all my current projects wrapped up.

I have read that some of the better mux chips round off the switched waveforms to the LEDs to reduce the interference, but at the moment I have a simplex link with no error checking ( apart from repeating the data three times and compare it ) and it is working very well.
Thanks for the code though, the data link will be my next challenge in modernising my systems :slight_smile:

Yes, the 7221 has slew rate limiting
"The MAX7221 is compatible with SPI?, QSPI?, and MICROWIRE?, and has slewrate-
limited segment drivers to reduce EMI."
Is nice to use tho with the built in registers and just 1 resistor needed to control current limiting.
Have you tried requesting samples from Maxim? I don't know what their policyis re: worldwide shipping.

The TPIC6B595 (20 pin dip) are like $1.73 in small qtys here. You've got a great price at <$0.50.

Wow, what are you paying for the MAX7221 there btw ? ( the TPICs I bought 100 of for that price )
It sounds like the way to go when I eventually drag myself into the 21st century :wink:
I also saw that some of the chips available test for open and short circuit LEDs, and you can even fine tune the brightness to match LED batches - wonderful stuff.
Samples would be nice if I knew I could get a better price if I switched to the chips, but its a bit of a commitment having boards made etc.
( I must fit my dremel to my first Arduino project ( a 2 axis machine ) and make my own prototype boards )

Look at that, :stuck_out_tongue: I am nesting brackets in paragraphs since I found it works for switch / case functions

If you go to maxim-ic.com, they show the max7221CGN (24 pin dip) for $12.61.
I got 2 as free samples from maxim directly.

Try it!

Here is their sample policy. Enter your address and see if its supported or not.
This one chip can replace a lot of parts and wiring and can make your final PCV smaller.

Samples
Maxim's sample program is one of the most generous in the industry. Free samples of most
parts are available to registered members using commercial (e.g. @companyname.com) or
educational institution (e.g. @edu.com) email accounts. Public domain email accounts (e.g.
@yahoo.com) are not supported.
A Sample Cart is provided for sample orders. Parts may be added to the Sample Cart directly or
via the “Sample Now” button included on the “Find a Part” results page. Up to eight part numbers
may be included on a single sample order. Part Number, Quantity, Estimated Annual Usage and
Application are required fields.
Some parts (e.g. Military parts, tape-and-reel parts) are not available for sampling via this site.
Others may require approval based on the specific part requested, the quantity requested or
sampling activity over the previous 90 days. In the event your sample request requires additional
approval, you will be notified at the time of submission and upon review. If you submit a sample
order for a device not yet included on our site, you will be asked to verify the part number. Upon
verification, your request will be submitted for review.
The majority of sample requests ship within one day of order receipt. Most ship from Asia with a
total average transit time of 3-5 business days. Shipment upgrades using a customer nominated
carrier and account number are available.
Sample orders and shipments may be viewed via the “My Orders: Order Status” menu option.
Please note that we are unable to ship samples to P.O. boxes and to certain countries due to
U.S. government restrictions or logistical issues associated with freight to certain territories.

Ok I will try it and see , but I need to choose a chip I can get regularly, as I manufacture scoreboards, so I have to consider the price....

I totally understand. I am designing a fencing scoring machine and looking at the same tradeoffs.
I am still prototyping: 2 digit score for each fencer (to go up to 45 for team events), with warning/penalty/coin toss winner lights for each side, 4 digit time display, wireless command reception, score/end of time alarm/sound, and a remote control to start/stop/set time, the other lights, increase/decrease score, coin toss. Been busy putting in features I want to use as a referee that I find lacking in the machines that are out there, like no sound, or maybe just a much reduced level, when fencers test weapons and time is not running (foil/sabre are closed circuit weapons, so the machine can't differentiate between a broken wire & a fencer not being connected & start blaring away - why make any noise at all if time is not running? I am programming mine not too).
Was playing with 75dB piezo buzzers and a little speaker from a modem, smoked both yesterday tring to get more volume. Finished my testing with a computer desktop speaker, much better. Ordered some surplus 2" speakers yesterday for $1.49 each that should do the trick. I am using the Tone example from the playground to make a pleasant warble that should not be headache inducing at the end of a long day listening to 8-10 of these going on.

I am thinking hand assembly/low quantity, so reduced total parts counts is one of the things I consider as well.

That's an interesting project, I don't know if anyone fences here in South Africa, perhaps I can put some micro-switches in the Zulu fighting sticks...
Sounds quite a complicated system, I definitely wouldn't try all that with cmos !

I have been doing mainly cricket, hockey, basketball and soccer/rugby boards, www.scorebauds.co.za and had my little niche of 7 segment numerical only displays, but it was when demand made it that I had to have team names as well that I looked at micros and found Arduino.
I am still using the Holtek ht12 remote chip for the encoding/decoding, and can handle up to 32 digits with one chip, but now I want to do some real comms.

I like the idea of using the Tone example for the sounder, I have had hassles with hooters and piezo things, so perhaps I will have a small 20 watt amp and a horn speaker. It would be nice to record the traditional horn sound at the end of a rugby match here, and save it as a wav file perhaps?

Good luck with your fencing device, I would like to see the photos when its done.

Don't see why you couldn't play back recorded sound from an SD card and the MP3 shield that is talked about a lot here in the forums.

I have some pics posted.
http://crossroadsfencing.com/fencingmachineback.jpg

http://crossroadsfencing.com/Finals%20Box.jpg - little dark, haven't found good way to photograph lit LEDs yets. The unlit blocks of 20 LEDs are the lights that go off when a touch is made. The smaller pairs above those are the warning & penalty lights, the pair on the bottom is the coin toss winner indication.
This was with the MAX6291, only lasted a few hours, think it didn't like the parallel LEDs per segment (but couldn't do 12V for series connection). The MAX7221 is working out much better, no problems with 5V and 3 LEDs in parallel per segment.

http://crossroadsfencing.com/RemoteControlFront.jpg
http://crossroadsfencing.com/RemoteControlBack.jpg
1000mAH battery still going strong powering 3.3V 8MHz promini (power goes into VCC, bypasses the regulator). Just ordered some more panelmount 2.1mm jacks so I can bring in 5V for a charger chip (will go in the empty socket with a couple Rs & Cs and a charging indicator LED.
Need to write some code & read the switches & send that out as part with the byte of the button push as a unique address kind of thing, and code the same on the display side. Works great with virtual wire. Goes into powerdown sleep mode after the datasend, wakes on keypress & sends the next button press. Range is at least 30 feet, the length of my house. Haven't tried walking outside & see how far it will go.

All wirewrapped at the moment. The little display is to show the period (1-9) in a team event where teams of 3 fence (so each fencer has 3 bouts against the other teams 3 members in 3 minute bouts or one side reaching the next multiple of 5 score (ex 5-3, then 8-10, then 15-12, etc as the lead changes, up to 45 or the final 9th bout running out of time).

There is plenty of fencing in South Africa. Like most things, Google brings up some interesting things, here are a couple:

http://charleskohler.co.za/fencing/fencing.htm
http://www.sascoc.co.za/2010/06/about-fencing-in-south-africa/

There's none so blind as they that do not Google !

Perhaps I should look into a fencing scoreboard when I catch up !

I have never tried LEDs in parallel, does each have its own resistor? I don't see any on the pics.
The enclosures look very interesting , what are they sold as ?

I have a day job as well, and thats where I am finishing off a vga overlay unit that also has an announcer with the SD card, which was my third arduino project, I now have to get both cards to queue in case several buttons are pressed while the first is playing ... keeps me off the streets !

Couldn't hurt! Favaro seems to be in most clubs. We are opening our own club tho, gonna have some building our own and maybe sell to other small clubs looking to expand also.
It started as just add-on extension lights (just for touches) for an existing scoring machine. We have 3 pairs of those built up. Will build up 3 more, but will be connecting to this big one instead, and use the small touch only machines for when we travel to teach intro classes at recreation centers.

No series resistor with the parallel LEDs, the MAX7221 takes care of the current limiting, current is set for all segments with just the one Rset there.

The enclosures are these boxes that our local office supply carries, made in the UK. Easy to work with, lots of sizes.

I have 4L for the display, a 0.2L for the remote, and I just got some 0.14L to try out the remote lights in (versus a stretch pencil case we are using now, which works okay, figure I'd go for consistent looks tho. May drop the idea as the pencil case only needs one connector).
http://www.crossroadsfencing.com/box_collection.jpg

I have a 7404 in there to invert the signal to/from the scoring machine that gives me the touch information, serial data but 0/5V with 0 as spaces (while ATMeg wants High as spaces (I am in the process of designing my own touch sensing circuits so I won't need that eventually, unless I sell this as an add-on to that machine). There are two 74LS374s, one to drive a 7406 (open collector) to drive the 6 touch lights (sourced from +12V), and one to drive a 7447 to drive the period indicator.
Now that I've seen the high current capable TPIC6B595, I think I will pull those 4 chips out and put in 2 of the TPICs instead, and add a 3rd one to display E/F/S for the weapon in use.

Those boxes look really space age, we have a company called Plastics for Africa here that has all sorts of boxes, I will have a look with a new eye when I get a chance.
I was wondering how you balance the current through the LEDs in the same segment if they are in parallel, but I think nowadays the Vf is pretty matched in a batch when you buy them ,and I can't see much difference in your photos.
Your sport certainly seems to lend itself to electronics ( right back to the days of the Russian guy disqualified at the Olympics :slight_smile:
It must have been hard for a judge to see who hit who first before electronics!
My wife plays lawn bowls, not much scope ( or lightning speed ) there..

The TPIC6B595 is cheap, although it has no current limiting, but I find a resistor to each segment makes the track layout so much easier, its like a free jumper ( I waste hours trying to layout my boards without jumpers just due to pride, I should just let the autorouter do its untidy best )

Yes, the boxes are pretty nice. The first one I bought for the remote I was bouncing around the carpeted store a little to make sure it would stand up to some mishandling.
The little ones, I bought 5 to play with. Got them home, and one had a side that was all cracked and a piece missing! Took it back for a replacement. Very odd, as the others were quite sturdy, accepting drilling, carving with a knife. They are marked for Temp range too, -15C to +80C.

I just bought a Nibbler which should allow easier trimming of holes in the next one.

http://www.homedepot.com/h_d1/N-5yc1vZ1xh3/R-100647884/h_d2/ProductDisplay?langId=-1&storeId=10051&catalogId=10053

The parallel LEDs do seem pretty even. We have 4 different colors (red, orange, yellow, white) and they seem to match up ok.

I have also had a lot of fun laying out boards, like the double sided on top of the little blue box.
Have done prelim layouts for the other display as well, need to finish up now that we have connectors & stuff all defined.

Got a lunch date - more later.