LEDで蛍光灯を作る 3

Arduinoのスケッチはこちら。
(Gistを使って表示しています。Bloggerを動的ビューにして見ている方には見えないかも。)
/*
LED fluorescent-light simulation.
Low speed PWM(50Hz and 50-90 percent duration) flickers each light.
Each switch-on time delays randomly.
Sometime it turns off and on like an error.
output:d0-d3
random seed:a2
also detects mains off.
Wire mains to a0 input through an resistor and a0 to ground through another resistor
in order to fit the input voltage within 0-5v.
(for example,I use dc12v as mains,so I choose 15k and 4.7k resistor to get almost 3v.)
*/
int outPins[4] = {0,1,2,3};
byte lightState[4] = {0,0,0,0};
const unsigned long OFFSET[4] ={0,5,10,15};
const unsigned long PERIOD = 20; // T[ms}=1000[ms]/50[Hz]
const unsigned long DUR = 80;
const unsigned long DELAY_MAX = 1000;
const long BAD_DENOM_BOOT = 4; // denominator of failure probability on booting
const long BAD_DENOM_RUN = 40000; // denominator of failure probability on running
const byte anaPin = 2;
long mainsTh;
void setup() {
randomSeed(analogRead(anaPin));
mainsTh = analogRead(anaPin) * 9 / 10;
for(int i=0; i<4; i++){
pinMode(outPins[i],OUTPUT);
}
startSeq(outPins,lightState,OFFSET,PERIOD,DUR,DELAY_MAX,mainsTh,anaPin);
}
void loop() {
isMainsOff(mainsTh,anaPin,outPins,OFFSET,PERIOD,DUR);
for(int i = 0; i < 4; i++){
pwmWrite(outPins[i],lightState[i],OFFSET[i],PERIOD,DUR);
}
if(random(BAD_DENOM_RUN) == 0){
turnIt(2,0,outPins,lightState,OFFSET,PERIOD,DUR,DUR/4,DELAY_MAX*4,mainsTh,anaPin);
turnIt(2,1,outPins,lightState,OFFSET,PERIOD,DUR,DUR,DELAY_MAX/2,mainsTh,anaPin);
}
if(random(BAD_DENOM_RUN/2) == 0){
turnIt(3,0,outPins,lightState,OFFSET,PERIOD,DUR,DUR/4,DELAY_MAX*5,mainsTh,anaPin);
turnIt(3,1,outPins,lightState,OFFSET,PERIOD,DUR,DUR,DELAY_MAX/2,mainsTh,anaPin);
}
delay(1);
}
void startSeq(int outPins[],byte lightState[],const unsigned long offSet[],unsigned long period,unsigned long dur,unsigned long delayMax,long mainsTh,byte anaPin){
shuffle(outPins,4);
turnIt(0,1,outPins,lightState,offSet,period,dur,dur,delayMax/2,mainsTh,anaPin);
for(int i=1;i < 4; i++){
turnIt(i,1,outPins,lightState,offSet,period,dur,dur,delayMax/(4-i),mainsTh,anaPin);
}
if(random(BAD_DENOM_BOOT) == 0){
turnIt(2,0,outPins,lightState,offSet,period,dur,dur/4,delayMax*2,mainsTh,anaPin);
turnIt(2,1,outPins,lightState,offSet,period,DUR,dur,delayMax/2,mainsTh,anaPin);
}
if(random(BAD_DENOM_BOOT/2) == 0){
turnIt(3,0,outPins,lightState,offSet,period,dur,dur/4,delayMax*3,mainsTh,anaPin);
turnIt(3,1,outPins,lightState,offSet,period,dur,dur,delayMax,mainsTh,anaPin);
}
}
void turnIt(int i,byte flag,int outPins[],byte lightState[],const unsigned long offSet[],unsigned long period,unsigned long dur,unsigned long durIt,unsigned long delayMax,long mainsTh,byte anaPin){
unsigned long delayTime = (unsigned long) random(delayMax);
unsigned long startTime = millis();
while(lightState[i] != flag){
if(millis() - startTime > delayTime){
lightState[i] = flag;
}
isMainsOff(mainsTh,anaPin,outPins,offSet,period,dur);
for(int j = 0; j < 4; j++){
if(i == j){
pwmWrite(outPins[j],lightState[j],offSet[j],period,durIt);
}else{
pwmWrite(outPins[j],lightState[j],offSet[j],period,dur);
}
}
delay(1);
}
}
byte isMainsOff(long mainsTh,byte anaPin,int outPins[],const unsigned long offSet[],unsigned long period,unsigned long dur){
if(mainsTh <= analogRead(anaPin)){
return 0;
}
while(mainsTh > analogRead(anaPin)){
for(int j=0;j<4;j++){
pwmWrite(outPins[j],0,offSet[j],period,dur);
}
delay(1);
}
return 1;
}
void shuffle(int ary[],int arySize){
for(int i=0;i< arySize-1; i++) {
int j = random(i,arySize);
int t = ary[i];
ary[i] = ary[j];
ary[j] = t;
}
}
void pwmWrite(int pin,byte state,unsigned long offSet,unsigned long period,unsigned long dur){
if(state == 0){
digitalWrite(pin,LOW);
return;
}
if ((((millis() + offSet) % period) * 100) < (period * dur)){
digitalWrite(pin,HIGH);
return;
}else{
digitalWrite(pin,LOW);
return;
}
}

コメント