LEDR, LEDG, LEDB never quite turn off with analogWrite() #74
Description
Arduino Nano 33 BLE Sense v1.1.4
Arduino IDE 1.8.9, (Windows 10)
Sketch shows a problem with analogWrite() and Arduino Nano 33 BLE
LEDR, LEDG, LEDB all don't quite turn all the way off.
analogWrite() goes from 0-255, but mbedos expects a float 0.0-1.0.
I think 255 (0xff) turned into about 0.996 instead of 1.000.
This leaves LEDR, LEDG, LEDB still partly on, at about 0.4% intensity.
LED_PIN is not quite 100% on (still only at 99.6%).
Setting analogWrite(LEDx, 256) turns the LED off, but it's no longer an 8-bit value.
void setup() {
}
void loop() {
int waitTime = 2000; // msec
analogWrite(LEDR, 255); // Cathode tied to +3V3
analogWrite(LEDG, 255);
analogWrite(LEDB, 255);
analogWrite(PIN_LED, 0); // Anode tied to GND
//Serial.println("All LEDs should be completely OFF");
delay(2000);
analogWrite(LEDR, 0);
analogWrite(LEDG, 0);
analogWrite(LEDB, 0);
analogWrite(PIN_LED, 255);
//Serial.println("All LEDs should be 100% ON");
delay(2000);
//#define UINT8_HAS_9_BITS
#ifdef UINT8_HAS_9_BITS
// 256 is 0x100 -- 9 bits. Demonstrates you CAN turn the LED off by cheating.
analogWrite(LEDR, 256);
analogWrite(LEDG, 256);
analogWrite(LEDB, 256);
analogWrite(PIN_LED, 0);
//Serial.println("All LEDs are completely OFF -- but used out of range values");
delay(500);
#endif
}
I think the fix might be in the two lines 40 and 95 in the analogWrite() functions in .../cores/arduino/wiring_analog.cpp.
Change from:
float percent = (float)val/(float)(1 << write_resolution);
to:
float percent = (float)val/(float)((1 << write_resolution) - 1);
This makes the (8 bits maximum) value 255 correctly map to 1.0 (the mbedos equivalent).