Offline
Newbie
Karma: 0
Posts: 13
|
 |
« on: December 11, 2012, 05:23:09 pm » |
Hey guys, this place is really great. I am currently working on a project that is basically remote controlled Christmas lights. I have an app on my Android phone that sends a specific byte of data depending on the button pressed. (in my case i have 4 relays, so 1-4 for each relay, 5 for random flashing, 6 for all relays closed and 7 for all relays open) The Arduino receives the data via a bluetooth receiver. My idea was as follows, i want to be able to control the relay turning on and off, just with sending the byte '1' and if it is on, it turns off, and the other way around. This is my code to do so.
if (command == 1) //Relay 1 { while (command != 7) { if (digitalRead(pinB) == LOW) //Checks if the relay is closed { digitalWrite(pinB,HIGH); //The relay stays on } else { digitalWrite(pinB,LOW); //The relay turns off } } }
And the first relay closes perfectly fine, but when i send a second '1' it does nothing. Also, i have this code in it as well to turn all of the relays off... if (command == 7) { while (command != 6) { digitalWrite(pinA, LOW); digitalWrite(pinB, LOW); digitalWrite(pinC, LOW); digitalWrite(pinD, LOW); } } but even when i send the byte '7' to the Arduino, the first relay stays closed. This is confusing me thoroughly. The only thing i can think of is the Arduino isn't taking the second the second byte at all, it is too focused on the first one received. Any tips? I can post the full code if needed. Thanks so much.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6344
-
|
 |
« Reply #1 on: December 11, 2012, 06:28:32 pm » |
I suggest you post all of your code, and enclose it in [ code ] and [ /code ] tags. But before you do that, re-read the sticky "Read this before posting a programming question".
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #2 on: December 11, 2012, 06:46:39 pm » |
Thanks for the push to re-read the sticky, my fault. Here is the full code in the correct format. I'm not worried about the random flashing part for right now. const int pinA = 4; const int pinB = 5; const int pinC = 6; const int pinD = 7; byte command; int randomPin; //for use in the random function const int rHigh = 1000; // sets the upper limit for the random delays const int rLow = 200; // sets the lower limit for the random delyas
void setup() { pinMode (pinA, OUTPUT); // set the relays pin as an output pinMode (pinB, OUTPUT); // set the relays pin as an output pinMode (pinC, OUTPUT); // set the relays pin as an output pinMode (pinD, OUTPUT); // set the relays pin as an output Serial.begin(9600); // initialize serial communications: }
void loop() { digitalWrite (pinA, LOW); //Shuts off relay A at the beginning of the program and after the stop command is sent digitalWrite (pinB, LOW); //Shuts off relay B at the beginning of the program and after the stop command is sent digitalWrite (pinC, LOW); //Shuts off relay C at the beginning of the program and after the stop command is sent digitalWrite (pinD, LOW); //Shuts off relay D at the beginning of the program and after the stop command is sent
if ( Serial.available() > 0 ) // Check if a command has been sent. { command = Serial.read(); // write the serial command value if (command == 1) //Relay 1 { while (command != 7) { if (digitalRead(pinA) == LOW) //Checks if the relay is closed { digitalWrite(pinA,HIGH); //The relay stays on } else { digitalWrite(pinA,LOW); //The relay turns off } } }
if (command == 2) //Relay 2 { while (command != 7) { if (digitalRead(pinB) == LOW) //Checks if the relay is closed { digitalWrite(pinB,HIGH); //The relay stays on } else { digitalWrite(pinB,LOW); //The relay turns off } } } if (command == 3) //Relay 3 { while (command != 7) { if (digitalRead(pinC) == LOW) //Checks if the relay is closed { digitalWrite(pinC,HIGH); //The relay stays on } else { digitalWrite(pinC,LOW); //The relay turns off } } }
if (command == 4) //Relay 4 { while (command != 7) { if (digitalRead(pinD) == LOW) //Checks if the relay is closed { digitalWrite(pinD, HIGH); //The relay stays on } else { digitalWrite(pinD, LOW); //The relay turns off } } }
if (command == 5) //Random flashing { while (command != 7) //Until stop command is sent { randomPin = random(pinA, pinD + 1); //Selects a random relay digitalWrite(randomPin, HIGH); //Turns it on delay(random(rLow, rHigh)); //Stays on for a random time period digitalWrite(randomPin, LOW); //Turns off delay(random(rLow, rHigh)); //Optional off delay } }
if (command == 6) { while (command != 7) { digitalWrite(pinA, HIGH); digitalWrite(pinB, HIGH); digitalWrite(pinC, HIGH); digitalWrite(pinD, HIGH); } }
if (command == 7) { while (command != 6) { digitalWrite(pinA, LOW); digitalWrite(pinB, LOW); digitalWrite(pinC, LOW); digitalWrite(pinD, LOW); } }
} }
|
|
|
|
|
Logged
|
|
|
|
|
Saskatchewan
Offline
Full Member
Karma: 10
Posts: 222
When the going gets weird, the weird turn pro. - Hunter S. Thompson
|
 |
« Reply #3 on: December 11, 2012, 06:48:26 pm » |
if (command == 7) { while (command != 6) { digitalWrite(pinA, LOW); digitalWrite(pinB, LOW); digitalWrite(pinC, LOW); digitalWrite(pinD, LOW); } } but even when i send the byte '7' to the Arduino, the first relay stays closed. This is confusing me thoroughly. The only thing i can think of is the Arduino isn't taking the second the second byte at all, it is too focused on the first one received. Any tips? I can post the full code if needed. Thanks so much. Not surprising. If command == 7 it will always !=6 so you will be stuck in that while loop. The while loop needs command == 6 to exit. You don't need that loop at all. It sounds like a switch statement might be a better idea.
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 38
Posts: 1850
|
 |
« Reply #4 on: December 11, 2012, 06:59:18 pm » |
The command variable never gets updated inside of any of your while loops, so they'll loop forever.
If the code to drive the relays is intended to happen once, get rid of the while loops. If it's intended to happen over and over again (like a blink), then it should be outside of the if statement that checks for available serial data.
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15314
Measurement changes behavior
|
 |
« Reply #5 on: December 11, 2012, 07:04:26 pm » |
If you look at the very beginning of your loop() function you are turning off all the relays. As the loop() is always...well looping... continuously...., I think this might be fooling with your desired relay logic states. If even needed this initial set up state of the relays should probably be in the setup() function.
Loop() keeps on loopin, sounds like a good song chorus!
And I agree a switch statement might go further to let you express and see what you want to happen.
Lefty
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #6 on: December 11, 2012, 07:08:08 pm » |
The command variable never gets updated inside of any of your while loops, so they'll loop forever. If the code to drive the relays is intended to happen once, get rid of the while loops. If it's intended to happen over and over again (like a blink), then it should be outside of the if statement that checks for available serial data. I think i can say i understand that. Well the intent was for it to happen once, then stay how it is until another command that involves that pin is received. So, if pinA becomes HIGH, i want it to stay HIGH, until i turn all pins LOW, I set them to go randomly, or I send the '1' byte again and set it to be LOW. What i'm trying not to do is make it so that if pinA is HIGH and it receives the byte '2', pinA becomes LOW and pinB goes HIGH.
|
|
|
|
« Last Edit: December 11, 2012, 07:10:08 pm by 3tuxedo »
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 38
Posts: 1850
|
 |
« Reply #7 on: December 11, 2012, 07:11:46 pm » |
What i'm trying not to do is make it so that if pinA is HIGH and it receives the byte '2', pinA becomes LOW and pinB goes HIGH.
So then just put that in each case. If it's '1', turn pinA HIGH, pinB,C and D Low. If it's '2', pinB to HIGH, pinA, C, D to LOW, etc.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #8 on: December 11, 2012, 07:26:34 pm » |
So then just put that in each case. If it's '1', turn pinA HIGH, pinB,C and D Low. If it's '2', pinB to HIGH, pinA, C, D to LOW, etc. But see, wouldn't that turn off pinA if a '2' is received to turn pinB HIGH? If pinA is HIGH, and a '2' is received, that shouldn't affect it, it should only affect pinB.
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 38
Posts: 1850
|
 |
« Reply #9 on: December 11, 2012, 07:27:54 pm » |
So then just put that in each case. If it's '1', turn pinA HIGH, pinB,C and D Low. If it's '2', pinB to HIGH, pinA, C, D to LOW, etc. But see, wouldn't that turn off pinA if a '2' is received to turn pinB HIGH? If pinA is HIGH, and a '2' is received, that shouldn't affect it, it should only affect pinB. So then don't turn off pinA and just turn on pinB...
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #10 on: December 11, 2012, 07:38:39 pm » |
So then don't turn off pinA and just turn on pinB... Easy enough! Thanks so much. How would I go about writing the code so that in the switch statement, if the pin is already on, turn it off, and if it is already off turn it on? Just an if statement inside of the case?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #11 on: December 11, 2012, 07:55:09 pm » |
The command variable never gets updated inside of any of your while loops, so they'll loop forever. I think that may be the over arching problem. Do i need the command variable in setup? Or still in the loop just updated each time? I am unsure of how to do that if it's right.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35478
Seattle, WA USA
|
 |
« Reply #12 on: December 11, 2012, 07:58:01 pm » |
Do i need the command variable in setup? No. Or still in the loop just updated each time? Something inside the while loop, or external to the loop() function (such as an interrupt service routine) must update the variable(s) that the while loop is monitoring, if the while loop is ever to end.
|
|
|
|
|
Logged
|
|
|
|
|
Saskatchewan
Offline
Full Member
Karma: 10
Posts: 222
When the going gets weird, the weird turn pro. - Hunter S. Thompson
|
 |
« Reply #13 on: December 11, 2012, 07:59:46 pm » |
Easy enough! Thanks so much. How would I go about writing the code so that in the switch statement, if the pin is already on, turn it off, and if it is already off turn it on? Just an if statement inside of the case? You could store each relay state in a variable and toggle both the relay and the variable if you want. You could read the pin's state directly and take action. I get the idea that you might just turn off all the relays right before you turn on what you want.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #14 on: December 11, 2012, 11:07:42 pm » |
You could store each relay state in a variable and toggle both the relay and the variable if you want. You could read the pin's state directly and take action. So depending on the state a different function, or statement, or what have you, will take action to the relay. That sounds like it may possibly work, considering i have absolutely 0 experience with interrupt service routines. Although that is probably a way to do it as well. Do you mind sharing an idea of how you were thinking of achieving this?
|
|
|
|
|
Logged
|
|
|
|
|
|