October 2018
Su Mo Tu We Th Fr Sa
30 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 31 1 2 3

Google ads

現在開発中の鉄道模型ポイント切替装置

Nゲージ、HOゲージはデフォルトで対応、16chになります。

意外とこういう装置はありませんでした。まあ、そんなに売れる物でも無いですし、、、

最近鉄道模型関連のお仕事のお話が出てきて、自動運転装置なる物を作りましたが、、

それ以外にも色々お話が出てきて、、大型レイアウトになるとこう言う物が必要になり、

おもちゃのポイント切替機を何個も揃えてやっているのが現状みたいです。

ただ、価格はやっぱりおもちゃの方が圧倒的に安いです。

しかし、それでは満足できない人もいて、、自分で操作卓作ったりと苦労しているみたいです。

お客様から作れない?と聞かれたので作ろうと思えば作れますが、、、、価格高いです、、、

それでも良いとの事なので、、と言うことで作ってみました。

これなら配線を繋ぐだけで好きな操作卓にこの基盤を入れて配線すればすぐ動きます。

また、電源もACアダプターで取りますのでパワーパックから電源引っ張ることも無いので使い勝手は良いです。

そのうちどっかの模型ショーデビューでしょうか?

業務用用途で利用が可能です。

 

ポイント切替 16Ch

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);
}