Switching LED through serial monitor with ONE character

Hello!

I'm trying to switch an LED on and off only with one character from my keyboard. I was simply unable to find a code like this, however I'm sure it is possible :slight_smile:

Here's my code:

#define SpeakerPin 9

byte byteRead;

void setup() {
// initialize serial communication:
Serial.begin(9600);
pinMode(SpeakerPin, OUTPUT);
digitalWrite(SpeakerPin, LOW);

}

void loop() {

if (Serial.available() > 0) {
byteRead = Serial.read();
}

switch (byteRead) {
{case 'a':
int SpeakerPinState;
SpeakerPinState = digitalRead(SpeakerPin);
Serial.print (SpeakerPinState);
if (SpeakerPinState = 0)
{
digitalWrite(SpeakerPin, 1);
}
else if (SpeakerPinState = 1)
{
digitalWrite(SpeakerPin,0);
}
}
break;
//default:
//digitalWrite(SpeakerPin, 0);
}
}

This isn't work, but I'm not sure why, It always gives me 0 through serial monitor. I have an idea why but I'm not sure about it and I'm also not 100% sure how this communication works when I press "a".

Can you help me please?

if (SpeakerPinState = 0)

Did you mean to assign the value 0 or compare to 0? = or ==?

      int SpeakerPinState;
      SpeakerPinState = digitalRead(SpeakerPin);

Is there some valid reason for declaring a local variable with no initial value and assigning a value to it using two lines of code?

Save some typing:

      int SpeakerPinState = digitalRead(SpeakerPin);

Thanks a lot, now the shape of the code is okay but I still have the logical problem what I was afraid of.

Now it does the following:

when I send the "a" on serial monitor, it turns the output to 1 and it falls into endless switching.

I've written my first virus! :smiley:

So how can I get out of that cycle?

Thanks a lot!

Have you fixed the problem shown in reply#1?

AWOL:
Have you fixed the problem shown in reply#1?

And have you used Tools + Auto Format so your code doesn't look like it was typed by a drunken monkey?

{And} {have} {you} {deleted} {the} {useless} {curly} {braces} {?}

WoW Autoformat is cool :smiley:
I am not exactly sure which {} are useless.

Here's the code now:

#define SpeakerPin 9

byte byteRead;

void setup() {
// initialize serial communication:
Serial.begin(9600);
pinMode(SpeakerPin, OUTPUT);
digitalWrite(SpeakerPin, LOW);
}

void loop() {

if (Serial.available() > 0) {
byteRead = Serial.read();
}

switch (byteRead)

//{case 'a':
// do
// {
// if (SpeakerPinState == 0)
// {
// digitalWrite(SpeakerPin, 1);
// }
// }
// while (

switch (byteRead) {
{ case 'a':
int SpeakerPinState = digitalRead(SpeakerPin);
Serial.print (SpeakerPinState);
if (SpeakerPinState == 0)
{
digitalWrite(SpeakerPin, 1);
}
else if (SpeakerPinState == 1)
{
digitalWrite(SpeakerPin, 0);
}
}
break;
default:
digitalWrite(SpeakerPin, 0);
}
}

Probably I should use a while somewhere, I tried to figure it out without any success yet.

I am not exactly sure which {} are useless.

{ case 'a':
Individual cases do not need to be in curly braces. The set of cases need to be.

What do you have the line ending set to on the serial monitor? Are you sending just the 'a' or are you sending 'a lf cr'

If I press the button "a" and than enter with the setup:

  1. No line ending

than I get ...1010101... endlessly, it stucks

  1. Newline

than I get exactly this "0101010101010101"

  1. Carriage return

the same as 2.

the same as 2 and 3

Sure. byteRead still has the value 'a' so it still gets into that case and triggers a toggle. It will just keep doing that every time loop repeats until byteRead gets a new value. Try setting byteRead to something else in that case statement. Or try sending a different character.

Oh yeah, it works!!!
This is how I did it:

I've put 15 ms delay to wait for the character to arrive.
And commented the default part of the switch function.

Now it works!

Thanks guys!

switch (byteRead) {
{ case 'a':
int SpeakerPinState = digitalRead(SpeakerPin);
Serial.print (SpeakerPinState);
if (SpeakerPinState == 0)
{
delay (15);
digitalWrite(SpeakerPin, 1);
}
else if (SpeakerPinState == 1)
{
delay (15);
digitalWrite(SpeakerPin, 0);
}
}
break;
//default:
// digitalWrite(SpeakerPin, 0);

I've put 15 ms delay to wait for the character to arrive.

?

Please remember h to use code tags when posting code.

Okay, sorry.

I've read this delay thing somewhere a few days earlier and it came to my mind.

I've modified the delay value to 1 /delay (1)/ and it also works. If I comment the delay line out than it doesnt.

Is there anybody who can explain this to me?

Is there anybody who can explain this to me?

  Serial.begin(9600);

Okay, I've read the definiton and googled and now it is 100% clear.

I copy it here, maybe it will be usefull later for somebody:

http://forum.arduino.cc/index.php?topic=48103.0

"That delay(1) is in that code to compensate for the time it takes for the character to be received by the hardware USART. You have to take into consideration that the serial data is being received at, more than likely, a slower speed than it takes for the microcontroller to process instructions.

Picture this: if the microcontroller and the USART were in a foot race, the microcontroller would win every time.

This means that you have to introduce delays to let the USART catch up to the microcontroller.

I assume that you're communicating at some speed faster than 9600 bps, because that code would not work if you were at 9600 bps or lower. This is because it takes over 1 millisecond to receive each character at 9600 bps.

I would recommend using what I posted above, as that is a logical way of receiving the data (although it could be improved by adding time-outs and other fail-safes).
"

This means that you have to introduce delays to let the USART catch up to the microcontroller.

Introducing a delay, and waiting for the data to arrive are not the same thing.

Think about it; at 9600 bits per second, the minimum delay between characters is a bit more than a millisecond, and the maximum delay is potentially infinite(or at least until the heat-death of the Universe).
Don't use delay ().

Okay, I'm lost.

Can you write me this code in the correct way? Without delay? I don't understand how should it look like.