GR KURUMI + LEDマトリクス (その2)
id:currygyu:20130528
前回↑が消化不良だったので、改良してみました。
修正点
・トランジスタアレイを使ってLED用の電源を別に確保
・上記に関連して、電源を3.3Vから5Vに変更
(3.3Vで始めたらトランジスタアレイの電圧降下でLEDが点灯しなくなりました)
・74HC595(x2)でインタフェースをSPI化
はんだ付けを1箇所ずれたまま進めてしまい、半日悩んだりしましたが、どうにか完成しました。
次はフルカラーのLEDマトリクスをいじってみようかと思います。
SPI化したので、GR KURUMIのスケッチもシンプルになりました。
/*GR-KURUMI Sketch Template Version: V1.00*/ #include <RLduino78.h> #include <spi.h> byte leddat[8] = { 0x18, 0x24, 0x42, 0x81, 0x81, 0x42, 0x24, 0x18 }; void disp_update(unsigned long u32ms); // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. pinMode(9, OUTPUT); // SS(STCP) digitalWrite(9, HIGH); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV128); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); delay(50); attachCyclicHandler(1, disp_update, 1000); } // the loop routine runs over and over again forever: void loop() { byte i=0; for(i=0; i<8; i++){ SPI.transfer((byte)(0x01<<i)); SPI.transfer(leddat[i]); digitalWrite(9, HIGH); digitalWrite(9, LOW); delay(1); } } void disp_update( unsigned long u32ms ) { int y, x; int num = 0; int alive = 0; byte work[8]; for(y=0; y<8; y++){ work[y] = leddat[y]; } for(y=0; y<8; y++){ for(x=0; x<8; x++){ num = 0; /* count around */ if( x != 0 ){ if( ( ( leddat[y] >> ( 8-x ) ) & 0x01 ) != 0 ){ num ++; } } if( x != 7 ){ if( ( ( leddat[y] >> ( 6-x ) ) & 0x01 ) != 0 ){ num ++; } } if( y != 0 ){ if( ( ( leddat[y-1] >> ( 7-x ) ) & 0x01 ) != 0 ){ num ++; } if( x != 0 ){ if( ( ( leddat[y-1] >> ( 8-x ) ) & 0x01 ) != 0 ){ num ++; } } if( x != 7 ){ if( ( ( leddat[y-1] >> ( 6-x ) ) & 0x01 ) != 0 ){ num ++; } } } if( y != 7 ){ if( ( ( leddat[y+1] >> ( 7-x ) ) & 0x01 ) != 0 ){ num ++; } if( x != 0 ){ if( ( ( leddat[y+1] >> ( 8-x ) ) & 0x01 ) != 0 ){ num ++; } } if( x != 7 ){ if( ( ( leddat[y+1] >> ( 6-x ) ) & 0x01 ) != 0 ){ num ++; } } } /* decide */ if( ( ( leddat[y] >> ( 7-x ) ) & 0x01 ) == 0 ){ if( num == 3 ){ work[y] |= ( 0x80 >> x ); } } else{ if( ( num != 2 ) && ( num != 3 ) ){ work[y] &= ~( 0x80 >> x ); } } } } for( y=0; y<8; y++ ){ leddat[y] = work[y]; } }
表示内容は前回と同じライフゲームです。
1秒ごとにタイマで呼ばれるdisp_update関数の中で、表示内容を設定するleddat配列を書き換えています。その辺りをいじれば好きな表示内容に変更も可能かと。
※leddat配列は、ドットを8ビットで表現したものを1行目から順に8行分入れたたものです。
SPIで16ビット送信していますが、最初の8ビットは行指定、次の8ビットは点灯内容となっていて、送信後に74HC595にラッチの信号(KURUMIの9ピン)を入れて表示内容を反映させています。
よくあるやりかたなので、検索すればたくさんでてきます。僕もマネしました。
回路図
https://docs.google.com/file/d/0B9mpDLlbvvN8Wi04eVk1VGpBSkk/edit?usp=sharing
※7/5 配線ミス修正&PDFの窓を出すのやめました