En multithreaded blinkande theremin drivs av VIPER (5 / 6 steg)
Steg 5: Förklara koden
Varför använder VIPER
En av de begrepp som många människor hitta utmanande när börjar skriva kod för mikrokontroller är hur du hanterar flera maskinvarurelaterade aktiviteter, till synes alla kör på samma gång. Designers är följaktligen frustrerade över svårigheterna att genomföra sådana funktioner i microcontrollers.
För att lösa dessa smärtor, VIPER stöder alla mest använda hög nivå funktioner i Python som moduler, klasser, multitrådning, callbacks, timers och undantag, plus några maskinvarurelaterade funktioner som avbryter, PWM, digitala I/O, etc.
Varje tråd i VIPER är en slags separerade och parallell process som körs självständigt på brädan. En tråd kräver en funktion som ska köras som indata för definitionen. Samma funktion kan exemplifieras av olika tråd ger dig möjlighet att skriva mycket kortfattat och lättläst kod. Med trådar kan du designa din algoritm arkitektur förutsatt att parallellitet som är typisk för hög nivå. Mer information här.
Inne i koden
Skriptet implementeras med 4 trådar som körs parallellt. En tråd som används för att förvärva och normalisera de analoga signaler som förvärvats genom en potentiometer och en IR rörelsesensor. De andra tre trådarna används för att initiera en generisk blink() funktion som driver två lysdioder på olika frekvenser och en generisk buzz() funktion som driver en Summer på annan frekvens e längd sömn (för att skapa en "beat" effekt), beräknad på grundval av de förvärvade analoga signalerna.
Hämta skriptet från github. Koden har massor av kommentarer. Bara ett par anteckningar.
- Delay() vs sleep()
I Arduino/kablar med delay() har en bieffekt - Arduino gör ingenting för att även. För att få två eller fler "åtgärder" att köra oberoende av varandra, kan inte du använda delay().
I VIPER avbryts funktionen sleep() den aktuella tråden för tiden uttryckt i time_units men alla andra trådar är fria att fortsätta deras utförande!
- VIPER inbyggda funktioner
VIPER VM sträcker Python med inbyggda funktioner för att hantera de allmänna ändamål Input Output stiften på den inbyggda enheten. Dessa funktioner liknar de som används av Arduino, men är mer flexibel.
analogRead() vs adc.read()
Funktionen analogRead() tillhandahålls som ett inbyggt att underlätta övergången från den Arduino/ledningar till VIPER.
Men det bästa sättet att läsa en analog pinne i VIPER är:
# importera adc föraren
importera adc
x = adc.read (pin, prov = 1)
Läser analoga värden från PIN-kod som måste vara en av Ax stiften. Om prover är 1 inte eller, returnerar heltalsvärdet läsa från stift. Om prover som är större än 1, returnerar en tupel med heltal storlek prover.
analogWrite() vs pwm.write()
Arduino's analogWrite() funktion ger ett enkelt gränssnitt till maskinvaran PWM, men ger inte någon kontroll över frekvens. Funktionen analogWrite() tillhandahålls som ett inbyggt att underlätta övergången från den Arduino/ledningar till VIPER. Men det bästa sättet att använda pwm i VIPER är:
# importera pwm föraren
importera pwm
PWM.write (pin, period, puls, time_unit = MILLIS)
Statligt av pin slås regelbundet mellan låg och hög enligt parametrar:
-perioden är varaktigheten av en pwm fyrkantsvåg
-puls är tiden pwm fyrkantsvåg stannar i tillståndet hög
-time_unit är den tidsperiod och puls uttrycks i time_unit