Counter up/down with Tpic6c596 shift register

Hi everyone,

I am new with Arduino and working on one of my projects which involves 7-segment display counter that counts up and down from 0 to 999 by two buttons , i have 3 big 7-segment display for that reason i am using SparkFun Large Digit Driver (TPIC6C596) that can provide the high power to the display segments, i got an example code from sparkfun web page that counts 0 to 99 without buttons and resets at 99, can any one help me to modify the code for my project , i have attached the code i got from sparkfun

    /*
 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 = 3;
byte segmentLatch = 4;
byte segmentData = 2;

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

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
  }
}

number %= 1000; //Reset x after 999

Read the two buttons, and increase or decrease the "number" variable.
You can learn how to use a button in the examples of the IDE.

Is this a continuation (cross-post) of
https://forum.arduino.cc/index.php?topic=552531.0
Leo..

yes that will make it count till 999 but how to add button control so i can count up and down :o

Only a few things happen in loop().

  1. showNumber(number); // send to display

  2. number++; // increase value by one

  3. Serial.println(number); // for debugging only

  4. delay(500); // slow things down for us humans

Forget about that display for now, and write some two-button code that changes a variable ("number") up/down and displays it's value in the serial monitor. Once you understand that, it should be easy to add that to the above code.
Leo..

int  upButton =    8;
int  downButton =  9;
int  score =       0;


void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");
  
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  
  }

void loop()
{

  if (! digitalRead(upButton)) {
    score++;
    score %=1000;
    
  Serial.println(score); //For debugging
   
   delay (200);
  
  }
 if (! digitalRead(downButton)) {
    score--;
    Serial.println(score); //For debugging

     delay (200);
     if(score <= 0) score = +999;

}
}

:confused:

i can count up and down with button with this short code and see it in serial monitor but i have no idea how i can merge this code with the first code i posted.... can any one please guide me ...... direct me in right direction

Only wrote the loop() part. Didn't look at the Sparkfun part.
Untested.
Leo..

/*
  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
const byte  upButton = 8;
const byte  downButton = 9;
int number = 0; // score
int previousNumber;

byte segmentClock = 3;
byte segmentLatch = 4;
byte segmentData = 2;


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);

  pinMode(upButton, INPUT_PULLUP); // button between pin and ground, no resistor
  pinMode(downButton, INPUT_PULLUP);

  showNumber(number); // show 0 on startup
}


void loop() {
  if (!digitalRead(upButton) && number < 999) number++;
  if (!digitalRead(downButton) && number > 0) number--;

  if (number != previousNumber) { // if number has changed
    Serial.println(number); // print to serial monitor for debugging
    showNumber(number); // show on display
    previousNumber = number; // update
    delay(500); // some button timeout to stop rapid firing
  }
}

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
  }
}

hi,

thank you for explaining learning a lot, i tried to understand the code and everything seemed simple however when i run the code i see that my 3rd digit is not shifting out as it should , it displayed the same digit as on first digit, but from the code it shouldn't do that

ie

if (!digitalRead(upButton) && number < 999) number++;
if (!digitalRead(downButton) && number > 0) number--;

i double checked my setup and everything seem to be normal
am i doing something wrong?

Seems to count ok on the serial monitor, just not on the big display.

Still a coding noob, but I think this for loop (line 66) restricts shifting to two digits.

for (byte x = 0 ; x < 2 ; x++)

Try changing the 2 to a 3.
Leo..