Go Down

Topic: LED PWM & I2C & Adafruit 16-channel PWM/Servo Shield (Read 3027 times) previous topic - next topic

yellowLooksWhite

Hello,

I'm doing an audiovisual project, and I'm trying to use control 8 13W RGBW LEDs with PWM and two Adafruit PWM Shields (chip: https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf). I'm not using the shield to power the LEDs. Right now I'm having a problem writing to the PWM pins over I2C.

The LEDs work fine with the PWM pins on my Mega 2560 and analogWrite(), and I've been reading a lot about PWM and I2C, but some lack of understanding about PWM and/or I2C is probably to blame.

I want to be able to address the PWM pins 0-15 individually, sending them a value between 0 and 255 from Max/MSP. (I'll be sending e.g. '65 0 0 0 0', where 65 indicates the first LED 'A' and the rest are values b/t 0 and 255 and correspond to R, G, B, and W, and parsing this string in the Arduino.)

The way I understand it, the reason analogWrite(9, 255) works is because 255 is half 500, which is roughly the PWM frequency of the Mega's pins. Reading the Adafruit library, it's clear their code doesn't have what I need. Their code involves calculating the actual cycle information.But I like that I can set the PWM frequency, so I use this in my code.

I checked the pinning of the PCA9685, and find that LED0 = Pin 6.

(Attachment 1)

So I think: Great, now I can tell the Arduino

-Tell the shield I'm talking to it
-Send a value 0-255 to the PWM pin 6

Here's the code I think should work:

(Attachment 2)

Obviously, there's I2C stuff missing. I need some sort of internal address. I also need to address the pull-up resistor (ssn't that handled by begin/endTransmission?).

So I look at the registers and this scares me. 'LED0 output and control byte 0, 1, 2, 3' (?) :

(Attachment 3)

All I want to do is send the PWM value (what I think is most easily done from Max/MSP to Arduino as a single integer, and not a convoluted calculation as an actual parameter).


I'm frustrated and tired and I've been searching for so long, but nobody seems to have a similar issue. If I'm wrong, I'd appreciate if someone could link me to that and I'll be on my merry way. In any case, I appreciate any and all help you guys will give me.

Thanks,

Keith

Wawa

PWM frequency has nothing to do with dimming.
It's just how often a "refresh" is happening.
PCA9685 default is 200Hz.

The commands to dim a LED are inside the library, but I don't know the Adafruit one.

I am using this one:
https://github.com/brunnels/PCA9685

I declared I2C address of the first board.
PCA9685 board_0(0x5F);

And entered board_0 in setup()
board_0.begin();
board_0.setFrequency(200);

Setting a dim level is as simple as
board_0.setChannels8bit(0, 5, 40); // set channel 1 to 6 on dim level 40
or
board_0.setChannel8bit(15, 255); // set channel 16 to max

This is using the chip's 12-bit dimming with an 8-bit lookup table for 255 equal brightness steps.
Look through the examples, or post back when you need help with that.
Leo..

yellowLooksWhite

Thanks Leo!

The example code test.ino doesn't work, but yours does!

For anyone else who uses this, be sure to change

setPWMFrequency() to setFrequency()

and

PWM() to either setChannel8bit() or setChannels8bit(), the latter for multiple channels.

Also make sure to change the 'Wire/Wire.h' to 'Wire.h' in the library if you only have new libraries.

I had to download 'I2C.h', which I found at https://github.com/rambo/I2C.

Here is my code for one RGBW star:
Code: [Select]

#include <PCA9685.h>
#include <I2C.h>


PCA9685 PWMboard1(0x40);

void setup() {
  PWMboard1.begin();
  Serial.begin(9600);

  PWMboard1.setFrequency(500);

  //turn everything off
  PWMboard1.setChannels8bit(0,15,0);
}

void loop() {
  //Red
  PWMboard1.setChannel8bit(0,0);
  //Green
  PWMboard1.setChannel8bit(1, 255);
  //Blue
  PWMboard1.setChannel8bit(2, 0);
  //White
  PWMboard1.setChannel8bit(3, 0);
 

}



This was so much easier than I had even hoped. Thanks again, Leo!

Wawa

At some stage the library did have a big change.
There were more commands, and the old ones (from the example) did not work anymore.
Glad you have sorted it.
Leo..

Go Up