Mellanliggande Arduino: Ingångar och utgångar (1 / 9 steg)
Steg 1: Blink utan Delay()
Hittills vi har använt funktionen delay() för att pausa den Arduino skissen ögonblickligt så lite då kan passera mellan två Arduino kommandon. I LED blinkar skissen använde vi delay() att ställa in tiden Arduino tändes och hur lång tid det var avstängd:
digitalWrite (ledPin, hög), //turn LED på
Delay(1000); / / vänta på 1000 millisekunder (en sekund)
digitalWrite (ledPin, låg); //turn LED av
fördröjning (1000); //wait en sekund
Ibland med hjälp av delay() är inte ett bra alternativ eftersom Arduino inte kan utföra några sekundära aktiviteter medan förseningen händer. Tänk dig ville vi blinka en LED och upptäcka en knapptryckning samtidigt med delay():
loop() {
digitalWrite (ledPin, hög);
Delay(1000);
digitalWrite (ledPin, låg);
Delay(1000);
booleska buttonState = digitalRead(7);
}
I koden ovan mäter vi bara knappen en gång varannan sekund, så det kan ta upp till två sekunder innan en knapptryckning upptäcks, och mycket korta pressar kan någonsin få identifieras inte alls.
Millis() ger oss kontroll när händelser inträffar utan att sätta pauser i skissen. Varje gång som vi kallar millis() i en Arduino skiss, returnerar den antalet millisekunder sedan Arduino sattes på.
Kör följande kod för att se hur millis() fungerar:
lagringstiden med Arduino millis()
void setup() {
Serial.BEGIN(9600);
}
void loop()
{
osignerade långa currentMillis = millis();
Serial.println(currentMillis);
}
Här är hur du använder millis() för att blinka en LED utan att använda delay().
Blink ledde utan delay()
int ledPin = 7.
int ledState = låg, //current statligt av LED
osignerade långa timeOfLastLedEvent = 0; //the förra gången LED uppdaterades
int intervalON = 1000; //how lång vi vill bo LED
int intervalOFF = 500, //how lång vill vi LED att stanna utanför
void setup() {
pinMode (ledPin, produktionen);
digitalWrite (ledPin, ledState);
}
void loop() {
osignerade långa currentMillis = millis();
om (ledState == låg) {//if LED är redan borta
om (currentMillis - timeOfLastLedEvent > intervalOFF) {//and tillräckligt med tid har gått
digitalWrite (ledPin, hög); //turn det på
ledState = hög; //store nuvarande tillstånd
timeOfLastLedEvent = currentMillis; //update tiden av detta nya evenemang
}
} annat {//if lysdioden är redan på
om (currentMillis - timeOfLastLedEvent > intervalON) {
digitalWrite (ledPin, låg);
ledState = låg;
timeOfLastLedEvent = currentMillis;
}
}
}
Skissen ovan introducerar några nya saker:
osignerade långa är en annan datatyp (hittills har vi sett int och boolesk). Osignerade långa är som int, men större, jag ska förklara... Varje datatyp kräver en viss mängd utrymme i den Arduino minne, och mängden utrymme som Arduino befriar dig för en viss variabel dikterar den min och max värden som kan lagras i variabeln. Till exempel kan int's variera från-32,768 till 32 767, om du försökte göra något sånt här:
int myVariable = 100 000;
Du skulle sluta med en mycket konstig bugg i koden. Detta kan verka som en godtycklig utbud, men det kommer från det faktum att int's kräver 16 bitar av utrymme i den Arduino minne, och med 16 bitar för binary kan du lagra nummer från 0 till (2 ^ 16 - 1) = 65535. Men beslöt att int ska kunna lagra negativa tal också, så en av bitarna i 16-bitars nummer används för att lagra tecken (positiva eller negativa) och de resterande 15 bitarna lagra värdet: 2 ^ 15 = 32768. Inklusive 0, vi sluta med intervallet-32,768 till 32 767. En annan datatyp kallas en insigned int lagrar inte tecken, så det blir intervallet 0 till 65535 som jag beräknade innan, men du kan inte lagra ett negativt tal i en insigned int.
När vi behöver använda siffror större än 65535 eller mindre än-32768, använder vi en datatyp som kallas lång. Långa tilldelas 32 bitar av utrymme i den Arduino minne. 2 ^ 32 = 4,294,967,296, centrera det omkring noll för att få en rad:-2,147,483,648 till 2 147 483 647. Osignerade långa har, som unsigned int är alltid positiva, så de sträcker sig från 0 till 4,294,967,295.
Det finns ingen större datatyp för lagring av nummer än långa, så om du behöver spara ett större än 4,294,967,295, du har att komma med ett annat sätt att lagra det (kanske första 9 bitar i en siffra och de sista nio i en annan?). Denna begränsning har några intressanta konsekvenser för funktionen millis(). Eftersom millis returnerar osignerade långa produkter, och det hela tiden räknar i millisekunder, återställer millis() faktiskt tillbaka till noll när det når:
4,294,967,295 ms
= 4,294, 967seconds
= 49.71 dagar
Om du använder millis() och du planerar på att hålla du projektet igång för längre tid utan att någonsin att stänga av eller återställa, bör du vara uppmärksam på detta.
En ytterligare kommentar om datatyper: vi kunde har blitt användande long eller osignerade långa här hela tiden när vi deklarerar pin-koder eller andra variabler i exempel skisser så långt, men generellt är det en bra idé att använda minsta data skriver möjligt för en variabel, så du har gott om extra utrymme i den Arduino minne för andra saker. I Arduino, längtar används sällan, men millis() är ett bra exempel på när de kommer i händig.
Att komma tillbaka till skiss, är den allmänna idén att lagra den senaste gången du växlas LED på eller av och jämför det med den aktuella tiden som returneras av millis(). När skillnaden mellan de två gånger är större än vissa intervall, vet du det är tid att växla LED igen. För att göra detta har jag ställt upp vissa nya lagring variabler:
int ledState = låg, //current statligt av LED
osignerade långa timeOfLastLedEvent = 0; //the förra gången LED uppdaterades
int intervalON = 1000; //how lång vi vill bo LED
int intervalOFF = 500, //how lång vill vi LED att stanna utanför
I loop() finns det en massa logik som kontrollerar för att se om tillräckligt med tid har gått, och i så fall växlar mellan LED, uppdaterar variabeln "timeOfLastLedEvent" och växlar mellan de lagrade tillståndet av LED. Logiken upprepas två gånger, en gång för det fallet att LED är hög, och en gång för LED är låg, jag ska upprepa låg fallet nedan:
om (currentMillis - timeOfLastLedEvent > intervalOFF) {//and tillräckligt med tid har gått
digitalWrite (ledPin, hög); //turn det på
ledState = hög; //store nuvarande tillstånd
timeOfLastLedEvent = currentMillis; //update tiden av detta nya evenemang
}
currentMillis är en osignerade långa som representerar den aktuella tiden som uppdateras varje gång den Arduino loop() funktion startar. (currentMillis - timeOfLastLedEvent) ger tid sinus lysdioder staten ändrades senast, vi jämför detta mot intervalOFF att se om det är dags att stänga av lampan, om det inte är Arduino kommer att hålla uppdatera currentMillis och upprepa kontrollen tills det är dags.