In this project I am trying to accomplish turning on a LED with a switch and being able to send a switch case through the COM port to effect the same LED.
Switch (http://www.arduino.cc/en/tutorial/switch): Works great. It can detect if the "int inPin" is already high or low and do the opposite with a switch press.
I would like to add something like:
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
int speed; // Local variable
for (int thisPin = 2; thisPin < 11; thisPin++) {
pinMode(thisPin, OUTPUT);
switch (inByte) {
//Pins 13 - LED
case '1': //Press 1 to do something
digitalWrite(13, HIGH); // Turns on Lights
break;
But for the:
switch (inByte) {
case '1': //Press 1 to do something
digitalWrite(13, HIGH); // Turns on Lights
break;
I would like the same outcome like Switch has (detect if "int inPin" is already high or low and do the opposite:
case '1': //Press 1 to do something
digitalWrite(13)
f (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
Not sure how to accomplish this, testing thus far has not worked.
Here is the full code I am using for controlling the "switch (inByte) cases"
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
}
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
int speed; // Local variable
for (int thisPin = 9; thisPin < 11; thisPin++) {
pinMode(thisPin, OUTPUT);
switch (inByte) {
//Pins 9 - Lights
case '1':
digitalWrite(9, HIGH); // Turns on Lights
break;
case '2':
digitalWrite(9, LOW); // Turns off Lights
break;
default:
// turn all the connections off:
for (int thisPin = 9; thisPin < 11; thisPin++) {
digitalWrite(thisPin, LOW);
}
}
}
}
}
Sorry, I was giving the arduino "Switch" code as a reference but didn't past it to save room:
It has the int pin already in it.
/* switch
*
* Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
* press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's
* a minimum delay between toggles to debounce the circuit (i.e. to ignore
* noise).
*
* David A. Mellis
* 21 November 2006
*/
int inPin = 2; // the number of the input pin
int outPin = 13; // the number of the output pin
int state = HIGH; // the current state of the output pin
int reading; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 200; // the debounce time, increase if the output flickers
void setup()
{
pinMode(inPin, INPUT);
pinMode(outPin, OUTPUT);
}
void loop()
{
reading = digitalRead(inPin);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
}
digitalWrite(outPin, state);
previous = reading;
}
After figuring out how to use my code to detect the pin state, I would like to incorporate it into the "Switch" code above. My code currently will cut a LED off/on by pressing 1 or 2 on the keyboard through a serial program like Putty.
Fair enough. There are two things I need to accomplish my goal.
I am working on the first part right now and just resetup my test.
I need a way for the following code to be able to detect the current state of the selected pin and do the opposite when a keyboard press is sent to the arduino.
This is my default code. If you press "1" the pin (9) will go High and light the LED. If "2" is pressed the LED will turn off as the pin (9) has gone low.
I need to modify this to be able to have the same button on a keyboard pressed to drive the pin High or Low depending on what it is currently set at. Something to the tune of "if pin (9) high, set low and vice versa.)
Desired outcome would be much in the way of how the "Switch code" works with a physical switch.
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
}
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
int speed; // Local variable
for (int thisPin = 9; thisPin < 11; thisPin++) {
pinMode(thisPin, OUTPUT);
switch (inByte) {
//Pin 9 - LED
case '1':
digitalWrite(9, HIGH); // Turns on LED
break;
case '2':
digitalWrite(9, LOW); // Turns off LED
break;
default:
// turn all the connections off:
for (int thisPin = 9; thisPin < 11; thisPin++) {
digitalWrite(thisPin, LOW);
}
}
}
}
}
Yes, the opposite of the current pin stats; if Low make high. If high, make low.
--
Keyboard presses are as easy as defining them as switch cases:
case '1': will listen for the "1" key
or
case 'k': would listen for the "k" key.
digitalWrite(9, HIGH); would currently make Pin 9 go high and turn the LED on.
digitalWrite(9, LOW); Makes the LED turn off.
Neat and simple huh?
--
The final button could be any button. We can call that "k" if you would like. It would drive pin 9.
switch (inByte) {
// Turn LED on or OFF with key press
case 'k':
digitalWrite(9, Detect current state some how, do opposite. (if high make low / if low make high)
I am not sure if and how much timing would be needed. keyboard presses have never had a timing issue (integer flood issue) before. But might end up needing timing so that the LED does not flash or flicker if the key is held down too long. (Usually repeated HIGH or LOW commands do not have an effect since the LED would already be ON or OFF) Yeah after typing that out and thinking about it, timing might be a good idea.
This will be the next part, it will be necessary but not yet. Lets work through this COM control with the keyboard presses first =)
"All that other jazz in the example you posted is all about responding to the state change on the input pin."
Press "k" light comes on -- if "k" is held the code will wait 15000 ms (15 seconds) until it will send another "k" this would keep a key being held from making the LED flicker. It would however make it turn on and off every 15 seconds, lol. 15 seconds is acceptable.
You kept making me repeat my questions so I elaborated.
After the:
digitalWrite(13, !digitalRead(13));
You asked about timing
That example code you showed, it also has some timing involved. Do you need the timing? How should that work?
I had moved on to timing to keep the LED from flashing... something I hadn't put a lot of thought into but is a really good idea. I just added to to my first what if long English example. I was not ignoring your code.
For the last F-ing time and then you're on your own. What pin?
Dude, the pin the LED is on. We already covered this and I was pretty sure you knew what I was asking due to your example. I apologize for the communication mix up.
UKHeliBob - Much appreciated both of your examples were exactly what I came to the forum to find in the first place.
case '1':
digitalWrite(9, HIGH); // Turns on LED
break;
case '2':
digitalWrite(9, LOW); // Turns off LED
break;
To the following:
digitalWrite(9, !digitalRead(9));
How should it actually be?
Guys, I only want to be able to turn the LED (Pin 9) on and off with the same button on a keyboard (Key doesn't matter, it has been "1" in the examples). Maybe have a little bit of a wait time to make sure that the LED does not blink on and off if the key is accidentally held down too long. Not sure how this got so blown up.
I'm not sure why you have a for loop in loop(). It isn't necessary. Get rid of it. I think it is what is causing the problem. On one iteration of the loop, you turn the pin on (or off). Then, on the next iteration, you reverse it. That makes no sense. The pin should change state ONLY ONCE, when there is input from the serial port.
Hi!
I've read the posts and I made the code below for inverting LED (Pin 9) state after pressing '1'. It's quite simple but I think it's what you want.
void setup() {
pinMode(9,OUTPUT);
digitalWrite(9,LOW);
Serial.begin(115200);
Serial.println("Reading now...");
Serial.println("Press 1 to invert LED (Pin 9) state.");
}
void loop() {
if(Serial.available() > 0){
byte inByte = Serial.read(); //Read the Serial and return the first byte.
switch(inByte){
case '1':
Serial.println("Inverting LED (Pin 9) state");
digitalWrite(9, !digitalRead(9));
break;
default:
Serial.println("Nothing to do");
break;
}
Serial.read(); //Clear Serial incoming buffer
}
}
Doesn't break anything. Actually that was there originally to have the pins go low if any other keyboard key was pressed that was not defined in the code. It is now unnecessary.
I figured I probably pulled out too much of the code from the 1st part.
I have tried killing variations of the whole 2 lines and "for (int thisPin = 2; thisPin < 11; thisPin++) {" along with the "thisPin" in pinMode(thisPin, OUTPUT);
default:
// turn all the connections off:
for (int thisPin = 9; thisPin < 11; thisPin++) {
digitalWrite(thisPin, LOW)
And having just:
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
}
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
int speed; // Local variable
for (int thisPin = 9; thisPin < 11; thisPin++) {
pinMode(thisPin, OUTPUT);
switch (inByte) {
//Pins 9 - LED
case '1':
digitalWrite(9, HIGH); // Turns on LED
break;
case '2':
digitalWrite(9, LOW); // Turns off LED
break;
}
}
}
}
Happily works.
However the following does not:
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
}
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
int speed; // Local variable
pinMode(OUTPUT);
switch (inByte) {
//Pins 9 - LED
case '1':
digitalWrite(9, HIGH); // Turns on LED
break;
case '2':
digitalWrite(9, LOW); // Turns off LED
break;
}
}
}
}
I know something has to be written there or else the commands will not output to the board pins.
I know something has to be written there or else the commands will not output to the board pins.
You need to post ALL of your code. You need to assign the mode of the pins. It is not clear that you are doing that, since setup() is missing in the "code that doesn't work". We could theorize that it doesn't work because you are diddling with the pullup resistor on an input pin.
It does NOT make sense to have the switch statement INSIDE the for loop. There is no reason to turn a specific pin on or off multiple times. ONCE is enough.
Lets just theorize for a second that I really suck at this...
Setup is in the top of the code that I pasted:
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
It does NOT make sense to have the switch statement INSIDE the for loop. There is no reason to turn a specific pin on or off multiple times. ONCE is enough.
Are you saying that
switch (inByte) {
Should be before:
void loop() {
If I move switch (inByte) { before the void loop() { I get the following error:
sketch_apr12a.ino: In function 'void setup()':
sketch_apr12a:3: error: 'inByte' was not declared in this scope
int LED_1 = 9;
#define PIN_ON 0
#define PIN_OFF 1
void setup() {
Serial.begin(9600); // Setup Serial library at 9600 bps
pinMode(LED_1, OUTPUT);
digitalWrite(LED_1, PIN_OFF);
}
void loop() {
// read the IO:
if (Serial.available() > 0) {
int inByte = Serial.read();
switch (inByte) {
//Pin 9 - LED
case '1':
digitalWrite(9, !digitalRead(9)); // Turns on LED
break;
}
}
}
It will now turn on and off with the same key press.
I was having an issue where the LED would come on when the board was reset or plugged into the USB. So upon doing some research and pulling apart examples, I came up with the:
#define PIN_ON 0
#define PIN_OFF 1
And:
digitalWrite(LED_1, PIN_OFF);
To keep the LED off by default. I also now understand the difference between the Setup and Loop functions.
... Off to play around with adding a physical switch in addition to the "keyboard switch".
Nope, testing... It looks like I forgot that delay so that if the key is held down it doesn't make the LED flicker off and on in rapid succession. I am looking at "Debounce" but I am not sure that is really what I am looking for. Is there another way to stop the flickering if the key is held down. Debounce uses a timer, but I would like to able to press as fast as I want, as long as the key has been let go of before the command is resent.
Something in the neighborhood of; do not resend command until key "1" is let go of and repressed..