0

I've been piecing together various lighting effects. I am wanting to have each lighting effect loop until another button is pressed to trigger another lighting effect.

I've come to a bit of standstill at the moment. I've created a loop that doesn't seem to end. I've had a look around but I can't work out how to fix my code. Sorry in advanced, I'm new to using arduinos but if anyone could help out, it would be much appreciated. Thanks!

//www.elegoo.com
//2016.12.9

#include "IRremote.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6


Adafruit_NeoPixel strip = Adafruit_NeoPixel(20, PIN, NEO_GRB + NEO_KHZ800);

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'
int Remote = 0;

/*-----( Function )-----*/
void translateIR() // takes action based on IR code received

// describing Remote IR codes 

{

  switch(results.value)

  {
  case 0xFFA25D: Serial.println("POWER"); 
  ArrowRight(strip.Color(25, 0, 0), 100); //Red
  ArrowRight(strip.Color(0, 0, 25), 100); //Blue
//  Remote = 0xFFA25D;
  break;

  case 0xFFE21D: Serial.println("FUNC/STOP"); 
  ArrowLeft(strip.Color(25, 0, 0), 100); // Red
  ArrowLeft(strip.Color(0, 0, 25), 100); // Blue
//  Remote = 0xFFE21D;
  break;

  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK");    break;
  case 0xFF02FD: Serial.println("PAUSE");    break;
  case 0xFFC23D: Serial.println("FAST FORWARD");   break;
  case 0xFFE01F: Serial.println("DOWN");    break;
  case 0xFFA857: Serial.println("VOL-");    break;
  case 0xFF906F: Serial.println("UP");    break;
  case 0xFF9867: Serial.println("EQ");    break;
  case 0xFFB04F: Serial.println("ST/REPT");    break;
  case 0xFF6897: Serial.println("0");    break;
  case 0xFF30CF: Serial.println("1");    break;
  case 0xFF18E7: Serial.println("2");    break;
  case 0xFF7A85: Serial.println("3");    break;
  case 0xFF10EF: Serial.println("4");    break;
  case 0xFF38C7: Serial.println("5");    break;
  case 0xFF5AA5: Serial.println("6");    break;
  case 0xFF42BD: Serial.println("7");    break;
  case 0xFF4AB5: Serial.println("8");    break;
  case 0xFF52AD: Serial.println("9");    break;
  case 0xFFFFFFFF: Serial.println(" REPEAT");break;  

  default: 
    Serial.println(" other button   ");

  }// End Case

  delay(0); // Do not get immediate repeat


} //END translateIR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode"); 
  irrecv.enableIRIn(); // Start the receiver
  strip.begin();
  strip.show();
  Remote = 0;

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if (irrecv.decode(&results)) // have we received an IR signal?

  {
    translateIR(); 
    irrecv.resume(); // receive the next value
  }  
}/* --(end main loop )-- */

void ArrowRight(uint32_t c, uint8_t wait) {
  while (Remote = 0xFFA25D) { 
    for (uint16_t i = strip.numPixels()/2; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
    for (uint16_t i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, 0);
    }
    strip.show();
    delay(wait);
  }
}

void ArrowLeft(uint32_t c, uint8_t wait) {
  while (Remote = 0xFFE21D) { // The j<# determines how many cycles
    for (uint16_t i = strip.numPixels()/2-1; i + 1 > 0 ; i--) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
    }
    for (uint16_t i = strip.numPixels(); i + 1 > 0 ; i--) {
      strip.setPixelColor(i, 0);
    }
    strip.show();
    delay(wait);
  }
}
  • what loop runs constantly? – Chad G May 21 '18 at 22:51
  • Both of them seem to do it at the moment. I think its because I've got Remote to equal the value that corresponds to the button press on my remote. I think the issue is that I've not been able to implement an "override" as you may say, to switch over to a different loop. Cheers. – YaBo11 May 21 '18 at 22:58
  • both of which ones? Are you referring to the the while loops in the Arrow functions? And they run forever when you press the corresponding button and release it? – Chad G May 21 '18 at 23:11
  • I think you don't need the while loops -- you should take them out & turn them into one-shots and take the translateIR() out of the conditional in loop(). Inside the conditional, if you do get a new message, copy it to from a temp variable into &result instead of updating &result each loop() – Dave X May 21 '18 at 23:26
  • 3
    while (Remote = 0xFFE21D) You have to use == here, or this will be an assignment – chrisl May 22 '18 at 5:18
1

There are a few causes for eternal loops and other things that will go wrong in your code.

As ChrisL noted above you are assigning a value to Remote in the while condition which is almost certainly not what you wanted to do. On the plus side, every C/C++ programmer ever has also made that same mistake at some time or another.

Now if you change it to while (Remote == 0xcFFE21D) it still won't work, because Remote is always 0. You have commented out the lines that set Remote, but they are after the call to the function. To be honest since you know the value before you call the function (because of the switch statement) you don't need to check the value within the function so you could remove the while loop all together. If you intention is to call this function repeatedly until a different button is pressed on the remote, the way you are doing it won't work. you need to store the last button pressed value and then pass that into the switch statement. When a different button is pressed update the 'last button pressed' value.

You for loop conditions need looking at. I don't think that the number of lights in the strip is going to change while the program is running. If that's true then your are wasting processor instructions by doing strip.numPixels()/2-1 you might want to look at setting global values in setup.

Also the for loops might benefit from using i >= 0 because then you don't need to do i+1 every loop.

  • Hi Gorilla, thank you and everyone else for your help. I'm fairly new to C/C++, as is quite evident. Like you have suggested, I am wanting to call a certain function, repeatedly, until another button is pressed, to switch to another function. I'm going to have a go at it now but if anyone could help me amend the code that would be very helpful, thanks! – YaBo11 May 22 '18 at 16:09
  • You'll learn more if you do it yourself.:) You have said what you need to do in the above comment, "... call a certain function, repeatedly, until another button is pressed..." So ensure that the function you call does its think once and then returns. The code that calls the function is the one that is checking to see if the "until ..." has occurred, because it was that code that decided to call the function in the first place. You are 90% of the way there. – Code Gorilla May 23 '18 at 10:34
  • You might want to tinker with C/C++ programming concepts in an IDE that has a symbolic debugger, including tracing and breakpoints. Debugging Arduino programs is a pain in the butt since you don't have any of those tools. You have to add serial port print statements and do a fair amount of guesswork. – Duncan C Aug 16 at 1:42
  • Once you work out your basic logic using normal non-Arduino C/C++, you can re-implement your code on Ardino. – Duncan C Aug 16 at 1:42

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.