Pages: 1 2 [3] 4   Go Down
Author Topic: LED fade will not listen to IR input for interupt.  (Read 2102 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24457
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
This calls the loop() function.  What is that all about ?
It's all about heartache and hair-loss, that's what it's about.
Even well-controlled recursion is risky on a RAM-limited micro.
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.

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 90
Posts: 3523
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you seen the dictionary definition of recursion ?

"See recursion"
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I am reading your code right you have

Code:
attachInterrupt(pbIn, CheckYellow, HIGH);

pbIn is set to 0 so I interpret that as "call the CheckYellow function when the pin associated with interrupt 0 is HIGH"
Although I freely admit that I am not familiar with interrupts, reading the reference pages I see that interrupt 0 is associated with pin 2 and that the possible values of the third parameter of attachInterrupt() are LOW, CHANGE, RISING OR FALLING.

Have you got anything attached to pin 2 ?
What will happen with the parameter set to HIGH ?

If the interrupt ever causes the CheckYellow function to be called

Code:
void CheckYellow() {
  if (results.value           == 0x96B47 ) {
    loop();
  }
}
This calls the loop() function.  What is that all about ?

Your code won't compile for me because I don't have the library but there are also other errors reported

Code:
sketch_jan16a:69: error: 'IRrecv' does not name a type
sketch_jan16a:70: error: 'decode_results' does not name a type
sketch_jan16a.ino: In function 'void setup()':
sketch_jan16a:76: error: 'irrecv' was not declared in this scope
sketch_jan16a.ino: In function 'void loop()':
sketch_jan16a:80: error: 'irrecv' was not declared in this scope
sketch_jan16a:80: error: 'results' was not declared in this scope
sketch_jan16a.ino: In function 'void CheckYellow()':
sketch_jan16a:184: error: 'results' was not declared in this scope
sketch_jan16a.ino: In function 'void getIR()':
sketch_jan16a:211: error: 'IRrecv' was not declared in this scope
sketch_jan16a:211: error: expected `;' before 'irrecv'
sketch_jan16a:212: error: 'decode_results' was not declared in this scope
sketch_jan16a:212: error: expected `;' before 'nresults'

Your code has got so mangled through attempts to fix problems that it is practically unreadable.  Can I suggest that you create an example of what you want to do, keeping it as simple as possible as I for one cannot see the wood for the trees.

It actually compiles for me with no errors, and it may be because I have extra libraries. Also, I am using compiler version 1.0.1 , not sure if that helps. As far as the interrupt, I have the output pin of the IR receiver going to pin 2, which in a perfect world would register as HIGH the moment I hit a button on the remote. I am trying to keep the interrupt code small, so I wanted it to check and decode looking for only one value, the yellow button.

I tried cleaning the code using some autoit apps I came across, but it keeps stripping out needed operators. I don't have any formal programming training, so this is kind of thrown together by an amateur smiley-wink

As for the WHILE after the IF statement, the only reason I have that is because it will only execute the pattern once and stop otherwise. When I added WHILE, it actually loops the pattern which is what I was going for.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 90
Posts: 3523
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Even with the IRremote library it will not compile for me.  Does the IRremote library depend on others ?

You say that "I have the output pin of the IR receiver going to pin 2"  I cannot see where that is defined in your code, nor can I see a pinMode definition for pin 2.  Have I missed it ?

Cleaning the code with an an autoit app sounds like a nightmare.  Was it written specifically to tidy Arduino code ? What does it try to do ?  Putting each brace on its own line would be a start I suppose.

I don't know what you mean about the WHILE after the IF.  I was questioning calling loop() from the CheckYellow() function though.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


You say that "I have the output pin of the IR receiver going to pin 2"  I cannot see where that is defined in your code, nor can I see a pinMode definition for pin 2.  Have I missed it ?


I was pulling from http://arduino.cc/en/Reference/AttachInterrupt

If I understand it, int.0 is supposed to point to pin 2 on the Arduino Mega. Essentially, i wanted it to perform this logic:

While in the fade, if you see any change in activity on pin2 which is also connected to the emitter of the IR REC, then determine what code is being sent. If the code is the same as my yellow button, then you can jump out of what you are doing, and go back to the loop.

As for the includes, I will get a list of includes i have on my laptop at home and let you know.

My mental logic which is flawed (because if it wasn't, then this would work) indicated that having an interrupt could call this:

Code:
void CheckYellow() {
  if (results.value           == 0x96B47 ) {
    loop();
  }
}

to execute the intended logic above.  I'm sure you can see where I am trying to go with it, I just cant fin that little nitch that would actually make it work. Once I get past this hurdle, I can grow the code to all new heights.

The reason the code looks so complicated is i have so many declarations, it looks like they make up half the script. At the moment, there are 2 fade options, one simple, one complex and configurable. It also has a blink what works exactly as designed, because it uses BlinkWithoutDelay with a built in adjustable speed to make it blink faster or slower based on IR volume buttons up and down, which works great.

I took the fader scripts and tried to remove the delay() and substitute it with the BlinkWithoutDelay method which works great, only during the fade calculations, the IR receiver is ignored, and I am thinking this is because it is busy making calculations, or, it does not see enough reason to interrupt the code and take me back to ground zero in the code.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cleaning the code with an an autoit app sounds like a nightmare.  Was it written specifically to tidy Arduino code ? What does it try to do ?  Putting each brace on its own line would be a start I suppose.

I intend to rewrite the AutoIT code clean/tidy tools to work with C++, but I really want to tackle this first.

It will be as simple as run the EXE, select your ino or other file, then specify where to save it. It will remove empty lines, give the option to remove comments, and fix all tabs.  (and more as the revisions flow)
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the problem with your understanding of the purpose of an interrupt. You're looking at it like the bell at a speed dating event: once you hear it, you stop talking to the person you are talking to and go talk to someone else. In reality, however, an interrupt is more like a doorbell. If you're making dinner and the doorbell rings, you answer the door then go back to making dinner.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the problem with your understanding of the purpose of an interrupt. You're looking at it like the bell at a speed dating event: once you hear it, you stop talking to the person you are talking to and go talk to someone else. In reality, however, an interrupt is more like a doorbell. If you're making dinner and the doorbell rings, you answer the door then go back to making dinner.

Hmm.. Is there a way I can make it more the speed dating type? I was hoping to do this by saying " once the bell rings, see if its yellow, and if it is, stop what you are doing, and call this function"

That is what I hope to do, only because I dont want the code to stop every time it picks up one little Ir blip. Just want it to be able to be interrupted when it sees a certain code come in through IR.
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm.. Is there a way I can make it more the speed dating type?

Not in a way I care to describe.

What you need to do is restructure the bulk of your code so that it doesn't block, and it doesn't use for loop/delays. You want to be polling for data as often as possible. Here is a simple example demonstrating how to do that using a simple LED fade in which the fade up/fade down is determined by the state of a switch.

The first example will not allow you to "interrupt" the fading; you have to let the cycle finish before you can change direction:

Code:
const int ledPin = 13;
const int switchPin = 2;
const unsigned long fadeInterval = 20;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin, INPUT_PULLUP);
}

void loop()
{
  int switchState = digitalRead(switchPin);
  for (int i=0; i<=255; i++)
  {
    if (switchState == HIGH)
      analogWrite(ledPin, i);
    else
      analogWrite(ledPin, 255-i);

    delay(fadeInterval);
  }
}

To allow it to respond more quickly to the switch, you can rewrite it like this:

Code:
const int ledPin = 13;
const int switchPin = 2;
const unsigned long fadeInterval = 20;

unsigned long lastFadeTime = 0;
int pwmValue = 0;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin, INPUT_PULLUP);
}

void loop()
{
  int switchState = digitalRead(switchPin);
  if (millis() - lastFadeTime > fadeInterval)
  {
    lastFadeTime = millis();
    if (switchState == HIGH)
      pwmValue = constrain(pwmValue+1, 0, 255);
    else
      pwmValue = constrain(pwmValue-1, 0, 255);

    analogWrite(ledPin, pwmValue);
  }
}

The latter sketch allows us to poll the switch's state much more often than the former sketch.

*Disclaimer: I didn't compile or test these sketches
« Last Edit: January 16, 2013, 02:24:40 pm by Arrch » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm.. Is there a way I can make it more the speed dating type?

Not in a way I care to describe.

What you need to do is restructure the bulk of your code so that it doesn't block, and it doesn't use for loop/delays. You want to be polling for data as often as possible. Here is a simple example demonstrating how to do that using a simple LED fade in which the fade up/fade down is determined by the state of a switch.

The first example will not allow you to "interrupt" the fading; you have to let the cycle finish before you can change direction:

Code:
const int ledPin = 13;
const int switchPin = 2;
const unsigned long fadeInterval = 20;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin, INPUT_PULLUP);
}

void loop()
{
  int switchState = digitalRead(switchPin);
  for (int i=0; i<=255; i++)
  {
    if (switchState == HIGH)
      analogWrite(ledPin, i);
    else
      analogWrite(ledPin, 255-i);

    delay(fadeInterval);
  }
}

To allow it to respond more quickly to the switch, you can rewrite it like this:

Code:
const int ledPin = 13;
const int switchPin = 2;
const unsigned long fadeInterval = 20;

unsigned long lastFadeTime = 0;
int pwmValue = 0;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin, INPUT_PULLUP);
}

void loop()
{
  int switchState = digitalRead(switchPin);
  if (millis() - lastFadeTime > fadeInterval)
  {
    lastFadeTime = millis();
    if (switchState == HIGH)
      pwmValue = constrain(pwmValue+1, 0, 255);
    else
      pwmValue = constrain(pwmValue-1, 0, 255);

    analogWrite(ledPin, pwmValue);
  }
}

The latter sketch allows us to poll the switch's state much more often than the former sketch.

*Disclaimer: I didn't compile or test these sketches

That is a good explanation, however I am able to have it change speeds, and the switching mechanism according to your code is a physical switch, where I use Infrared.

The goal I am looking to accomplish is, if the IR receiver picks up the code: 0x96B47, it simply resets. That is the simplest form I can put it in, because on reset, there is no longer a previous value to determine what the script should be doing.

Is that possible?

If IR sees 0x96B47, then reset the arduino. While waiting for that code, let the fades work.
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

however I am able to have it change speeds, and the switching mechanism according to your code is a physical switch, where I use Infrared.

Which is why I called it a "simple example" and not "the code to fix your problem". It was simply demonstrate the concept and rewriting code that utilizes methods which cause a delayed response.

Code:
The goal I am looking to accomplish is, if the IR receiver picks up the code: 0x96B47, it simply resets. That is the simplest form I can put it in, because on reset, there is no longer a previous value to determine what the script should be doing.

So you need a state machine. Whenever you receive the "reset" code you set it back to it's original state. It still requires ensuring the concept demonstrated in my last post, except instead of polling a switch, you will be checking the state.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

however I am able to have it change speeds, and the switching mechanism according to your code is a physical switch, where I use Infrared.

Which is why I called it a "simple example" and not "the code to fix your problem". It was simply demonstrate the concept and rewriting code that utilizes methods which cause a delayed response.

Code:
The goal I am looking to accomplish is, if the IR receiver picks up the code: 0x96B47, it simply resets. That is the simplest form I can put it in, because on reset, there is no longer a previous value to determine what the script should be doing.

So you need a state machine. Whenever you receive the "reset" code you set it back to it's original state. It still requires ensuring the concept demonstrated in my last post, except instead of polling a switch, you will be checking the state.

Yes and no...   It would have to look for not only pin 2 to go HIGH, but to see if it brings in a certain value, and if it does, rerun the loop, or reset.. whatever is easier to call.

In the example,
Code:
   if (switchState == HIGH)

would execute the moment any IR signal is picked up.
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes and no...   It would have to look for not only pin 2 to go HIGH, but to see if it brings in a certain value, and if it does, rerun the loop, or reset.. whatever is easier to call.
Neither, you would check the conditions and update the state variable; you can't "rerun" the loop or reset the device.

Quote
In the example,
Code:
  if (switchState == HIGH)

would execute the moment any IR signal is picked up.

Again, it was a simple example to demonstrate the concept of not "pausing code" to allow other code to run frequently; you seem to be focusing on the conditions which were just part of making the example simple, and completely missing the point of the example.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes and no...   It would have to look for not only pin 2 to go HIGH, but to see if it brings in a certain value, and if it does, rerun the loop, or reset.. whatever is easier to call.
Neither, you would check the conditions and update the state variable; you can't "rerun" the loop or reset the device.

Quote
In the example,
Code:
  if (switchState == HIGH)

would execute the moment any IR signal is picked up.

Again, it was a simple example to demonstrate the concept of not "pausing code" to allow other code to run frequently; you seem to be focusing on the conditions which were just part of making the example simple, and completely missing the point of the example.

I understand the theory of having the code check something while it is in the process of a fade, what I am stuck on is actually getting it to work. In theory, it should be polling the IR pin to see if there is any incoming signals and check to see if its the yellow button. If it is the yellow button, the value of "results.value" should change, and it would execute whatever is in the new value. With the code the way it is, it should work, but for some strange reason it doesn't.
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So then post "the code the way it is"
Logged

Pages: 1 2 [3] 4   Go Up
Jump to: