Pages: [1]   Go Down
Author Topic: Can 'blocked' code miss an interrupt?  (Read 521 times)
0 Members and 1 Guest are viewing this topic.
Lindenwold, NJ USA
Offline Offline
Jr. Member
**
Karma: 2
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a stepper motor running in a bit-banger tight loop to give a "JOG" mode.   A button is tied to INT0, and on the first press the loop is entered and the motor starts to run. On the second button press, the flag is set to false and it should stop.
The loop is (basically) like this psuedo code:

while (jogging) {
 do steps
}

The var jogging is a pointer to the var in the main program, which on the first button press is set to true, and the jog function is called, and the motor starts running.  When I do the second press, it just sets that var FALSE - but the motor won't stop.

I know the function (a library class I wrote) is reading the 'joggging' flag because if set it false to start - the motor won't run.
It seems that tight loop may be blocking the interrupt as well...   Is this true?

I'm using an AttachInterrupt to tie the button press the the jog function - is there some other way I could do this?

=Alan R.
Logged

+++++++++++++++++++++++++++++++++++++
The completion date of a software project is 2 weeks from any given date.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 651
Posts: 50845
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It seems that tight loop may be blocking the interrupt as well...   Is this true?
No. The interrupt happens, and then your code resumes running. Why you don't notice it is a mystery, as you posted no code.

Quote
I'm using an AttachInterrupt to tie the button press the the jog function - is there some other way I could do this?
Maybe. Without seeing your code, any advice would be worthless.
Logged

USA
Offline Offline
Jr. Member
**
Karma: 4
Posts: 92
If you can't fix it with a hammer, it must be an electrical problem.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Buttom bounce issue?
Logged


Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 362
Posts: 17305
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buttom bounce issue?

Or floating input wiring for the button. But first the code should be reviewed and if found not wanting then describe how you have the button wired, pull-up/pull-down etc.

 If you are attaching using a high or low trigger that can screw the pouch.
Logged

Lindenwold, NJ USA
Offline Offline
Jr. Member
**
Karma: 2
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok - here is the whole situation - hope this extra detail will help.

Interrupted being blocked?

There is a main project with several sketches.  There is also a libarary I created to handle the Big Easy Driver.  The code works to start the motor (all other functs work - no major coding issues) but will not respond to the toggled boolean and stop.

The switch is wired with a 10k pullup, but not debounced, and tied to Arduino pin 2 which is the pin for INT0.  In this instance I don't think debouncing is a BIG issue as I'd see the motor attemtping to stat/stop/start/stop if it was responding to bounces when the switch is pressed.  I suspect in some way the interrupt is being blocked when in that while-loop in the libary.  Here is a condensed overview of the situtation, with real code fragments:

Code:
// In the project:

bool jogging = false;
bool *jogflag = &jogging.

//in setup:

AttachInterrupt(0,BM_Jog,FALLING);

// In project, the BM_Jog function (which is the ISR for INT0) is:

void BM_Jog() {
jogging == true ? jogging = false : jogging = true;  // Toggle jog mode

if(!jogging) {
MotorState = MOTOR_STEPPING;
jogging = true;
long rpm = 4;
BEDMotor.Jog(rpm,jogflag);
}
}

// In the Library code here is the BEDMotor.jog func:

void BEDstep::Jog(int rpm, boolean *jogflag) {
long mdelay = rpm * rpmspeed[cur_rpmspeed];
while(*jogflag == true) {
digitalWrite(S_PIN, HIGH);
delayMicroseconds(mdelay);

digitalWrite(S_PIN, LOW);
delayMicroseconds(mdelay);
}
}
Logged

+++++++++++++++++++++++++++++++++++++
The completion date of a software project is 2 weeks from any given date.

0
Offline Offline
Shannon Member
****
Karma: 220
Posts: 12700
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are not debouncing the button in software, so it had better be debounced in hardware!

Your interrupt routine is calling Jog which has the very while loop that is blocking -
absolute no-no, interrupt routine must simply exit, nothing else can happen till it does.
You communicate between interrupt routine and the rest of the program with variables
declared volatile.  Interrupts are asynchronous, and block other interrupts until you
return from the ISR.

You don't need an interrupt to read a button, interrupts are for fast urgent events,
not something on a human timescale.

Also this is amusing:
Code:
jogging == true ? jogging = false : jogging = true;  // Toggle jog mode
when you realise there's a logical not operator:
Code:
jogging = !jogging ;
Logged

[ I won't respond to messages, use the forum please ]

Northern Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am a big fan of hardware debouncing.  A low pass filter with a schmidtt trigger makes for a very clean signal.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26621
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
jogging == true ? jogging = false : jogging = true;
Or, more succinctly
Code:
jogging = ! jogging;
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Full Member
***
Karma: 3
Posts: 114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I notice that the variable jogging is used in both the main program and in the interrupt service routine.  Such variables should be declared volatile, as in

Code:
volatile bool jogging = false;

As far as I know, accessing jogging via a pointer does not eliminate this requirement.
Logged

Lindenwold, NJ USA
Offline Offline
Jr. Member
**
Karma: 2
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am aware of the 'volatile' construct. However when I tried to use it, "C" complained and wouldn't accept it!  I'm using Visual Studio 2013 with the Visual Micro add-on.  Overall it works pretty good, but maybe it is throwing a 'false positive' in this case.  When I get back I'll retry that is the way it should be done.

I changed the flag-toggle to a more explicit way just in case I had the ! = version wrong!

Switch bounce is not to be taken lightly, but in this case it isn't as bad an issue. The motor starts fine, but simply will not stop. Even if the switch was bouncing, with a firm finger press at least one of the bounces should get thru and stop the motor.    smiley-lol   I'm wondering if that tight loop is causing the Arduino to block and miss the interrupts...  Next I may put an LED on and use that as a 'breakpoint-light' to show where I am!  The Visual Micro debugger won't break there, and I put a manual Serial.Print in the main code where the 'jogging' flag is toggled, and it never prints, so it seems the code may be stuck in that loop.

=A.
Logged

+++++++++++++++++++++++++++++++++++++
The completion date of a software project is 2 weeks from any given date.

London
Offline Offline
Edison Member
*
Karma: 48
Posts: 1526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As MarkT said:
You don't need an interrupt to read a button, interrupts are for fast urgent events, not something on a human timescale.
Logged

0
Offline Offline
Shannon Member
****
Karma: 220
Posts: 12700
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm wondering if that tight loop is causing the Arduino to block and miss the interrupts...

I thought I'd made it perfectly clear YOU MUST NOT WAIT WHILE IN AN ISR!!
The presence of a while loop in code called from an ISR should ring alarm bells immediately.

Do your waiting in loop().  Interrupts are only blocked when you explicitly disabled them or are in an ISR already.
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: