September 2019
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5

Google ads

LED制御のお仕事が入りarduinoで制御してやろうと思い電流源型LEDドライバ基板 PCA9955BTW を買ってみた。

こいつはI2CでLEDを16個電流制御できる物だ。

動くまでハマったので備忘録として書いておく。

まず、この基盤はスイッチサイエンスさんの物で仕様によるとI2Cアドレスは0xcaになっているらしい。

でwireライブラリーでアクセスしてみると、うごかねえ・・・・

こんな感じ、、

Wire.beginTransmission(0xca);
Wire.endTransmission();

そこで、i2cのアドレスサーチプログラムを動かしてどこだか探してみたすると、、、

以下そのプログラム


 

#include <Wire.h>

// Arduino i2c
// Ana 5 ----- 2pin scl (pull-up 2.2k ohm)
// Ana 4 ----- 3pin sda (pull-up 2.2k ohm)
// constants won't change. They're used here to

void setup() {
// put your setup code here, to run once:
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600) ; // パソコンとシリアル通信の準備を行う
Serial.println("bigin") ; // 読み取った値をパソコン(IDE)に送る
}

void loop() {
byte error, address;
int nDevices;

Serial.println("Scanning...");

nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();

if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");

nDevices++;
}
else if (error==4)
{
Serial.print("Unknow error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");

delay(5000); // wait 5 seconds for next scan
}

 


すると、、


Scanning...
I2C device found at address 0x65 !
I2C device found at address 0x70 !
done

なんだよ、0x65じゃねえか・・・

ちょっとまてarduinoのwireライブラリのアドレスは最後のビットは使って無いので1ビット右シフトしなきゃいけないことに気付いた・・

0xca >> 1  は、0x65 ってことだよね。

そして、いよいよLED動作、仕様書とにらめっこして

02h 0 0 0 0 0 1 0 LEDOUT0 read/write LED output state 0

03h 0 0 0 0 0 1 1 LEDOUT1 read/write LED output state 1

04h 0 0 0 0 1 0 0 LEDOUT2 read/write LED output state 2

05h 0 0 0 0 1 0 1 LEDOUT3 read/write LED output state 3

ってのを見つけ投げるアドレスは0x20

なげるデータは

LDRx = 00 — LED driver x is off (x = 0 to 15).

LDRx = 01 — LED driver x is fully on (individual brightness and group dimming/blinking not controlled). The OE pin can be used as external dimming/blinking control in this state.

と書いてあるから、とりあえずFULLY ON で点灯!!

Wire.beginTransmission(0x65);
Wire.write(0x02);
Wire.write(B01010101); //これでLED0~4までがフルオン!!
error = Wire.endTransmission();

うんともすんとも動かない・・・・ 

通信はできている模様。。。

うーん

ここでしばらくめげた・・・

また色々仕様書と格闘!! なんかつかない原因あるんじゃないか????

いろいろ探していたら、このボードは電流制限型だと思い返した。

また仕様書と格闘、以下に気になる項目が・・・

IREF0 to IREF15, LED output current value registers

--------------------------- Table 14. IREF0 to IREF15 - LED output gain control registers (address 18h to 27h) bit description Legend: * default value. Address Register Bit Access Value Description

18h IREF0 7:0 R/W 00h* LED0 output current setting

19h IREF1 7:0 R/W 00h* LED1 output current setting

1Ah IREF2 7:0 R/W 00h* LED2 output current setting

1Bh IREF3 7:0 R/W 00h* LED3 output current setting

カレントセッティングが電流 0 になっている 。

これかなと思い。

全開の0xffを投げてみる。

Wire.beginTransmission(PCA9955BTW_DEV_ID);
Wire.write(0x02); // LED0-3
Wire.write(B01010101); //fully on
error = Wire.endTransmission();

Wire.beginTransmission(PCA9955BTW_DEV_ID);
Wire.write(0x18); //IREF0
Wire.write(0xff);// 電流全開!! 
error = Wire.endTransmission();

LED0点きました!!

ここまで来れば、、どうにでもなるな^^

とりあえず全点灯プログラム張っておきます。

すきに使ってください!


 

void setup() {

Wire.beginTransmission(PCA9955BTW_DEV_ID);//送信先のアドレスを指定して通信開始
Wire.write(0x00); //MODE制御用のレジスタ
Wire.write(B10000001);
Wire.endTransmission(); //通信終了

 }

 

void LedDataSend( ) {

for(int i =0 ; i < 4 ; i++)

{
Wire.beginTransmission(PCA9955BTW_DEV_ID);
Wire.write(0x02+i);
Wire.write(B01010101);
error = Wire.endTransmission();
}
for(int i =0 ; i < 16 ; i++)
{
Wire.beginTransmission(PCA9955BTW_DEV_ID);
Wire.write(0x18 + i);
Wire.write(0x2f); //電流の値、1ポート最大で56mA位みたいなので、とりあえずこんなもんか?
error = Wire.endTransmission();
}

Serial.print("LED return code ");
Serial.print(error, HEX);
Serial.println(" !");
delay(500);
}