Den skygga Nightscape - Jed Diller och Ken Hoff (3 / 6 steg)
Steg 3: Beteendemässiga Kodöversikt
Mål för skygg Nightscape beteendemässiga koden:
-3 olika grupper av lysdioder: stjärnor, öga par och firefly, alla med en distinkt beteende.
-Individuell stjärnor och öga par fungera som separata enheter
-Firefly fungerar som en enhet
-Stjärnorna tona in och ut, imitera glimten. (Detta var gjort med puls bredd modulation)
-Öga paren blinka slumpmässigt
-Alla grupper svarar på ljud och återuppta beteende kontinuerligt.
Hur det fungerar:
-Under de viktigaste loop är varje entitet (stjärna, öga par, firefly) vaken eller sover
-Om vaken, slumptal används för att bestämma när blink/fade ögon/stjärnorna och firefly fortsätter på sin väg till nästa LED stift
-Om sover, ökas 'tid sovande' variabeln
När det finns ett ljud (och tröskeln kränks):
-Varje enhet är inställd somna, och tiden sover börjar öka
-Medan en enhet sover:
-Varje gång en sovande enhet besöks, ett slumptal genereras och jämfört med den tid företaget har varit sömn - om tid sovande är större, entiteten vaknar upp.
-Detta leder till varje entitet som vaknat upp slumpmässigt på olika tider.
Frågor och råd:
-När du skriver beteendemässiga koden, den inbyggda Arduino delay() funktion måste undvikas eftersom den rymmer upp alla andra processer som pågår. Detta är ohållbart med tre LED grupper beter sig annorlunda och samtidigt. I stället kan antalet huvudloop iterationer användas för tid beroende av beteende. Observera att den tid det tar för varje huvudloop iteration är beroende på hur mycket saker som du har på gång inom it. Prova och konsten av förfining är dina vänner.
-Som beskrivs i steg 3, hade vi oöverstigliga mikrofon buller med mikrofonen på samma styrelse som lysdioder att bli manipulerad. Vår lösning var att helt skilja mikrofonen genom att låta det vara den enda komponenten på en separat ombord, Arduino Uno.
Exempelkod:
Detta är den kod som vi sprang på Arduino Mega under drift. Koden kan köras på Uno finns i steg 2.
---------------------------------------------------------------------------------------------------------------------
Först måste du initiera alla variabler som dina klasser och huvudloop kommer att använda
int max_led = 50;
int star_twinkle_delay = 10;
CONST int light_sensor = A0;
int sensorValue = 0;
int sensorMin = 1023; minsta sensorn värde
int sensorMax = 0;
int tröskel = 255;
flyta a0 = 0,3; coeff för innevarande värde
flyta a1 = 0,2; coeff för plus & minus 1 från calc
flyta a2 = 0,1; coeff för plus & minus 2 från calc
flyta a3 = 0,05; coeff för plus & minus 3 från calc
int sV_adjusted; lagrade justerade värde
int sV_m3; sensor värdet 3 före calc
int sV_m2; sensor värdet 2 före calc
int sV_m1; sensor värdet 1 före calc
int sV_0; sensor värde beräkning centrerar av kurva
int sV_p1; sensor värdet 1 efter att calc
int sV_p2; sensor värdet 2 efter att calc
int sV_p3; sensor värdet 3 efter att calc (vad är actaully att läsa)
Här är där din 3 klasser (typer av lysdioder) definieras. De har en setup och loop funktion, precis som Arduino.
Star
klass stjärna
{
offentlig:
int pin;
int blekning;
int ljusstyrka;
int vaken;
int time_asleep;
void setup_star()
{
vaken = 1;
fading = rand() % 2.
ljusstyrka = rand() % max_led + 1.
}
void twinkle()
{
om (vaken == 1)
{
om (fading == 1)
{
ljusstyrka + = 1;
}
annan ljusstyrka-= 1;
om (ljusstyrka > max_led)
{
ljusstyrka = max_led;
fading = -1;
}
annars om (ljusstyrka < 10)
{
ljusstyrka = 10;
fading = 1;
}
analogWrite (pin, ljusstyrka);
Delay(1);
}
}
};
Ögon
klass eye_pair
{
offentlig:
int pin;
int vaken;
int blinkar;
int blink_duration;
int time_since_blink;
int time_asleep;
void setup_eyes()
{
vaken = 1;
time_since_blink = rand() % 1000;
}
void display_eyes()
{
om (vaken == 1)
{
om (blinkande == 1)
{
digitalWrite (pin, låg);
blink_duration ++;
om (blink_duration > ((rand() % 20) + 10))
{
blinkande = 0;
blink_duration = 0;
time_since_blink = 0;
}
}
om (blinkande == 0)
{
digitalWrite (pin, hög);
om (time_since_blink > ((rand() % 1000) + 500))
{
blinkande = 1;
digitalWrite (pin, låg);
}
annat time_since_blink ++;
}
}
}
};
Firefly - handtag det är egen pin setup
klass firefly
{
offentlig:
int stift [12].
int tid;
int time_to_blink;
int on_off;
int current_pin;
int vaken;
int time_asleep;
void setup_firefly()
{
vaken = 1;
time_to_blink = 100;
för (int jag = 0; jag < 12, i ++)
{
stift [i] = i + 40;
pinMode (stift [i], produktionen);
digitalWrite (stift [i], låg);
}
current_pin = 0;
}
void go_firefly()
{
om (vaken == 1)
{
Stäng av
om ((on_off == 1) & & (tid > (rand() % 100) + 400))
{
digitalWrite (stift [current_pin], låg);
tid = 0;
ON_OFF = 0;
}
slå på
om ((on_off == 0) & & (tid > time_to_blink))
{
current_pin = (current_pin + 1) % 12.
digitalWrite (stift [current_pin], hög);
tid = 0;
ON_OFF = 1;
}
tid ++;
}
}
};
Definierar stjärnor, ögon och firefly objekt - samtal firefly objekt frank bara för att skilja den
stjärniga stjärnor [12] ;// = {2,3,4,5,6,7,8,9,10,11,12,13}.
eye_pair ögon [31].
Firefly frank;
Setup - initialiserar stjärnor, ögon, firefly och sensor
void setup()
{
Serial.BEGIN(9600);
för (int jag = 0; jag < 12, i ++)
{
stjärnor [i] .pin = i + 2.
pinMode (stjärnor [i] .pin, produktionen);
Stars[i].setup_star();
}
för (int jag = 0; jag < 16; i ++)
{
ögon [i] .pin = i + 24.
pinMode (ögon [i] .pin, produktionen);
Eyes[i].setup_eyes();
}
Frank.setup_firefly();
sV_m3 = analogRead(light_sensor);
sV_m2 = analogRead(light_sensor);
sV_m1 = analogRead(light_sensor);
sV_0 = analogRead(light_sensor);
sV_p1 = analogRead(light_sensor);
sV_p2 = analogRead(light_sensor);
}
Huvudloop - läser in ljudingång, sedan hanterar lysdioder
void loop()
{
sV_p3 = analogRead(light_sensor);
beräkna justerat värde
sV_adjusted = (int) (a3 * (float) sV_m3 + a2 * (float) sV_m2 + a1 * (float) sV_m1 + a0 * (float) sV_0 + a1 * (float) sV_p1 + a2 * (float) sV_p2 + a3*(float)sV_p3);
Skift-värden runt för nästa iteration
sV_m3 = sV_m2;
sV_m2 = sV_m1;
sV_m1 = sV_0;
sV_0 = sV_p1;
sV_p1 = sV_p2;
sV_p2 = sV_p3;
om (sV_adjusted < tröskel)
{
för (int jag = 0; jag < 13; i ++)
{
Stars[i].twinkle();
om (stjärnor [i] .time_asleep > ((rand() % 100000000) + 3000))
{
stjärnor i [i] .awake = 1;
stjärnor i [i] .time_asleep = 0;
}
annat
{
stjärnor i [i] .time_asleep ++;
}
}
för (int jag = 0; jag < 30; i ++)
{
Eyes[i].display_eyes();
om (ögon [i] .time_asleep > ((rand() % 100000000) + 3000))
{
ögon [i] .awake = 1;
ögon [i] .time_asleep = 0;
}
annat
{
ögon [i] .time_asleep ++;
}
}
Frank.go_firefly();
om (frank.time_asleep > ((rand() % 100000000) + 3000))
{
Frank.Awake = 1;
Frank.time_asleep = 0;
}
annat
{
Frank.time_asleep++;
}
}
annat
{
för (int j = 0; j < 54; j ++)
{
digitalWrite (j, låg).
för (int jag = 0; jag < 13; i ++)
{
stjärnor i [i] .awake = 0;
}
för (int jag = 0; jag < 30; i ++)
{
ögon [i] .awake = 0;
}
Frank.Awake = 0;
}
}
}
---------------------------------------------------------------------------------------------------------------------
Beteendemässiga kod anteckningar:
Du kanske märker att faltning beteende ses i den här koden alltför. Denna faltning är att vara stöpta på analoga värden som håller på att produktionen av Uno. Om en mer stabil och mindre bullriga mikrofon (eller en ljussensor) användes, användning av Uno kunde elimineras och denna kod inte skulle behöva ändras.