project problem

I have a problem with my scoreboard that I built.

The scoreboard has 3 segments. A triple digit, A double digit and a single digit. I am using a arduino uno and some sparkfun tpic6c596 shift registers.

All the shift registers are looped together and connected to the arduino. the problem I am having is.

The 3 digit works fine counts up to 1000 and returns to zero.

The 2 digit counts to 33 and then all the segments go back to zero.

The 1 digit will not count at all but the 3 digit moves to 2 with one press of the button and then back to zero with the next press of the button and so on 4/0.6/0.8/0. and then to zero and stops there.

I connected my computer to the Arduino and put it into serial monitor Avery thing looks fine. What is strange is the 2 digit sends every thing back to zero at 33 if I keep pressing the button and watch the serial monitor it keeps counting and when it gets to 66 the digits start to move again. I have tried to attach the code but without success. Would you say it is a code or a wiring problem.

Eddie

/*
   

*/

// Define the mask for each segment
#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;

//GPIO declarations
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
const byte segmentClock = 2;
const byte segmentLatch = 3;
const byte segmentData = 4;
const byte scoreUpButton = 5;
const byte scoreDownButton = 6;
const byte oversUpButton = 7;
const byte oversDownButton = 8;
const byte wicketUpButton = 9;
const byte wicketDownButton = 10;
const byte fourButton = 11;
const byte sixButton = 12;
const byte resetScore = 13;

//Variables declarations
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
int score = 0;
int overs = 0;
int wickets = 0;
unsigned long output = 0;
bool updateNow = false;

void setup()
{
  Serial.begin(9600); // Debug output start
  Serial.println("Cricket scoreboard controller V3.1");
  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);
  pinMode(scoreUpButton, INPUT_PULLUP);
  pinMode(scoreDownButton, INPUT_PULLUP);
  pinMode(wicketUpButton, INPUT_PULLUP);
  pinMode(wicketDownButton, INPUT_PULLUP);
  pinMode(oversUpButton, INPUT_PULLUP);
  pinMode(oversDownButton, INPUT_PULLUP);
  pinMode(resetScore, INPUT_PULLUP);
  pinMode(fourButton, INPUT_PULLUP);
  pinMode(sixButton, INPUT_PULLUP);
  showNumber(output);
  Serial.println(output);
}

void loop()
{


  // If the score,wickets or overs has changed, updaye the display
  if (updateNow)
  {
    updateOutput();
    showNumber(output);
    Serial.println(output);
    Serial.print("Score : ");
    Serial.println(score);
    Serial.print("Overs : ");
    Serial.println(overs);
    Serial.print("Wickets : ");
    Serial.println(wickets);
    delay(250);
    updateNow = false;
  }

  // Read Score Up button
  if (!digitalRead(scoreUpButton))
  {
    updateNow = true;
    score++;
    if (score == 1000)
    {
      // Rollover score from 1000 to 0
      score = 0;
    }
  }

  // Read Score Down button
  if (!digitalRead(scoreDownButton))
  {
    updateNow = true;
    score--;
    if (score == -1)
    {
      // Rollover score from -1 to 999
      score = 999;
    }
  }

  // Read four button
  if (!digitalRead(fourButton))
  {
    updateNow = true;
    score = score + 4;
    if (score > 999)
    {
      score = 999;
    }
  }

  // Read six button
  if (!digitalRead(sixButton))
  {
    updateNow = true;
    score = score + 6;
    if (score > 999)
    {
      score = 999;
    }
  }

  // Read Overs Up button
  if (!digitalRead(oversUpButton))
  {
    updateNow = true;
    overs++;
    if (overs > 99)
    {
      overs = 99;
    }
  }

  // Read Overs Down button
  if (!digitalRead(oversDownButton))
  {
    updateNow = true;
    overs--;
    if (overs < 0)
    {
      overs = 0;
    }
  }

  // Read wickets Up button
  if (!digitalRead(wicketUpButton))
  {
    updateNow = true;
    wickets++;
    if (wickets > 9)
    {
      wickets = 9;
    }
  }

  // Read wickets Down button
  if (!digitalRead(wicketDownButton))
  {
    updateNow = true;
    wickets--;
    if (wickets < 0)
    {
      wickets = 0;
    }
  }

  // Read reset score button
  if (!digitalRead(resetScore))
  {
    updateNow = true;
    score = 0;
    wickets = 0;
    overs = 0;
  }
}

void showNumber(float value)
{
  int number = abs(value);            //Remove negative signs and any decimals

  for (byte x = 0 ; x < 6 ; 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
}

void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

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

void updateOutput()
{
  output = (100000 * wickets) + (1000 * overs) + score;
}

hi

I expect your problem is that there is type-casting is not happening correctly (int to unsigned long, unsigned long to float, float to int). You can use unions and other mechanisms to do that correctly, but the easy way is make all the variables “unsigned long” as I have done in the example below.

unsigned long score = 567;		// for showing the example
unsigned long overs = 34;
unsigned long wickets = 8;
unsigned long output = 0;

void setup() {

  Serial.begin(9600); // Debug output start

   updateOutput();
   Serial.print("after update output ");
   Serial.println(output);

   showNumber(output);

}

void loop() {
  // put your main code here, to run repeatedly:
}

void updateOutput()
{
  output = (100000 *  wickets) + (1000 *  overs) + score;
}

void showNumber(unsigned long value)
{
  unsigned long number = value;		// not needed to make abs (it is unsigned already)
  
  for (byte x = 0 ; x < 6 ; x++)
  {
    unsigned long remainder =  number % 10;

    Serial.print ("output ");
    Serial.print (number);
    Serial.print (" remainder ");
    Serial.println (remainder); 
    postNumber(remainder);

    number /= 10;
  }
}

void postNumber(unsigned long number)
{
  Serial.print ("Selected ");
  
  switch (number)		// just to show it makes the right selection
  {
    case 1: Serial.println ("1");  break;
    case 2: Serial.println ("2"); break;
    case 3: Serial.println ("3"); break;
    case 4: Serial.println ("4"); break;
    case 5: Serial.println ("5"); break;
    case 6: Serial.println ("6"); break;
    case 7: Serial.println ("7"); break;
    case 8: Serial.println ("8"); break;
    case 9: Serial.println ("9"); break;
    case 0: Serial.println ("0"); break;
    case ' ': Serial.println ("space"); break;
    case 'c': Serial.println ("c"); break;
    case '-': Serial.println ("-");break;
  }
}

regards,

Paul

It’s nice to make things generic, but in this case, I would simplify things. Definitely no need to bother with floats for this.

  if (updateNow)
  {
    temp = score;
	for (ii = 0; ii < 3; ii++)
	{
	  postNumber(temp % 10, false);
	  temp /= 10;
	}
	temp = overs;
	for (ii = 0; ii < 2; ii++)
	{
	  postNumber(temp % 10, false);
	  temp /= 10;
	}
	postNumber (wickets, false);
    //Latch the current segment data
    digitalWrite(segmentLatch, LOW);
    digitalWrite(segmentLatch, HIGH);   //Register moves storage register on the rising edge of RCK

    Serial.print("Score : ");
    Serial.println(score);
    Serial.print("Overs : ");
    Serial.println(overs);
    Serial.print("Wickets : ");
    Serial.println(wickets);
    delay(250);
    updateNow = false;
  }

Two other things come to mind - you are ignoring button inputs for a quarter of a second after changing the display, and you do not have any debouncing on the button inputs.

/mike