前回vividさんに助言を頂き、AVRのランダム点灯のプログラム作りました。
まっ、ランダムと言っても疑似乱数なので、スイッチを入れると毎回同じ順番でランダムに点灯します。
なんかわかりにくい文章ですねw
たとえば、15,3,42,34,11・・・・てな順番で乱数が生まれるとすると、スイッチを再度入れ直しても15,3,42,34,11、・・・・・てな感じで同じ乱数が生成されるということです。
今回は「線形合同法」という式を使いました。式は {Xn+1=(Xn*a+b)/c}てな物らしいです。私もよく理解できていませんw
で、プログラムはこんな感じになりました。
//——————————————————————————————-
#include <avr/io.h>
void wait(uint16_t w){while(w–){volatile uint16_t i=1;while(i–);}}
int a=10,s=10,h;
//——— timer —————————————
void ta(){for(h=0;h<a;h++){wait(10000);}}
void t5(){for(h=0;h<12;h++){wait(10000);}}
void t4(){for(h=0;h<10;h++){wait(10000);}}
void t3(){for(h=0;h<8;h++){wait(10000);}}
void t2(){for(h=0;h<6;h++){wait(10000);}}
void t1(){for(h=0;h<4;h++){wait(10000);}}
//———-Randam—————————————
void myRand(){
a=(a*1812433253+12345)%11+3;
s=(s*1812433253+12345)/128;
}
//——————————————————-
int main(void)
{
DDRB = 0b00011111;
PORTB = 0b00011111;
t5();
while(1) {
myRand();
PORTB =s;
ta();
}
}
timerの部分には必要ない関数も入ってます。さらにPORTBに乱数sを直接放り込む乱暴なプログラムですがw動きますw
点滅するLEDと点滅間隔がランダムになるようにしています。
myRand()内の数字は適当です。
これを動かすとこんな感じになります。
乱数で動作しているので完全に無作為になっているため、光っているLEDが1つだけとか結構あります。で、最も問題なのが全てのLEDが消えている(動画の53秒あたり) 時もあるんですよね・・・・。
さらに時間のランダム感も薄いようなw←コレは私のプログラム能力の無さが原因ですがw
今回の電飾にはむしろ前回自分でランダムぽく書いていたコントロールされたプログラムの方がいいかもしれません。
それと、パネル全体の点滅のタイミングが一緒というのも面白くないので、タイミングを変更したATtiny13Aを追加することにしました。
AVRをまとめてATmega168Pとかにしないのはプログラム考えるのが面倒だからですw ATtiny13Aならプログラムが使いまわしできるから、数で勝負w
結局プログラムは以前のランダムぽく書いてあったプログラムの方を使い1つのAVRに付きLED3つで、タイミングの違うAVR2つ、LED合計6つで点灯させてパネルごとの動作の違いを表現してみました。
こんな感じになります。
この手法で全体のランダムな点灯を表現しようかなと思っています。
関連すると思われる記事:
- None Found
おはようございます!
そうですね〜、6jiroさんのオリジナルの方がとっても良いですね。
RAND関数の方はクリスマスツリーみたいです(笑)
点灯させたいLEDのブロック毎に点滅周期の上下限値の設定がいるのかもしれません。
しかし電飾の場所が多いので実感が出ますね!
vividさん こんにちは!
randam関数はおっしゃる通り上下の限界値の設定が必要ですね。
どこかでそのようなプログラム見た記憶が頭のどこかにあるのですが・・・・・。
まっ、今回は偽ランダムで行ってみます。AVRはあともう一つくらいたして3つでコクピット全体を賄ってみようかなと思っています。