Strange values from math operaiton?

I have a problem with a calculated value. I have to calculate CPM (CountsPerMinute). And i want to have different measurement cycles (10s,5s,2s and so). So i have to calculate the conversion factor

If mesCycle is 5

CPM = counts * x

x = (60/mesCycle)

60/5 is 12, so Counts * 12 becomes CPM

if mes Cycle is 10, then its 60/10

and so on

to test the conversion, i made a serial.print for x.

X remains stable when counts is 0.
if counts are high like, 20 or so, then strange values appear... like 450, 192, 500...

What could be the problem here?

The Important Code parts are here:

Setup..

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
  mesCycle=EEPROM.read(30);
.....
}

loop

void loop() {
unitCalculation();
}

unitCalculation();

  void unitCalculation(){
    if(millis()-lastTimeCycle > (mesCycle*1000)){
      
      lastTimeCycle = millis();
      int count = pulseCount - lastTimeCounts;
      lastTimeCounts = pulseCount;
      cpm = count * (60/mesCycle);
      Serial.print(60/mesCycle);
      Serial.println();
      usv = ( float(cpm) / convfactor);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(cpm);
      lcd.setCursor(13,0);
      lcd.print("CPM");
      lcd.setCursor(0,1);
      lcd.print(usv);
      lcd.setCursor(11,1);
      lcd.print("uSv/h");
    
      
      
      }
  }

It's probably the data types you used but couldn't be bothered to post

Post the entire sketch... The problem is somewhere in it, but you are likely to guess wrongly
where it is if you cannot identify the nature of the problem.

For a start you are seem to be using integer division which is probably inappropriate.

As requested the full code attached

I had to use attachement because message size is only 9000Characters

gktest.ino (9.3 KB)

    if(digitalRead(BT1) == HIGH | digitalRead(BT2) == HIGH |digitalRead(BT3) == HIGH){

I really don't think you want | there. I think you want ||.

void pulseDetected() {
    detachInterrupt(GMPULSE);
    pulseCount++;
    lastDetected = millis();
    digitalWrite(LED, HIGH);
    digitalWrite(SPEAKER, HIGH);
    attachInterrupt(GMPULSE, pulseDetected, RISING);
    }

Detaching and reattaching the interrupt handler is silly.

     cpm = count * (60/mesCycle);

Integer arithmetic is being performed. Is that what you want?

PS. Do yourself, and us, a favor, and learn to use Tools + Auto Format.

PaulS:

    if(digitalRead(BT1) == HIGH | digitalRead(BT2) == HIGH |digitalRead(BT3) == HIGH){

I really don't think you want | there. I think you want ||.

I want to do something if one of the three inputs is pressed.

PaulS:

void pulseDetected() {

detachInterrupt(GMPULSE);
   pulseCount++;
   lastDetected = millis();
   digitalWrite(LED, HIGH);
   digitalWrite(SPEAKER, HIGH);
   attachInterrupt(GMPULSE, pulseDetected, RISING);
   }



Detaching and reattaching the interrupt handler is silly.

I took this from an existing code, they say in the case when another interrupt happens, while the interrupt function is still doing some work, the function will not be finished properly.

Is that false? Could i just delete the detach/attach in the function?

PaulS:

     cpm = count * (60/mesCycle);

Integer arithmetic is being performed. Is that what you want?

PS. Do yourself, and us, a favor, and learn to use Tools + Auto Format.

I want that the number 60 (for 60seconds) is divied by the value that is stored in mesCycle, it can be 1 to 255.

sgt_johnny:
I want that the number 60 (for 60seconds) is divied by the value that is stored in mesCycle, it can be 1 to 255.

you'll get pretty inaccurate results the way you are doing it. You could use integers, but not the way you have it now.

e.g.: 60 / 30 = 2,
60 / 31 = 1
60 / 60 = 1
60 / 61 = 0
60 / 254 = 0

So, use floats, or depending on the possible size of your "count", do the multiplication first, like this:

count * 60 / mesCycle;

(which is the same as: (count * 60) / mesCycle;

Also, put in a bit more debugging to show all values being used in the calculation, and the result. This should let us know what the problem is.

i.e:
print count, mesCycle, cpm for a number of values that show the problem.

arduinodlb:
So, use floats, or depending on the possible size of your "count", do the multiplication first, like this:

count * 60 / mesCycle;

(which is the same as: (count * 60) / mesCycle;

Thank you! Changing CPM to float, and float(mesCycle) it works now perfectly! :slight_smile: