Need help for 2x7 segments display projet

Hi,
I am new to arduino and I need some help for my projet. It is for a sport (dodgeball). It a box with lights, buttons and 2x 7 segements display (see images) I want that when you press the blue button, the blue lights light up and a 10 sec countdown start on the 2x7 segements display (same thing with the red buttons and lights). I need that the buttons to be hold press for the countdown to start and the countdown to reset when you released the bouton (using arcade buttons). There will be a clock timer too using a lcd panel.

I am using a arduino uno for now, but in the futur I am will use a mega 2560 (broke the usb, waiting for parts :frowning_with_open_mouth:)

Using TPIC6C596 for the 7 segements:

There code I write for the boutons:

int ledPinRED = 11;
int ledPinBLUE = 10;
int butttonREDpin = 8;
int butttonBLUEpin = 9;

byte leds = 0;

void setup() 
{
  pinMode(ledPinRED, OUTPUT);
  pinMode(ledPinBLUE, OUTPUT);
  pinMode(butttonREDpin, INPUT_PULLUP);  
  pinMode(butttonBLUEpin, INPUT_PULLUP);
}

void loop() 
{
  if (digitalRead(butttonREDpin) == LOW)
  {
    digitalWrite(ledPinRED, HIGH);
  }
  if (digitalRead(butttonREDpin) == HIGH)
  {
    digitalWrite(ledPinRED, LOW);
  }
    if (digitalRead(butttonBLUEpin) == LOW)
  {
    digitalWrite(ledPinBLUE, HIGH);
  }
  if (digitalRead(butttonBLUEpin) == HIGH)
  {
    digitalWrite(ledPinBLUE, LOW);
  }
}

This is the code for testing the TPIC6C596, found there:
https://learn.sparkfun.com/tutorials/large-digit-driver-hookup-guide#board-overview

    /*
 Controlling large 7-segment displays
 By: Nathan Seidle
 SparkFun Electronics
 Date: February 25th, 2015
 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

 This code demonstrates how to post two numbers to a 2-digit display usings two large digit driver boards.

 Here's how to hook up the Arduino pins to the Large Digit Driver IN

 Arduino pin 6 -> CLK (Green on the 6-pin cable)
 5 -> LAT (Blue)
 7 -> SER on the IN side (Yellow)
 5V -> 5V (Orange)
 Power Arduino with 12V and connect to Vin -> 12V (Red)
 GND -> GND (Black)

 There are two connectors on the Large Digit Driver. 'IN' is the input side that should be connected to
 your microcontroller (the Arduino). 'OUT' is the output side that should be connected to the 'IN' of addtional
 digits.

 Each display will use about 150mA with all segments and decimal point on.

*/

//GPIO declarations
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
}

int number = 0;

void loop()
{
  showNumber(number); //Test pattern
  number++;
  number %= 100; //Reset x after 99

  Serial.println(number); //For debugging

  delay(500);
}

//Takes a number and displays 2 numbers. Displays absolute value (no negatives)
void showNumber(float value)
{
  int number = abs(value); //Remove negative signs and any decimals

  //Serial.print("number: ");
  //Serial.println(number);

  for (byte x = 0 ; x < 2 ; x++)
  {
    int remainder = number % 10;

    postNumber(remainder, false);

    number /= 10;
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

//Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (number)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

And the code a found for the clock timer:

#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27, 16, 2);

boolean button1WasUp = true;
boolean button2WasUp = true;
boolean button3WasUp = true;
boolean button4WasUp = true;

byte w = 0;

int SEC = 0;
int MIN = 0;
unsigned long timer;

void setup() {
   pinMode(2, INPUT_PULLUP);
   pinMode(4, INPUT_PULLUP);
   pinMode(6, INPUT_PULLUP);
   pinMode(8, INPUT_PULLUP);

   pinMode(10, OUTPUT);
   pinMode(12, OUTPUT);
   digitalWrite(10, HIGH);

   LCD.init();
   LCD.backlight(); 

   LCD.setCursor(2, 0);
   LCD.print("TIMER  STOP");
   LCD.setCursor(5, 1);
   LCD.print(MIN);
   LCD.print(" : ");
   LCD.print(SEC);
}

void loop() {
   boolean button1IsUp = digitalRead(2);
   boolean button2IsUp = digitalRead(4);
   boolean button3IsUp = digitalRead(6);
   boolean button4IsUp = digitalRead(8);

    if (button1WasUp && !button1IsUp) {
      delay(10);
      button1IsUp = digitalRead(2);
      if (!button1IsUp) {
         MIN = MIN - 1; SEC = 0;
         if (MIN < 0) { MIN = 0; }
         LCD.clear(); 
         LCD.setCursor(2, 0); 
         LCD.print("TIMER STOP"); 
         LCD.setCursor(5, 1); 
         LCD.print(MIN); 
         LCD.print(" : "); 
         LCD.print(SEC);
      }
   } 
   button1WasUp = button1IsUp;
   
   if (button2WasUp && !button2IsUp) {
      delay(10); 
      button2IsUp = digitalRead(4); 
      if (!button2IsUp) { 
         MIN = MIN + 1; SEC = 0; 
         LCD.clear(); 
         LCD.setCursor(2, 0); 
         LCD.print("TIMER STOP"); 
         LCD.setCursor(5, 1); 
         LCD.print(MIN); 
         LCD.print(" : "); 
         LCD.print(SEC);
      }
   } 
   button2WasUp = button2IsUp;

   if (button3WasUp && !button3IsUp && MIN > 0) {
      delay(10);
      button3IsUp = digitalRead(6);
      if (!button3IsUp) {
         if (SEC == 0) { SEC = 60; MIN = MIN - 1; }
         if (MIN < 0 ) { MIN = 0; }
         digitalWrite(10, LOW);
         w = 1;
      }
   }
   button3WasUp = button3IsUp;

   if (button4WasUp && !button4IsUp) {
      delay(10);
      button4IsUp = digitalRead(8);
      if (!button4IsUp) {
         MIN = 0; SEC = 0;
         digitalWrite(10, HIGH);
         LCD.clear();
         LCD.setCursor(2, 0);
         LCD.print("TIMER STOP");
         LCD.setCursor(5, 1);
         LCD.print(MIN);
         LCD.print(" : ");
         LCD.print(SEC);
      }
   }
   button4WasUp = button4IsUp;

   while (w == 1 ) {
      if (millis() - timer > 995) { 
         timer = millis();
         SEC = SEC - 1;

         if (SEC == 0 && MIN == 0) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER  STOP");
            LCD.setCursor(5, 1);
            LCD.print(MIN);
            LCD.print(" : ");
            LCD.print(SEC);
            digitalWrite(10, HIGH);
            tone(12, 100);
            delay(3000);
            noTone(12);
            w = 0;
         }

         if (SEC == 0) {
            SEC = 59; MIN = MIN - 1;
            if (MIN < 0 ) { MIN = 0; }
         }

         if (w == 1) {
            LCD.clear();
            LCD.setCursor(2, 0);
            LCD.print("TIMER START");
            LCD.setCursor(5, 1);
            LCD.print(MIN);
            LCD.print(" : ");
            LCD.print(SEC);
         }
     }
 
     boolean button3IsUp = digitalRead(6);
     if (button3WasUp && !button3IsUp) {
        delay(10);
        button3IsUp = digitalRead(6);
        if (!button3IsUp) {
           LCD.setCursor(2, 0);
           LCD.print("TIMER  STOP");
           w = 0;
        }
     }
     button3WasUp = button3IsUp; 
   }
}

Thank you for your help
(sorry for the bad english, not a native speaker)

Lots of material....
Any problem? What's the question?

Hi,
I dont know how to code the 7 segments.
I want this behavior:

  1. Press hold the button the light is ON
  2. the 2x7 segements start a countdown (10,9,8,7,6,5,4,3,2,1,0)
  3. When you released the button the light close and it reset the countdown to 10.

Thank you

Post your project schematic.

Use the "Search Forum" function, up to the right, in this window, or Uncle Google. Go for (Your unknown controller + 7 segment LED". Plenty has been done there. Wiring and code.

Search for how to wire and read buttons.

When You master that You can start thinking about the interaction between the connected devices.

Button

sorry speak I french, sometime some word sound the same but is written differently.

I new to this, is there a easy place to draw schematic?

draw freehand.

See if this is what you need:

1 Like

Thank you, that's almost it. I would like the countdown to only happen if you hold one of the buttons down and for it to reset when you release it.

SO ,
button pressed = light on + 10 seconds countdown
button released = light off + reset conuntdown

moreover,
During my research, I understood that it would be better to use millis instead of delays, but I'm not sure how to do it.

OK, try this one:

1 Like

Yes that's it, that's exactly what I wanted thank you. However, it seems that there is a bug. When you touch nothing, after a certain time (around 1 minute) the counter no longer works.

Find the bug. Missing a long in line 50.
unsigned myTime = 0; replace by unsigned long myTime = 0;
https://wokwi.com/projects/386686453774853121

I'd like to duplicate the counter with this module.
This is so that the operator of my box can also see the 10 seconds countdown.
https://fr.aliexpress.com/item/1005005985362888.html?spm=a2g0o.order_list.order_list_main.11.32255e5bAGr2HK&gatewayAdapt=glo2fra

When I replace my current display with this one for testing, the numbers are displayed incorrectly. I feel like the #define a...g dp are not the same. I couldn't find the documentation for this module. If there's another module that would be more suitable, I'm also interested.

byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;
#define blueBt 2
#define redBt 3
#define blueLed 4
#define redLed 8

int number = 0;
unsigned long oneSeg = 1000;
unsigned long myTime = 0;
bool redSet = false;
bool blueSet = false;
//--------------------------------------------------------------------
void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");
  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);
  pinMode(blueBt, INPUT_PULLUP);
  pinMode(redBt, INPUT_PULLUP);
  pinMode(blueLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
  showNumber(number); //Test pattern
  myTime = millis();
}
//--------------------------------------------------------------------
void loop()
{
  if (redSet == true)
  {
    if (millis() - myTime >= oneSeg)
    {
      myTime = millis();
      if (number <= 0)
      {
        number = 0;
       // digitalWrite(redLed, LOW);
        showNumber(number); //Test pattern
      }
      else
      {
        number--;
        showNumber(number); //Test pattern
      }
    }
}
  if (digitalRead(redBt) == LOW and redSet == false)
  {
    myTime = millis();
    redSet = true;
    number = 10;
    showNumber(number); //Test pattern
    digitalWrite(redLed, HIGH);
  }
  if (digitalRead(redBt) == HIGH and redSet == true)
  {
    redSet = false;
    digitalWrite(redLed, LOW);
    showNumber(0); //Test pattern
  }

  if (blueSet == true)
  {
    if (millis() - myTime >= oneSeg)
    {
      myTime = millis();
      if (number <= 0)
      {
        number = 0;
        //digitalWrite(blueLed, LOW);
        showNumber(number); //Test pattern
      }
      else
      {
        number--;
        showNumber(number); //Test pattern
      }
    }
}
  if (digitalRead(blueBt) == LOW and blueSet == false)
  {
    myTime = millis();
    blueSet = true;
    number = 10;
    showNumber(number); //Test pattern
    digitalWrite(blueLed, HIGH);
  }
  if (digitalRead(blueBt) == HIGH and blueSet == true)
  {
    blueSet = false;
    digitalWrite(blueLed, LOW);
    showNumber(0); //Test pattern
  }
}
//--------------------------------------------------------------------
//Takes a number and displays 2 numbers. Displays absolute value
// (no negatives)
void showNumber(float value)
{
  int number = abs(value); //Remove negative signs and any decimals
  for (byte x = 0 ; x < 2 ; x++)
  {
    int remainder = number % 10;
    postNumber(remainder, false);
    number /= 10;
  }
  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register
  // on the rising edge of RCK
}
//Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (number)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

From the picture on the aliexpress web site it uses a 5011bs display. Some data is here.

From the schematic of the pin connections to the segments you should be able to figure out how the segments are mapped to the 74HC595.

I may be making things more complicated by mixing cathodes and anodes, so I may have to make the smaller display myself.

Would it be more appropriate to use 2 of these modules with some 5161AS that I already have?
firefox_6zTcG4n3Uh
https://www.aliexpress.com/item/1005003203148891.html?spm=a2g0o.detail.0.0.6a26HgrOHgrODE&gps-id=pcDetailTopMoreOtherSeller&scm=1007.40050.354490.0&scm_id=1007.40050.354490.0&scm-url=1007.40050.354490.0&pvid=25048f83-a21d-4c00-949c-27b253850040&_t=gps-id%3ApcDetailTopMoreOtherSeller%2Cscm-url%3A1007.40050.354490.0%2Cpvid%3A25048f83-a21d-4c00-949c-27b253850040%2Ctpp_buckets%3A668%232846%238107%231934&pdp_npi=4%40dis%21CAD%211.09%210.47%21%21%210.79%210.34%21%402101c59817055292732816241ecd3d%2112000024642049281%21rec%21CA%213863320961%21&utparam-url=scene%3ApcDetailTopMoreOtherSeller%7Cquery_from%3A

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.