0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« on: December 10, 2012, 11:11:04 am » |
Hi, I am trying to get a digitalRead/Write statement to switch the mode within my Switch/Case loop. I want to be able to switch the mode to (mode = 5) when the button attached to 'StopPin' is pressed. Preferably only whilst (mode = 6) is running. I know the wiring to the button/Test LED is right as I have tested it with the bit of code greyed out - // buttonState = digitalRead(StopPin); // if (buttonState == HIGH) {digitalWrite(TestPin, HIGH);} so I know the switch works fine. My problem is as soon as I move this to within the IF variables in the code it stops working. I have tried to get it to light up the Test LED and switch the mode with no luck. I am assuming it is something to do with the fact it is working alongside the serial input (which all works great) but I cannot see why. I have tried moving the read/write to different parts of the loop but cant seem to get it to do anything. Can anyone see why? Thanks in advance const int ShakePin = 4; const int FeedPin = 5; const int StopPin = 8; const int TestPin = 13; byte mode; int buttonState = 0;
void setup() { pinMode(ShakePin, OUTPUT); //Shaker Relay Pin digitalWrite(ShakePin, LOW); // pinMode(FeedPin, OUTPUT); // Feeder Relay Pin digitalWrite(FeedPin, LOW); // pinMode(StopPin, INPUT); // Cutout Switch digitalWrite(StopPin, LOW); // pinMode(TestPin, OUTPUT); // pin 12 shakermotor as OUTPUT digitalWrite(TestPin, LOW); // pin 12 shakermotor as OUTPUT Serial.begin(115200); // start serial communication at 115200bps
} void loop() { // buttonState = digitalRead(StopPin); // if (buttonState == HIGH) {digitalWrite(TestPin, HIGH);} if( Serial.available() >= 2){ buttonState = digitalRead(StopPin); //Is the stop pin high int key = Serial.read(); int val = Serial.read(); if ( mode == 0 && key == 4 && val == 1){ mode = 1;} if ( mode == 0 && key == 5 && val == 1){ mode = 2;} if ( mode == 0 && key == 13 && val == 1){ mode = 3;} if (buttonState == HIGH) {mode = 5;} // If Pin is high light the stopPin // if ( mode == 6 && buttonState == HIGH){ mode = 5;} // if (buttonState == HIGH) {digitalWrite(TestPin, HIGH);} // If Pin is high light the TestLED switch (mode){ case 0: // do nothing and wait break;
case 1: // Shake digitalWrite (ShakePin, HIGH); delay (5000); digitalWrite (ShakePin, LOW); mode = 5; break;
case 2: // Feed digitalWrite (FeedPin, HIGH); delay (3000); digitalWrite (FeedPin, LOW); delay (1000); mode = 6; break;
case 3: //LED Test digitalWrite (TestPin,HIGH); delay (3000); digitalWrite (TestPin,LOW); mode = 5; break;
case 5: // Reset all variables and go to wait mode key = 0; val = 0; mode = 0; break;
case 6: // Run Motor until Interupt from StopPin digitalWrite (FeedPin, HIGH); break;
} } }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #1 on: December 10, 2012, 11:22:36 am » |
if ( mode == 0 && key == 4 && val == 1){ mode = 1;} if ( mode == 0 && key == 5 && val == 1){ mode = 2;} if ( mode == 0 && key == 13 && val == 1){ mode = 3;}
Nested ifs would make this clearer. if ( mode == 0 && val == 1) { if (key == 4) { mode = 1;} if (key == 5) { mode = 2;} if (key == 13) { mode = 3;} } My problem is as soon as I move this to within the IF variables in the code it stops working. You can't move stuff into the IF variables. Into the if statement block, yes. But, you need to show WHERE you moved that to. I am assuming it is something to do with the fact it is working alongside the serial input (which all works great) but I cannot see why. I can't see any basis for that assumption. Put each { and } on a new line, and use Tools + Auto Format to properly indent your code. That may make your problem apparent. If not, post the code you are having problems with, without commented out code.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #2 on: December 10, 2012, 11:43:59 am » |
ok, reformatted - anyway, here is the problem - when the (buttonState == HIGH) it does not switch the case to (mode = 7), turning the pin to low and returning the mode to 0. I have an LED attached to the FeedPin at the moment. When I trigger [key 5] the LED lights up for three seconds, off for a second then back on, which indicates that it is succesfully running mode-2 then switching to mode-6 with no problems, however the LED does not turn off when I press the switch attached to the StopPin, which indicates to me that it is not switching to Mode-7. (changed slightly from original posted code) void loop() {
if( Serial.available() >= 2){
buttonState = digitalRead(StopPin); //Is the stop pin high
int key = Serial.read(); int val = Serial.read();
if ( mode == 0 && val == 1) { if (key == 4) { mode = 1;} if (key == 5) { mode = 2;} if (key == 13) { mode = 3;} if (buttonState == HIGH) { mode = 7;} }
switch (mode){
case 0: // do nothing and wait break;
case 1: // Shake digitalWrite (ShakePin, HIGH); delay (5000); digitalWrite (ShakePin, LOW); mode = 5; break;
case 2: // Feed digitalWrite (FeedPin, HIGH); delay (3000); digitalWrite (FeedPin, LOW); delay (1000); mode = 6; break;
case 3: //LED Test
digitalWrite (TestPin,HIGH); delay (3000); digitalWrite (TestPin,LOW); mode = 5; break;
case 5: // Reset all variables and go to wait mode key = 0; val = 0; mode = 0; break;
case 6: // Run Motor until Interupt from StopPin digitalWrite (FeedPin, HIGH); break; case 7: // Reset all variables and go to wait mode digitalWrite (FeedPin, LOW); key = 0; val = 0; mode = 0; break;
} } }
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 37
Posts: 1827
|
 |
« Reply #3 on: December 10, 2012, 11:59:27 am » |
Are you sending it serial data while StopPin is HIGH? You have a requirement that there be two bytes (0 and 1) of incoming serial data while StopPin is HIGH in order to change modes.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #4 on: December 10, 2012, 12:15:57 pm » |
Hi, no there is only serial data when I press a button on the andorid app that is communicating with the serial port, I see the problem now as it can only read the button state when the serial data is being sent, due to it being within the serials IF statement.
Any idea how I can implement reading the pin state and changing the mode whilst also monitoring the serial input?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #5 on: December 10, 2012, 12:26:24 pm » |
Any idea how I can implement reading the pin state and changing the mode whilst also monitoring the serial input? Do them independently. Read the switch state. Then, read the serial data, if any.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #6 on: December 10, 2012, 12:49:49 pm » |
Thanks, Can I change the mode within another IF statement from outside the IF statement? I need to be able to interupt {mode = 6} with the switch, making the program stop? I thought that is what I had done already, unsuccesfully
|
|
|
|
« Last Edit: December 10, 2012, 12:52:39 pm by flotilla »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #7 on: December 10, 2012, 01:05:51 pm » |
Can I change the mode within another IF statement from outside the IF statement? You keep using the definitive article - the IF statement. There is more than one if statement. You need to clarify what if statement you are referring to. Most likely, the answer is yes. I need to be able to interupt {mode = 6} with the switch, making the program stop? You don't want to interrupt mode 6. That implies letting it resume after the interruption. You want to terminate mode 6. Anytime you are in mode 6, you can read the switch state, and change to a different mode if the state is to your liking.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #8 on: December 10, 2012, 01:28:27 pm » |
Anytime you are in mode 6, you can read the switch state, and change to a different mode if the state is to your liking. I have tried adding the following to within the (mode = 6) code: case 6: // Run Motor until StopPin pressed digitalWrite (FeedPin, HIGH); buttonState = digitalRead(StopPin); if (buttonState == HIGH) { mode = 7;} break; case 7: // Reset all variables and go to wait mode digitalWrite (TestPin,HIGH); digitalWrite (FeedPin, LOW); key = 0; val = 0; mode = 0; break;
} } }
The TestPin does not go HIGH and the FeedPin does not go LOW when the StopPin switch is pressed whilst mode = 6 is running. I am trying to find out where in my code I need to monitor the StopPin to allow me to interrupt (sorry, change mode) whilst mode 6 is running. It currently does not. Can anyone suggest where I need to monitor the switch to allow the mode to be changed
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #9 on: December 10, 2012, 01:34:33 pm » |
I have tried adding the following to within the (mode = 6) code: Which looks correct. The TestPin does not go HIGH and the FeedPin does not go LOW when the StopPin switch is pressed whilst mode = 6 is running. You need to add a Serial.print() statement to loop, to print out the value in mode.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #10 on: December 10, 2012, 02:10:25 pm » |
You need to add a Serial.print() statement to loop, to print out the value in mode. Thanks, can you explain to me where in the loop and what this would achieve? If it is just to monitor the state of the button I can't actually view the serial port output as the app does not support it. Or is this to output the button state to the serial port to allow it to be read by the program? I know the switch works because If I hold it whilst the key is pressed the mode does change (as indicated by the test LED lighting up after 3 seconds) Sorry but I am trying to understand why this would work rather than 'it works' Thanks
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #11 on: December 10, 2012, 02:26:44 pm » |
The way I understand it my code is operating as the following at the moment:
If Serial bytes received, read bytes and change mode based on the byte value. Only read the button value if serial data is being received.
What I need it to do is:
If serial bytes received, read bytes and change mode based on the byte value. when mode 6 is running, monitor StopPin and if value goes high change mode to 7.
I am having trouble finding exactly where in my code I need to put the monitor to allow me to switch the mode without simultaneously receiving data from the serial port.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #12 on: December 10, 2012, 02:29:41 pm » |
Thanks, can you explain to me where in the loop and what this would achieve? Just before the switch(mode) statement would be good. You'd KNOW what state the code is in, instead of guessing/hoping/wondering. If it is just to monitor the state of the button I can't actually view the serial port output as the app does not support it. What app doesn't support "it"? Or is this to output the button state to the serial port to allow it to be read by the program? It is to output to the serial port the mode (not the state of a switch). Read by what program? What do you have on the PC end of the serial port?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #13 on: December 10, 2012, 02:44:21 pm » |
Sorry, more information. I am using a Bluetooth module attached to the arduino. I am using an android app which when you set up a touchbutton and press it, it sends two bytes of information (key,val) over bluetooth to the serial port. This is all working great and triggers the right pins when the right touch button is pressed.
Because the app does not have a serial monitor I cannot see what is going on, the only way I know is by using LEd's on the pins to monitor the mode changes. Using the PC serial monitor as well as the BT module does not work as I think the BT module is the serial input/output port. (I am a beginner so I am still working all this out)
I know that there is no problem with monitoring the switch input because It does switch the mode if I am already making the StopPin HIGH when the mode starts (if I hold down the StopPin button whilst pressing the button on the app).
I know this is because I have the mode changes within the IF serial.available statement and changes can only be made at the same time as serial information is being recieved. I cannot work out a way to have the StopPin change the mode, within the Switch/case block whilst Mode 6 is already running, without having to recieve serial data at the same time.
Sorry if this is confusing as hell
|
|
|
|
« Last Edit: December 10, 2012, 02:46:43 pm by flotilla »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 46
Arduino rocks
|
 |
« Reply #14 on: December 10, 2012, 03:45:33 pm » |
Ok, solved this, thanks for your help PaulS but I think part of my problem was explaining my problem. After many an hour head scratching I have solved it.
My problem was having the switch/case inside the if (serial.available(){ so monitoring of the input could only happen whilst it was receiving serial data.
I moved it outside of the IF statement so that all the above did was write the values to key and val and it worked a charm
void loop() {
if( Serial.available() >= 2){ key = Serial.read(); val = Serial.read(); }
if (key == 4 && val == 1){ mode = 1;} if (key == 5 && val == 1){ mode = 2;} if (key == 13 && val == 1){ mode = 3;}
switch (mode){
Thanks again for help
|
|
|
|
|
Logged
|
|
|
|
|
|