I've just got my Arduino and am really enjoying figuring out how to use it. I've got to the fade example in the basics section of the tutorials, had it running fine and then started tinkering with the code to try and really understand it. This is what I started with:
int led = 9;
int brightness = 0;
int fadeAmount = 5;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
analogWrite(led, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
delay(30);
}
I then changed the if statement to remove the lower bound on the checking i.e.
My expectation was that the code would run normally for one fade up and fade down cycle, but then the LED would never relight again because the value of brightness would just become more and more negative.
What actually happens is that the LED fades up, fades down and then simply jumps back to fully illuminated.
I will be very grateful if somebody can explain what is going on, always good to properly understand what you're seeing happening.
Because you took off the lower bound, it will continue to decrement brightness until it rolls over and brightness once again equals 255. Afterwards it will then increment until it again rolls over and brightness equals 255.
What you are seeing with your LED is the error with the wiring_analog library. It looks like this:
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
else
{
...
}
Thanks for the response. So does the rollover happen when it reaches the limit of the int variable? Feels like it gets to -32,767 pretty quickly. Or is something else happening?
AWOL:
Negative brightness?
That would be cool, kind of a mini black hole controlled by the Arduino. If I manage to get it working I'll post on here.
Had an idea on how to answer by own question and started sending the value of brightness out through the serial port. The value of brightness keeps becoming more negative, but even when it is negative, the LED continues to brighten and fade. Does this relate to the error in the wiring_analog library? I thought I had understood it, but now suspect I haven't.
ClimberSam:
Had an idea on how to answer by own question and started sending the value of brightness out through the serial port. The value of brightness keeps becoming more negative, but even when it is negative, the LED continues to brighten and fade. Does this relate to the error in the wiring_analog library? I thought I had understood it, but now suspect I haven't.
Yes, right now the value that is sent to the PWM timer is only looking at the first byte of the int (2 bytes). That byte is controlling the LEDs brightness, regardless if the value is negative or not, it will still only be seen as 0 - 255.
However if you fix the library with what I showed you, then the LED will be fully off the the value is negative or zero and below, and fully on if the value is 255 and above. The only time the LED will fade is when the value is in between 0 and 255.
The library needs NO fixing. It is expecting an 8-bit unsigned integer (0-255). If you feed it with a 16-bit signed integer with negative values, -1 is 0xFFFF, -2 is 0xFFFE so the lower 8 bits just keeps decreasing as you get more negative. Your effect is 255->254->253.....1->0->255... so bright to dark and immediately bright.
You dig pretty deep, good for you.
OCR0 = val; // set pwm duty
OCR0A or B register is 8-bit.