OiO - en skrivbordslampa som har en själ (5 / 7 steg)
Steg 5: Koden, själen
Den mest intressanta delen, det är där all din hård arbete hittills kommer att betala av. Vi har arbetat för att ta hand om alla fysiska detaljer, nu, vad är känslomässiga de? : p
Som en start, kommer att du behöva har Arduino IDE installerade för ditt OS, måste du manuellt installera Adafruit bibliotek för att kunna styra NeoPixel ifall du har beslutat att använda dem.
Bifogat är den fullständiga koden för oiO som av tiden jag skriver detta. Han får definitivt mer kod och utbildning som jag går :) Observera att koden är kalibrerad för att arbeta med sensorer och servon jag använde, så kanske det inte kommer att vara meningsfullt för dig när du försöker det. Du kommer att behöva gå igenom många prövningar tills du hittar de bra värdena (mer om detta i nästa avsnitt)
Introduktion
För mig är hela poängen bakom detta projekt att göra oiO interaktiva och autonoma, agerar på egen hand. han bör fortsätta att ge sin viktigaste funktion, ger dig ljus, men han har också sitt humör, och humörsvängningar, det ändrar hållning och interagerar med sina användare.
Men det var en utmaning för mig, sammanfattas i den nedan punkter
1) hur kan jag flytta 3 servon samtidigt, eller separat om det behövs
2) hur kan jag underlätta rörelser och införa vissa lättnader för att simulera en flytande rörelse. Också ha viss kontroll på hastigheten på servon att simulera olika beteenden.
3) hur kan jag läsa och kontrollera alla sensorer och servon samtidigt veta att Arduino inte inbyggt stöd för multitasking.
4) hur kan jag göra Oio's beteende trovärdigt, och undvika robotic svar på liknande ingångar, så vill jag honom att reagerar olika för samma input (ljud och närhet), alla här vet att Arduino bara läser koden från topp till botten och sedan loopar
5) oiO måste ha en känsla av tid förbi, en handling enligt den.
Allt detta ska göras med 32KB dynamisk minne tillgängligt på Arduino för koden, och samtidigt hålla det enkelt!
Efter 2 dagar att skriva kod, tror jag jag nått mitt mål och svarat på fem frågan på ett godtagbart sätt med några kompromisser.
Vi kan argumentera om hur bra jag gjorde detta och hur trovärdigt det är, men slutet av dagen, den video som du såg, använder bara 17 procent av koden minne och det finns ett stort utrymme för förbättringar, som jag kommer att fortsätta att driva. men eftersom du har koden, skriv mig ner några förslag, eller bara dela din förbättringar.
I nästa avsnitt kommer jag att dela några snuttar av koden jag kände jag måste diskutera, till er läsa den fullständiga koden och att göra känsla av det, det är tungt kommenterade också för att hjälpa bättre förståelse och för mig att komma ihåg Detaljer 3 månader från nu:). Jag hoppas jag gjorde över det inte!
Punkterna 1 & 2
Flytta 3 servon samtidigt på Arduino är inte möjligt inbyggt. så jag var tvungen att skriva en funktion som tar 3 servon och 3 mål lägen för varje, förutom en lättnader faktor att styra hastighet och användarvänlighet servon. Funktionen kontrollerna servon med writeMicroseconds() i stället för att anropa, vilket den före detta ger mer exakt kontroll på grund av sitt större antal värden, kontrollera servon genom att ange exakta PWM pulse bredd i millisekunder, i stället för den senare det användare kantiga grader.
Funktionen är:
Ogiltig < stark > move3Servos < / strong > (Servo < stark > servo1Name </strong >, float < stark > target_pos1 </strong >, Servo < stark > servo2Name </strong >, float < stark > target_pos2 </strong >, Servo < stark > servo3Name </strong >, float < stark > target_pos3 </strong >, float < strong > lättnader </strong >) < br >
- target_posX: har gränser å börja och avsluta positioner, mellan 600 och 2400 mS, några servon fungerar mellan 1000 och 2000... Kontrollera din servon gränser genom provning eller datablad innan du anger värdena
-lättnader: är ett värde mellan 0,0 och 5.0, där:
-värden mellan 0,0 till 1,0 orsak servon till start rörelse snabbt men avsluta nervcellerna, värden runt noll (ex: 0,05) ger mycket långsammare/önskas svar av utjämning, värdet av 0,1 är tillräckligt snabbt
-värden mellan 1,0 och 5.0, är inte ansett lätta faktorer, som de orsakar en förändring i beteende, orsakar servon att flytta linjärt börja att stoppa med x steg beroende på värdet i. Värdet av 2.0 är turtle hastighet, medan ett värde av 5.0 är relativt snabb.
För att simulera samtidig kontroll av 3 servon, funktionskontroll varje servo ett steg i taget, men i rad, det vill säga flyttar servo1 en liten steg sedan flyttar servo 2 ett litet steg, sedan servo3 på samma sätt, då den gör detta igen och igen i en loop tills alla servon hade nått sina mål positioner. Slutresultatet, alla servon tycks ha flyttat på samma gång till sina mål positioner.
Punkterna 3 och 4
Motverka detta, var tricket att separera läser de sensorer värde från faktiskt agerar på servon och ögon. Detta gör att jag kan skapa räknare som räknar ljud och närheten därav följande upptäckter, och även mäta timing mellan dessa händelser. Dessa räknare och tidsstämplar kan användas senare självständigt i den del som lag om servon och ögon. Jag testa för Räknare-värden och se hur länge det tog användaren mellan varje upptäckt. Detta är exempelvis hur oiO kan skilja mellan en användare närmar sig honom 3 gånger på snabbt sätt, alltså att göra oiO arg med röda ögon och ryckiga rörelser eller om användaren kontaktat honom efter varandra i en långsam sätt, vilket gör oiO lugnare med varmare ögonfärg och graciösa rörelser...
I ett nötskal, få sensorer värde först och sedan agera senare. men eftersom den Arduino loop() kör tillräckligt snabbt, användaren kommer inte att märka förseningen.
Punkt 5
Eftersom Arduino inte är ansluten till en extern timing källa, kan inte det således tala om absolut tid, så oiO använder interna tidpunkten för Arduino använder funktionen millis() som räknar antalet millisekunder sedan start/Nollställning av Arduino. Räknaren rullar över efter ca. 50 dagar, mer än tillräckligt för oiO livscykel. Detta bör vara tillräckligt för att beräkna exempelvis: 15 min har gått så gör det och det, eller har det varit 60 sekunder som användaren inte interagera med oiO.
Detta är exempelvis hur oiO kommer att upptäcka att användaren inte interagera med honom sedan 1 timme, och därmed börjar slumra, följt av djup sömn!
...
oiO kommer att gå till sova om ingen åtgärd av användaren för mer än 'sleepIfNoActionTimer' sekunder
IF((Millis() - lastAction) > sleepIfNoActionTimer) {
doseOff();
}
< p > //oiO kommer att nysa varje "sneezeTimer" min (inte kommer att registreras som en användaråtgärd) < /p > if(millis() % sneezeTimer == 0) {
sneeze();
}
...
Kontrollera ögonen
Jag har använt Adafruit biblioteket eftersom de ger intressanta funktioner för att styra NeoPixels, jag har lagt till några funktioner som setEyesColor() och dimmer() att ha enkel tillgång till inställning båda ögon färgerna och även styra dimming på en viss färg med en given hastighet och riktning.
void dimmer (int a, int b, int rött, int grön, int blå, int fadeDirection, int stepSpeed)
en: min ljusstyrka
b: max ljusstyrka
r, g, b: är RGB färgkomponenter, varje kan ha ett värde mellan 0-255
fadeDirection: kan vara 1 = upp, 2 = ner, 3 = updown
stepSpeed, fördröjning i millisekunder mellan färgen blekna steg
Slutsats
Jag högt rekommendera läsa koden och förstå det och ändra det som behövs. Alla variabler i initiering av koden (dvs före och inuti setup()) bör fastställas efter dina behov.