0

The INT0 pin of a custom Arduino-like board based on Atmega16 is configured in INPUT_PULLUP mode and connected to a N.O contact of a limit switch, the other end of the switch is connected to GND.

in the main loop an ac motor is activated each hour, and stops when hitting the limit switch:

void loop()
{
.....
.....
if((millis() - lastT) >= ONE_HOUR) {
    GICR &= 0xBF;  //disable INT0 interrupt
    digitalWrite(MOTOR_PIN, HIGH);
    lastT = millis();
  }
delay(5000); //time for motor to quit the limit switch
GICR |= 0x40;  //enable INT0 interrupt
.....
.....
}//end of main loop

disabling the INT0 for few seconds allow the time to the motor to release the limit switch because this motor has unpredictable direction of rotation... then the INT0 is re-enabled waiting for the limit switch to be hitted and the ISR to be excuted as INT0 pin becomes Low:

ISR(INT0_vect){
  digitalWrite(MOTOR_PIN, LOW);
  GICR &= 0xBF;  //disable INT0 interrupt
}

the INT0 is disabled to allow the next cycle of the motor after one hour...

the problem is that the motor stops sometimes in the middle before hitting the limit switch and sometimes it continue turning after hitting the limit switch... and the majority of times it work as expected...

I do not understand the reason for this behavior... and what are the elements to check...

EDIT: the full code

#define LIMIT_SWITCH     2       // pd2 (INT0)
#define HEATER_PIN      29       // pc7
#define MOTOR_PIN       27       // pc5

#define  ONE_HOUR (1*60*60*1000)

Si7021 sensor = Si7021();

unsigned long lastT;

float tmp , Setpoint;

void setup()
{
  Serial.begin(9600);
  Setpoint = 37;
  lastT = millis();
  pinMode(MOTOR_PIN, OUTPUT);
  pinMode(LIMIT_SWITCH, INPUT_PULLUP);
  GICR|=0x40;                        // enable INT0 interrupt
  MCUCR=0;
}

ISR(INT0_vect){
  digitalWrite(MOTOR_PIN, LOW);  
  GICR &= 0xBF;                      // disable INT0 interrupt
}

void loop()
{
  tmp = sensor.readTemperature();
  if(tmp>Setpoint + 0.5) digitalWrite(HEATER_PIN, LOW);
  if(tmp<Setpoint - 0.5) digitalWrite(HEATER_PIN, HIGH);
  Serial.println(tmp);

  if((millis() - lastT)>=ONE_HOUR) {
    GICR &= 0xBF;                    // disable INT0 interrupt
    digitalWrite(MOTOR_PIN, HIGH);
    lastT = millis();
  }

  delay(5000);                       // time for motor to quit the limit switch
  GICR |= 0x40;                      // enable INT0 interrupt
}
  • A race condition? Please post a Minimal, Complete, and Verifiable example – Nick Gammon May 19 '18 at 8:28
  • How is the direction of the motor unpredictable? – chrisl May 19 '18 at 17:08
  • @chrisl: excuse my late response... it's a microwave turntable ac motor... unpredictable means that it starts turning in a random direction... – moyoumos May 20 '18 at 10:24
  • I think that the issue comes from the internal pull-up resistor wich i think is insufficient... I connect a 5.5kOhm resistor between INT0 pin and Vcc and until this time everything is OK... – moyoumos May 20 '18 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.