attachinterrupt problem

i have a problem..
i have 2 pushbutton 1= for rpm speed counter and 2 is for motor control PMW
if i run pushbutton 1 with no push the 2 the attachinterrupt works FINE!
if i run first pushbutton 2 and after pushbutton 1 the attachinterrupt going a crazy number ?

my code

#include <LiquidCrystal.h>
int ledPin = 13; //IR TX
int readrpm;
int rpmpin = 6; //pushbutton 1
int inPin = 4; ///pushbutton 2
int state = 0;
int reading;
int previous = LOW;
long time = 0;
long debounce = 200;
int counter = 0;
int count = 0;
const int analogInPin = A0;
const int analogOutPin = 5;
int sensorValue = 0;
int outputValue = 0;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
volatile float timer = 0;
volatile float time_last = 0;
volatile int rpm_array[5] = { 0,0,0,0,0};

void setup() {
lcd.begin(16, 2);
pinMode(inPin, INPUT);
pinMode(rpmpin, INPUT);
attachInterrupt(0, fan_interrupt, FALLING);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
}

void loop() {
readrpm = digitalRead(rpmpin);
if (readrpm == HIGH)
rpms();
reading = digitalRead(inPin);
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == 1){
state = 0;
}
else {
state = 1;
}

time = millis();
}
if (state == 1){
sensorValue = analogRead(analogInPin);
}
else {
sensorValue = 0;
}
outputValue = map(sensorValue, 0, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);
float resistor = sensorValue * (10.0 / 1023.0);
float pulseRatio = (outputValue * (10000.0 / 255.0))/100.0;
float volt = outputValue * (5.0 / 255.0);
lcd.setCursor(0, 0);
lcd.print(F("Rin = "));
lcd.print(resistor);
lcd.print(F(" Kohm "));
lcd.setCursor(0, 1);
lcd.print(F("PWM = "));
lcd.print(int(pulseRatio));
lcd.print(F(" % "));
delay(350);
if (counter == 35){
lcd.clear();
while (count < 2 ){
for (int i=16; i > 0; i--)
{
readrpm = digitalRead(rpmpin);
if (readrpm == HIGH)
rpms();
reading = digitalRead(inPin);
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == 1){
state = 0;
}
else {
state = 1;
}

time = millis();
}
if (state == 1){
sensorValue = analogRead(analogInPin);
}
else {
sensorValue = 0;
}
outputValue = map(sensorValue, 0, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);
float volt = outputValue * (5.0 / 255.0);
lcd.setCursor(0, 0);
lcd.print(F("PWMout = "));
lcd.print(volt);
lcd.print(F(" V "));
lcd.setCursor(i, 1);
lcd.print(F("|Stratos r00t| "));
delay(400);
}

lcd.clear();
previous = reading;
count++;
if (count == 2){
counter = 0;
}
//delay(300);
}
count = 0;
lcd.clear();
}
previous = reading;
counter++;
}
void rpms() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Curent RPM : "));
int rpm = 0;

while(1){

//Slow Down The LCD Display Updates
delay(400);

//Clear The Bottom Row
lcd.setCursor(0, 1);
lcd.print(" ");

//Update The Rpm Count
lcd.setCursor(0, 1);
lcd.print(rpm);

////lcd.setCursor(6, 1);
////lcd.print(timer);

//Update The RPM
if(timer > 0)
{
//5 Sample Moving Average To Smooth Out The Data
rpm_array[0] = rpm_array[1];
rpm_array[1] = rpm_array[2];
rpm_array[2] = rpm_array[3];
rpm_array[3] = rpm_array[4];
rpm_array[4] = 60*(1000000/(timer*7)); //7 is the blade of the fan
//Last 5 Average RPM Counts Eqauls....
rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;
}
readrpm = digitalRead(rpmpin);
if (readrpm == HIGH)
return;
}

}

//Capture The IR Break-Beam Interrupt
void fan_interrupt()
{
timer = (micros() - time_last);
time_last = micros();
}

can anyone help me ?
thanks :slight_smile:

volatile float timer = 0;
volatile float time_last = 0;

These should not be floats they should - look it up in the spec of micros().

Mark

Please put your code inside [ code ] [ /code ] tags so that it displays correctly. You can do that by editing your post, selecting the code with the mouse and then clicking the # button in the edit window.

Which Arduino board are you using?

How are your switches wired, and how is the signal source connected to your Arduino?

#include <LiquidCrystal.h>
int ledPin = 13;
int readrpm;
int rpmpin = 6;
int inPin = 4;
int state = 0;
int reading;
int previous = LOW;
long time = 0;
long debounce = 200;
int counter = 0;
int count = 0;
const int analogInPin = A0;
const int analogOutPin = 5;
int sensorValue = 0;
int outputValue = 0;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
volatile float timer = 0;
volatile float time_last = 0;
volatile int rpm_array[5] = {
  0,0,0,0,0};

void setup() {
  lcd.begin(16, 2);
  pinMode(inPin, INPUT);
  pinMode(rpmpin, INPUT);
  attachInterrupt(0, fan_interrupt, FALLING);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  readrpm = digitalRead(rpmpin);
  if (readrpm == HIGH)
    rpms();
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == 1){
      state = 0;
    }
    else {
      state = 1;
    }

    time = millis();    
  }
  if (state == 1){
    sensorValue = analogRead(analogInPin);
  }
  else {
    sensorValue = 0;
  }
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  analogWrite(analogOutPin, outputValue);
  float resistor = sensorValue * (10.0 / 1023.0);
  float pulseRatio = (outputValue * (10000.0 / 255.0))/100.0;
  float volt = outputValue * (5.0 / 255.0);
  lcd.setCursor(0, 0);
  lcd.print(F("Rin = "));
  lcd.print(resistor);
  lcd.print(F(" Kohm "));
  lcd.setCursor(0, 1);
  lcd.print(F("PWM = "));
  lcd.print(int(pulseRatio));
  lcd.print(F(" %  "));
  delay(350); 
  if (counter == 35){
    lcd.clear();
    while (count < 2 ){
      for (int i=16; i > 0; i--)
      {     
        readrpm = digitalRead(rpmpin);
        if (readrpm == HIGH)
          rpms();
        reading = digitalRead(inPin);
        if (reading == HIGH && previous == LOW && millis() - time > debounce) {
          if (state == 1){
            state = 0;
          }
          else {
            state = 1;
          }

          time = millis();    
        }
        if (state == 1){
          sensorValue = analogRead(analogInPin);
        }
        else {
          sensorValue = 0;
        }
        outputValue = map(sensorValue, 0, 1023, 0, 255);
        analogWrite(analogOutPin, outputValue);
        float volt = outputValue * (5.0 / 255.0);
        lcd.setCursor(0, 0);
        lcd.print(F("PWMout = "));
        lcd.print(volt);
        lcd.print(F(" V "));
        lcd.setCursor(i, 1);
        lcd.print(F("|Stratos r00t| "));
        delay(400);
      }

      lcd.clear();
      previous = reading;
      count++;
      if (count == 2){
        counter = 0;  
      }
      //delay(300);  
    }    
    count = 0;   
    lcd.clear();
  }
  previous = reading;
  counter++;
}
void rpms() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Curent RPM : "));
  int rpm = 0;

  while(1){    

    //Slow Down The LCD Display Updates
    delay(400);

    //Clear The Bottom Row
    lcd.setCursor(0, 1);
    lcd.print("                ");   

    //Update The Rpm Count
    lcd.setCursor(0, 1);
    lcd.print(rpm);   

    ////lcd.setCursor(6, 1);
    ////lcd.print(timer);   

    //Update The RPM
    if(timer > 0)
    {
      //5 Sample Moving Average To Smooth Out The Data
      rpm_array[0] = rpm_array[1];
      rpm_array[1] = rpm_array[2];
      rpm_array[2] = rpm_array[3];
      rpm_array[3] = rpm_array[4];
      rpm_array[4] = 60*(1000000/(timer*7)); //7 is the blade of the fan    
      //Last 5 Average RPM Counts Eqauls....
      rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;
    }
    readrpm = digitalRead(rpmpin);
    if (readrpm == HIGH)
      return;
  }

}

//Capture The IR Break-Beam Interrupt
void fan_interrupt()
{
  timer = (micros() - time_last); 
  time_last = micros();
}

i have arduino uno . the signal is from ir phototranzistor.. and the wire for button is the clasic wire 10k .. the button play ok with no problem the problem is in my code with te interrupt ...

holmes4 : you have right i have number with (-) but only with 2 button push ... if i push only the button with rpm meter they haven got a problem....

if i run first the motor PMW control button and after the rpm speed button there is the problem with the micros..they puts crazy number ..

i have arduino uno . the signal is from ir phototranzistor.. and the wire for button is the clasic wire 10k .. the button play ok with no problem the problem is in my code with te interrupt ...
[/quote]

Your use of floats is obviously wrong and should be corrected to use unsigned long, but at this stage I wouldn't assume the main issue is a software problem. What circuit do you have connected to the interrupt pin (2)?

and with this code.. if i run only this code work perfect but the interrupt have problem if i run some other with this !
i use now unsigned long but i have the same resault .. with the PMW control make some crazy !

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
int ledPin = 13;    
volatile float time = 0;
volatile float time_last = 0;
volatile int rpm_array[5] = {0,0,0,0,0};

void setup()
{
  //Digital Pin 2 Set As An Interrupt
  pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, HIGH);
 attachInterrupt(0, fan_interrupt, FALLING);

  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Current RPM:");
}

//Main Loop To Calculate RPM and Update LCD Display
void loop()
{
  int rpm = 0;
  
  while(1){    

     //Slow Down The LCD Display Updates
  delay(400);
  
  //Clear The Bottom Row
  lcd.setCursor(0, 1);
  lcd.print("                ");   
  
  //Update The Rpm Count
  lcd.setCursor(0, 1);
  lcd.print(rpm);   

  ////lcd.setCursor(4, 1);
  ////lcd.print(time);   

  //Update The RPM
  if(time > 0)
  {
    //5 Sample Moving Average To Smooth Out The Data
      rpm_array[0] = rpm_array[1];
      rpm_array[1] = rpm_array[2];
      rpm_array[2] = rpm_array[3];
      rpm_array[3] = rpm_array[4];
      rpm_array[4] = 60*(1000000/(time*7)); //7 is the blade of the fan    
    //Last 5 Average RPM Counts Eqauls....
      rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;
  }
 
 }
}

//Capture The IR Break-Beam Interrupt
void fan_interrupt()
{
   time = (micros() - time_last); 
   time_last = micros();
}

peiperakos:
i use now unsigned long but i have the same resault

The code you posted still uses float variables for time. If you've corrected that and still got a problem, please post your corrected code.

You still haven't explained what circuit you have connected to pin 2 which is triggering the interrupts.

peter i upload an image i have wire just is it :slight_smile: is an IR phototrazistor..

#include <LiquidCrystal.h>
int ledPin = 13;
int readrpm;
int rpmpin = 6;
int inPin = 4;
int state = 0;
int reading;
int previous = LOW;
long time = 0;
long debounce = 200;
int counter = 0;
int count = 0;
const int analogInPin = A0;
const int analogOutPin = 5;
int sensorValue = 0;
int outputValue = 0;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
volatile unsigned long timer = 0;
volatile unsigned long time_last = 0;
volatile unsigned long rpm_array[5] = {0,0,0,0,0};

void setup() {
  lcd.begin(16, 2);
  pinMode(inPin, INPUT);
  pinMode(rpmpin, INPUT);
  attachInterrupt(0, fan_interrupt, FALLING);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  readrpm = digitalRead(rpmpin);
  if (readrpm == HIGH)
    rpms();
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == 1){
      state = 0;
    }
    else {
      state = 1;
    }

    time = millis();    
  }
  if (state == 1){
    sensorValue = analogRead(analogInPin);
  }
  else {
    sensorValue = 0;
  }
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  analogWrite(analogOutPin, outputValue);
  float resistor = sensorValue * (10.0 / 1023.0);
  float pulseRatio = (outputValue * (10000.0 / 255.0))/100.0;
  float volt = outputValue * (5.0 / 255.0);
  lcd.setCursor(0, 0);
  lcd.print(F("Rin = "));
  lcd.print(resistor);
  lcd.print(F(" Kohm "));
  lcd.setCursor(0, 1);
  lcd.print(F("PWM = "));
  lcd.print(int(pulseRatio));
  lcd.print(F(" %  "));
  delay(350); 
  if (counter == 35){
    lcd.clear();
    while (count < 2 ){
      for (int i=16; i > 0; i--)
      {     
        readrpm = digitalRead(rpmpin);
        if (readrpm == HIGH)
          rpms();
        reading = digitalRead(inPin);
        if (reading == HIGH && previous == LOW && millis() - time > debounce) {
          if (state == 1){
            state = 0;
          }
          else {
            state = 1;
          }

          time = millis();    
        }
        if (state == 1){
          sensorValue = analogRead(analogInPin);
        }
        else {
          sensorValue = 0;
        }
        outputValue = map(sensorValue, 0, 1023, 0, 255);
        analogWrite(analogOutPin, outputValue);
        float volt = outputValue * (5.0 / 255.0);
        lcd.setCursor(0, 0);
        lcd.print(F("PWMout = "));
        lcd.print(volt);
        lcd.print(F(" V "));
        lcd.setCursor(i, 1);
        lcd.print(F("|Stratos r00t| "));
        delay(400);
      }

      lcd.clear();
      previous = reading;
      count++;
      if (count == 2){
        counter = 0;  
      }
      //delay(300);  
    }    
    count = 0;   
    lcd.clear();
  }
  previous = reading;
  counter++;
}
void rpms() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("Curent RPM : "));
  int rpm = 0;

  while(1){    

    //Slow Down The LCD Display Updates
    delay(400);

    //Clear The Bottom Row
    lcd.setCursor(0, 1);
    lcd.print("                ");   

    //Update The Rpm Count
    lcd.setCursor(0, 1);
    lcd.print(rpm);   

    ////lcd.setCursor(6, 1);
    ////lcd.print(timer);   

    //Update The RPM
    if(timer > 0)
    {
      //5 Sample Moving Average To Smooth Out The Data
      rpm_array[0] = rpm_array[1];
      rpm_array[1] = rpm_array[2];
      rpm_array[2] = rpm_array[3];
      rpm_array[3] = rpm_array[4];
      rpm_array[4] = 60*(1000000/(timer*7)); //7 is the blade of the fan    
      //Last 5 Average RPM Counts Eqauls....
      rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;
    }
    readrpm = digitalRead(rpmpin);
    if (readrpm == HIGH)
      return;
  }

}

//Capture The IR Break-Beam Interrupt
void fan_interrupt()
{
  timer = (micros() - time_last); 
  time_last = micros();
}

Hard to judge, but you seem to have failed to keep the previous = reading;
statements all in the right place - this needs to be done immediately after each
if-statement testing reading and previous.

You have two slabs of identical code in loop to do with this inPin handling, place this
in a separate function and make the code more readable - in general a function more than
20 lines long is a candidate for breaking down into smaller functions.

Something like:

int check_state ()
{
  int reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce)
  {
    state = 1 - state ;
    time = millis();    
  }
  previous = reading ;
  return state ;
}

I haven't looked at the whole circuit, but the part relating to the optical diode looks OK. I notice you don't show a series resistor for the LED emitter on pi 13 - do you have one?

There is quite a lot of code duplication as MarkT pointed out - I suggest you take his advice to eliminate the duplication. I haven't seen how that would cause the symptoms you describe, but the logic is quite convoluted and there could easily be a bug in the duplicated code which is causing this problem.

I notice that the main effect of the second pushbutton is to toggle the value of state - when it is 1 this also triggers reading of the analog input and some calculations and output based on that. Was this processing intended to happen repeatedly after that, or just once per button press?

I also noticed that you call rpms() when the rpmpin state is HIGH, and rpms() returns as soon as rpmpin state is HIGH which means it's likely to return immediately in most cases. Was that what you were trying to achieve, and if so what's the purpose of the while loop in rpms()?