Timing gate with two 7 segment displays - work separately, but not together.

Hi,

I’m trying to put together a timing gate to measure lap times of our student racing car and display the results on two 7- segment LED displays. I am using the bits and bobs I can put my hands on as our budget is almost out, so I have to work with an Arduino Uno and two Kingbright SC52-11LSRWA 7-segment displays.

I have a laser pointed at an LDR which is in a potential divider so the voltage drops when the car breaks the beam. This is working fine on its own when its printing to the screen or saving the time on EEPROM.

I have the two 7-segment displays attached to outputs 2 to 13 on the Arduino. I know, that’s only 12 outputs. I haven’t connected up the bottom LED segment, but you can still read the numbers fine without. When I used pins 0 and 1 I kept getting an error message. This arrangement works fine when I give it a number to display. I display the number in two sections, as it will only be between 0 and 30 with 2 decimal places needed, I do the tens and ones first, delay, then show the tenths and hundredths.

The problem is that when I put the two together, the display does not correctly display the time. The tens and ones are fine, it’s the tenths and hundredths that won’t work. I have tried everything I can think of to correct this and looked up what I think it could be, but I can’t find out what the problem is. The number that the code tells me it’s trying to display is not the number that appears.

Also, the lap time is now not correct. It is less than the actual time. I think this may be due to the delay, but I can’t find out why this is happening, as all I have read about millis is that it is continuous.

Bellow is the full code. Sorry, it’s quite lengthy, but I wasn’t sure which bit I could cut out without missing what may be wrong. I have tried to comment it fully for ease of reading.

Thank you for any assistance you may be able to give me with this. Much appreciated. :slight_smile:

*
FS Timing Gate sketch
sketch to calculate lap time and speed from car breaking laser beam pointed at 
LDR in potential divider
Car passsing => LOW input, no car => HIGH input
Measures the time input is LOW, measures time input is HIGH 
- adds together HIGH + LOW to find total lap time
- divides car length by LOW to find speed
by Anita Crompton
version 2.2
written 18/11/13) 
updated 7/12/13  */

const int sensorPin = 0; // analog 0 pin connect to centre of potential divider (LDR)
float startTime; // value for time since millis started (starts on power up)
float lapTime; // variable to store the duration of the LOW input (during lap)
float speedTime; // variable to store the time of the car passing the gate
float timeInSec;  // variable to convert the time to seconds
float gateSpeed; // variable to store speedtrap speed
float speedInSec; // for speedtrap time
int i=1; // for looping to assign values to arrays
float n=0; // used for the display number


void setup()
{
  pinMode (sensorPin, INPUT); // set to read the input
  digitalWrite(sensorPin, HIGH); // turns on pull up resisitor
  Serial.begin (9600); // communicates with laptop
}

void loop ()
{
  
 if (analogRead (sensorPin) > 700) // read if high - car on lap
 {
 startTime = millis();
 while (analogRead (sensorPin) > 700);
 lapTime = millis()-startTime;
 timeInSec = lapTime/1000;
 }
 
 if (analogRead (sensorPin) < 700) // read if low - car passing gate
 {
   startTime=millis();
   while (analogRead (sensorPin) < 700);
 speedTime = millis()-startTime;
 speedInSec=speedTime/1000;
 gateSpeed= 2.0 /speedInSec; // 2.0 is length of car in meters to get meters per sec

 }
 timeInSec = timeInSec+speedInSec; // total lap time
 Serial.print("Lap time =");
 Serial.println (timeInSec); // duration between light pulses displayed on screen
 
 // display the 10s on the LHS 7-segment display - using 6 segments
 if (timeInSec<10)
 {n = 0;
 digitalWrite (2,1);
 digitalWrite (3,1);
 digitalWrite (4,1);
 digitalWrite (5,1);
 digitalWrite (6,1);}
 if (timeInSec >10 && timeInSec <20)
 { n = 1;
   digitalWrite (3,1);
 digitalWrite (4,1);}
  if (timeInSec >20 && timeInSec <30)
 {n = 2;
   digitalWrite (2,1);
 digitalWrite (4,1);
 digitalWrite (5,1);
 digitalWrite (7,1);
 }
 …. and so on for each number ….

   if (timeInSec >90 && timeInSec <100)
 {n=9.0;
  digitalWrite (3,1);
 digitalWrite (4,1);
 digitalWrite (5,1);
 digitalWrite (6,1);
 digitalWrite (7,1); }
 Serial.print ("N for 10s ");
 Serial.println (n);
 n=n*10; // value of tens in timeInSec
 timeInSec = timeInSec-n; // to display second number, removes 10s

 // display the 1s on the RHS 7-segment display - using 6 segments

 if (timeInSec<1)
 {n = 0;
   digitalWrite (8,1);
 digitalWrite (9,1);
 digitalWrite (10,1);
 digitalWrite (11,1);
 digitalWrite (12,1);}
 if (timeInSec >1 && timeInSec <2)
 { n = 1;
   digitalWrite (9,1);
 digitalWrite (10,1);}

 …. and so on for each number ….

   if (timeInSec >9 && timeInSec <10)
 {n=9;
   digitalWrite (9,1);
 digitalWrite (10,1);
 digitalWrite (11,1);
 digitalWrite (12,1);
 digitalWrite (13,1);
 }
    Serial.print ("N for 1s ");
 Serial.println (n);
 
  timeInSec = timeInSec-n; // to display second number, remover 1s
  timeInSec = timeInSec*100; // times by 100 to display fraction of seconds
 
delay (3000); // so can read first two digits

 // display the 10ths on the LHS 7-segment display
 if (timeInSec<10)
 {n = 0;
 digitalWrite (2,1);
 digitalWrite (3,1);
 digitalWrite (4,1);
 digitalWrite (5,1);
 digitalWrite (6,1);}
 if (timeInSec >10 && timeInSec <20)
 { n = 1;
   digitalWrite (3,1);
 digitalWrite (4,1);}

 …. and so on for each number ….

   if (timeInSec >90 && timeInSec <100)
 {n=9;
  digitalWrite (3,1);
 digitalWrite (4,1);
 digitalWrite (5,1);
 digitalWrite (6,1);
 digitalWrite (7,1); }
 
 Serial.print ("N for tenths ");
 Serial.println (n);
 
 n=n*10; // value of tens in number
 timeInSec = timeInSec-n; // to display second number, removes 10s

 // display the 100ths on the RHS 7-segment display

 if (timeInSec<1)
 {n = 0;
   digitalWrite (8,1);
 digitalWrite (9,1);
 digitalWrite (10,1);
 digitalWrite (11,1);
 digitalWrite (12,1);}
 if (timeInSec >1 && timeInSec <2)
 { n = 1;
   digitalWrite (9,1);
 digitalWrite (10,1);}

  …. and so on for each number ….

   if (timeInSec >9 && timeInSec <10)
 {n=9;
   digitalWrite (9,1);
 digitalWrite (10,1);
 digitalWrite (11,1);
 digitalWrite (12,1);
 digitalWrite (13,1);
 }
 Serial.print ("N for 100ths ");
 Serial.println (n);
 
 delay (3000); // so can read the second digit
 
 // reset the display to blank ready for the next lap time
for (int i=2; i < 14 ; i++)
{
    pinMode(i, OUTPUT);
    digitalWrite(i,0);
}
}
float startTime; // value for time since millis started (starts on power up)
float lapTime; // variable to store the duration of the LOW input (during lap)
float speedTime; // variable to store the time of the car passing the gate

Time, as reported by millis() is NOT a float value. Why are you storing the value in a float?

…. and so on for each number ….

You need to spend time, not money, learning to use functions.

I have the two 7-segment displays attached to outputs 2 to 13 on the Arduino.

But, you don’t declare them as outputs. Why not use two analog pins as digital pins?

When I used pins 0 and 1 I kept getting an error message.

Hard to believe.

 // reset the display to blank ready for the next lap time
for (int i=2; i < 14 ; i++)
{
    pinMode(i, OUTPUT);
    digitalWrite(i,0);
}

Wrong. Changing the mode of the pin is NOT how to turn it off.

Kingbrightusa.com says:
"Part Number Search Result For "SC52-11LSRWA"No Part Number Found !"
Do you have the correct part number?

How long are the lap times? Tens of seconds kinds numbers?

const int sensorPin = 0; // analog 0 pin connect to centre of potential divider (LDR)

You want to use A0 here for analog pin 0. What you are actually doing is specifying digital pin 0. (I know, "A0" doesn't look like an integer value, but the Arduino preprocessor will convert that to the appropriate integer value based on what Arduino board you are compiling for. e.g. If you are compiling for UNO the value will be 14, not sure about other boards like Mega which actually have a digital pin 14.)

Also to reenforce PaulS's query about why you are using float for storing timing values. millis() will never respond with a fractional component, and floating point math is expensive for AVR chips. Try to keep your math to integer values if possible, and select the correct datatype based on what the Arduino reference for millis() tells you the result will be.

I was able to find SC52-11LSRWA on octopart. Is this the correct part? Since you are likely running out of pins trying to drive two 7-segment displays, maybe consider using shift registers (like an inexpensive 74HC595). See ARXD circuit 5 for a tutorial on using shift registers. You can daisy chain two or more shift registers, one for each 7-segment, and only ever have to use 3 I/O pins of your Arduino.

So would the correct thing be to use a long?

No, the correct thing to do is to use unsigned long, unless time can flow backwards in your universe.

The error message I got when I tried to upload any code to the Arduino with connections to 0 and 1 was
stk500_getsync() not in sync resp=0x00
I looked on the forums and there were many different resolutions to this problem, none of which I found worked for me.

The only one that really works is to disconnect whatever is connected to pins 0 and 1 while uploading. I'm sure that that was one of the things that was suggested. It's hard to accept that that didn't work for you.

If I am using the wrong method, I would be grateful if you could tell me the correct way to turn a pin off. This is the way I found in the Arduino book I have and so is the way which I used.

digitalWrite(somePin, LOW);

I think you should toss the book you are using, if it really suggested using pinMode() to turn a pin off.

I tried A0, but it didn't like that for some reason.

"it"? What is it that didn't like A0? How did it manifest that dislike?

Handwaving has little place on this forum.