Cwik klocka v1.0 - An Arduino binär klocka (4 / 15 steg)
Steg 4: Programmering klockan
Programstruktur
Arduino program har 2 huvudsakliga metoder; en metod som körs en gång i början där initiering sker (kallas setup), och en annan metod som kallas kontinuerligt (kallas loop).
Setup(), ska vi ställa in tiden till 00:00, och ställa in vilket stift kommer att driva 13 lysdioder.
I loop() ska vi se om mer än en sekund har ellapsed (och i så fall öka tiden) och sedan Visa tid av driver rätt lysdioderna. Den millis() metoden är avgörande för att hålla tiden. Returnerar antalet millisekunder som har ellapsed eftersom kretsen drevs som en osignerad lång. "Unsigned" innebär att det inte kommer att vara negativa och lång avser hur många bitar (32 att vara exakt) används för att hålla reda på detta nummer (bitar är antalet binära siffror).
Sarkasm med millis()
Eftersom det finns ett begränsat antal bitar i en osignerad lång, någon gång ska vi slut på siffror! Enligt Arduino dokumentation på millis(), det kommer att linda runt (dvs, återställs till noll) efter cirka 50 dagar. Hur irriterande vore att återställa din klocka varje 50 dagar? Som en av de mål vi strävar efter funktionella perfektion och detta distruptive är oacceptabel. Logiken i vår tick() metod används således att se när vi svepa runt och fortsätta utan att någon att vara klokare.
Stifttilldelningar
Innan vi hoppa rätt in och börja tilldela digitala stift, ska vi krävs en PWM (pulse width modulated) stift att Visa sekunder på den analog mätaren i ett senare steg. På Arduino Uno, stift 3, 5, 6, 9, 10 och 11 är aktiverade för PWM (som innebär den "~"). Jag är alltså spara stift 11 för analog visning och använder stift 0 - 10, 12 & 13 för binära LED-displayen.
Koden
/*
Cwik klocka v1.0 - prototyper displayen
Författare: Dennis Cwik
Datum: Juli 23, 2012
Detta program är registeransvarige för en binär klocka, med lysdioder
kopplade till digital stift 0 till 10, 12 och 13.
Denna exempelkod är offentlig.
*/
Detta kan ändras för debug ändamål att göra en minut gå snabbare.
int ONE_SECOND = 1000; mäts i millisekunder
int DELAY_BETWEEN_LOOP_CALLS = 200. mäts i millisekunder
Jag kom inte med detta, det är från arduino dokumentationen
osignerade långa MAX_UNSIGNED_LONG = 4294967295; = (2 ^ 32) - 1
1: a kolumnen av lysdioder
int PIN_MIN1 = 0;
int PIN_MIN2 = 1;
int PIN_MIN4 = 2;
int PIN_MIN8 = 3;
2: a kolumnen av lysdioder
int PIN_MIN10 = 4;
int PIN_MIN20 = 5;
int PIN_MIN40 = 6;
3: e kolumnen av lysdioder
int PIN_HOUR1 = 7.
int PIN_HOUR2 = 8;
int PIN_HOUR4 = 9;
int PIN_HOUR8 = 10;
4: e kolumn med lysdioder
int PIN_HOUR10 = 12;
int PIN_HOUR20 = 13.
sista gången sekunderna i tiden var ökas
osignerade långa m_lastTick;
brukade berätta för oss om vi ställer tiden eller inte
booleska m_inTimeSetMode = false;
tid
byte m_second;
byte m_minute;
byte m_hour;
Rutinen installationsprogrammet körs en gång när du trycker på reset
void setup()
{
initiera stiften används för utskrift av tid som utgång
pinMode (PIN_MIN1, OUTPUT);
pinMode (PIN_MIN2, OUTPUT);
pinMode (PIN_MIN4, OUTPUT);
pinMode (PIN_MIN8, OUTPUT);
pinMode (PIN_MIN10, OUTPUT);
pinMode (PIN_MIN20, OUTPUT);
pinMode (PIN_MIN40, OUTPUT);
pinMode (PIN_HOUR1, OUTPUT);
pinMode (PIN_HOUR2, OUTPUT);
pinMode (PIN_HOUR4, OUTPUT);
pinMode (PIN_HOUR8, OUTPUT);
pinMode (PIN_HOUR10, OUTPUT);
pinMode (PIN_HOUR20, OUTPUT);
initiera klocka variabler
m_lastTick = 0;
setTime (0, 0, 0);
}
Rutinen loop kör om och om igen för alltid
void loop()
{
se om vi ställa in tiden, eller att låta tiden flöde normalt
om (m_inTimeSetMode)
{
getTimeFromPots();
}
annat
{
Tick();
}
nu när tiden har uppdaterats, Visa tid
displaySeconds();
displayMinutes();
displayHours();
godtyckliga fördröja så att vi inte behandlar bort 100% av tiden,
en handling av energispar
Delay(DELAY_BETWEEN_LOOP_CALLS);
}
/**
* En helper metoden att ställa in m_second, m_minute och m_hour.
*/
void setTime (byte newHour, byte newMinute, byte newSecond)
{
m_second = newSecond;
m_minute = newMinute;
m_hour = newHour;
}
/**
* Denna metod håller reda på det logiska flödet av tid. Om tillräckligt med tid har
* gått sedan den senaste gången som det kallades, m_second, m_minute och m_hour
* kommer att uppdateras lämpliga. Detta beaktar den millis() rullar
* över ungefär varje 50 dagar.
*/
void tick()
{
osignerade långa nu = millis();
osignerade långa msElapsed;
först måste vi ta reda på hur mycket tid har gått sedan senast gången vi
kallas tick()
om (nu < m_lastTick)
{
Flämta, antingen har vi lyckats resa tillbaka i tiden, eller millis() virad runt!
msElapsed = (MAX_UNSIGNED_LONG - m_lastTick) + nu;
}
annat
{
msElapsed = nu - m_lastTick;
}
för varje sekund som har passerat (förhoppningsvis bara 1, om inte vår kod är verkligen laggar),
Lägg 1 sekund till tiden och öka minuter & timmar om det behövs.
för (int jag = 0; jag < msElapsed / ONE_SECOND; ++ jag)
{
m_lastTick = m_lastTick + ONE_SECOND;
++ m_second;
om (m_second == 60)
{
m_second = 0;
++ m_minute;
om (m_minute == 60)
{
m_minute = 0;
++ m_hour;
om (m_hour == 24)
{
m_hour = 0;
}
}
}
}
}
void displaySeconds()
{
TODO styra analoga visningen
}
/**
* Denna metod läser den rörliga m_minute, omvandlar den till ett binärt och visar
* det på lämplig lysdioder (de vara PIN_MIN *).
*/
void displayMinutes()
{
byte som = m_minute % 10.
digitalWrite (PIN_MIN1, kära & B1);
digitalWrite (PIN_MIN2, kära & B10);
digitalWrite (PIN_MIN4, kära & B100);
digitalWrite (PIN_MIN8, kära & B1000);
uppdelningen är ganska dyra, men antar vi att sammanställa optimerar detta för oss :)
byte tior = m_minute / 10;
digitalWrite (PIN_MIN10, tens & B1);
digitalWrite (PIN_MIN20, tens & B10);
digitalWrite (PIN_MIN40, tens & B100);
}
/**
* Denna metod läser den rörliga m_hour, omvandlar den till ett binärt och visar
* det på lämplig lysdioder (de vara PIN_HOUR *).
*/
void displayHours()
{
byte som = m_hour % 10.
digitalWrite (PIN_HOUR1, kära & B1);
digitalWrite (PIN_HOUR2, kära & B10);
digitalWrite (PIN_HOUR4, kära & B100);
digitalWrite (PIN_HOUR8, kära & B1000);
byte tior = m_hour / 10;
digitalWrite (PIN_HOUR10, tens & B1);
digitalWrite (PIN_HOUR20, tens & B10);
}
/**
* Denna metod läser värdena från de 2 potentiometrar, konverterar dem till
* mimnutes och timmar, och uppsättningar m_minute och m_hour till de associerade värdena.
*/
void getTimeFromPots()
{
TODO läsa potentiometrar, ange timmar och minuter
}