Serialprint is different if written first to variable

Good day folks,
I have a motor with an encoder and the following code:

void setup() {
Serial.begin(115200);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), count1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), count1, CHANGE);
TCCR1B = TCCR1B & B11111000 | B00000001; 

}

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

   if(set==true){
    
    timeold = timenew;
    timenew = micros();
    rpm1 = double(double(enc_count1) * double(333333.33 / (timenew - timeold))); //60000000/180=333333,33
    set=false;
    Serial.println(rpm1);
    enc_count1=0;
      }
   
  analogWrite(PIN_OUTPUT,100);

}

void count1()//ISR für den Hallsensor
{
  set=true;
  static int8_t lookup_table[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
  static uint8_t enc_val1 = 0;
  enc_val1 = enc_val1 << 2;
  enc_val1 = enc_val1 | ((PIND & 0b1100) >> 2);
  enc_count1 = enc_count1 + lookup_table[enc_val1 & 0b1111];
  
  
}

The output for the serial.print has a lot of Zeros in it, which kills my sensing of the rpm. But if I use the following instead of Serial.println(rpm1): Serial.println(double(double(enc_count1) * double(333333.33 / (timenew - timeold))));
it works, no zeros in it. But as I need the value of rpm1 for further calculations I would want it to print the same as calculated directly in serial.print.
Where are the zeros coming from?
thanks

Hello

where is rpm1 declared ? what's its type? we are missing all the variables definitions

I can't compile your sketch:

/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino: In function 'void setup()':
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino:7:19: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
   TCCR1B = TCCR1B & B11111000 | B00000001;
                   ^
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino: In function 'void loop()':
sketch_sep22a:12: error: 'set' was not declared in this scope
   if (set == true) {
       ^
sketch_sep22a:13: error: 'timeold' was not declared in this scope
     timeold = timenew;
     ^
sketch_sep22a:13: error: 'timenew' was not declared in this scope
     timeold = timenew;
               ^
sketch_sep22a:15: error: 'rpm1' was not declared in this scope
     rpm1 = double(double(enc_count1) * double(333333.33 / (timenew - timeold))); //60000000/180=333333,33
     ^
sketch_sep22a:15: error: 'enc_count1' was not declared in this scope
     rpm1 = double(double(enc_count1) * double(333333.33 / (timenew - timeold))); //60000000/180=333333,33
                          ^
sketch_sep22a:20: error: 'PIN_OUTPUT' was not declared in this scope
   analogWrite(PIN_OUTPUT, 100);
               ^
/Users/john/Documents/Arduino/sketch_sep22a/sketch_sep22a.ino: In function 'void count1()':
sketch_sep22a:25: error: 'set' was not declared in this scope
   set = true;
   ^
sketch_sep22a:30: error: 'enc_count1' was not declared in this scope
   enc_count1 = enc_count1 + lookup_table[enc_val1 & 0b1111];
   ^
exit status 1
'set' was not declared in this scope

Can you please give examples of the output "with zeroes in it" and output without zeroes in it ?

Do you mean leading zeroes and if so, do they matter when using the value in a numerical comparison ?

As stated above, the code you posted is not complete and won’t compile. Please fix that.

I’m gonna guess that ‘set’ and ‘enc_count1’ are global and shared between the ISR and loop().

Make sure you declared them as volatile. Also, the block of code in loop() that accesses the shared variables should be surrounded by a noInterrupts() / interrupts() pair. Then, rearrange loop() so that you do the minimal amount of stuff while interrupts are disabled. Don’t use Serial.print() until interrupts are enabled again:

void loop() {
  int tempCount;
  unsigned long tempTime;
  if (set==true) {
    noInterrupts();
    tempTime = millis();    
    tempCount = enc_count1;
    set = false;
    enc_count1 = 0;
    interrupts();

    timeold = timenew;
    timenew = tempTime;
    rpm = some function of tempCount, timeold, timenew;
    Serial.println(rpm1);
  }
}

Sorry for the missing declarations:

unsigned long timeold, timenew;
volatile long enc_count1=0;
bool set=false;
double rpm1=0;
double rpm_mittel1=0;

void setup() {
Serial.begin(115200);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), count1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), count1, CHANGE);
TCCR1B = TCCR1B & B11111000 | B00000001; 

}

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

   if(set==true){
    
    timeold = timenew;
    timenew = micros();
    rpm1 = double(double(enc_count1) * double(333333.33 / (timenew - timeold))); //60000000/180=333333,33
    set=false;
    Serial.println(rpm1);
    enc_count1=0;
      }
   
  analogWrite(6,100);

}

void count1()//ISR für den Hallsensor
{
  set=true;
  static int8_t lookup_table[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
  static uint8_t enc_val1 = 0;
  enc_val1 = enc_val1 << 2;
  enc_val1 = enc_val1 | ((PIND & 0b1100) >> 2);
  enc_count1 = enc_count1 + lookup_table[enc_val1 & 0b1111];
  
  
}

Hey,
gfvalvo thanks for the reminder of volatile. I forgot to declare the set variable as volatile. Now it works. Thanks you guys so much

you need to code what has been suggested in #4 about the interrupt as well. You have a critical section where you use things that can be modified behind your back during the math.