Stap 8: Met behulp van de RTC om te rijden de meters
We moeten ook wat code de minuten en uren te bevorderen en om terug te keren de meters tot nul wanneer ze max. Dit is werkelijk ongecompliceerd, maar ik liep in een klein probleem. Wanneer de naalden naar nul uit hun volledige reis terugkeert, doen ze vrij krachtig. Genoeg om een door te klikken op lawaai en oorzaak bezorgdheid over de levensduur van de d'Arsonval bewegingen in de meters. Ik wilde een zachte return routine te implementeren in de software die op het eerste gezicht leek vrij gemakkelijk te doen. Ik uiteindelijk krijgen om te werken en ik zal u hoe tonen. Sommigen van u elektronica goeroes mogelijk om erachter te komen een hardwareoplossing voor deze (GLB-kosten en riool door een diode weerstand regeling wanneer de PWM op nul of iets gaat). Zo ja, laat het me weten. Ik nam het pad van de software, en een meer tijd te denken over het nog niet uitgegeven.
Een kleine video van de code hieronder uitvoeren. De O'scope-trace is de blokgolf van de RTC. Aankondiging telkens ontspringt, de seconden hand stappen.
Hier is een programma dat de RTC op basis van een interrupt gegenereerd door het RTC blokgolf gekoppeld lezen zal aan 2 van de arduino pin en output van de waarde van de seconden op pin 5 (PWM).
Deze routine omvat niet de zachte return voor de naald.
#include < Wire.h >
#define DS3231_I2C_ADDRESS 104
#define int_pin 2
#define gauge_pin 5
byte seconden, minuten, uur, dag, datum, maand, jaar;
byte secpos;
char weekdag [4];
Booleaanse int_tick;
byte tMSB, tLSB;
float temp3231;
VOID Setup
{
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(DS3231_I2C_ADDRESS); 104 is DS3231 apparaatadres
Wire.send(0x0E); //
Wire.send(B00000000);
Wire.endTransmission();
pinMode (int_pin, INPUT);
digitalWrite(2,HIGH); opdagen op interne trekken van pin 2
attachInterrupt (0, int0handler, stijgt); interrupt nul sluit aan op pin 2 en de functie int0handler aanroepen wanneer pin 2 een stijgende spanning ziet
secpos = 0;
}
void loop
{
Als (int_tick) {}
updategauge();
}
watchConsole(); gebruikt de tijd en datum wijzigen
}
ongeldig int0handler() {}
int_tick = 1;
}
ongeldig updategauge() {}
Serial.println("int");
get3231Date();
Serial.Print(weekDay); Serial.Print (","); Serial.Print (maand, DEC); Serial.Print("/"); Serial.Print (datum, DEC); Serial.Print("/"); Serial.Print (jaar, DEC); Serial.Print ("-");
Serial.Print (uren, DEC); Serial.Print(":"); Serial.Print (minuten, DEC); Serial.Print(":"); Serial.Print (seconden, DEC);
Serial.Print ("temperatuur:"); Serial.println(get3231Temp());
secpos = seconden * 4;
Als (secpos > = 240) secpos = 0; Dit geeft de tweede naald aan einde van de reis
analogWrite (gauge_pin, secpos);
int_tick = 0; Reset de int teek vlag
}
Normale decimale getallen omzetten in binary coded decimal
byte decToBcd(byte val)
{
retourneren ((val/10 * 16) + (val % 10));
}
VOID watchConsole()
{
Als (Serial.available()) {/ / zoeken char in seriële wachtrij en proces als gevonden
Als (Serial.read() == 84) {//If command = "T" instellen datum
set3231Date();
get3231Date();
Serial.println("");
}
}
}
VOID set3231Date()
{
T(SEC)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(Year)
T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
Voorbeeld: 02-Feb-09 @ 19:57:11 voor de 3e dag van de week -> T1157193020209
seconden (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48)); Gebruik van (byte) type gieten en ASCII-wiskunde om resultaat te bereiken.
minuten (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48));
uren (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48));
dag = (byte) (Serial.read() - 48);
datum (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48));
maand (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48));
jaar (byte) = ((Serial.read()-48) * 10 + (Serial.read() - 48));
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.send(0x00);
Wire.send(decToBcd(seconds));
Wire.send(decToBcd(minutes));
Wire.send(decToBcd(hours));
Wire.send(decToBcd(Day));
Wire.send(decToBcd(date));
Wire.send(decToBcd(month));
Wire.send(decToBcd(Year));
Wire.endTransmission();
}
VOID get3231Date()
{
verzoek tot het ontvangen van gegevens beginnen bij register 0
Wire.beginTransmission(DS3231_I2C_ADDRESS); 104 is DS3231 apparaatadres
Wire.send(0x00); Start op registreren 0
Wire.endTransmission();
Wire.requestFrom (DS3231_I2C_ADDRESS, 7); zeven bytes voor aanvragen
if(Wire.available()) {}
seconden = Wire.receive(); krijgen seconds
minuten = Wire.receive(); Ontvang minuten
uren = Wire.receive(); uren krijgen
dag = Wire.receive();
datum = Wire.receive();
maand = Wire.receive(); Temp maand
jaar = Wire.receive();
seconden = (((seconds & B11110000) >> 4) * 10 + (seconden & B00001111)); BCD converteren naar een decimaal getal
minuten = (((minutes & B11110000) >> 4) * 10 + (minuten & B00001111)); BCD converteren naar een decimaal getal
uren = (((hours & B00110000) >> 4) * 10 + (uren & B00001111)); BCD converteren naar een decimaal getal (neem aan 24-uurs modus)
dag = (dag & B00000111); 1-7
datum = (((date & B00110000) >> 4) * 10 + (datum & B00001111)); 1-31
maand = (((month & B00010000) >> 4) * 10 + (maand & B00001111)); msb7 is een overloop van de eeuw
jaar = (((year & B11110000) >> 4) * 10 + (jaar & B00001111));
}
else {}
Oh noes, geen gegevens!
}
schakelaar (dag) {}
Case 1:
strcpy (weekdag, "Sun");
breken;
Case 2:
strcpy (weekdag, "Ma");
breken;
Case 3:
strcpy (weekdag, "Di");
breken;
Case 4:
strcpy (weekdag, "wo");
breken;
Case 5:
strcpy (weekdag, "Do");
breken;
Case 6:
strcpy (weekdag, "VR");
breken;
Case 7:
strcpy (weekdag, "za");
breken;
}
}
float get3231Temp()
{
tijdelijke registers (11u - 12u) krijgen bijgewerkt automatisch elke 64s
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.send(0x11);
Wire.endTransmission();
Wire.requestFrom (DS3231_I2C_ADDRESS, 2);
if(Wire.available()) {}
tMSB = Wire.receive(); 2 de aanvulling int gedeelte
tLSB = Wire.receive(); breuk, deel
temp3231 = (tMSB & B01111111); 2's wiskunde op Tmsb
temp3231 += ((tLSB >> 6) * 0,25); alleen de zorg over bits 7 & 8
}
else {}
Oh noes, geen gegevens!
}
Return temp3231;
}