Arduino (ATMega328p) boards can be used to control multiple LEDs. To simplify the management of the pulse width modulation and use only a couple of arduino's pins for many LEDs I used PCA9685 controller. PCA9685 is connected to Arduino using I2C interface that requires only two data pins. .. image:: /media/2019-12-blinking-multiple-leds-with-arduino-atmega328p-and-pca9685/sketch_bb.png :width: 600px :alt: breadboard Blinking multiple LEDs with Arduino (ATMega328p) and PCA9685 .. image:: /media/2019-12-blinking-multiple-leds-with-arduino-atmega328p-and-pca9685/sketch_schem.png :width: 600px :alt: schema Blinking multiple LEDs with Arduino (ATMega328p) and PCA9685 .. image:: /media/2019-12-blinking-multiple-leds-with-arduino-atmega328p-and-pca9685/foto1.jpg :width: 600px :alt: foto1 Blinking multiple LEDs with Arduino (ATMega328p) and PCA9685 .. image:: /media/2019-12-blinking-multiple-leds-with-arduino-atmega328p-and-pca9685/foto2.jpg :width: 600px :alt: foto2 Blinking multiple LEDs with Arduino (ATMega328p) and PCA9685 Arduino connects to PCA9685 using :code:`Adafruit_PWMServoDriver` library: .. code-block:: #include Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Initialization in :code:`setup()`: .. code-block:: pwm.begin(); pwm.setPWMFreq(1600); // This is the maximum PWM frequency Then for each loop we will blink with 2 LEDs. That can be easily extended to more LEDs: Initialization in :code:`setup()`: .. code-block:: void loop() { // set state 1 digitalWrite(LED_BUILTIN, HIGH); pwm.setPWM(0, 0, 3072); pwm.setPWM(1, 0, 4096); // wait delay(500); // set state 2 digitalWrite(LED_BUILTIN, LOW); pwm.setPWM(0, 0, 4096); pwm.setPWM(1, 0, 4095); // wait delay(500); } :code:`pwm.setPWM(p, start, end);` means that for the pin :code:`p` the signal should transition from low to high at tick :code:`start` (between 0..4095) and the signal should transition from high to low at tick :code:`end` (between 0..4095). There are special settings for full on and full off. Full on: .. code-block:: pwm.setPWM(pin, 4096, 0); Full off: .. code-block:: pwm.setPWM(pin, 0, 4096); Along with the other LED we will also control an LED that is built in the Arduino: .. code-block:: void setup() { pinMode(LED_BUILTIN, OUTPUT); // ... } void loop() { digitalWrite(LED_BUILTIN, HIGH); // LED on // ... digitalWrite(LED_BUILTIN, LOW); // LED off // ... } Here is the full listing: .. code-block:: #include Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); void setup() { pinMode(LED_BUILTIN, OUTPUT); pwm.begin(); pwm.setPWMFreq(1600); // This is the maximum PWM frequency } void loop() { // set state 1 digitalWrite(LED_BUILTIN, HIGH); pwm.setPWM(0, 0, 3072); pwm.setPWM(1, 0, 4096); // wait delay(500); // set state 2 digitalWrite(LED_BUILTIN, LOW); pwm.setPWM(0, 0, 4096); pwm.setPWM(1, 0, 4095); // wait delay(500); } Results: .. raw:: html
One issue I had with that Adafruit_PWMServoDriver library is that it is blocking. If your PCA9685 is off or gets disconnected the whole program freezes. As far as I understand Adafruit_PWMServoDriver uses `Wire` as a backend and `Wire` is blocking. That is a known issues and there are some `workarounds `_.