Help needed with gear indicator + x-sim+ Arduino

I'm currently working on a gear indicator for LFS using x-sim and a deumilanove. However, I'm running into issues getting all the gears to display correctly on my common anode, 7 segment LED.

As it stands, only 1st, 3rd, and 4th gear are displaying correctly but not 2nd or 5th.
-2nd and 5th just shows me 1

So my question is, why is it doing this?

The following is how I'm connecting the 7 segment LED to the arduino, as well as screen shots of the X-sim settings.

Lastly, in the coding, I've highlighted and bolded a line in the code that I've noticed had the greatest impact on the display working or not. It changes things by a lot if I change the number "6" to something else.

int rpm;
int i;
int leds;
int Speed;
int fuel;
int ebrake;
int brake;
int fuelled;
int Turbo;
int gear;
int previous_potion = 0;
int rotate;
char kind_of_data;
void setup(){

  • Serial.begin(115200);*
  • pinMode(2, OUTPUT);*
  • pinMode(3, OUTPUT);*
  • pinMode(5, OUTPUT);*
  • pinMode(7, OUTPUT);*
  • pinMode(8, OUTPUT);*
  • pinMode(9, OUTPUT);*
  • pinMode(10, OUTPUT);*
  • pinMode(12, OUTPUT);*
  • pinMode(13, OUTPUT);*
    }
    void loop()
    {
  • while(Serial.available() > 0)*
  • {*
  • kind_of_data = Serial.read();*
  • if (kind_of_data == 'R' ) Read_Rpm();*
  • if (kind_of_data == 'S' ) Read_Speed();*
  • if (kind_of_data == 'B' ) Read_Brake();*
  • if (kind_of_data == 'G' ) Read_Gear();*
  • }*
    }
    void Read_Rpm(){
  • delay(1);*
  • int Rpm100 = Serial.read()- '0';*
  • delay(1);*
  • int Rpm10 = Serial.read()- '0';*
  • delay(1);*
  • int Rpm1 = Serial.read()- '0';*
    _ int rpm = 100Rpm100 + 10Rpm10 + Rpm1;_
  • analogWrite(7,map(rpm,127,255,75,210));*
  • if (rpm>375) digitalWrite(7,HIGH);*
  • if (rpm<375) digitalWrite(7,LOW);*
  • if (rpm>380) digitalWrite(8,HIGH);*
  • if (rpm<380) digitalWrite(8,LOW);*
  • if (rpm>385) digitalWrite(9,HIGH);*
  • if (rpm<385) digitalWrite(9,LOW);*
  • if (rpm>395) digitalWrite(12,HIGH);*
  • if (rpm<395) digitalWrite(12,LOW);*
  • if (rpm>410) digitalWrite(13,HIGH);*
  • if (rpm<410) digitalWrite(13,LOW);*
    }
    void Read_Speed(){
  • delay(1);*
  • int Speed100 = Serial.read()- '0';*
  • delay(1);*
  • int Speed10 = Serial.read()- '0';*
  • delay(1);*
  • int Speed1 = Serial.read()- '0';*
    _ Speed = 100Speed100 + 10Speed10 + Speed1;_
  • tone(10, map(Speed,127,255,0,950));*
    }
    void Read_Brake(){
  • delay(1);*
  • int Brake100 = Serial.read()- '0';*
  • delay(1);*
  • int Brake10 = Serial.read()- '0';*
  • delay(1);*
  • int Brake1 = Serial.read()- '0';*
    _ brake = 100Brake100 + 10Brake10 + Brake1;_
  • if (brake>200) digitalWrite(5,HIGH);*
  • if (brake<200) digitalWrite(5,LOW);*
    }
    void Read_Gear(){
    delay(2);
    int Gear100 = Serial.read()- '0';
    delay(2);
    int Gear10 = Serial.read()- '0';
    delay(2);
    int Gear1 = Serial.read()- '0';
    gear = 100* Gear100 + 10*Gear10 + Gear1;
    gear = map(gear,127,255,0,6);
  • pinMode(2, OUTPUT);*
  • pinMode(3, OUTPUT);*
  • pinMode(4, OUTPUT);*
  • pinMode(5, OUTPUT);*
  • pinMode(6, OUTPUT);*
  • pinMode(7, OUTPUT);*
  • pinMode(8, OUTPUT);*
    if ( gear == 0 ){
  • digitalWrite(35,HIGH);*
  • digitalWrite(37,HIGH);*
    }
    if ( gear == 1 ){
  • // write '1'*
    digitalWrite(2, 1);
    digitalWrite(3, 0);
    digitalWrite(4, 0);
    digitalWrite(5, 1);
    digitalWrite(6, 1);
    digitalWrite(7, 1);
    digitalWrite(8, 1);
    }
    if ( gear == 2 ){
  • // write '2'*
    digitalWrite(2, 1);
    digitalWrite(3, 1);
    digitalWrite(4, 0);
    digitalWrite(5, 1);
    digitalWrite(6, 1);
    digitalWrite(7, 0);
    digitalWrite(8, 1);
    }
    if ( gear == 3 ){
    // write '3'
    digitalWrite(2, 0);
    digitalWrite(3, 0);
    digitalWrite(4, 0);
    digitalWrite(5, 0);
    digitalWrite(6, 1);
    digitalWrite(7, 1);
    digitalWrite(8, 0);
    }
    if ( gear == 4 ){
  • // write '4'*
    digitalWrite(2, 1);
    digitalWrite(3, 0);
    digitalWrite(4, 0);
    digitalWrite(5, 1);
    digitalWrite(6, 1);
    digitalWrite(7, 0);
    digitalWrite(8, 0);
    }
    if ( gear == 5 ){
  • // write '5'*
    digitalWrite(2, 0);
    digitalWrite(3, 1);
    digitalWrite(4, 0);
    digitalWrite(5, 0);
    digitalWrite(6, 1);
    digitalWrite(7, 0);
    digitalWrite(8, 0);
    }
    }

Your code relies heavily on delays to ensure that serial data is available. It may not be. Revise it to use Serial.available instead. This will have the additional advantage that you can use the serial monitor to test it manually and add in some additional serial.prints to see what values you're getting for the components of gear.

How are sent datas ?

is it always like 'RwwwSxxxFyyyGzzz' (with www, xxx, yyy, zzz differents numbers) or do you receive datas like

GaaaGbbbGccc when you play only with gear ?

In your code, you check that there is at least one byte of serial data to be read, then read one byte and call a function to read 3 more. You may not be reading what you expect.

It looks like x-sim is sending binary data, but you are expecting and reading ASCII data. You may not be reading what you expect.

In the function to read the gear, why are you redefining the mode of the pins? They only need to be defined once.

What are pins 35 and 37 for? Are you using a Mega with that many pins?

Have you tried using the Serial Monitor to send data to the Arduino, and echo back what was read?

To light up a 1, you appear to be setting segments B and C off, with the other segments on. Hardly how I'd expect to show a 1.

To light up a 2, you appear to be setting segments A, B, D, E, and F on, with the other segments off. That pattern doesn't look anything like a 2.

What gives? Does writing a 1 to the pin turn the segment on or off? In any case, the pattern for 2 is incorrect.

you can in the first time change your code in each function (not the best way to do, but simple and effective).

replace in each function (Read_xxxxx) this code :

delay(1);
  int Rpm100 = Serial.read()- '0';
  delay(1);
  int Rpm10 = Serial.read()- '0';
  delay(1);
  int Rpm1 = Serial.read()- '0';

by :

  byte cpt=0;  // index value
  byte value;     // char to read
  int Rpm=0;   // the value we want to read

  while(cpt<3)     // we should read 3 digits to get an 'full' value
  {
     if (Serial.avalable()>0)     // there is character in the serial buffer
     {
        value = Serial.read()-'0';  // Read the value converted to int.
        if (cpt==0)                   // first char then multiply by 100
           Rpm += value * 100;   
        if (cpt==1)                   // second char then multiply by 10
           Rpm += value * 10;
        if (cpt==2)                  // third char then add it 
           Rpm += value;

        cpt++;                        // one char was read, lets go for next
     }
  }

This is not elegant but this is the way of using Serial.available and Serial.read.

This will works only if the datas that are transmited by your soft is like 'R123'

PaulS:
In your code, you check that there is at least one byte of serial data to be read, then read one byte and call a function to read 3 more. You may not be reading what you expect.

It looks like x-sim is sending binary data, but you are expecting and reading ASCII data. You may not be reading what you expect.

In the function to read the gear, why are you redefining the mode of the pins? They only need to be defined once.

What are pins 35 and 37 for? Are you using a Mega with that many pins?

Have you tried using the Serial Monitor to send data to the Arduino, and echo back what was read?

To light up a 1, you appear to be setting segments B and C off, with the other segments on. Hardly how I'd expect to show a 1.

To light up a 2, you appear to be setting segments A, B, D, E, and F on, with the other segments off. That pattern doesn't look anything like a 2.

What gives? Does writing a 1 to the pin turn the segment on or off? In any case, the pattern for 2 is incorrect.

So many replied :slight_smile:

Anyhow, for some reason when I set the command to 0, it actually turns ON the light so I'm really lighting up B and C for 1.

For 2 I fixed it but it still didn't read it.
I do not have the arduino mega and so I have no idea why the 35 is there. I used the general code from another user on this forum however they've been inactive for quite awhile.

I'm still trying to understand what some of you posted but I'll try and see if I can do what you guys suggested however I'm still fairly new to the arduino coding and understanding all this weird language like ASCII and stuff.

What do you mean by this statement?

In the function to read the gear, why are you redefining the mode of the pins? They only need to be defined once.

duffman1278:
What do you mean by this statement?

In the function to read the gear, why are you redefining the mode of the pins? They only need to be defined once.

You only need to set the pinmode once, unless you're changing it. Since you set the pins to output mode in the setup function, there is no need to do it again in read_gear. Note however, that you have not set all, your pins in setup. Pins 4 & 6 are missing.

It worked!! Ends up that pins 4 and 6 were not defined and several pins were being used for another control. After removing the pins that were used twice for 2 different operations, it worked out fine! Thanks

You really need to read about arrays.

if ( gear == 1 ){
// write '1'
digitalWrite(2, 1);
digitalWrite(3, 0);
digitalWrite(4, 0);
digitalWrite(5, 1);
digitalWrite(6, 1);
digitalWrite(7, 1);
digitalWrite(8, 1);
}

if ( gear == 2 ){
// write '2'
digitalWrite(2, 1);
digitalWrite(3, 1);
digitalWrite(4, 0);
digitalWrite(5, 1);
digitalWrite(6, 1);
digitalWrite(7, 0);
digitalWrite(8, 1);
}

if ( gear == 3 ){
// write '3'
digitalWrite(2, 0);
digitalWrite(3, 0);
digitalWrite(4, 0);
digitalWrite(5, 0);
digitalWrite(6, 1);
digitalWrite(7, 1);
digitalWrite(8, 0);
}

if ( gear == 4 ){
// write '4'
digitalWrite(2, 1);
digitalWrite(3, 0);
digitalWrite(4, 0);
digitalWrite(5, 1);
digitalWrite(6, 1);
digitalWrite(7, 0);
digitalWrite(8, 0);
}

if ( gear == 5 ){
// write '5'
digitalWrite(2, 0);
digitalWrite(3, 1);
digitalWrite(4, 0);
digitalWrite(5, 0);
digitalWrite(6, 1);
digitalWrite(7, 0);
digitalWrite(8, 0);
}