Archive for 9月, 2016
祝!『流れるウインカー』解禁!ということなのでちょっと作ってみる!(とりあえずブレーキランプを流してみる実験編)
久々のコンピューターネタです・・・
クルマのウインカーって、ちょっと前までは、流れるような点灯方式のものはダメだったけど、AudiやMercedesなんかの欧州車で標準装備化されたものが出てきた。
これらの欧州車メーカーは、大のお得意様である日本向けにも、同じ仕様で販売したいという思いがあったのかなかったのかは知らんが、結局のところ、国土交通省さんも外圧に負けて一部許可することになったようです。
国産メーカーも早速のところ、レクサスブランドのクルマの一部にはもう適用されてるもんね。。。
小生の小学校中学校時代くらいの40年前くらいには、自転車のフラッシャーで結構はやったようなモンやな。。。
こんなのこんなの!あったあった!!!
今、見れば結構ケバケバシイ。。。
コンピューターなんかがまだ超高価なものであった時代のものやったやろうから、電子回路的にはほとんどトランジスターとリレーで構成してたんやろか。。。
回路を見てみたいモン。。
とてもカッコいい!とはお世辞にもいえんわな。。。
でも、当時は斬新でかっこええと思ってたわけやし、そのころの憧れを今になって、クルマで再現させてみちゃいましょう!
今や時代は進化して、格安にマイコンが使える時代でもあり、今回は、ウインカーとともにあるブレーキランプも流しちゃおうということで、とりあえずブレーキランプを流してみるための試作をやってみることに。。
まぁかっこいいか悪いかは、作ってから考えるということで、かっこ悪かったら不採用ということにしましょうかね。。。
そういうことで、とりあえずどうやって作るか!
一応は小生は、コンピューターエンジニアの端くれでもあるので、今回は試作ということでもあり、PICを使ってLEDを制御する方法としましょうかね。。。
PICってのは、Microchip社から販売されているマイコンチップで、このチップの中にパソコンと同じようなCPUやメモリなんかが入ってて、この中にC言語やアセンブラでプログラムを作って書き込んで動作させるってもの。。。
詳しくは、PICフリーカーがいろいろと情報を発信してるのでそっちを見てみてちょうだい!
【PIC 入門】
PICは秋月電子で簡単に手に入りますんで、この中で今回は、PIC16F628Aというお手軽に使える石を採用してみました。
(時間に余裕があれば、以下のサイトから調達すると超激安で調達できますよー もう日本の価格とは比較にならないほどの価格ですよー)
今回の仕様は。。。
PIC(マイコンチップ) | PIC16F628A | 1個 |
点灯させるLED数 | 32列×2行 | 32個 |
32列のLEDを制御のためのシフトレジスタ | 74HC595 | 4個 |
電流確保のためのトランジスタ(アレイ) | TD62083AP | 4個 |
こんな感じの部品で作っちゃいます。
とりあえずは、PICで動かすプログラムを作ります。。。
32列もあるので結構いろいろなパターンを作れそうです。。。
Microchip社のPIC開発環境(MPLABX)やC言語コンパイラは、ほとんどがタダで提供してくれているので、素人が作るようなものであればこれで十分です!
プログラムは、昔取った杵柄の馴染みのC言語を使って書くことに。。。
[html]
#include <xc.h>
#pragma config BOREN = OFF
#pragma config CPD = OFF
#pragma config FOSC = INTOSCIO
#pragma config MCLRE = OFF
#pragma config WDTE = OFF
#pragma config CP = OFF
#pragma config LVP = OFF
#pragma config PWRTE = ON
#define _XTAL_FREQ 16000000
#define SI RA0 // データ信号出力ピン
#define SCK RA1 // クロック動作出力ピン
#define RCK RA2 // ラッチ信号出力ピン
#define LightCount 32
#define Blank_Out_Interval 30
#define Full_Flash_Interval 30
#define Center_Diffusion_Interval_1 10
#define Center_Diffusion_Interval_2 10
#define Center_Block_Diffusion_Interval 30
#define Stack_Block_Interval 10
void shiftOut(int bitOrder, unsigned long value){
// bitOrder: 0=LSBFIRST 1=MSBFIRST
int x,i;
unsigned long up_data;
unsigned long lo_data;
up_data = value>>(LightCount/2);
lo_data = value <<(LightCount/2); lo_data = lo_data >>(LightCount/2);
for (i=0;i<LightCount;i++){
SCK=0;
if (bitOrder==0) {x=i;}
else{x=LightCount-1-i;}
if(x<16) {
if(lo_data&(1<<x)){x=1;}
else{x=0;}
}else{
if(up_data&(1<<(x-(LightCount/2)))){x=1;}
else{x=0;}
}
SI=x;
SCK=1;
}
}
void Blank_Out(){
RCK=0;
shiftOut(1,0);
RCK=1;
__delay_ms(Blank_Out_Interval);
}
void Full_Flash(int disp_mode){
//disp_mode = 1 全灯点滅
//disp_mode = 2 両端内側交互点滅
unsigned long Full_On=4294967295;
unsigned long Harf_Outside=4278190335;
unsigned long Harf_Inside=16776960;
RCK=0;
if(disp_mode==1){shiftOut(1,Full_On);}
else if(disp_mode==2){shiftOut(1,Harf_Outside);}
RCK=1;
__delay_ms(Full_Flash_Interval);
RCK=0;
if(disp_mode==1){shiftOut(1,0);}
else if(disp_mode==2){shiftOut(1,Harf_Inside);
}
RCK=1;
__delay_ms(Full_Flash_Interval);
}
void Center_Diffusion(int disp_mode){
// disp_mode = 1 中央から拡大
// disp_mode = 2 中央へ縮小
int i;
unsigned long up_data = 0;
unsigned long lo_data;
unsigned long disp_data;
for(i=0;i<LightCount/2;i++){
RCK=0;
if(disp_mode==1){
lo_data = 65535;
up_data=(up_data<<1)+1;
lo_data=lo_data<<((LightCount/2)-i-1);
lo_data=lo_data<<(LightCount/2); lo_data=lo_data>>(LightCount/2);
disp_data=(up_data<<(LightCount/2))+lo_data; }else if(disp_mode==2){ up_data=65535; lo_data=65535; up_data=up_data>>i;
lo_data=lo_data<<i;
lo_data=lo_data<<(LightCount/2); lo_data=lo_data>>(LightCount/2);
disp_data=(up_data<<(LightCount/2))+lo_data;
}
shiftOut(1,disp_data);
RCK=1;
if(disp_mode==1){
__delay_ms(Center_Diffusion_Interval_1);
}else if(disp_mode==2){
__delay_ms(Center_Diffusion_Interval_2);
}
}
}
void Center_Block_Diffusion(){
int i;
unsigned long disp_data;
for(i=0;i<LightCount/4;i++){
RCK=0;
unsigned long up_data=771;
unsigned long lo_data=49344;
up_data=up_data<<i;
up_data=up_data<<(LightCount/2); lo_data=lo_data>>i;
disp_data=up_data+lo_data;
shiftOut(1,disp_data);
RCK=1;
__delay_ms(Center_Block_Diffusion_Interval);
}
}
void Center_Stack_Block(){
for(int i=0;i<(LightCount/2);i++){
for(int x=0;x<(LightCount/2)-i;x++){
RCK=0;
unsigned long out_data;
unsigned int up_data=1<<x; unsigned int lo_data=32768>>x;
out_data=up_data;
out_data=out_data<<(LightCount/2);
out_data=out_data+lo_data;
if(i!=0){
for(int z=0;z<i;z++){
unsigned long tmp;
tmp=1<<((LightCount/2)-z-1);
tmp=tmp<<16;
out_data=out_data+tmp;
}
out_data=out_data+((1<<i)-1);
}
shiftOut(1,out_data);
RCK=1;
__delay_ms(Stack_Block_Interval);
}
}
}
void main(){
int i,x;
TRISA=0b00000000;
PORTA=0b00000000;
for(i=0;i<8;i++){
if(i<4){
Full_Flash(1);
}else{
Full_Flash(2);
}
}
while(1) {
for(i=0;i<4;i++){
Center_Diffusion(1);
Center_Diffusion(2);
}
Blank_Out();
for(i=0;i<4;i++){
Center_Block_Diffusion();
}
for(i=0;i<4;i++){
Center_Stack_Block();
Center_Diffusion(2);
Blank_Out();
}
}
}
[/html]
まっこんな感じ。。。
あんまり綺麗なプログラムじゃないんで、C言語の勉強には使わないほうがいいかもね。。。(とほほ。。。)
これをMicrochip社のXC8のC言語コンパイラでコンパイルして、RCDライタでPICに書き込みをするわけですけど・・・
ここのサイトの回路図を参考に。。。
こんな感じでRCDライターを作ってみました。。
これでPICに書きこんだもので。。。
実際に稼働させるための電気的な回路は、単純シンプルでPICから発信されるデータピンとクロックピンとラッチピンをシフトレジスタに流して、単純にシフトレジスタをイモヅルで4個ぶら下げるってもの。
とりあえず、PICとシフトレジスタだけで32個のLEDを光らせてみたら。。。
こんな感じ。。。
INTERVALの時間をもうちょっと調整しなきゃね。。。
こんなパターンでPIC16F628Aのプログラム領域は大体90%くらい!
ちゃんと効率的なプログラムを組めばもっと下げられるかもね。。。
もうちょっといい点灯パターンはないかねー。。。芸術的なデザイン能力は無いのでこんなもんしかできません。。。
まぁとりあえず、こんな感じ!
次はウインカーバージョンをやってみるかね。。。
〜後日追記〜
激安でリアガーニッシュをGetしました。
クルマやバイクなどのメカ好きにはたまらないパラダイスを発見!アップガレージで3KJエンジンとE51エルグランドのリアガーニッシュをGET!
これを使って本格的にやってみる計画中!
乞うご期待!