LED関係   

 LED点灯に関係する制作物です。


 6 LEDをセンサーとして使う 2024.03.03
 5 LチカRGB遊び心 その2 2019.09.23
 4 LチカRGB遊び心 2019.09.06
 3 7セグ4桁LEDユニット赤(UART)2011.11.09
 2 7セグ4桁LEDユニット青(UART)2011.11.07
 1 ルーレット(インチキ付き) 2011.10.31






 6 LEDをセンサーとして使う >2024.03.03

 LEDは光起電力があり、光センサーとして使用が可能です。ずっと昔にLEDで明るさを調べて、同じLEDで光を出すものを作っていましたが紛失してしましました。記録はどこのもありません。 LEDが一つだけで明るければ消灯し、暗ければ点灯する様子が楽しくて作り直すことにしました。

以前はmega48を使いC言語で書いたと思うのですが、最近はarduinoばかりですのでそうしています。AD変換を使うと電源電圧で1024を返しますが、とりあえず100で点灯することにしました。3.3V×100/1024=0.32Vの起電力で消灯することになります。なお、赤色LEDは強い光で1.5Vほどの起電力があるそうです。



回路が簡単ですから、基盤はカッターで溝を付けて作りました。プログラム書き込み端子もはんだ付けで済ましています。測定データをPCで読めるようにしていますが端子もはんだ付けで一時的なものとしています。
左上の赤マジックが汚いのですが+-の印でつけることにしています。

ところで何故かACからの電源ではLEDが点滅します。電池では問題がありません。理由は不明です。

/* led_sensor01 */

int a;

void setup() {
  Serial.begin(9600);  // 9600bpsでポートを開く
  Serial.println("serial OK!");
}

void loop() {
  while (1) {
    pinMode(17, OUTPUT);
    digitalWrite(17, LOW);
    delay(1);
    pinMode(17, INPUT);
    delay(1);

    a = analogRead(3);
    Serial.println(a);

    pinMode(17, OUTPUT);
    if (a > 100) digitalWrite(17, LOW);
    else digitalWrite(17, HIGH);;

    delay(100);
  }
}
なお、mega48のヒューズは E2 DF FF です。
     6 LEDをセンサーとして使う top



 5 LチカRGB遊び心 その2 2019.09.23

 廃基板から取り外したチップLEDを使ったものです。こちらが本来の目的で、前のものはテストケースで作ったものでした。


電源スイッチをつけたこと、LEDを4コに増やしたこと、LEDの端子を PC0〜PC2、 PC3〜PC4、 PD0〜PD2、 PD3〜PD5 に変更したのが主な違いです。
LEDのポートを整理したことでLEDの色指定が楽になりました。色を R=1、G=2、Y=3、B=4、M=5、C=6、W=7 として、LEDを左からA、B、C、D としたときに
  PORTC=A+B*8; PORTD=C+D*8;
として、A、B、C、D に 1〜7 を書けば表示されます。

回路図です。


    5 LチカRGB遊び心 その2 おわり  top





 4 LチカRGB遊び心  2019.09.06

 RGBのLEDを3個並べて点灯するおもちゃをつくりました。どのような雰囲気になるのか、ぼつぼつプログラムを書いてみることにします。最近はArduino-IDEばかりだったのでAVRを忘れていますが、思い出しながら書いてみましょう。


回路図はこうなっています。


リセットで点灯メニュー受付状態となり、中央のメニューボタンを押すごとにメニューが順次変わります。メニュー番号はLEDの2進数で表すことにします。リセット後最初に押すと右端のLEDが青く点灯し、2番目は中央の赤、3番目は赤と青が点灯します。
1番はランダム点灯、2番は順次点灯、3番目は赤緑青の同時PWM点灯です。

プログラムは書いている途中ですが現在はこれです。
/* *********************************************************************
  m88p_blink01.c LED点灯プログラム  カラーLED 3個        
  MCU=ATmega88p
  clock 8MHz(X'tal)
  fuse FD D5 FB
  LED  PD3=red  PD4=green  PD5=blue 
       PD6=red  PD7=green  PB0=blue 
       PB1=red  PB2=green  PB3=blue 
  SW  PC0=menu  PC1=start
  
  
********************************************************************** */
#define F_CPU 8000000UL  // 8MHzのとき  より前に定義してください   

#include <avr/io.h>
//#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>

void wait_ms(uint16_t);

volatile uint8_t f=0;   //割り込み関連変数

ISR(TIMER0_OVF_vect){
  TCNT0=240;                        /* タイマカウンタ再設定 255に近づけると周期が短くなる */
  f=1;                              /* 割込ルーチンではフラグを立てているだけ */
}

int main(void){                       /* void:空 引数なし */
	uint8_t n=10,i,menu=0,start=0;
	uint8_t cnt=0,cnt2=0,a0=0,a1=5,a2=10,a3=15,a4=20,a5=25,a6=30,a7=35,a8=40;
/*
	uint8_t d[99]={1,1,1,1,1,1,2,2,3,3,3,3,4,4,4,4,5,5,6,6,7,8,9,10,11,12,13,14,15,16,18,20,
					22,24,27,30,32,35,38,42,46,50,55,60,66,73,79,87,95,99,
					95,87,79,73,66,60,55,50,46,42,38,35,32,30,27,24,22,20,
					18,16,15,14,13,12,11,10,9,8,7,6,6,5,5,4,4,4,4,3,3,3,3,2,2,2,1,1,1,1,1};
*/
	uint8_t d[100]={10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,12,13,14,15,16,18,20,
					22,24,27,30,32,35,38,42,46,60,70,80,99,99,99,99,99,99,
					95,99,99,99,99,80,70,60,46,42,38,35,32,30,27,24,22,20,
					18,16,15,14,13,12,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10};
	
  DDRB=0xff; PORTB=0x00;	// DDRx:0=in 1=out  PORTx:0=low 1=high
  DDRC=0x00; PORTC=0x00;
  DDRD=0xff; PORTD=0x00;
  PORTB=0b00000010;		//
	
  TIMSK0=_BV(TOIE0);                              //タイマー割込許可
  TCCR0B=3;                                      //分周比1/64
  TCNT0=206;                                     //タイマカウンタ初期値 一瞬だから何でもよい
  
	
	cli(); /* 割り込みを無効にする */	
  
	while(start==0){		// set mwnu
		if((PINC & 0b00000001)==0) {menu++;wait_ms(500);}
		if(menu==0) {PORTD=0b00100000; PORTB=0b00000000;}
		if(menu==1) {PORTD=0b00000000; PORTB=0b00001000;}
		if(menu==2) {PORTD=0b01000000; PORTB=0b00000000;}
		if(menu==3) {PORTD=0b01000000; PORTB=0b00001000;}
		
		if((PINC & 0b00000010)==0) start=1;
	    
	}
	
	if(menu==1){
		for(;;){
			i=rand()%9;
			switch(i){
				case 1: PIND=0b00001000; break;		// PINx: 1=toggle both IN and OUT
				case 2: PIND=0b00010000; break;
				case 3: PIND=0b00100000; break;
				case 4: PIND=0b01000000; break;
				case 5: PIND=0b10000000; break;
				case 6: PINB=0b00000001; break;
				case 7: PINB=0b00000010; break;
				case 8: PINB=0b00000100; break;
				case 9: PINB=0b00000100; break;
				break;
			}
    			wait_ms(1000);
		}
	} //if(menu==1)

	if(menu==2){
		while(1){
			for(int i=0;i<8;i++){
			//	PORTB=i*2;
			//	if(i<4) PORTD+=64*i;
			//	if(i>3) {PORTB+=1;PORTD+=64*(i-3);}
				if(i==0){PORTB=0x00; PORTD=0x50;}
				if(i==1){PORTB=0x02; PORTD=0x98;}
				if(i==2){PORTB=0x04; PORTD=0xE0;}
				if(i==3){PORTB=0x07; PORTD=0x28;}
				if(i==4){PORTB=0x09; PORTD=0x70;}
				if(i==5){PORTB=0x0B; PORTD=0xB8;}
				if(i==6){PORTB=0x0D; PORTD=0xC0;}
				if(i==7){PORTB=0x0E; PORTD=0x08;}
				wait_ms(1000);
			}
		}
	} //if(menu==2)
	
	if(menu==3){
		sei(); /* 割り込みを有効にする */	
		while(1){
			if(f){
				f=0;                                        /* フラグをリセット */
		//      if(PORTD&_BV(6)){PORTD&=~_BV(6);}else{PORTD|=_BV(6);}    /* 割込時間測定用端子 割込毎に反転 */
				cnt++;
				if(cnt==100){                               /* 割込100回で1クール */
					cnt=0;
					PORTB=0b00000010;	PORTD=0b10100000;                              /* 全LEDを点灯して        */
					cnt2++; if(cnt2==3){cnt2=0;}              /* 2を3,4・・・と増加すると点滅の周期が長くなる */
					if(cnt2==0){                              /* しかし、ちらつきが目立つようになる        */
						a8++;
						a0++;if(a0==99){a0=0;}
						a1++;if(a1==99){a1=0;}
						a2++;if(a2==99){a2=0;}
						a3++;if(a3==99){a3=0;}
						a4++;if(a4==99){a4=0;}
						a5++;if(a5==99){a5=0;}
						a6++;if(a6==99){a6=0;}
						a7++;if(a7==99){a7=0;}
					}
				}
/*
				if(cnt==d[a0]){PORTB&=0b11111110;}   // デューティに応じて消灯
				if(cnt==d[a1]){PORTB&=0b11111101;}   // ***** 
				if(cnt==d[a2]){PORTB&=0b11111011;}   //  
				if(cnt==d[a3]){PORTD&=0b01111111;}   // **** 
				if(cnt==d[a4]){PORTB&=0b11101111;}   //  
				if(cnt==d[a5]){PORTB&=0b11011111;}   //  
				if(cnt==d[a6]){PORTB&=0b10111111;}   //  
				if(cnt==d[a7]){PORTD&=0b11011111;}   // **** 
*/
				if(cnt==d[a1]){PORTB&=0b11111101;}   // *デューティに応じて消灯**** 
				if(cnt==d[a1]){PORTD&=0b01111111;}   // **** 
				if(cnt==d[a1]){PORTD&=0b11011111;}   // **** 
 			}			
		}
	} //if(menu==3)
	
}//***************** end  of main *************************

/* サブルーチン */
void wait_ms(uint16_t t) {        //ウエイトルーチン 引数1で1ms
  while (t--) _delay_ms(1); 
}
   
    4 LチカRGB遊び心 おわり  top





 3 7セグ4桁LEDユニット赤(UART) 

下に書いた「7セグ4桁LEDユニット青(UART)」の原型で以前に作ったものですが物理的に安定な形に改良したものです。
プログラムも一部変更して、通信速度も 19200bps に変えました。
3.3V電源にすると表示が少し暗くなりますが消費電流は半分近くまで少なくなるようです。ドライブトランジスタ無しでもいけるかもしれません。





以下は最初に作ったときの記述です。
 LED表示は読みやすいディスプレイなのですが、4桁であっても12本のポートが必要なのとその割り振りに悩むことがあるので使いにくいときがあります。以前に、それを回避することも考えて I2C や SPI 通信によるLED表示を作りました。
今回のUART通信によるものは、ほとんどのmcuがUART機能をハードウエア的に持っていることと、データ流し込み方式だと信号線は1本で済ませられること、mcuが低価格で入手できること、LEDの消費電力からmcuが2つになっても影響がないこと、趣味の自作では考え方が単純な方がいいこと、などから作ってみた次第です。

mcuはこれからは新規採用しない 90S2313 としました。新しく買うならtiny2313の方が安くて振動子も要らないのですが、手持ちを消化するために使っています。完成度を考えるならSOICにすると収まりが良くなります。

通信は、数字以外の文字を受けると数字受付の初期化を行い、続けて4桁の数字プラス小数点の位置を表す数字(最高位が1)の5桁の数値を表す文字を受け付けます。
数字以外の文字に続く5個の数字文字を受けると表示文字列として処理します。このとき数字5個が続かないと表示ルーチンには送られません。
試行錯誤の結果プログラムはこのような形になりました。         筆者メモ F:\prA\_2011\led4keta_s2313

  3 7セグ4桁LEDユニット赤(UART)おわり



 2 7セグ4桁LEDユニット青(UART) 

高輝度の青色7セグメントLED表示器を秋月で購入しました。低い駆動電流で実用になるそうです。そこで 3.3V電源で、IOポート直接駆動を目論みました。
事前に電流を調べると、3.3V電源で220Ω制限抵抗を付けてエレメントを発光させると 2.1mA の電流でやや輝度が小さい感じがしますが実用になりそうです。2.1mA×8エレメントで 17mA ですからポートの出力容量に収まりそうです。
tiny2313の出力電圧とVf=3.3Vの条件が気がかりでしたが、無理なら5Vでもいいと考えて試作しました。





以前にも書きましたが4桁LEDはドライブに8+4=12のポートを必要としますので他のポートを多く使いたいときに配置に苦労しますし、また連続したポートを取りにくいケースがありますのでtiny23131個が余分に必要にはなりますがメインボードではTXD1ポートで駆動できることで試作がらくになります。

写真のようにすっきりしたものになりました。桁ドライブのトランジスタ4個とベース抵抗4本は以外と場所と手間を必要としますが今回はそれが無いので製作もらくになっています。電源の電流計が約20mAを示しています。かなりの誤差はありますがIOポートが酷使されていることは無いでしょう。輝度はやや低めですが室内では十分実用になりそうです。
物珍しさで青色を選びましたが数値を読みとるという機能からは赤や緑が適しているように思いました。赤は危険の色、緑は安全の色という概念がありますが「灯り」に関しては赤が自然なのかもしれません。余談ですが車のヘッドライトに1万ケルビンを超えるものがありますが私は嫌悪感を持ちます。6000ケルビン以下が落ち着きます。
さし当たっての用途はありませんが実験パーツとして利用しようと考えています。
プログラムです。     筆者メモ: F:\prA\_2011\led4keta_blue

  2 7セグ4桁LEDユニット青(UART)おわり



 1 ルーレット(インチキ付き) 

 MCUとは例えばこのようなものですよ、と見てもらうために作ってみました。配線が見えるように穴無し基板で、すべてを表面に実装してみました。


スタートボタン(リセットボタン)で遅い回転から速くなり最後は40msで1周します。ストップボタンで回転が遅くなりあるスピードになると止まります。ボタン押下から停止までの移動回数は一定になっていますからボタンを押すときに数値が決まりますが5msで次の数値に変わりますから意図的に決めることはできないと考え乱数になると思います。
付け加えたのは『インチキ機能』です。クイズ番組などで回答者が電子ルーレットできまる(座席にランプが順について止まる)ものがありますが、あれは偶然とは考えにくいものです。誰に当たるか分からなくては打ち合わせもできません。見ている者には偶然のように感じさせますがきっとうち合わせで決まっているのでしょう。
物理的なルーレットでは難しいことですが、知らない人は電子機器を信用しますが電子機器故に簡単に人為的な行為ができるサンプルとして付けてみました。
丸ピンソケットを利用した簡易スイッチで番号を指定しますとその番号で止まります。本来は隠しスイッチにするものでしょうがあえて前面に出しています。

mcuは手持ちの内でIOポートの多いmega48を使いました。ポートBでインチキスイッチを検出し、ポートDでLEDを点灯しています。ポートC0にストップスイッチを付けました。電源は裏面に平たいLi-ion電池を貼り付けています。
プログラム                    筆者メモ F:\prA\_2011\m48_roulette

  1 ルーレット(インチキ付き)おわり























工事中

 0 タイトル 2019.00.00

 
     0 タイトル おわり  top



inserted by FC2 system