Quick question on coding for PWM servo drivers

I'm currently working on an LED controller, and although it works on a Mega, I want to use a Nano, but I ran out of pins. I then came across an Adafruit 16 Channel 12 Bit PWM/Servo Driver. I haven't bought it yet, but looking at the example, and it looks simple enough....

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel PWM test!");

  pwm1.begin();
  pwm1.setPWMFreq(1600);  // This is the maximum PWM frequency

  pwm2.begin();
  pwm2.setPWMFreq(1600);  // This is the maximum PWM frequency
}

But I'd like to be able to add it to add it into the already existing LED sketch...

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 3;            // pin for channel 4

Can I just define 'Adafruit_PWMServoDriver pwm1' as 'oneLed', 'Adafruit_PWMServoDriver pwm2' as 'twoLed', etc and let the sketch take over from there?

I will assume you are talking about the Adafruit PCA9685 PWM/ServoDriver. Once we knew that a search of the library manager turned up a few hits, I chose the library with an author who has many libraries and is well known for quality work. See pic. Once installed, looking at the sample code that comes with the library should help you solve your problem in a few minutes.

Thanks, but the sample code I posted came from the Adafruit site itself.

My question was about defining the 'Adafruit_PWMServoDriver pwm1' as 'oneLed', instead of recoding the entire sketch to use Adafruit_PWMServoDriver pwm1', etc, etc.

Can I use

Adafruit_PWMServoDriver oneLed = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver twoLed = Adafruit_PWMServoDriver(0x41);
Adafruit_PWMServoDriver threeLed = Adafruit_PWMServoDriver(0x42);
Adafruit_PWMServoDriver fourLed = Adafruit_PWMServoDriver(0x43);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 3;            // pin for channel 4

Would that work?

Did you try to compile it? It will fail because you e.g. have two variables called oneLED.

The PCA9685 can control up to 16 LEDs so it's not very useful to have four of them for only 4 LEDs. How many LEDs do you want to control?

Thanks. I haven't tried to compile it yet, as I haven't bought one yet. I was trying to see what was involved before getting one. I realize it can do 16 channels... my project works on a Mega, but uses too many pins as it is for a Nano. Besides LEDs, I also have fans, pumps, DHT and DS18B20 sensors. Without the sensors, pumps and fans, I'm fine. But if I want to use all my mods, I need more pins.

I guess I should just order one and start testing then.

Cheers.

That does not matter, you can always compile.

2 Likes

Very true. Thanks, I'll try that.

I was originally going to use an LCD shield to free up the 6 pins of the LCD, 1 pin for the backlight, and another 4 for the buttons, using only the i2c pins instead, along with vcc and gnd. But I'm mounting everything in a box, and need the buttons separate from the shield, and the unit from Adafruit now comes with them already soldered to the board. I tried desoldering them, but they're smd, and quite stubborn. No luck. There's a hobby shop in town that has the older version without everything already soldered together, and with through-hole buttons, but they were out of stock. This was my next idea.

Holy crap... it worked.

#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x42);
Adafruit_PWMServoDriver pwm4 = Adafruit_PWMServoDriver(0x43);


// LED variables. These control the behavior of lighting. Change these to customize behavoir
int oneLed = 0x40;             // pin for channel 1
int twoLed = 0x41;            // pin for channel 2
int threeLed = 0x42;          // pin for channel 3
int fourLed = 0x43;            // pin for channel 4

Well, at least it compiles... will still have to see if it's functional or not. Board arrives on Friday. Will test it then.

Cheers.

Without other modifications to your existing code it will not work.

Note with the PCA9685 if you want to drive LEDs and servo motors at the same time the LEDs can be connected directly to the chip's output pins.

But the output to the servos must be inverted for it to work correctly.

I used a PNP BC237 transistor to do this but many others will do equally as well. This is the circuit I used to control both the servos and the LEDs on my animatronic skull Mulder. Forget the fact that it is using a Raspberry Pi that bit applies to all processors driving the chip.

This is Mulder in action.

1 Like

The sketch has the option for setting the channels to be inverted, so that's not an issue...

// variables to invert the output PWM signal,
// for use with drivers that consider 0 to be "on"
// i.e. buckpucks. If you need to provide an inverted 
// signal on any channel, set the appropriate variable to true.
boolean oneInverted = false;
boolean twoInverted = false;
boolean threeInverted = false;
boolean fourInverted = false;

But... I decided to cancel the order, then ordered a 5 pack of the LCD shields. I just realized I can still reassign the buttons to actual Arduino pins instead of trying to remove the buttons from the shield, then rewiring new buttons to mount on the front of the box I'm housing everything in. I should have figured that out the first time. It still frees up all the pins used by the LCD.

OK if you are really really sure about that. Remember my circuit if that doesn't work.

1 Like

Thanks Mike, already downloaded and saved.

Cheers.

Well, turns out I ordered the wrong LCD backpack... all this one does is connect to an Uno, using the regular pinout, no i2c whatsoever. Sending it back. But then I just discovered that Nano pins D0/RX and D1/TX can be used as digital i/o, as long as you don't require serial communication. I don't. And... those 2 pins are all that I need to complete my project on a Nano. Wish I figured that out earlier.

It is true, but please note that you must disconnect anything from these pins while you upload the code to the board.

2 Likes

Thanks, b707. I had read that in the posts I came across, but forgot to mention it. I plan on programming the Nano before inserting into the box I'm planning for it anyway, so that's not an issue. I tested by moving the LEDs from D9 and D10 to D0 and D1, and although they lit up while programming, they'd be controlled by a relay anyway, which wouldn't be active while programming. That's 'if' I wanted to program while in the circuit.

Cheers.

edit: or even better... I'm planning on connecting the LED's PWM signal wires to the box via stereo plugs and jacks, so I can just disconnect while programing, then reconnect when done. I ordered some DIY mini usb male connectors, which I plan on wiring to a usb-c female breakout header to fit in the usb-c port of the box I'm mounting everything into.. a DeskPi Lite case used for Raspberry Pi 4's that already has holes for all the plugs I want to use. Hopefully I can wire up the usb-c to mini usb for data as well, not just power. Then if I need to reprogram for any reason, I won't even need to pull it from the box. Hopefully.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.