DigisparkにCharlieplexingは不向きかな。 [Arduino]
以前にもマトリックスLEDでCharlieplexingの応用で駆動するのをやりましたが、Digisparkのようなピン数の少ないものほどよい適応かなと思って作ってみました。
結論からいくと、Digisparkではやや動作がおかしいので、Arduino Nano互換機でやりました。
10ポイント青色バーLEDアレイOSX10201-B ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gI-04294/
これをCharlieplexingで光らせるには4ピンあればOKです。(4ピンあれば12個のLEDまでいける)
端切れ基盤にICソケットとピンヘッダと抵抗を載せてポリウレタン銅線で配線。
いざDigisparkでやってみると、なにかおかしい。
光っちゃいけないところがぼやっと光ったりする。
理由として考えられること:
・リセットピン(P5)をI/Oピンとして使うとドライブ能力が低い
・純粋なピンはP0、P2しかなく、他はUSBやbuilt-in LEDとつながっている
という感じだと推測しています。
たとえば、A → B と電流が流れてLEDを光らせる場合、 A → C → B という経路にはほぼ流れないんだけど、ピンの条件が均一でないために A → C → B という経路でもそこそこ流れてしまうのかなって。
仕方ないので、Arduino Nanoの互換機で試してみました。
結論からいくと、Digisparkではやや動作がおかしいので、Arduino Nano互換機でやりました。
10ポイント青色バーLEDアレイOSX10201-B ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gI-04294/
これをCharlieplexingで光らせるには4ピンあればOKです。(4ピンあれば12個のLEDまでいける)
端切れ基盤にICソケットとピンヘッダと抵抗を載せてポリウレタン銅線で配線。
いざDigisparkでやってみると、なにかおかしい。
光っちゃいけないところがぼやっと光ったりする。
理由として考えられること:
・リセットピン(P5)をI/Oピンとして使うとドライブ能力が低い
・純粋なピンはP0、P2しかなく、他はUSBやbuilt-in LEDとつながっている
という感じだと推測しています。
たとえば、A → B と電流が流れてLEDを光らせる場合、 A → C → B という経路にはほぼ流れないんだけど、ピンの条件が均一でないために A → C → B という経路でもそこそこ流れてしまうのかなって。
仕方ないので、Arduino Nanoの互換機で試してみました。
// Drive 10 LEDs with 4 pins
//
// A A A B B B C C C D D D
// +---------------------+ | |
// | | | | | | | | | | | | | |
// | _ _ _ _ _ _ _ _ _ _ | _ _ Cathode(K)
// | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | ^ ^ Anode(A)
// | | | | | | | | | | | | | |
// +---------------------+ | |
// B C D A C D A B D A B C
//
const uint8_t LEDsK[12] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3 }; // Cathode side (0:A, 1:B, 2:C, 3:D)
const uint8_t LEDsA[12] = { 1, 2 ,3, 0, 2, 3, 0, 1, 3, 0, 1, 2 }; // Anode side
const uint8_t LEDsPn[4] = { 2, 3, 4, 5 }; // Arduino pin number (or DDRxn, PORTxn)
static uint8_t pos = 0, dir = true; // Position and Direction(0:-, 1:+) of light
void setup() {
}
void loop() {
lightUpD( dir ? pos++ : pos-- );
delay(50);
if(pos == 9 || pos == 0) dir = 1 ^ dir;
}
void lightUp(uint8_t n){ // Arduino form
for(uint8_t i=0; i<4; i++) {
if( LEDsA[n]==i || LEDsK[n]==i ) { // If the pin is connected to the anode or cathode of the LED,
pinMode( LEDsPn[i], OUTPUT ); // set to output pin
digitalWrite( LEDsPn[i], LEDsA[n]==i ); // set cathode LOW, Set anode HIGH
} else {
pinMode( LEDsPn[i], INPUT ); // Set to Hi-
}
}
}
void lightUpD(uint8_t n){ // port D version
for(uint8_t i=0; i<4; i++) {
bitWrite( DDRD , LEDsPn[i], LEDsA[n]==i || LEDsK[n]==i );
bitWrite( PORTD, LEDsPn[i], LEDsA[n]==i );
}
}