Dimmer Example, analogwrite resets to 0

Hello,

this is my slightly modfied version of the dimmer example:

const int ledPin = 3;      // the pin that the LED is attached to
int brightness;
void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // check if data has been sent from the computer:
  if (Serial.available() > 0) {
    int brightness = Serial.parseInt();
    analogWrite(ledPin, brightness);
    Serial.print(brightness);
    } 
}

Upon entering e.g. 100 the LED gets brighter, and then turns off. Output of my code is

>> 100
>> 0

I just can't figure out why brightness gets set to 0 again. Even if I say

const int ledPin = 3;      // the pin that the LED is attached to
int brightness = 10;
void setup() {
...

the LED stays on as long as I don't enter anything. When I enter a number in the serial monitor, the LED will turn off afterwards.

brightness is defined outside of the if environment, so it should "live" on?

Thanks in advance!

edit: I would expect the LED to stay at a certain value until I enter another. Just in case it isn't clear what I expect the code to do.

Damm newlines!

What does parseInt() do if it does not find an int!

Mark

int brightness = Serial.parseInt();

You are re-defining the variable in loop(). You need to use the global one so the value is saved.

You are re-defining the variable in loop(). You need to use the global one so the value is saved.

No! OP needs to get rid of the (unused) global variable. There is NO reason for brightness to be global when the ONLY time it's value matters is when there is serial data to value it.

OP: What line ending do you have set? It should be new line only or carriage return only, not both and not neither.

holmes4:
Damm newlines!

What about them?

holmes4:
What does parseInt() do if it does not find an int!

For my purpose I don't need to catch that exception. I'll only enter integers.

PaulS:
OP: What line ending do you have set? It should be new line only or carriage return only, not both and not neither.

No line ending. I'm sorry, I didn't post the output verbatim (I do realize that's the only thing I should have done). I thought it would enhance readability. I edited the output in my first post. Couldn't do it anymore, so:

Enter: 100
Output: 1000

Or for a series of values:

Enter: 100
Output: 1000
Enter: 50
Output: 1000500
Enter: 23
Output: 1000500230

PaulS:
No! OP needs to get rid of the (unused) global variable. There is NO reason for brightness to be global when the ONLY time it's value matters is when there is serial data to value it.

I will test that tonight. Still wondering why it becomes 0, even it is set globally to 10 e.g.

    Serial.print(brightness);

Make that println(), so you don'tgetalltheoutputjammedtogether.

Then, I'll bet that you see
100
0
50
0
23
0

Where the extra zero is because parseInt() returns 0 if the input stream does not contain data that represents a valid integer value.

For my purpose I don't need to catch that exception. I'll only enter integers.

Exceptions are NOT used on the arduino. The method will ALWAYS return something regardless of what is in the buffer.

Mark

const int ledPin = 3;      // the pin that the LED is attached to
int brightness_old;
void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // check if data has been sent from the computer:
  if (Serial.available() > 0) {
    int brightness = Serial.parseInt();
    if (brightness == 0) {
      brightness = brightness_old;
    }
    analogWrite(ledPin, brightness);
    brightness_old = brightness;
  }
}

However now I obviously can't send a 0. Why does parseInt() gets called in the first place? If I don't send anything the if loop in which it resides in shouldn't run. Probably I can't see the woods from the trees here.

parseInt() is a blocking function. It will wait for the input or until timeout exceeds, in which case it will return a 0.

Check what you receive.

void loop() {
  // check if data has been sent from the computer:
  if (Serial.available() > 0)
  {
    Serial.println(Serial.read(), HEX));
  }
}

The hex representation of each received character will be printed on a new line in the serial monitor (or other terminal program that youy might use). You can use e.g. http://www.asciitable.com/ what the values mean.

//Edit
You can read the updated Serial Input Basics to get ideas how to reliably read serial data.

sterretje:
The hex representation of each received character will be printed on a new line in the serial monitor (or other terminal program that youy might use).

That didn't really help with my understanding that the if function should be skipped after I read my entered value, thus parseint() not returning zero.

sterretje:
You can read the updated Serial Input Basics to get ideas how to reliably read serial data.

That did indeed helped me! I was able to get the code running as I desired. Ty!

chuckyx:
That didn't really help with my understanding that the if function should be skipped after I read my entered value, thus parseint() not returning zero.

The intention was to check if you received any strange characters (e.g. CR and/or LF; yes, I know you said 'no line ending')) that would cause the problem.

But glad you got it solved.