Hey, I'm currently working on a mini project. Essentially with this code, when the run/stop button is pressed it will ramp up/down a motor to a to a set speed/off. I am struggling with the intterupt for this. Also I have an emergency stop button which seems to work but I am trying to cut out the debouncing of the button, what would be the best way of going about that?
#define DEBUG_MODE
#define MOTOR_DRIVE 11 // Motor output PWM on Pin 11
#define E_STOP 2 // Emergency Stop on Pin 2
#define RUN_STOP 3 // Start/Stop on Pin 3
#define PMAX 255 // MAX Power 100%
#define RAMP_DELAY int(10000/PMAX) // Ten Second Ramp Time
int state = 0;
volatile int stop = 0;
void setup() {
#ifdef DEBUG_MODE
Serial.begin(9600);
Serial.println("Setup initiated");
#endif
pinMode(MOTOR_DRIVE, OUTPUT);
pinMode(E_STOP, INPUT_PULLUP);
pinMode(RUN_STOP, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(E_STOP), emerStop, FALLING);
attachInterrupt(digitalPinToInterrupt(RUN_STOP), runStop, FALLING);
#ifdef DEBUG_MODE
Serial.println("Setup complete");
#endif
}
void loop() {
if (digitalRead(RUN_STOP) == 0) {
#ifdef DEBUG_MODE
Serial.println("Run/Stop button pressed");
#endif
for (int i = 0; (i <= PMAX-1) && (i >= 1) ; i+=state)
{
if (stop)
{
#ifdef DEBUG_MODE
Serial.println("Emergency stop interrupt - shutting off motor");
#endif
digitalWrite(MOTOR_DRIVE, 0);
state = 0;
break;
}
if (state == 1)
{
analogWrite(MOTOR_DRIVE, i);
}
else
{
analogWrite(MOTOR_DRIVE, PMAX - i);
}
delay(RAMP_DELAY);
}
#ifdef DEBUG_MODE
Serial.println("Ramp up/down finished");
#endif
}
}
void runStop()
{
if (state == 1)
{
state = -1;
}
else
{
state = 1;
}
}
void emerStop()
{
#ifdef DEBUG_MODE
Serial.println("Debouncing test");
#endif
stop = 1;
}
Agree. The same idea I outlined can be deployed w/o using interrupts, and since the interrupt itself isn’t cutting power to the bomb, or whatever, reaction can be just as rapid.
void runStop()
{
//static so it lingers even when ISR finishes
static uint32_t lastInt = 0ul;
//get millis count now
uint32_t tNow = millis();
//if less than 20mS since last handled interrupt, just leave (i.e. ignore bouncing)
if( (tNow - lastInt) <= 20ul )
return;
//your logic is unchanged
if (state == 1)
{
state = -1;
}
else
{
state = 1;
}
//save the time of this handled interrupt for next debounce check
lastInt = tNow;
}//runStop
Some might suggest that s/he is going about stuffing your brain with items of knowledge in a suboptimal order.
A very high percentage of projects can be done without interrupts. I think they are best learned in the context of being essential to achieving success, and only used when they are. Indispensable.
But never mind, we go with the requirements of your assignment.