Previously I worked on a motor controller board that would deliver random pulses to a prop. It worked well, but I was not quite happy with the randomization algorithm, and I wanted more titratable control over the pulses. Additionally I wanted something that could be triggered by either a PIR sensor or a button.
I’ve now produced a beta version of this new controller and I’m looking for feedback. Here’s a demo video—
This is the schematic—
And here is the code—
// Jekyll-Labs Twitchy Attiny85 // Built for Twitchboard v1.5 // int fetpin = 0; int trigpin = 1; int potMpin = A1; int potRpin = A2; int potLpin = A3; int lambda = 5; // number of event int timeunit = 60; // in this time interval (sec) unsigned long last = 0; unsigned long timeinterval = 0; float exprob=0; void setup() { randomSeed(A1); pinMode(fetpin, OUTPUT); digitalWrite(fetpin, LOW); pinMode(trigpin, INPUT); pinMode(potLpin, INPUT); pinMode(potMpin, INPUT); pinMode(potRpin, INPUT); } void loop() { // duration of signal will last from 0.5 - 10 sec int durationpot = analogRead(potRpin); long duration = map(durationpot,100,1023,500,10000); if (duration <500) duration = 150; // read middle pot for PWM of fet signal int PWMpot = analogRead(potMpin); int PWM = map(PWMpot,0,1000,0,255); if (PWM>255) PWM = 255; // mean frequency of random signals is 5 events per time unit int freqpot = analogRead(potLpin); int timeunit = map(freqpot,512,1023,60,300); // 2nd half dial range 1-5 min if (freqpot>1000) timeunit = 3600; // far right dial 1hr if (freqpot<512) timeunit = map(freqpot,0,512,0,60); // 1st half dial range 10-60 sec if (freqpot<100) timeunit = 0; // bottom of dial continous on if (timeunit<=0){ // continuous on if left dial all counter clockwise analogWrite(fetpin,PWM); } else { // Check for trigger (X3 for debounce) and adjust // timeunit if trigger is positive. if (timeunit>0) { int trigger = digitalRead(trigpin); if (trigger == HIGH) { delay(100); int trigger = digitalRead(trigpin); if (trigger == HIGH) { delay (100); int trigger = digitalRead(trigpin); if (trigger == HIGH) { timeunit = (duration * 10)/1000; } } } } // Calcuate time interval between events. timeunit depends on: // Potentiometer value if trig = 0 // Duration multiplier (shorter) if trig = 1 unsigned long timeinterval = exprob * timeunit * 1000; // Check if time interval has passed if ((millis() - last) > timeinterval) { last = millis(); // updates timer to last event analogWrite(fetpin,PWM); delay(duration); digitalWrite(fetpin,LOW); // the following equation runs once per event and // generates a random float (exprob) that falls in an // exponential distribution. It will be used to // determine the interval time for the next event. // Events that occur at exponentially distributed // intervals form poisson processes. exprob = (-1)*(log((100-random(100))/100.00)/lambda); } else digitalWrite(fetpin,LOW); } delay(20); }
No comments:
Post a Comment