Meerdere patronen tegelijk behandelen is zeker mogelijk met een platform als Arduino, en er zijn een aantal manieren waarop je dit kunt aanpakken.
Een methode die ik zou overwegen, is het schrijven van functies die effectief elk patroon wiskundig. U geeft het gewoon de totale tijd die tot nu toe in uw programma is verstreken door, en het zal de juiste actie voor dat specifieke moment in de tijd uitvoeren. Het zal onmiddellijk daarna terugkeren (geen vertragingen of zoiets).
Om dat te doen, moet je eerst weten hoe lang een enkele cyclus van het patroon duurt. U kunt vervolgens de modulo-operator gebruiken om erachter te komen hoe ver u door de huidige cyclus bent. Van daaruit hoeft u alleen maar een paar if
-voorwaarden te hebben om te bepalen wat u op een bepaald moment moet doen.
Hier is hoe het eruit zou kunnen zien voor uw "5 seconden op, 5 seconden uit "pattern:
function pattern5on5off (unsigned long totalTime) {// Bereken hoe ver we door de huidige cyclus heen zijn const unsigned long cycleTime = totalTime% 10000; // Als we in de eerste 5 seconden van de cyclus zitten, doe dan het licht aan. // Schakel het anders uit. if (cycleTime < 5000) digitalWrite (3, HIGH); else digitalWrite (3, LOW);}
Toegegeven, constant digitalWrite ()
aanroepen als je dat technisch niet nodig hebt, is niet erg efficiënt. Het mag echter geen schade aanrichten en is vrij eenvoudig te optimaliseren indien nodig.
Om het bovenstaande voorbeeld in een sketch te gebruiken, hoef je het alleen maar aan te roepen in loop ()
, en geef het nummer door dat u krijgt van millis ()
; bijv .:
void loop () {const unsigned long totalTime = millis (); pattern5on5off (totalTime); // roep hier andere patronen aan ...}
Andere patronen zullen complexer zijn, maar volgen hetzelfde principe. Je zou gewoon de juiste if
-instructies moeten gebruiken om je logica uit te drukken.
Het belangrijkste om te onthouden is dat de functie een specifiek moment in de tijd vertegenwoordigt. Het mag het programma nooit pauzeren of vertragen, anders zal het voorkomen dat de andere patronen worden uitgevoerd.
Bewerken: timing op de eerste cyclus
Zoals jfpoilpret opgemerkt in de commentaren, de allereerste cyclus begint op een willekeurig punt. Dit komt doordat de eerste keer dat u millis ()
aanroept in loop ()
, het niet start bij 0 (het apparaat heeft al een korte tijd gedraaid loop ()
wordt aangeroepen). Het is echter gemakkelijk op te lossen, indien nodig.
Je zou het doen door de totalTime
-waarde te compenseren met de waarde die je de allereerste keer kreeg rond loop ()
. Bijvoorbeeld:
unsigned long g_startTime = 0; void loop () {unsigned long totalTime = 0; if (g_startTime == 0) {// Dit is de eerste cyclus. // Sla de starttijd op zodat we later kunnen compenseren. g_startTime = millis (); } else {// Dit is niet de eerste cyclus. // Compenseer de starttijd. totalTime = millis () - g_startTime; } pattern5on5off (totalTime); // etc ..}