Hello,
I just got my "NOOB" kit and can't believe how much fun this is. I have done some programming in VBasic years ago and am trying to make some LED's do some various patterns via IR remote control. Real simple LED progressions mind you. Such as blink one, two then three LEDs in progression, then all on, start over etc... Will work on the coding for that later on as I get better with the "no delay" aspect.
Before that however I am learning the various syntax of C++(Arduino).
I have several challenges right now but I'll tackle them one at a time, else my head will explode!
Firstly,
I have the IR remote library included in my sketch and so far am able to so simple case changes with the remote buttons. Button one turns on LED4, button 2 LED5 etc.... It all works.
There is a power button on the remote and I wish to make it turn all LED's on or if they are all already on, turn them off. (toggle)
I created a boolean called poweredOn and that is the key for each state.
Here is portions of the code that I am using and I am able to turn all LEDs OFF from any of my case scenarios, but I can't flip flop (toggle) the power button to turn on and off then on again. The IR is working each time as I have a built in LED flash to let me know the signal was received.
Here is only a portion of the code. (up to button number 1)
#include <IRremote.h>
int RECV_PIN = 8; // pin 8 connected to left(OUTPUT) pin of IR sensor
int redPin = 2; //Blue LED mode indicator
int firstLEDPin = 4; // LED connected to digital pin 4
int secondLEDPin = 5; // LED connected to digital pin 5
int thirdLEDPin = 6; // LED connected to digital pin 6
int fourthLEDPin = 7; // LED connected to digital pin 7
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean poweredOn = false;
//---------------------------void setup()-----------------------------------
void setup()
{
Serial.begin(9600);
unsigned char i;
for(i=1;i<=7;i++) //set pins 1-11 as output
pinMode(i,OUTPUT);
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
//Below is to turn on all lights on setup incase the battery is low on the IR remote
allOn();
irrecv.enableIRIn(); // Start the receiver
pinMode(RECV_PIN, INPUT); //sets pin 8 as input
}
//----------------------------------void loop()------------------------------------------------
void loop() {
if (irrecv.decode(&results)) {
long int decCode = results.value;
Serial.println(decCode);
switch (results.value) {
//--------------------------Button 0 (power On/Off button)---------------------------------
case 16753245: //Button 0 (Power button) pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
if (poweredOn = true)
allOff(); //call allOff function. Turns all LEDs off
poweredOn = false;
if(poweredOn = false)
allOn(); //call allOn function. Turns all LEDs on
poweredOn =true;
break;
//------------Button 1---------------------------------
case 16724175: //Button 1 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
allOff(); //turn off any leftover lights before starting new pattern.
Serial.println("Button 1");//displays "button 1" on serial monitor
digitalWrite(firstLEDPin, HIGH); // sets the LED on
poweredOn = true;
break;
I have tested the functions allOn() and allOff() and they do work on their own.
As I said, I can turn the LEDs off at will but can't turn them back on with the power button. I can turn them on with button 1 again however , so there is nothing frozen.
I realize that there are most likely better ways of writing this but why is this way not working now?
Thanks you all for your help!
First, welcome...you'll find this forum very helpful. That said, those of us here appreciate it when we have complete sketches submitted so we can duplicate the problems you're having. Also, under the Tools menu in the IDE is an Auto-Format option (also invoked with Ctrl-T) that makes your code much easier to read. When I supplied the missing braces to your code and applied Ctrl-T, I got:
#include <IRremote.h>
int RECV_PIN = 8; // pin 8 connected to left(OUTPUT) pin of IR sensor
int redPin = 2; //Blue LED mode indicator
int firstLEDPin = 4; // LED connected to digital pin 4
int secondLEDPin = 5; // LED connected to digital pin 5
int thirdLEDPin = 6; // LED connected to digital pin 6
int fourthLEDPin = 7; // LED connected to digital pin 7
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean poweredOn = false;
//---------------------------void setup()-----------------------------------
void setup()
{
Serial.begin(9600);
unsigned char i;
for(i=1;i<=7;i++) //set pins 1-11 as output
pinMode(i,OUTPUT);
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
//Below is to turn on all lights on setup incase the battery is low on the IR remote
allOn();
irrecv.enableIRIn(); // Start the receiver
pinMode(RECV_PIN, INPUT); //sets pin 8 as input
}
//----------------------------------void loop()------------------------------------------------
void loop() {
if (irrecv.decode(&results)) {
long int decCode = results.value;
Serial.println(decCode);
switch (results.value) {
//--------------------------Button 0 (power On/Off button)---------------------------------
case 16753245: //Button 0 (Power button) pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
if (poweredOn = true)
allOff(); //call allOff function. Turns all LEDs off
poweredOn = false;
if(poweredOn = false)
allOn(); //call allOn function. Turns all LEDs on
poweredOn =true;
break;
//------------Button 1---------------------------------
case 16724175: //Button 1 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
allOff(); //turn off any leftover lights before starting new pattern.
Serial.println("Button 1");//displays "button 1" on serial monitor
digitalWrite(firstLEDPin, HIGH); // sets the LED on
poweredOn = true;
break;
}
}
}
which is much easier to read. The direct answer is, Yes, you can have if-else within a switch. However, I think you have some other issues, too. For example:
if (poweredOn = true)
allOff(); //call allOff function. Turns all LEDs off
poweredOn = false;
if(poweredOn = false)
allOn(); //call allOn function. Turns all LEDs on
poweredOn =true;
First, unlike VB, the test for equality is a double equal sign (==). Your code assigns poweredOn to true. Then you set it to false, and test to see if it is false in the next statement. It will always be false. You may want to think through what you're trying to do here and use curly braces to mark off your if statements...it will help you see what you're controlling.
econjack,
Thank you very much for the great info. Sorry about not posting the entire sketch. I guess I didn't want to embarrass myself by showing you the rest of the sketch! Especially as you will see my Case (for button 7) that uses delay() that of course won't work well for monitoring future IR inputs. When I finish with your suggestions I will post the entire sketch. I'm sure there will be more questions!
Great tip on the auto format selection. I just (today) finished reading my first book on Arduino by Simon Monk and that is what I have learned so far. I enjoyed reading it but he didn't talk about the menu items in the IDE figuring it's pretty self obvious to most.
I wondered if == was the correct symbol to use. Can I ask you however, is my using a boolean like poweredOn a good way of setting up a current mode? If you look at the end of each case I assign that boolean as TRUE. (I'll change it to ==)
I now understand what you mean about the mis-use of the boolean in the if/then statement. In fact while I was coding it I wondered if that would be what would cause it. That was the last entry in a complete day's worth of trying different methods with the same result! (that's when my head exploded!)
You talk of the better use of the curly braces. I'll play with those and encapsulate the statements to see if that is what you mean.
This is great fun and it is great satisfaction to work hard on a code and finally it works! Great feeling of accomplishment!
Cheers and stay warm in Cinncie.
Mark
As already has been answered, yes, you can put an if-then construct inside a switch-case (you can even nest switch-case constructs as well).
What you don't know yet - but if you dare to research it (and I am not sure it would be really appropriate to do this on a microcontroller anyway) - you can really bastardize a switch-case statement (indeed, you can do really weird things with C constructs period). You can make C do things in unexpected ways that you would never thought were possible, if you dare to go down that road...
I guess I didn't want to embarrass myself by showing you the rest of the sketch!
We've all felt that way at least a few dozen times, especially in the early learning stages. Nobody here will thinlless of you because you haven't learned yet.
I wondered if == was the correct symbol to use. Can I ask you however, is my using a boolean like poweredOn a good way of setting up a current mode? If you look at the end of each case I assign that boolean as TRUE. (I'll change it to ==)
OOPS! Don't change the assignments to ==
== is a comparison operator
= is an assignment operator.
Yahoo, It works now. Big smile on my face!
Take a look at the sketch and see if I did what you intended or did I just get lucky?
I can now toggle the power switch on and off as much as I want now. I used curly brackets and used else if (not sure if that was significant) and changed the = to == in the 'if' statements only.
Here is the entire code. In reality, I will probably only code 3 or 4 cases, (right now I have 7 only because I was testing the success of all the buttons).
At my level of experience it sure would be easy for me to use the delay() function for many of my patterns that I wish to use. I read that pin 2 and 3 have an interrupt feature. Wouldn't that allow me to interrupt if I connected the IR receiver to pin 3?
Here's my entire (corrected) code. I put all my functions at the bottom so it wouldn't take so long to get to the main body of the program. Is that common?
Thanks again!
#include <IRremote.h>
/*
This set up it with 4 LEDs and one remote control supplied by SainSmart.
Must have IRremote.h from Library download from https://github.com/shirriff/Arduino-IRremote
* An IR detector/demodulator must be connected to the input RECV_PIN.
*IR reciever hook up like below when looking at the IR reciever lens
[***********]
[***********]
[***********]
[***********]
| | |
| | |
| | |
| | |
INPT Grd 5V
----------------------------------UPDATES--------------------
LATEST: Added "do while" for Button 7 WORKS! Now I need to make it without delay. however "do while"
seems to lock it up just like delay() does?
Wrote function "senseFlash()" to acknowlege IR signal to user with RED LED(quick 4 blinks)
Used delay but no big deal. Veryquick.
TODO: blink without delay on button 7 to start out.
Use Power button to turn all an and all off (if/then statement) Done. 1/6/14 Thanks econjack!
LED pins used in this sketch are 2/4/5/6/7 (outputs) and 8(input)
-------------------------------------------------------------------*/
#include <IRremote.h>
int RECV_PIN = 8; // pin 8 connected to left(OUTPUT) pin of IR sensor
int redPin = 2; //Blue LED mode indicator
int firstLEDPin = 4; // LED connected to digital pin 4
int secondLEDPin = 5; // LED connected to digital pin 5
int thirdLEDPin = 6; // LED connected to digital pin 6
int fourthLEDPin = 7; // LED connected to digital pin 7
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean poweredOn = false;
//---------------------------void setup()-----------------------------------
void setup()
{
Serial.begin(9600);
unsigned char i;
for(i=1;i<=7;i++) //set pins 1-11 as output
pinMode(i,OUTPUT);
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
//Below is to turn on all lights on setup incase the battery is low on the IR remote
allOn();
irrecv.enableIRIn(); // Start the receiver
pinMode(RECV_PIN, INPUT); //sets pin 8 as input
}
//----------------------------------void loop()------------------------------------------------
void loop() {
if (irrecv.decode(&results)) {
long int decCode = results.value;
Serial.println(decCode);
switch (results.value) {
//--------------------------Button 0 (power On/Off button)---------------------------------
case 16753245: //Button 0 (Power button) pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
if (poweredOn == true) {
allOff(); //call allOff function. Turns all LEDs off
poweredOn = false;
}
else if(poweredOn == false) {
allOn(); //call allOn function. Turns all LEDs on
poweredOn =true;
}
break;
//--------------------------Button 1---------------------------------
case 16724175: //Button 1 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
allOff(); //turn off any leftover lights before starting new pattern.
Serial.println("Button 1");//displays "button 1" on serial monitor
digitalWrite(firstLEDPin, HIGH); // sets the LED on
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//--------------------------Button 2---------------------------------
case 16718055: //Button 2 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 2");//displays "button 2" on serial monitor
allOff(); //turn off any leftover lights before starting new pattern.
digitalWrite(secondLEDPin, HIGH); // sets the LED on
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//--------------------------Button 3---------------------------------
case 16743045: //Button 3 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 3"); //displays "button 3" on serial monitor
allOff(); //turn off any leftover lights before starting new pattern.
digitalWrite(thirdLEDPin, HIGH); // sets the LED on
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//--------------------------Button 4---------------------------------
case 16716015: //Button 4 presssed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 4");//displays "button 4" on serial monitor
allOff(); //turn off any leftover lights before starting new pattern.
digitalWrite(fourthLEDPin, HIGH); // sets the LED on
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//----------------------button 5-------------------------------------
case 16726215: //Button 5 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 5");//displays "button 5" on serial monitor
allOff(); //turn off any leftover lights before starting new pattern.
//below is the same as allOn()
unsigned char j;
for (j=4;j<=7;j++)
digitalWrite(j, HIGH);
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//------------------------Button 6-----------------------------------
case 16734885: //button 6 pressed (all off at once)
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 6");//displays "button 6" on serial monitor
poweredOn=false; //sets mode key for the powerbutton toggle 'if' statement
allOff();
break;
//---------------------Button 7----------------------------------------------
case 16728765: //button 7 pressed blink in succession without delay up and down
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
Serial.println("Button 7");//displays "button 7" on serial monitor
poweredOn==true; //sets mode key for the powerbutton toggle 'if' statement
allOff();
do
{
unsigned char j;
for(j=4;j<=7;j++)
{
digitalWrite(j,HIGH);
delay(1000);
}
for(j=7;j>=4;j--)
{
digitalWrite(j,LOW);
delay(1000);
}
}
while (results.value=true);
break;
}
irrecv.resume(); // Receive the next value
}
}
//-----------------------------Called Functions ---------------------------------------
//--------------------------------void allOn()---------------------------------------
void allOn()
// turn on all lights
{
unsigned char i;
for (i=4;i<=7;i++)
digitalWrite(i, HIGH);
}
//------------------------------ void allOff()---------------------------------------
void allOff()
// turn off all lights
{
unsigned char i;
for (i=4;i<=7;i++)
digitalWrite(i, LOW);
}
//------------------------------------void senseFlash()-------------------------------------------------
void senseFlash() //This function is to acknowledge the fact that the IR reciever did recieve the signal. Red LED flashes fast.
//Uses delay() but only for a short time so no real hang up.
{
int flashSpeed = 50; //Red LED delay speed
digitalWrite(redPin, HIGH); //red LED flashes indicating mode 2
delay (flashSpeed);
digitalWrite(redPin, LOW);
delay (flashSpeed);
digitalWrite(redPin, HIGH);
delay (flashSpeed);
digitalWrite(redPin, LOW);
delay(flashSpeed);
digitalWrite(redPin, HIGH);
delay (flashSpeed);
digitalWrite(redPin, LOW);
delay (flashSpeed);
digitalWrite(redPin, HIGH);
delay (flashSpeed);
digitalWrite(redPin, LOW);
delay (500);
}
Glad you got it working. Simon's book is well-received and is a good place to start. You can still make the code more readable by carefully using your comments. For example, which is easier to read: your original code, or this:
switch (results.value) {
case 16753245: //Button 0 (Power button) pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
if (poweredOn == true) {
allOff(); //call allOff function. Turns all LEDs off
poweredOn = false;
} else {
if(poweredOn == false) {
allOn(); //call allOn function. Turns all LEDs on
poweredOn =true;
}
}
break;
case 16724175: //Button 1 pressed
senseFlash(); //Called senseFlash() Red LED flashes fast. Means IR signal was sensed
allOff(); //turn off any leftover lights before starting new pattern.
Serial.println("Button 1"); //displays "button 1" on serial monitor
digitalWrite(firstLEDPin, HIGH); // sets the LED on
poweredOn=true; //sets mode key for the powerbutton toggle 'if' statement
break;
//=============== The rest of your code... =======================
while (results.value=true); // What is the purpose of this?? You assign the value true, which means if the code ever
// get here, you'll be here forever. You've written:
// while (true)
// ;
// Always use curly braces with if, for, while
break;
}
With a switch, it's always a good idea to have a default case, such as:
switch (exp1) {
// a bunch of case statements...
default:
Serial.print("Fell into default case, with exp1 = ");
Serial.println(exp1);
break;
}
If you want another perspective on coding style, my book Beginning C for Arduino, is available at Amazon.
while (results.value=true); // What is the purpose of this?? You assign the value true, which means if the code ever
You are right econjack, it does get stuck in that pattern.
I used that as a way to repeat that pattern until another button was pushed. Without that "do/while" code it would only go through one time.
How do I make it repeat over and over again until a new command is entered in the IR receiver? That was a big hang up for me.
Cr0sh: If you were referring to Duff's Device, it makes perfect sense on a micro like the Arduino. It would work perfectly for DDS, for example. It was originally used for dumping raster data as quickly as possible to a memory-mapped IO board.
Since I'm new, let me ask all of you about forum protocol. My major question and the title of this forum has been answered. Thanks to all who responded. It was a great help. Especially econjack. Some of the answers sparked more thinking and ideas for improvement and along with that of course, more questions. But those questions, although brought up in this forum and regard my current project, are of a different subject matter.
Is it best to start a new topic?
Thank again all !
Mark
There's no absolute right or wrong but in my view, if the new questions are related to the ongoing discussion then it's reasonable to continue in the original thread. If they're not particularly related, they deserve to be in a separate thread. For example: if this thread had been started by somebody else and you wanted to ask your new question, would you consider that this thread was the best place to ask your question? If so then go ahead. But just because you've been involved in this thread in the past, it doesn't follow that every subsequent question belongs here - even if your questions are related by being asked by you and by being about your project.
My advice would be to start a new thread. The new title may well spark someone's interest who was not able to help with the original question but may have something to offer on a new topic.
For instance, I would probably never look at a thread about Fast Fourier transforms as I have nothing to offer, but one about using the TimeAlarms library would be a different matter.