Offline
Newbie
Karma: 0
Posts: 35
|
 |
« on: January 01, 2013, 02:38:36 pm » |
Hey Guys
For some reason my Arduino Nano's Interrupt pin 0 and 1 work really well the FIRST time. Before I implemented Interrupt pin 1 I only had 0 working and I could Interrupt it all I wanted to and how many times I wanted to as well. But for some reason after implementing 1 as well they stop working after I pulsed PIN 1. It does its job and then just goes off and after that neither of the Interrupts work.
Does anyone have an explanation for this?
Thanks guys
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #1 on: January 01, 2013, 02:42:49 pm » |
There's no general explanation for weird behaviour when ISRs are involved.
Post your code.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #2 on: January 01, 2013, 03:10:43 pm » |
Hmm ok heres the Code.
const int led = 13; const int Op1 = 8; const int Op2 = 9; const int Op3 = 10; const int Op4 = 11;
const int bt1 = 2; //Interrupt 0; const int bt2 = 3; //Interrupt 1; int ledState = LOW; int buttonState =0; unsigned long previousMillis = 0,P1=0,P2=0,P3=0,P4=0,PS=0,preInt=0; long interval = 1000; long GTime = 10; int StateFunc =1; int StateFunc2 =0; int ZRan=1,ZCop=1; int i=0; int Enabler=0,Enabler1=0,Enabler2=0,Enabler3=0,Enabler4=0,EnablerS; unsigned long PreMcounter =0; unsigned long MilliCounter =0;
void setup() { // digital pins=output pinMode(led, OUTPUT); pinMode(Op1, OUTPUT); pinMode(Op2, OUTPUT); pinMode(Op3, OUTPUT); pinMode(Op4, OUTPUT); pinMode(bt1, INPUT); pinMode(bt2, INPUT); attachInterrupt(0, SC, LOW); attachInterrupt(1, Func, LOW); } void loop() {
switch (ZRan) { case 1: { if (StateFunc == 1) { Flash(); Op1F(1000); break; } else{ digitalWrite(Op1, LOW); break; } } //-------------------------------- case 2: { if (StateFunc == 1) { Flash(); Op2F(1000); break; } else{ digitalWrite(Op2, LOW); break; } } //-------------------------------- case 3: { if (StateFunc == 1) { Flash(); Op3F(1000); break; } else{ digitalWrite(Op3, LOW); break; } } //-------------------------------- case 4: { if (StateFunc == 1) { Flash(); Op4F(1000); break; } else{ digitalWrite(Op4, LOW); break; } //------------------------------- case 5: { if (StateFunc == 2) { ZCop = ZRan; Op1F(10000); break; } } } //-------------------------------- } Flash(); } //---------------------------------------------------------------------------- //Special Zone function on Op1 int ZoneSpec1(int c) { if (EnablerS==0) { PS = millis(); EnablerS=1; } unsigned long curMS = millis(); if(curMS - PS < c) { digitalWrite(Op1, HIGH); digitalWrite(Op2, LOW); digitalWrite(Op3, LOW); digitalWrite(Op4, LOW); } else { digitalWrite(Op1, LOW); EnablerS =0; StateFunc = 0; } }
//---------------------------------------------------------------------------- //Zone Functions int Op1F(int c) { if (Enabler1==0) { P1 = millis(); Enabler1=1; } unsigned long curM1 = millis(); if(curM1 - P1 < c) { digitalWrite(Op1, HIGH); } else { digitalWrite(Op1, LOW); Enabler1 =0; ZRan = 2; } } //--------------------------------------------------------------------------------- int Op2F(int c) { if (Enabler2==0) { P2 = millis(); Enabler2=1; } unsigned long curM2 = millis(); if(curM2 - P2 < c) { digitalWrite(Op2, HIGH); } else { digitalWrite(Op2, LOW); Enabler2 =0; ZRan = 3; } } //----------------------------------------------------------------------------------- int Op3F(int c) { if (Enabler3==0) { P3 = millis(); Enabler3=1; } unsigned long curM3 = millis(); if(curM3 - P3 < c) { digitalWrite(Op3, HIGH); } else { digitalWrite(Op3, LOW); Enabler3 = 0; ZRan = 4; } } //------------------------------------------------------------------------------------- int Op4F(int c) { if (Enabler4==0) { P4 = millis(); Enabler4=1; } unsigned long curM4 = millis(); if(curM4 - P4 < c) { digitalWrite(Op4, HIGH); } else { digitalWrite(Op4, LOW); Enabler4 =0; ZRan = 1; StateFunc = 0; } } //--------------------------------------------------------------------------------------------- //LEDBlink Storie void Flash() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: if (ledState == LOW) ledState = HIGH; else ledState = LOW; // set the LED with the ledState of the variable: digitalWrite(led, ledState);
} } //---------------------------------------------------------------------------------------------- //PORTED CODE ! void Func() { ZCop = ZRan; if (StateFunc == 0) { StateFunc = 2; ZRan = 5; // digitalWrite(led, HIGH); } else if(StateFunc == 1) { StateFunc = 2; ZRan = 5; // digitalWrite(led, LOW); } }
/* void StateFunc(int x) { for (int i=0;i<x+1;i++) { if (StateFunc == 1) {} else if(StateFunc == 0) {break;} } }*/
/* int Op1F(int c) { unsigned long preM = previousMillis; unsigned long curM = millis(); if ((curM - preM) <= c) { curM = millis(); digitalWrite(Op1, HIGH); //SC(); ZRan = 1; previousMillis = preM; } else if ((curM - preM) > c) { digitalWrite(Op1, LOW); //SC() ZRan = 2; previousMillis = preM; } } */ void SC() { if (StateFunc == 0) { StateFunc = 1; Enabler =0; // digitalWrite(led, HIGH); } else if(StateFunc == 1) { StateFunc = 0; //digitalWrite(led, LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #3 on: January 01, 2013, 03:11:45 pm » |
Hey Tux,
Finally my Code seems to work accept for the Interrupt that seems to just stop every other interrupt from ever happening again.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #4 on: January 01, 2013, 04:11:12 pm » |
I'm sorry but I don't understand your code.
You could make it more readable: Press CTRL-T to have better indentation. Use variable names that describe their role or function.
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4641
|
 |
« Reply #5 on: January 01, 2013, 04:51:15 pm » |
What is driving the interrupt input pins? It may be that you should use interrupt mode FALLING instead of LOW.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #6 on: January 01, 2013, 05:08:45 pm » |
Well at the moment Im literally using my hand and a grounded wire. Sometimes I interrupt it like 3 times to fast for my hand. Still looking for a way around that though. How would I smooth out reoccurring interrupts? Even with LOW replaced with FALLING it still seems to do the same 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #7 on: January 01, 2013, 05:42:50 pm » |
I tried to remove some excess blank lines and give it a saner indentation... //Interrupt implemenation.
const int led = 13; const int zone1 = 8; const int zone2 = 9; const int zone3 = 10; const int zone4 = 11;
const int in1 = 2; //Interrupt 0; const int in2 = 3; //Interrupt 1; int ledState = LOW; int buttonState =0; unsigned long previousMillis = 0,preM1=0,preM2=0,preM3=0,preM4=0,preMS=0,preInt=0,preUni; long interval = 1000; unsigned long UniTime = 1000; //60*60*60*1000; int StateCheck =1; int StateCheck2 =0; int ZoneCheck=1,ZoneCopy=1; int i=0; int Track=0,Track1=0,Track2=0,Track3=0,Track4=0,TrackS,TrackUni; unsigned long PreMcounter =0; unsigned long MilliCounter =0;
void setup() { // digital pins=output pinMode(led, OUTPUT); pinMode(zone1, OUTPUT); pinMode(zone2, OUTPUT); pinMode(zone3, OUTPUT); pinMode(zone4, OUTPUT); pinMode(in1, INPUT); pinMode(in2, INPUT); attachInterrupt(0, StateChange, LOW); attachInterrupt(1, Check, LOW); }
void loop() { switch (ZoneCheck) { case 1: if (StateCheck == 1) { Flash(); Zone1F(UniTime); } else { digitalWrite(zone1, LOW); } break;
case 2: if (StateCheck == 1) { Flash(); Zone2F(UniTime); } else { digitalWrite(zone2, LOW); } break;
case 3: if (StateCheck == 1) { Flash(); Zone3F(UniTime); } else { digitalWrite(zone3, LOW); } break;
case 4: if (StateCheck == 1) { Flash(); Zone4F(UniTime); } else{ digitalWrite(zone4, LOW); } break;
case 5: if (StateCheck == 2) { ZoneCopy = ZoneCheck; Zone1F(10000); } break; }
Flash(); }
//---------------------------------------------------------------------------- //Special Zone function on Zone1 int ZoneSpec1(int c) { if (TrackS==0) { preMS = millis(); TrackS=1; }
unsigned long curMS = millis(); if(curMS - preMS < c) { digitalWrite(zone1, HIGH); digitalWrite(zone2, LOW); digitalWrite(zone3, LOW); digitalWrite(zone4, LOW);
} else { digitalWrite(zone1, LOW); TrackS =0; StateCheck = 0; } }
//---------------------------------------------------------------------------- //Zone Functions int Zone1F(int c) { if (Track1==0) { preM1 = millis(); Track1=1; }
unsigned long curM1 = millis(); if(curM1 - preM1 < c) { digitalWrite(zone1, HIGH); } else if (curM1 - preM1 > c) { digitalWrite(zone1, LOW); Track1 =0; ZoneCheck = 2; } }
//--------------------------------------------------------------------------------- int Zone2F(int c) { if (Track2==0) { preM2 = millis(); Track2=1; }
unsigned long curM2 = millis(); if(curM2 - preM2 < c) { digitalWrite(zone2, HIGH); } else { digitalWrite(zone2, LOW); Track2 =0; ZoneCheck = 3; } }
//----------------------------------------------------------------------------------- int Zone3F(int c) { if (Track3==0) { preM3 = millis(); Track3=1; }
unsigned long curM3 = millis(); if(curM3 - preM3 < c) { digitalWrite(zone3, HIGH); } else { digitalWrite(zone3, LOW); Track3 = 0; ZoneCheck = 4; } }
//-------------------------------------------------------------------------------------
int Zone4F(int c) { if (Track4==0) { preM4 = millis(); Track4=1; }
unsigned long curM4 = millis(); if(curM4 - preM4 < c) { digitalWrite(zone4, HIGH); } else { digitalWrite(zone4, LOW); Track4 =0; ZoneCheck = 1; StateCheck = 0; }
} //--------------------------------------------------------------------------------------------- //LEDBlink Storie void Flash() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { // save the last time you blinked the LED previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa: if (ledState == LOW) ledState = HIGH; else ledState = LOW;
// set the LED with the ledState of the variable: digitalWrite(led, ledState); } }
//---------------------------------------------------------------------------------------------- //PORTED CODE ! void Check() { ZoneCopy = ZoneCheck; if (StateCheck == 0) { StateCheck = 2; ZoneCheck = 5; // digitalWrite(led, HIGH); detachInterrupt(1); attachInterrupt(1, Check, LOW); } else if(StateCheck == 1) { StateCheck = 2; ZoneCheck = 5; // digitalWrite(led, LOW); detachInterrupt(1); attachInterrupt(1, Check, LOW); } }
//-------------------------------------------------------------------------------------------------- int UniDelay(int c) { int i=0; if (TrackUni==0) { preUni = millis(); TrackUni=1; } int t = (c*10000);
unsigned long curUni = millis(); if(curUni - preUni < t) { i++; } else { TrackUni =0; } } //--------------------------------------------------------------------------------------------------
/* void StateCheck(int x) { for (int i=0;i<x+1;i++) { if (StateCheck == 1) {} else if(StateCheck == 0) {break;} } }*/
/* int Zone1F(int c) { unsigned long preM = previousMillis; unsigned long curM = millis(); if ((curM - preM) <= c) { curM = millis(); digitalWrite(zone1, HIGH); //StateChange(); ZoneCheck = 1; previousMillis = preM; } else if ((curM - preM) > c) { digitalWrite(zone1, LOW); //StateChange() ZoneCheck = 2; previousMillis = preM; } } */
void StateChange() { if (StateCheck == 0) { StateCheck = 1; Track =0; // digitalWrite(led, HIGH); } else if(StateCheck == 1) { StateCheck = 0; //digitalWrite(led, LOW); } }
Uh ? detachInterrupt(1); attachInterrupt(1, Check, LOW); Still quite puzzling code, especially without any comment. You should either add copious comments or describe what you're trying to achieve.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #8 on: January 01, 2013, 06:18:23 pm » |
detachInterrupt(1); attachInterrupt(1, Check, LOW);
Yea sorry this was only something i tried to get the interrupts to work again.Didn't work though.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #9 on: January 01, 2013, 06:21:08 pm » |
I really don't get why the Interrupts will just become useless like that ?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 35
|
 |
« Reply #10 on: January 01, 2013, 06:32:24 pm » |
I just read about Interrupts get stuck in a Dead lock.Causing them to be unresponsive since they're already inside an interrupt but stuck. What can I do to make sure my Interrupts finish and one interrupt doesn't try and interrupt while inside another interrupt? Because this sure sounds like the problem I am having.
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 1
|
 |
« Reply #11 on: January 02, 2013, 05:22:45 pm » |
I too have this problem. My code is much simpler, so maybe this will help: (code fragments)
int rings = 0; ...
void setup(){ ... attachInterrupt(0,offHook,LOW); // Second ring, go off-hook. Ring tone output connected to pin 2 on the Arduino to trip interrupt. It goes low with rings ... }
/* ======== this is the interrupt function call ======= */ void offHook() { rings++; Serial.println(); Serial.print("Incoming rings: "); Serial.println(rings); if(rings == 2) { analogWrite(OH, 0); // Place a low on Off-Hook optical relay to close circuit rings = 0; // Reset rings for next time a call comes in detachInterrupt(0); //Without this line, the code stalls here after doing the analogWrite (Off-Hook LED comes on), but code does not continue. //With this line, the code works fine until the session is over and back On-Hook ready for the next LOW to trip the interrupt. // The interrupt fires twice, because the printout counts rings correctly. Once it reaches 2 the detachInterrupt(0) // breaks back to code as desired, but interrupt never works again in this session. // I've tried adding another attachInterrupt(0,offHook,LOW); statement in the code // before completing a cycle. I've tried adding it in the interrupt function after the detachInterrupt line, and I've tried to // use the noInterrupts(), interrupts() commands to try to revive this interrupt. The only thing that works is a reboot. } } // end interrupt function
This appears to be a Catch-22. You have to use detachInterrupt to get the function to release back to code, but once done, the only recourse is to pass through the setup() function again on reboot.
There must be a simple answer to this, since any programmer needs this functionality. Or a software reset would work. It tried that also and the only way I can control the "reset" pin is through a relay to ground. Any Arduino pin used to go from high-to-low and back high just sets off an endless loop of resets.
In a word: HELP
J. Wolf
|
|
|
|
|
Logged
|
Author of Fantastic Tales
|
|
|
|
California
Online
Edison Member
Karma: 37
Posts: 1827
|
 |
« Reply #12 on: January 02, 2013, 05:28:14 pm » |
I too have this problem. My code is much simpler, so maybe this will help: (code fragments)
Serial prints don't work inside ISRs and any variables that have there value changed inside an ISR need to be declared volatile.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
|
 |
« Reply #13 on: January 02, 2013, 08:32:23 pm » |
Unless one wants to specifically learn about interrupts, my suggestion is to leave them alone until their _theory_ of operation is fully understood. Instead of asking why a particular ISR doesn't work or stalls, it's much better to describe the problem one is trying to solve and ask for help about how to solve it. Chances are interrupts won't be needed in most cases.
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4641
|
 |
« Reply #14 on: January 03, 2013, 01:53:25 am » |
I too have this problem. My code is much simpler, so maybe this will help: (code fragments)
Your problem is caused by a combination of calling Serial.print from an ISR, and using a level-triggered interrupt without removing the source of the interrupt in the ISR. When you exit the ISR, the ring signal will still be low; so the ISR will be re-entered. All those serial prints will fill up the serial buffer, which causes the Serial.print call to block, and it will never return because the serial buffer can't be emptied until interrupts are re-enabled. So you need to do 2 things: 1. Remove the Serial.print calls from the ISR. Instead, set a flag inside the ISR. In loop() watch for the flag to be set; when it is set, do the Serial.print calls and clear it. 2. Use interrupt mode FALLING instead of LOW.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
|