OK, een aangepaste versie die een beetje netter en efficiënter is (snelheid en benodigde geheugen):
// Efficiënter om deze als define's op te geven ipv een variabele
// De compiler vervangt elk voorkomen van deze constanten meteen met de
// gedefinieerde waarde, en verbruikt dus geen geheugen voor variabelen
#define TijdsduurLEDAan 1000
#define interval 60000
// Bijhouden welke stap we doen, en wat het maximum aantal stappen is
// Hiervoor definiëren we Max aantal pinnen (4) en een array
// Dit maakt aanpassen makkelijk als je in de toekomst meer LEDs wilt toevoegen
#define MaxPins 4
int pins[MaxPins] = { 4, 5, 6, 7 }; // Definieer de 4 pinnen in een array
byte HuidigePin = 0; // Voor arrays start tellen bij nul en niet bij 1
unsigned long voorgaandeMillis = 0; // laatste keer dat iets werd uitgevoerd
void setup()
{
for(int Teller; Teller<MaxPins; Teller++) // tel van 0 t/m 3 om pinnen op
{ // output te zetten
pinMode(pins[Teller], OUTPUT);
}
}
void loop()
{
unsigned long huidigeMillis = millis();
if (huidigeMillis - voorgaandeMillis >= interval) {
// 1 minuut verstreken - dus bewaar dit meteen voor detectie van de volgende ronde
voorgaandeMillis = huidigeMillis;
// Omdat alle pinnen al op LOW staan, hoeven we alleen maar deze pin op HIGH te zetten
digitalWrite(pins[HuidigePin], HIGH);
if(HuidigePin<MaxPins) {
HuidigePin++; // volgende stap
} else {
HuidigePin = 0; // terug naar 1, maar arrays starten bij nul met tellen
}
delay(TijdsduurLEDAan); // 1 seconde wachttijd voor we de LED weer uitzetten
// Huidige LED weer uitzetten, de anderen stonden al uit
digitalWrite(pins[HuidigePin], LOW);
} // if
}
Ik zal even kort door de code lopen, in gedachten houdende wat we al eerder hebben besproken.
Omdat we de pinnen niet erg handig kunnen aanspreken heb ik een array gebruikt.
Ideaal zou zijn als we gewoon met 1, 2, 3, en 4 zouden kunnen werken, als we een pin willen aanspreken, maar de gebruikte pinnen staan dit niet toe (4, 5, 6, 7). We zouden kunnen overwegen om het pin nummer steeds te berekenen maar daarmee maak je het jezelf wel moeilijk als er in de toekomst iets veranderd (meer pinnen of andere pinnen).
We tellen 1, 2, 3, 4 omdat we posities tellen voor elke minuut.
digitalWrite(1,HIGH); // dit zou ideaal zijn, maar dat komt niet overeen met de pinnen
digitalWrite(1+3,HIGH); // steeds 3 optellen bij het nummer van de positie zou werken, als we niks veranderen
Er zijn dus een aantal trucjes die erg snel en efficiënt zijn, maar ... als we de gebruikte pinnen veranderen (verwisselen of uitbreiden) dan werken deze trucjes ineens niet meer. Dus een recept om later in de problemen te raken.
Daarom heb ik een array van nummers gebruikt (arrays kan in het begin een lastig onderwerp zijn). Arrays beginnen niet bij 1 met tellen, maar bij 0 (nul), en dat loopt dus 1 uit de pas met onze posities. We kunnen dat corrigeren door steeds 1 af te trekken van de positie om dan de positie in de array te krijgen. Of ... we gaan onze posities ook tellen door bij nul te beginnen.
In de "Setup()" gebruik ik een for-lus om sneller de pinnen op OUTPUT te zetten. Ik heb het wat uitgebreid weggeschreven maar een for-lus kan nog korter geschreven worden, maar dat neemt weer weg aan de leesbaarheid van de code - wat ik zelf altijd wel belangrijk vindt, zeker als je een paar maanden later nog eens terug gaat kijken om iets te wijzigen ...
Stel nu dat je in de toekomst 6 LEDs gaat gebruiken dan hoef je alleen maar deze 2 regels aan te passen:
#define MaxPins 6
int pins[MaxPins] = { 4, 5, 6, 7, 8, 9 }; // Definieer nu de 6 pinnen in een array
We zetten MaxPins op het aantal werkelijk gebruikte pinnen, en in de volgende regel voegen we de 2 extra pin nummers toe tussen de accolades.
Handig he?
Je ziet dat hierdoor het hele switch() statement niet meer nodig is en dat was een tweede doel die ik in gedachten had.
Ik heb ook het zetten van LOW en HIGH veranderd. Alle pinnen beginnen in een LOW state en gaan alleen maar naar HIGH als wij dat zeggen.
Dus als we een pin HIGH zetten en een seconde wachten dan weten we 100% zeker dat alleen die pin weer op LOW gezet moet worden.
Nu zie je misschien waarom ik eerst de uitgebreide code heb gegeven - het is stukken duidelijker wat er aan de hand is.
Maar, en zo werk ik nog weleens, daarna gaan we kijken hoe we dit efficiënter kunnen doen.
Blokken code die erg op elkaar lijken en meerdere keren herhaald worden nodige vaak uit voor een efficiëntere manier - maar dat leer je vanzelf naarmate je beter wordt met het lezen en denken in code.
Overigens, na het weghalen van een aantal commentaar regels zie je dat de code ook een stuk korter is geworden;
#define TijdsduurLEDAan 1000
#define interval 60000
#define MaxPins 4
int pins[MaxPins] = { 4, 5, 6, 7 }; // Definieer de 4 pinnen in een array
byte HuidigePin = 0; // Voor arrays start tellen bij nul en niet bij 1
unsigned long voorgaandeMillis = 0; // laatste keer dat iets werd uitgevoerd
void setup()
{
for(int Teller; Teller<MaxPins; Teller++) // tel van 0 t/m 3 om pinnen op
{ // output te zetten
pinMode(pins[Teller], OUTPUT);
}
}
void loop()
{
unsigned long huidigeMillis = millis();
if (huidigeMillis - voorgaandeMillis >= interval) {
voorgaandeMillis = huidigeMillis;
digitalWrite(pins[HuidigePin], HIGH);
if(HuidigePin<MaxPins) {
HuidigePin++; // volgende stap
} else {
HuidigePin = 0; // terug naar 1, maar arrays starten bij nul met tellen
}
delay(TijdsduurLEDAan); // 1 seconde wachttijd voor we de LED weer uitzetten
digitalWrite(pins[HuidigePin], LOW);
} // if
}
Merk op:
ik heb een aantal variabelen even een andere naam gegeven ivm leesbaarheid (ik woon en werk in de VS dus neig nog weleens naar de Engelse taal haha). Daarnaast heb ik de code niet kunnen testen (zit op m'n werk), maar de Arduino software zegt dat alles goed compileert.