Sev Seg Library - Test Program works, Program refuses to play.

Hi All.
I am in the process of putting together a Speed Monitor for our Local Miniature Railway.
The basis of the idea is taken from: an-arduino-powered-scale-speed-trap.html
2 Reed switches 620 mm apart measure the time and calculate the Speed.
I have A BT Module writing to a Tablet to log so I can also see what’s being sent.
the Seven Seg display is built from: Using-a-4-digit-7-segment-display-with-arduino/
Running their Test Program works just perfic.

I have combined the test program into my Speed Monitor Program and tried everything over the past 2 weeks. I’m now totally out of ideas.

I send a 4 digit number with the Speed Monitor program, I get Random Segmants. Back to the Test program it works.

I’m no programmer but do know enough to be dangerous.
Genuine Arduino Mega 2560
This is the program as it stands.

Any ideas would be greatly appreciated.

Many Thanks

// CSME Speed Monitor. code by  Mark A. Greenwood
//Modified by Alex Collins for use by the Chelmsford Society of Model Engineers.

// Include the SevenSeg Library
#include "SevSeg.h"
SevSeg sevseg; //Initiate a seven segment controller object

//keep the sketch size down by only compiling debug code into the
//binary when debugging is actually turned on
#define DEBUG 1

//all possible states of the state machine
const byte TRACK_SECTION_CLEAR = 0;
//the current state machine state
//the analog pins used for each sensor
const byte SENSOR_1 = 1;
const byte SENSOR_2 = 2;
//the digital pins for the signalling LEDs
const byte GREEN_LIGHT = 49;
const byte RED_LIGHT = 51;
const byte CAL_LIGHT = 53;
const byte AMBER_1 = 27;
const byte AMBER_2 = 29;
const byte AMBER_3 = 31;
const byte AMBER_4 = 33;
//the threshold values for each sensor
int sensor1 = 1024;
int sensor2 = 1024;
//intermediate steps to calcualte the scale distance we are measuring
const float scale = 1; //this is full scale
const float distance = 620; //measured in mm
const float scaleKilometer = 1000000.0/scale;
//This is the only value we actually need to do the calculation
//We could do this calculation on the computer and pass it across
//or store it in EEPROM. it all depends if we expect to always be
//attached to a computer or if we want to run standalone etc.
const float scaleDistance = distance/scaleKilometer;
//the track speed limit in mph
const float speedLimit = 6;
//the time (in milliseconds from the Arduino starting up that the
//first sensor was last triggered
unsigned long time;
void setup(void) {
// Setup the SevSeg Display
   byte numDigits = 4; 
   byte digitPins[] = {2, 3, 4, 5};
   byte segmentPins[] = {6, 7, 8, 9, 10, 12, 11, 13};
   sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins);

  //enable output on the digital pins
  //turn on both LEDs to show we are calibrating the sensors
  digitalWrite(GREEN_LIGHT, HIGH);
  digitalWrite(RED_LIGHT, HIGH);
  digitalWrite(CAL_LIGHT, HIGH);
  //configure serial communication
  //let the user know we are calibrating the sensors
  while (millis() < 5000) {
    //for the first five seconds check and store the lowest light
    //level seen on each sensor
    sensor1 = min(sensor1, analogRead(SENSOR_1));
    sensor2 = min(sensor2, analogRead(SENSOR_2));
  //the cut off level for triggering the state machine
  //is half the resistance seen during calibration
  sensor1 = sensor1/2;
  sensor2 = sensor2/2;  
  //we have now finished callibration so tell the user...
      Serial.println(" Done");
      Serial.print("Sensor 1 reading ");
      Serial.print("Sensor 2 reading ");

  //... and set the signalling to green (i.e. we haven't yet seen
  //anything break the speed limit!
  digitalWrite(GREEN_LIGHT, HIGH);
  digitalWrite(RED_LIGHT, LOW);
  digitalWrite(CAL_LIGHT, LOW);

void loop(void) {
  if (state == TRACK_SECTION_CLEAR) {
    //last time we checked the track was clear
    if (analogRead(SENSOR_1) < sensor1) {
      //but now the first sensor has been triggered so...
      //store the time at which the sensor was triggered
      time = millis();
      //advance into the next state
      #if (DEBUG)
        Serial.println("Train entering measured distance");
  else if (state == ENGINE_ENTERING_SECTION) {
    //the last time we checked the first sensor had triggered but
    //the second was yet to trigger
    if (analogRead(SENSOR_2) < sensor2) {
      //but now the second sensor has triggered as well so...
      //get the difference in ms between the two sensors triggering
      unsigned long diff = (millis() - time);
      //calculate scale speed in kph
      //3600000 is number of milliseconds in an hour
      float kph = scaleDistance*(3600000.0/(float)diff);
      //convert kph to mph
      float mph = kph*0.621371;

// grab the mph, X it by 100 and make it an integer      
//      float mphValue = mph * 100;

      float mphValue = mph;
      int testint = mphValue * 1000;
      Serial.println(" testint");
      mphValue  = testint / 1000.0;
      Serial.println(" Value");
      //report the time and speed to the user
      Serial.print("Speed Trap Record: ");
      Serial.print("ms ");
      Serial.print("kph ");
// Send the Value of MPH as an Integer to the display      
      sevseg.refreshDisplay(); // Must run repeatedly
      if (mph > speedLimit) {
        //if the speed we calculated was above the speed limit
        //then turn off the green LED and turn on the red one
        digitalWrite(GREEN_LIGHT, LOW);
        digitalWrite(RED_LIGHT, HIGH);
      else {
       //if the speed we calculated was not above the speed limit
       //then turn off the red LED and turn on the green one
       digitalWrite(GREEN_LIGHT, HIGH); 
       digitalWrite(RED_LIGHT, LOW);
      //move into the next state
  else if (state = ENGINE_LEAVING_SECTION) {
    //last time we checked both sensors had triggered but both
    //had yet to reset back to normal
    if (analogRead(SENSOR_1) > sensor1 && analogRead(SENSOR_2) > sensor2) {
      //both sensots are now clear so...

      //move back to the first state ready for next time
      state = TRACK_SECTION_CLEAR; 
      #if (DEBUG)
        Serial.println("Train is clear of measured distance");

The Current Bluetooth Output says:

162 testint
3649 testint
10688 testint

I'm guessing that you are trying to update the display too frequently. Instead of updating it each time through loop(), just update it every 500ms (see example sketch "blink without delay" in the IDE).
I also doubt that you need to clear the display each time before updating.

I'll give that a go.
the blank() was my last ditch attempt tonight.

My last comment was a little vague. By update I meant the setNumber(). You will of course have to call the refreshDisplay() as frequently as possible.

Struggling to work out how/where I integrate the “blink without delay” code. I do however see your idea and it does make sense.

I have (hopefully) attached an image of the display and output which may help with diagnosis.

Ideas would still be most welcome.




It requires a sevseg.refreshDisplay(); in every {} section after a value is declared and the number persists until you send it a new value.

It's only taken me 2 weeks of frustration...….

TY Arduarn for your replies.