I should get a value of 0, but instead i get a value different than 0 ! help !

hello everyone,
i am using for hardware simply a hall effect sensor switch, i tested a simple hall effect sketch with an LED, it worked fine, now i am trying to make a speedometer, i made my sketch, and i print the values on the serial monitor, so i must at the start get a speed of 0, but i am getting a value different than 0 !
in my sketch speed = distance / differentMicros, at the start without any change on the hall effect, i print distance it is 0, i print differentMicros it is 0 as well ! i print speed i get a this value 4294 KM/H !
can anyone help me please ? i am sure the problem from the division so far

here are my codes :

unsigned long wheel_circumference = 1500UL * 2UL * 31416UL; // = 94,248,000

// wheel circumference gets divided by microseconds, 1,000,000/sec (usec or us).
// wheel turns once for 94248000 mm/100 in 1000000 usecs =

unsigned long Speed = 0;
unsigned long PrevSpeed = 0;

volatile byte hall_rising = 0; // interrupt flag
volatile unsigned long irqMicros;

unsigned long startMicros;
unsigned long differentMicros;

unsigned long displayStartMillis;
const unsigned long displayWaitMillis = 200;
unsigned long ledFlashStartMillis;
const unsigned ledFlashWaitMillis = 100;

unsigned long hallEffectCount = 0;
unsigned long distance = 0;


void wheel_IRQ()
{
  irqMicros = micros();
  hall_rising = 1;
  hallEffectCount++;
}

void setup()
{
  pinMode( 2, INPUT ); // pin # is tied to the interrupt
  Serial.begin( 9600 ); // can this be faster? faster would be better
  //Serial.println(wheel_circumference); //prints the wheel perimeter
  //delay( 1000 );

  attachInterrupt( 0, wheel_IRQ, FALLING ); // pin 2 looks for LOW to HIGH change
}

void loop()
{
  //Serial.print("hallEffectCount ");
  //Serial.println(hallEffectCount);
  
  while(hall_rising == 1){
    differentMicros = irqMicros - startMicros;
    startMicros = irqMicros;
    hall_rising = 0;
  }
  
  
    distance = wheel_circumference * hallEffectCount;
    // print speed 1000/Wait (5 times per second)
  
    Speed =  wheel_circumference / differentMicros; //speed = distance / time

    if ( Speed != PrevSpeed )
    {
      Serial.println( Speed );
      Serial.println( distance );
      //Serial.println( differentMicros ); // this now shows mm/sec with no remainder
      //Serial.print( (Speed*3600)/1000000 ); // this converts the speed from mm/s to Km/h
      //Serial.print( "mm/s  alt=" );
      Serial.print( "KM/H  " );
      Serial.println( " " );

      
    }

    PrevSpeed = Speed;


}// end of void loop

anything divided by 0 is undefined.

So, 0 / 0 is undefined. You need to check if the denominator is 0.

arduinodlb:
anything divided by 0 is undefined.

So, 0 / 0 is undefined. You need to check if the denominator is 0.

yes the denominator is 0 at the start, because the differenMicros which is the different in time is 0
technically yes 0/0 is undefined, but in my case it should give a 0 the speed is set originally as 0

Ok Solved it ! thanks for the help, it made me see it clearly :slight_smile:

i had to add this if else statement after the while loop and make it 0 manually

    distance = wheel_circumference * hallEffectCount;
    // print speed 1000/Wait (5 times per second)
    
    if( differentMicros != 0 ){
      Speed =  wheel_circumference / differentMicros; //speed = distance / time
      Speed = (Speed*3600)/1000000; // this converts the speed from mm/s to Km/h
    }else if ( differentMicros == 0 ){
      Speed = 0;
      Serial.print( Speed ); 
      //Serial.print( "mm/s  alt=" );
      Serial.println( "KM/H  " );
    }
    if( differentMicros != 0 ){
      Speed =  wheel_circumference / differentMicros; //speed = distance / time
      Speed = (Speed*3600)/1000000; // this converts the speed from mm/s to Km/h
    }else if ( differentMicros == 0 ){

If the first if statement is not true, what is the value in differentMicros (what a stupid name)?

Is there a snowball's chance in hell that the second if statement will NOT be true, after the first one was false, so the else part was performed?

Fix the layout of your code. It sucks. NOTHING follows the } on the same line, in ANY recognized coding style. If you are going to use a different style, it MUST be better in some way. Your sloppy mess is NOT better in ANY way.

PaulS:
If the first if statement is not true, what is the value in differentMicros (what a stupid name)?

i corrected the name i meant difference of time in micros

PaulS:
Is there a snowball's chance in hell that the second if statement will NOT be true, after the first one was false, so the else part was performed?

removed it, i had a reason when i was making the sketch to put it but now removed it

PaulS:
Fix the layout of your code. It sucks. NOTHING follows the } on the same line, in ANY recognized coding style. If you are going to use a different style, it MUST be better in some way. Your sloppy mess is NOT better in ANY way.

about } i think you know there is plenty of styles of layouts ! i came from a background of PHP and javascript and i learned to code like this, and i learned there is plenty of coding styles and i learned that "i like the this style of coding " }else{ "

thanks for your reply i corrected my code now it became like this :

// wheel radius in mm * 100 * 2 * ( pi * 10000 ) = 94.248000 mm perimeter.
// 6 0's were used in scaling up radius and pi, 6 places are divided in the end
// and the units work out. You can use integers more accurate than float on
// Arduino at greatly faster speed. Both type of long can hold any 9-digits.
// Arduino variable type long long can hold any 19 digits is 19 place accuracy.
// if you work in Small Units and scale back later, integers are plenty accurate.
// remember, this value has to be divided by microseconds per turn.
const unsigned long wheel_perimeter = 1500UL * 2UL * 31416UL; // = 94,248,000 //radius * 2 * pi, 'UL' to force the constant into an unsigned long constant
// wheel perimeter gets divided by microseconds, 1,000,000/sec (usec or us).
// wheel turns once for 94248000 mm/100 in 1000000 usecs = 
//wheel radius is 15mm

unsigned long Speed = 0;
unsigned long PrevSpeed = 0;

volatile byte hall_rising = 0; // interrupt flag
volatile unsigned long irqMicros;

unsigned long startMicros;
unsigned long differenceMicros;

unsigned long displayStartMillis;
const unsigned long displayWaitMillis = 200;
unsigned long ledFlashStartMillis;
const unsigned ledFlashWaitMillis = 100;

unsigned long hallEffectCount = 0;
unsigned long distance = 0;


void wheel_IRQ()
{
  irqMicros = micros();
  hall_rising = 1;
  hallEffectCount++;
}

void setup()
{
  pinMode( 2, INPUT ); // pin # is tied to the interrupt
  Serial.begin( 9600 ); // can this be faster? faster would be better
  //Serial.println(wheel_circumference); //prints the wheel perimeter
  //delay( 1000 );

  attachInterrupt( 0, wheel_IRQ, FALLING ); // pin 2 looks for LOW to HIGH change
}

void loop()
{
  //Serial.print("hallEffectCount ");
  //Serial.println(hallEffectCount);
  
  while(hall_rising == 1){
    differenceMicros = irqMicros - startMicros;
    startMicros = irqMicros;
    hall_rising = 0;
  }
  
    distance = (wheel_perimeter * hallEffectCount)/1000000000; //distance in meters
    if( differenceMicros != 0 ){
      Speed =  wheel_perimeter / differenceMicros; //speed = distance / time
      Speed = (Speed*3600)/1000000; // this converts the speed from mm/s to Km/h
      
      if ( Speed != PrevSpeed )
      {
        Serial.print( distance );
        Serial.println( "mm  " );
        //Serial.println( differenceMicros ); // this now shows mm/sec with no remainder
        Serial.print( Speed ); // this converts the speed from mm/s to Km/h
        //Serial.print( "mm/s  alt=" );
        Serial.print( "KM/H  " );
        Serial.println( " " );
  
        
      }
    
    }else {
      Speed = 0;
      Serial.print( Speed ); 
      //Serial.print( "mm/s  alt=" );
      Serial.println( "KM/H  " );
    }
    
    

    PrevSpeed = Speed;


}// end of void loop

Aiming for the unreachable !

If that said "unreadable", you are about there with your code. Can't see what is important for all the useless comments. Can't see what it is supposed to do, because the names of variables mean so little.

And, your use of white space is inconsistent. The top of the program is a dense mess. The

end

has

every

spread

out

way

more

than

needed.

But, hey, it's your code to maintain. Good luck.

PaulS:
If that said "unreadable", you are about there with your code. Can't see what is important for all the useless comments. Can't see what it is supposed to do, because the names of variables mean so little.

And, your use of white space is inconsistent. The top of the program is a dense mess. The

end
has
every
spread
out
way
more
than
needed.

But, hey, it's your code to maintain. Good luck.

it was a draft, final sketch won't be like this, but thanks for telling next time i will be more careful about spaces and other when posting here on the forum :slight_smile: