Countdown Timer and Adafruit 4-Digit 7-Segment Display w/I2C Backpack

Hey guys, it’s me again. I’ve tried to figure this out on my own, but I’m stuck again. I found the code below, for a “Count Down Timer” in the Arduino Playground and wanted to try to incorporate it into a bigger project I’m working on. I’m using the Arduino Uno in this project but may use the Mega or a second UNO, if I keep adding to the size of the overall project. (running out of pins for everything I need it to do.)

I purchased the 4-Digit 7-Segment Display w/I2C Backpack from Adafruit thinking it would be easier to control the display, as claimed. I also went in search of a written sketch for countdown timers and found several, here and elsewhere. But none of them are using a I2C backpack and rely on 12 or more pins to control the individual segments of the display. It would be nice to be able to control the Display with just the two pins (plus GND & 5V) but I do not know how to “translate” the code to make it work.

I’ve asked Adafruit for help and so far I’ve received the following info.

But writing to the backpack is much simpler than writing directly to the pins of the display. To display the decimal value of a number, just call “Print(number, DEC)” … just replace all the pin-by-pin stuff with a call to Print().

This code looks like it will work, at least it does in the Serial Monitor. I just need to know how to change/add the code needed to make it display on the 4-Digit 7-Segment Display. There were no instructions on how to hook it up in the sketch.

Adafruit says to wire it up like this:

Wiring to the matrix is really easy

Connect CLK to the I2C clock - on Arduino UNO thats Analog #5, on the Leonardo it’s Digital #3, on the Mega it’s digital #21
Connect DAT to the I2C data - on Arduino UNO thats Analog #4, on the Leonardo it’s Digital #2, on the Mega it’s digital #20
Connect GND to common ground
Connect VCC+ to power - 5V is best but 3V also seems to work for 3V microcontrollers.

They also told me;

No need to call out pins. It uses i2c, so just connect as above and declare the dsplay as in the example code in the library.

#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.

#include “Adafruit_LEDBackpack.h”
#include “Adafruit_GFX.h”

Adafruit_7segment matrix = Adafruit_7segment();

Then you can print the countdown time using calls to matrix.print()

None of this works, at least I have no idea how to make it work.

I’ve also downloaded their libraries that are required to run the I2C board, but I’m at a loss to make it work. Their “test” sketch operates the display but I don’t understand what’s going on in the code to use it. And I found a section that Counts down that I can control, but it does not skip the 99 thru 60 numbers. I found some code that address that issue, but i can’t incorporate it into this code. I’ve also purchased a DS1307 RTC Breakout board if that would make this any better.

Below is the unaltered code that I’m trying to use. I know I need to add in the Adafruit Libraries. I’ve tried that and all the above suggestions…but no go.

Anyone willing to tell me how to change the code to make it work, would be greatly appreciated.

Thanks, Mark

//countdown timer
#include <Time.h>         //http://www.arduino.cc/playground/Code/Time

time_t t;
tmElements_t tm;
int seconds, minutes;

void setup(void)
{
    Serial.begin(115200);

    //initialize the starting time to 3 minutes and 0 seconds.
    //the rest of the elements (hours, etc., don't matter much but should
    //at least be set to something that makes sense.
    tm.Second = 0;
    tm.Minute = 3;
    tm.Day = 1;
    tm.Month = 4;
    tm.Year = CalendarYrToTm(2012);
   
    t = makeTime(tm);
}

void loop(void)
{
    seconds = second(t);
    minutes = minute(t);
   
    if (minutes < 10) Serial.print('0');    //leading zero
    Serial.print(minutes, DEC);   
    Serial.print(':');
    if (seconds < 10) Serial.print('0');    //leading zero
    Serial.println(seconds, DEC);
    --t;                                    //subtract a second
    if (seconds + minutes == 0) {
        Serial.println("BOOM!");
        while (1);                          //infinite loop, press reset to restart
    }
    delay(100);                             //10x normal speed for demo purposes
}

Hi Mark,

Be sure that you are installing the libraries correctly, and wiring the thing up as shown on Adafruit’s website. Here is some code that works with that hardware and libraries:

/***********************************************
* Count down using millis()
*
* Adafruit 7-segment, I2C, LED backpack display
*
* pin A5 -> C (on 7-segment)
* pin A4 -> D (on 7-segment)
*
************************************************/

#include <Wire.h>
#include "Adafruit_GFX.h"
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();

unsigned long previousSecondMillis = 0UL;
long oneSecond = 1000UL; // milliseconds per second

#define startMinute 4  //  Modify these defines to
#define startSecond 59 // change the timer interval
int minutes = startMinute;
int seconds = startSecond;

void setup()
{
  matrix.begin(0x72);
}

void loop() {

  // --------- Run this every second ------------------
  if (millis() - previousSecondMillis >= oneSecond) {

    matrix.writeDigitNum(0, (minutes / 10));
    matrix.writeDigitNum(1, (minutes % 10));
    matrix.writeDigitNum(3, (seconds / 10));
    matrix.writeDigitNum(4, (seconds % 10));
    matrix.writeDisplay();

    if (seconds-- == 0) {
      if (minutes == 0) {
        minutes = startMinute;
        seconds = startSecond;
        delay(1000);
      } else {
        minutes -= 1;
        seconds = 59;
      }
    }

    previousSecondMillis += oneSecond;
  }
}

I just wired this up as indicated: this sketch counts down from 4 minutes, 59 seconds, pauses a second, then does it over & over.

Thanks Chris,

I'll give this a try. I know it can't be as hard as I'm making it out to be, I just haven't quite figured out the proper language yet.

Mark

ridenhr: Thanks Chris,

I'll give this a try. I know it can't be as hard as I'm making it out to be, I just haven't quite figured out the proper language yet.

Mark

You're welcome Mark. I tried to make the code as simple and as self-documenting as I could.

Chris,

Thank you, Thank You, Thank you! It worked. Well, not right at first. The display would not turn on. I made sure my libraries were loaded corrected and then I loaded the sevenseg sketch that "comes" with the board from Adafruit and it turned on. I then looked to see what was different and saw that you were calling out a different I2C Address. "matrix.begin(0x72);" I changed it to 0x70 and it came on and itstarted counting down. Hurray!!!

Now I need to tweak the program to cause my special effect to be activated at the end. And stop if the puzzle is solved before time runs out. I think I know how to do that, but will add to the post if I get stuck.

Thanks again, Chris!

Mark

Chris, or anyone willing to help.

OK, I'm stuck. I was hopeful, but in, way over my head. I got the countdown timer working, that Chris wrote above. Now what I need to accomplish is;

  1. To have it START with a momentary push button.

  2. Have it STOP when signal from another program on another Arduino is received. (See below, Drawer HIGH signal)

  3. Once the STOP signal is received, have it PAUSE for 10 seconds and RESET the countdown time to 20 seconds and continue counting down.

  4. When it reaches the end either by NOT receiving the STOP signal in time or after the PAUSE & RESET, to send a signal back to the other Arduino to activate some special effects. (digitalWrite(smoke, light , sound, HIGH);

Ideally, could I incorporate this code into the below code to run it all on the one Arduino UNO in one code? Pins 9,8,3,2,1,0,A0,A1,A2,A3 are all available.

The code below is working as it should, and I've gotten all the "hardware" working with it. Getting ready to take it from breadboard to soldered Board.

/*Wire Cutting sequence   
 Cut the right wires in the right order and you win. Cut the wrong wire and or in the wrong order, 
  and you lose, and the special effect activates.
*/

const int  wrongWire = 13; // the number of the cut wire pin
const int firstWire = 12;  // the number of the first wire pin
const int secondWire = 11;  // the number of the second wire pin
const int thirdWire = 10;   // the number of the third wire pin
const int smoke = 7;   // the number of the smoke pin 
const int light = 6;   // the number of the light pin
const int sound = 5;   // the number of the sound pin
const int drawer = 4;   // the number of the drawer pin
 //int firstWireState = digitalRead(firstWire);
 //int secondWireState = digitalRead(secondWire);
 //int thirdWireState = digitalRead(thirdWire);

void setup()
{
  pinMode(wrongWire, INPUT); 
  pinMode(firstWire, INPUT); 
  pinMode(secondWire, INPUT); 
  pinMode(thirdWire, INPUT); 
  pinMode(smoke, OUTPUT);
  pinMode(light, OUTPUT);
  pinMode(sound, OUTPUT);
  pinMode(drawer, OUTPUT);
 }


void loop(){
 //represents the wrong wire being cut at any time.
  if (digitalRead(wrongWire) == HIGH) {
    digitalWrite(smoke, HIGH);
    digitalWrite(sound, HIGH);
    digitalWrite(light, HIGH);
    delay(500);
    digitalWrite(light, LOW);
    digitalWrite(sound, LOW); 
    delay(900000);  //15 minute delay
    //digitalWrite(smoke, digitalRead(wrongWire));
    //digitalWrite(light, digitalRead(wrongWire));
    //digitalWrite(sound, digitalRead(wrongWire));
}   

    //reminder to self: HIGH is wire Cut, LOW is wire Intact
    //To set off effects when second wire is cut before the first wire is cut
if (digitalRead(secondWire) == HIGH && digitalRead(firstWire) == LOW) {
   digitalWrite(smoke, HIGH);
   digitalWrite(sound, HIGH);
    digitalWrite(light, HIGH);
     delay(500);
    digitalWrite(light, LOW);
    digitalWrite(sound, LOW); 
    delay(900000);  //15 minute delay
}
  //To set off effects when third wire is cut before the first or second wire is cut
if (digitalRead(thirdWire) == HIGH && digitalRead(secondWire) == LOW)  {
  digitalWrite(smoke, HIGH);
  digitalWrite(sound, HIGH);
  digitalWrite(light, HIGH);
    delay(500);
    digitalWrite(light, LOW);
    digitalWrite(sound, LOW); 
    delay(900000);  //15 minute delay
}

if (digitalRead(thirdWire) == HIGH && digitalRead(firstWire) == LOW){
  digitalWrite(smoke, HIGH);
    digitalWrite(sound, HIGH);
    digitalWrite(light, HIGH);
    delay(500);
    digitalWrite(light, LOW);
    digitalWrite(sound, LOW); 
    delay(900000);  //15 minute delay
}
if (digitalRead(thirdWire) == HIGH && digitalRead(secondWire) == HIGH && digitalRead(firstWire) == HIGH) {
  delay(1000);
  digitalWrite(drawer, HIGH);
  delay(1000);
  digitalWrite(drawer, LOW);
}

}

I realize I'm asking a lot, but I really need to get this working. And I greatly appreciate your assistance, in advance!!

Mark

Hey Mark, I'm glad you got it working! I had forgotten that I changed the I2C address back when I got my 7 seg, because I already had another device that was using 0x72.

I'll take a look at your defuse-the-bomb game when I get a chance, but I can't promise anything. I don't really play computer games that much. I did read your other thread on the game, perhaps you should renew the conversation on that thread, rather then transfer it here. I looked like you were getting some serious input from a few of the power-hitters here. I'm a bit of a beginner myself - I answered your question because I had that number device and knew exactly how to make the program. The fun part was simplifying it without leaving anything out.


The way to stop and start the count down is to make a boolean variable - I'd call it "isCountingDown". Check that variable: if the clock should be counting, make the variable true; false if it shouldn't. Then, in the part of the code where the time is actually decremented - it starts with if (seconds-- == 0) ..., put in a test of the variable with if (isCountingDown) ... Do the count down only if the variable is true.

Thanks Chris,

I started a new thread because I had a different issue with a different part of the overall project. Now that I have that working, Thanks to you, I think you are right, I should move it back to the other thread to see if the Big Guns will help again. Especially since I want to in incorporate this into the other program.

I'm going to read up on your suggestions and try them when I get home tonight. My problem is I don't understand the programming language so thus , I don't know the best way to go about making something work.

I"m going to repost my request on the other string. I'll see you over there if you come up with any new ideas.

Thanks again, Mark

Chris,

I tried to put in a Boolean variable after reading up on it but, I'm not have any success. I guess part of my problem is I don't understand what line of your code makes the countdown timer start in the first place. I know once you hit reset it just goes. If i understood what command makes it start, then maybe I could tell it to start when the button is pushed.

Answered here → Defuse the Bomb! thread.