LED マトリクス2009/02/10 21:43

ドットマトリクスLEDの点灯実験を行いました。ロボットの目にする予定です。

LEDマトリクス(2)2009/02/13 18:06

回路図
ハードウェアは、
・マイコン :PIC 24FJ32GA002
・シフトレジスタ :74HC595 (列側)
           :TB62726 (行側)
・トランジスタアレイ : TD62784
・LEDマトリクス :LM-035VRB(鈴商で購入)
です。
TB62726は狭ピッチなので変換基板が必要です。今回は アイテムラボDIP24-1P78(2) を使用しました。
LEDの明るさは、シフトレジスタに与えるENABLE信号(PWM)とTB62726に接続するVRで調節します。
写真に写っているオペアンプ(右)とアナデバのIC(下)はこの実験には使っていません。
参考 :
スタータ・キット「TK-78K0/KF2」を利用した電光メッセージボードの作成

LEDマトリクス(3)2009/02/14 18:45

ソースコードです。マイコンのタイマー割り込み(4msecごと)でダイナミック点灯しています。14行を一度に点灯しこれを5回(列)まわします。
データは3次元配列で用意してアニメーションできるようになっています。

/*************************************************
LED MATRIX TEST
09.2.5 
*************************************************/
#include "p24FJ32GA002.h"
#include 
#include 

//configuration bit setting
_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF 
                  & COE_OFF & ICS_PGx1& FWDTEN_OFF )
_CONFIG2( IESO_OFF & FNOSC_FRCPLL & FCKSM_CSDCMD 
                  & OSCIOFNC_ON & IOL1WAY_OFF & POSCMOD_NONE )

unsigned char led_data[3][5][14] = {
       //pattern 0
	{	{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},//row 0
		{0,0,1,1,1,0,0, 0,0,1,1,1,0,0},//row 1
		{0,1,1,0,1,1,0, 0,1,1,0,1,1,0},
		{0,0,1,1,1,0,0, 0,0,1,1,1,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0}
	},
	//pattern 1
	{	{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},
		{0,0,1,1,1,0,0, 0,0,1,1,1,0,0},
		{0,0,1,0,1,0,0, 0,0,1,0,1,0,0},
		{0,0,1,1,1,0,0, 0,0,1,1,1,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0}
	},
	//pattern 2
	{	{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0},
		{0,0,0,1,0,0,0, 0,0,0,1,0,0,0}
	}
	};
unsigned char led_row = 0;
unsigned char led_pat = 0;
unsigned char isBlinking = 0;
int blink_counter = 0;

//******************************
//TIMER1 INTERRUPT every 4msec
//  LED dynamic drive
//******************************
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void){

	int i,j;
	IFS0bits.T1IF = 0;

	//send one row line serial data to shift register
	for(i=0;i<14;i++){
		LATBbits.LATB13 = 0;		//clock
		for(j=0;j<5;j++){}			//wait
		if(i == led_row+9){			//set column data
			LATBbits.LATB15 = 1;
		}else{
			LATBbits.LATB15 = 0;
		}	
		if(led_data[led_pat][led_row][i] == 1){	//set row data
			LATBbits.LATB14 = 1;
		}else{
			LATBbits.LATB14 = 0;	
		}	
		for(j=0;j<5;j++){}
		LATBbits.LATB13 = 1;	//clock
		for(j=0;j<10;j++){}
	}
	LATBbits.LATB15 = 0;
	LATBbits.LATB14 = 0;
	LATBbits.LATB13 = 0;
	LATBbits.LATB12 = 0;
	for(j=0;j<10;j++){}
	LATBbits.LATB12 = 1;	//latch
	for(j=0;j<10;j++){}
	LATBbits.LATB12 = 0;
	
	led_row++;
	if(led_row > 4)led_row = 0;
}

//******************************
//TIMER2 INTERRUPT every 20msec
//  animation control (not necessary)
//******************************
void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void){
	
	IFS0bits.T2IF = 0;
	
	OC3RS=10;	//led drive pwm
	
	//animation control
	if(isBlinking==0){
		if(rand()%100==0)isBlinking = 1;		
	}else{
		blink_counter++;
		if(blink_counter < 10){
			led_pat = 1;
		}else if(blink_counter < 20){
			led_pat = 2;
		}else if(blink_counter < 30){
			led_pat = 1;
		}else{
			led_pat = 0;
			blink_counter = 0;
			isBlinking = 0;
		}	
	}	
}

int main(void)
{
	CLKDIV = 0;			//set 1:1
	 
	TRISB = 0x07FF;			//portB RB11,12,13,14,15 output
	LATBbits.LATB15 = 0;
	LATBbits.LATB14 = 0;
	LATBbits.LATB13 = 0;
	LATBbits.LATB12 = 1;
	
	//output compair allocation
	RPOR5bits.RP11R = 20;		//OC3 to RP11 LED_STROBEZ
	
	//Timer1 initialise inner clock,1/256,FOSC=16MHz **LED control**
	T1CON = 0b1000000000110000;
	PR1 = 250;			//4msec
	IPC0bits.T1IP = 6;		//interrupt priority control
	IEC0bits.T1IE = 1;		//timer1 interrupt enable
	
	//Timer2 initialise inner clock,1/64,FOSC=16MHz
	T2CON = 0b1000000000100000;
	PR2 = 5000;			//20msec
	IPC1bits.T2IP = 5;		//interrupt priority control
	IEC0bits.T2IE = 1;		//timer2 interrupt enable
	
	//Timer3 initialise inner clock,1/8,FOSC=16MHz **LED STROBE**
	T3CON = 0b1000000000010000;
	PR3 = 40;			//20usec
	//OC3 initialise pwm mode with timer2
	OC3CON = 0x000E;
	OC3RS = 20;
		
	//メインループ
	while(1){}
}	
			

モデラー(1)2009/02/21 16:51

ローランドのモデラーMDX-15を使用してメカ部品の加工などをしています。手軽に買える値段ではありませんが、精度もそこそこ(0.1mmレベル)なので便利に使っています。
最初の頃は加工中にいつの間にか位置がずれたり、途中で止まったりとかいろいろと苦労しましたので、経験から得たTipsをのせていきます。
写真は騒音対策用の遮音箱です。ホームセンターで売っているバックルコンテナというプラスチックのケースに入れています。これだけでもかなり効果があり、普通に会話できるぐらいの音に低減できます。

モデラー(2)2009/02/24 20:54

切削途中で位置ずれがでると完璧なリカバリーは非常に困難です。10時間以上も削ったあとの刃物交換でずれたりすると悲惨です。リブの左右での削り量が急に変わったりするのでわかります。
原因のひとつは、VIEWボタンで刃物を退避させたときにレールの端に切り粉が溜まっていることです(矢印)。写真ぐらいの量なら大丈夫ですが、何センチもたまってしまうとキャリアが端まで戻れずにこれを駆動しているステッピングモーターが脱調してしまいます。
対策は、VIEWするときには必ずここにたまったくずをハケで取り除くことです。付属のカバーがついているとこれができませんので、カバーと連動している右側のスイッチは細工して常時ONにしています。(カバーは使っていない)
スイッチを常時ONにすると刃物のZ方向の位置決めもやりやすくなります。普通にZ方向の位置決めをする場合、スピンドルが回転している状態でボタンによる上下動をさせなければならず微妙な調整はできません。スイッチを殺しておけば少し手前までモーターで降ろしたあと、手動でネジをゆるめて刃物をストンと落とせば正確にゼロ位置に合わせられます。