Master voor een slave stationsklok.
Re: Master voor een slave stationsklok.
nicoverduin schreef:Piet,
Je zou kunnen overwegen dat op het moment dat de DTS laatste een uur afwijkt tov van de DTS tijd vorige, dan is dat het moment dat de wisseling plaats vindt. Dan kun je de puls correctie uitvoeren
Tegelijkertijd heb je ook nog te maken met een reset c.q. power-down oid dan moet je ook nog iets doen. Het moment is volgens mij dacht ik iets van 02:00 (winter naar zomertijd) en 03:00 (bij zomer naar wintertijd).
Dat moment is te detecteren. Dus iets in die richting
omschakelen heb ik zelf als volgt gedaan, mijn RTC is een DS3231
Bij de variabelen heb ik DST als een int.
in de setup staat:
- Code: Alles selecteren
DSTVlag = EEPROM.read(0);
#if defined DEBUG
Serial.print("DST-Vlag: ");
Serial.println(DSTVlag);
if (DSTVlag==0){
Serial.println("Wintertijd");
}
if (DSTVlag==1){
Serial.println("Zomertijd");
}
#endif
de functie voor afvragen van de klok:
- Code: Alles selecteren
void displayClock(void) {
if(millis() - KlokCounter > KlokInterval) // iedere seconde
{
KlokCounter = millis();
int second,minute,hour,date,month,year,temperature,day;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=2000+Clock.getYear();
day=Clock.getDoW();
// check of we naar wintertijd moeten gaan
if (day == 7 && month == 10 && date >= 25 && date <=31 && hour == 3 && DSTVlag==1)
{
// Ja, schrijf naar EEPROM en zet klok 1 uur terug
Clock.setHour(2);
DSTVlag = 0;
EEPROM.write(0, DSTVlag);
}
// check of we naar zomertijd moeten gaan
if (day == 7 && month == 3 && date >= 25 && date <=31 && hour == 2 && DSTVlag==0)
{
// Ja, schrijf naar EEPROM en zet klok 1 uur vooruit
Clock.setHour(3);
DSTVlag = 1;
EEPROM.write(0, DSTVlag);
}
char* dag=dagen[day];
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setTextSize(2);
tft.setCursor(0,0);
tft.print(dag);
// print datum
char dateBuffer[12];
sprintf(dateBuffer,"%02u-%02u-%04u ",date,month,year);
tft.setCursor(35,0);
tft.setTextColor(ST7735_YELLOW,ST7735_BLACK);
tft.print(dateBuffer);
// print tijd
sprintf(dateBuffer,"%02u:%02u:%02u",hour,minute,second);
//tijd=dateBuffer;
tft.setCursor(48,17);
tft.setTextColor(ST7735_YELLOW,ST7735_BLACK);
tft.print(dateBuffer);
}
}
Advertisement
Re: Master voor een slave stationsklok.
MarcelK schreef:omschakelen heb ik zelf als volgt gedaan, mijn RTC is een DS3231
Dat is ook een interessante optie, die ik uitga proberen.
Dankjewel Marcel.
Re: Master voor een slave stationsklok.
bossie schreef:MarcelK schreef:omschakelen heb ik zelf als volgt gedaan, mijn RTC is een DS3231
Dat is ook een interessante optie, die ik uitga proberen.
Dankjewel Marcel.
Tsja, je ziet het pas over een half jaar of het werkt
Ik heb het er ook pas in gezet dus moet ook afwachten.
Ik heb mijn info hier vandaan: https://arduinodiy.wordpress.com/2015/10/13/the-arduino-and-daylight-saving-time/
Re: Master voor een slave stationsklok.
Nou in ieder geval heb ik genoeg leeswerk om me in te verdiepen.
bedankt.
bedankt.
Re: Master voor een slave stationsklok.
Het lukt me niet om de tips van Marcel te incorporeren in mijn Klok sketch
Dus ben ik zelf aan het 'broddelen' gegaan.
Om een uur vooruit te simuleren leg ik via een drukknop port 8 tegen de voedings -.
Nu zit ik met het volgende probleem.
Ik had bedacht dat deze code voor zou kunnen zorgen dat, nadat de één uur vooruit loop was doorlopen, ik de RTC zo gelijk kon zetten.
Die Serial.print() statements heb ik er ingezet om te kunnen achterhalen waar het fout gaat.
Maar in eens heeft de RTC een jaartal dat het huidige, + 18 is.
Waarom is dat?
Wat doe ik verkeerd?
grt Piet.
Dus ben ik zelf aan het 'broddelen' gegaan.
- Code: Alles selecteren
/*
* TimeRTC.pde
************************************************************************************
* NZH-KLOK *
* Naar een idee van Piet Bos *
* Aangepast op de specifieke vereisten van de Stations Klok van het NZH museum *
* Aanpassingen: *
* Piet Bos v *
* De derde status van POS - NEG - POS vverwijderd 22/10/2015 *
* De startup meldingen in het display aangepast 23/10/2015 *
* De sturing en gebruik van de digitale uitgangen 3 en 4 -> 6 en 7 25/10/2015 *
* De wissel van even en oneven minuten 25/10/2015 *
* *
* *
************************************************************************************
* uses an RTC (real time clock) to drive an old station clock
*
* every minute, there is a pulse POS or NEG on 2 relays (D7 pos , D6 neg)
* Even minutes the pulse is on Port 7
* Odd minutes the pulse is on Port 6
*
* RTC connects to
* +5V (or 3,3V depending ont ype)
* GND
* SCL (I2C clock pin ) ----> to Analog 5
* SDA (I2C data pin ) ----> to Analog 4
*
* other boards than Arduino Uno
* Board I2C / TWI pins
-------------------------------------------------
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), (SDA1, SCL1 )
* LCD display functionality added:
* The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
//#include <LiquidCrystal.h>
#include <LiquidCrystal_16x4.h>
//#include <Timezone.h>
//Central European Time (Frankfurt, Paris)
// TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time
//TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time
//Timezone CE(CEST, CET);
//TimeChangeRule *tcr; //pointer to the time change rule, use to get the TZ abbrev
time_t utc;
int local_t;
const char *Maandnaam[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char *Weekdag[7] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
tmElements_t tm;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int seconden = 0;
int lastseconde = 0;
int beatsec = 0;
int Weekday = 0;
int maandindex = 0;
int Save_maandindex = 0;
int negpuls = 6; // use digital out 6 as negative current relay driver
int pospuls = 7; // use digital out 7 as positive current relay driver
const int switch_H = 8; // Schakelaar om een 60 minuten loop te maken.
int pulseLED = 10; // use this LED to indicate pulse being sent
int cycleLED = 13; // use this LED to indicate cycle activity
int pulsDuur = 500; // minimal pulse length 1 seconde
int waitDuur = 500; // minimal pause length 0.5 seconde
int Button = 0;
boolean TisTime = false;
const char TMzone[] = "CET";
const char UTCzone[] = "UTC";
void setup() {
Serial.begin(9600);
for (int pin=0; pin<13; pin++)
{
pinMode(pin, OUTPUT);
}
pinMode(cycleLED,OUTPUT);
pinMode(pulseLED,OUTPUT);
pinMode(switch_H,INPUT_PULLUP); // Set de pin to input.
// Maak de pin HIGH zodat de schakelaar naar ground goed
// is voor een trap.
// set up the LCD's number of columns and rows:
lcd.begin(16, 4);
// Print a message to the LCD.
lcd.print("NZH Museum klok");
delay(500);
lcd.setCursor(0,1);lcd.print("Init v1.1/04-11");
delay(500);
pinMode(pospuls,OUTPUT);
pinMode(negpuls,OUTPUT);
digitalWrite(negpuls,LOW); // negative puls - Relay off
digitalWrite(pospuls,LOW); // positive puls - Relay off
/*
bool parse=false;
bool config=false;
// deze routine uitzetten bij 'normaal' gebruik.
// get the date and time the compiler was run
if (getDate(__DATE__) && getTime(__TIME__))
{ parse = true;
if (RTC.write(tm)) {config = true;} }
Serial.print("System configured Time=");
Serial.print(__TIME__);
Serial.print(", Date=");
Serial.println(__DATE__);
Serial.println("Set deafult system time to download time");
setTime(tm.Hour,tm.Minute,tm.Second,tm.Day,tm.Month,tm.Year);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
*/
// deze routine uitzetten bij 'normaal' gebruik.
}
void loop(){
// test knop. switch_H = 9; // creeer pulsen om een uur vooruit te gaan(WIN-->ZOM)
int digitalVal = digitalRead(switch_H);
Button = 0;
if( NULL == digitalVal && Button == 0)
{
// int New_hour, Save_hour, Save_minute, Save_second; Save_hour = hour();
// Save_maandindex = maandindex;
Serial.println(" ");
//Routine om de mechanische klok 1 uur vooruit te zetten.
// declareer i, en test of deze kleiner is dan 31, i wordt met 1 opgehoogd
// 31 omdat het doorlopen van deze lus ook tijd vergt moet de klok 1 uur + 1 minuut vooruit
// 2 minuten omdat elke puls 500+1000 = 1500 ms in beslag neemt. Dus 60x1500 = 90.000 ms
// of anders gezegd er is anderhalve minuut nodig om de klok te synchroniseren. vandaar 1 min extra
// deze extra minuut wordt gegenereerd door een extra HIGH puls na de eigenlijke lus.
// en bij de eerstvolgende normale puls zal de klok dan weer gelijk lopen
for (int i=0; i<31; i++)
{digitalWrite(pospuls,HIGH); // zet pin 7 aan
delay(pulsDuur); // lengte van de puls
digitalWrite(pospuls,LOW); // zet pin 7 uit
delay(500); // 2 sec pauze tussen de pulsen voor mechanische beweging en om motorspoel te laten koelen
showClock(); // Laat de display gewoon 'doorlopen'.
digitalWrite(negpuls,HIGH); // zet pin 6 aan
delay(pulsDuur); // lengte van de puls
digitalWrite(negpuls,LOW); // zet pin 6 uit
Serial.print(" ");Serial.println(i);
delay(500); // 2 sec pauze tussen de pulsen voor mechanische beweging en om motorspoel te laten koelen
}
/*
digitalWrite(pospuls,HIGH); // zet pin 7 aan // de extra puls voor het compenseren van de beweging van 60 tikken.
digitalWrite(pospuls,LOW);
*/
// en nu moeten we nog de RTC klok een uur voortuit zetten zodat de Arduino de correcte tijd oppikt ...
setSyncProvider(RTC.get); // haal de huidige tijd van de RTC
Serial.print("\n Oude tm is : ");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
tm.Hour = hour()+1; // 1 uur bijtellen
tm.Minute = minute();
tm.Second = second();
tm.Day = day();
tm.Month = month();
tm.Year = year();
Serial.print("Nieuwe tm is : ");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
if (RTC.write(tm))
{Serial.print("RTC updated");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
}
else
{Serial.println("RTC SYNC ERROR !");}
// Eens buiten deze lus gearriveerd, zal de klok nu gelijk lopen
Button = 1; // er voor zorgen dat de button vlag ge cleared is.
}
// get the data from the RTC
setSyncProvider(RTC.get); // the function to get the time from the RTC
Serial.print("\n");
utc = now();
local_t = utc - 1;
delay(500);
// run heartbeat and check clock status
heartbeat();
seconden = second(); //remember second value
if (lastseconde==59 && seconden==0)
{TisTime= true;lastseconde=0;}
else {lastseconde=seconden;TisTime=false;}
// if it is time to advance : send pulse
if (TisTime) {stuurPuls();}
// weekday() contains 7 daynames (Sun=1...Sat=7
Weekday = weekday()-1; // the first element of an array has index 0
// Saturday is day 7 and array element 6.
// month() contains 12 monthnames (Jan=1...Dec =12)
maandindex = month()-1; // the first element of an array has index 0
// December is month 12 and array element 11.
/*
Serial.print("Dag vande week: "); Serial.print(Weekdag[Weekday]);
*/
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void showClock()
{ Serial.print(Weekdag[Weekday]);Serial.print(" ");
Serial.print(day());Serial.print(" ");
Serial.print(Maandnaam[maandindex]); Serial.print(" ");
sPrintI00(year()); Serial.print(" ");
sPrintI00(hour());
sPrintDigits(minute());
sPrintDigits(second());
// lcd.clear();
// De routine die de klok tijd op de LCD zet.
if (day() < 10) { // dag kleiner dan 10
lcd.setCursor(0,3);lcd.print("0");
lcd.setCursor(1,3);lcd.print(day());
}
else { // dag groter of gelijk aan 10
lcd.setCursor(0,3);lcd.print(day());
}
lcd.setCursor(3,3);lcd.print(Maandnaam[month()-1]);
lcd.setCursor(7,3);lcd.print(year());
if (day() < 10) { // dag kleiner dan 10
lcd.setCursor(0,0);lcd.print("0");
lcd.setCursor(1,0);lcd.print(day());
}
else { // dag groter of gelijk aan 10
lcd.setCursor(0,0);lcd.print(day());
}
lcd.setCursor(3,0);lcd.print(Maandnaam[month()-1]);
lcd.setCursor(7,0);lcd.print(year());
lcd.setCursor(0,1);lcd.print("0");
lcd.setCursor(2,1);lcd.print(":0");
lcd.setCursor(5,1);lcd.print(":0");
if (hour() < 10) {
lcd.setCursor(1,1);lcd.print(hour());
}
else {
lcd.setCursor(0,1);lcd.print(hour());
}
if (minute() < 10){
lcd.setCursor(4,1);lcd.print(minute());
}
else {
lcd.setCursor(3,1);lcd.print(minute());
}
if (second() < 10)
{
lcd.setCursor(7,1);lcd.print(second());
}
else {
lcd.setCursor(6,1);lcd.print(second());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void stuurPuls()
{// generate pulses
lcd.clear(); //12345678901234567
lcd.setCursor(0,0);lcd.print("Impuls --> Klok ");
delay(500);
lcd.clear();
// Serial.print("\nPulse started \n");
digitalWrite(pulseLED, HIGH); // led on
digitalWrite(cycleLED, HIGH); // led on
//
// Digital outputs.
//
// bij de even minuten moet Port Dig 7 en bij de oneven minuten moet Port Dig 6
// van status veranderen.
if ( minute() % 2 == 0 ) // Neem de modulus van minute() is de uitkomst 0 dan even getal anders is het oneven.
{
Serial.print("\nRest van de deling "); Serial.print(minute() % 2); Serial.print(" - Minuten zijn een even.");
// Positive output settings. Port Dig 7 LE02 - zwarte draad
// lcd.setCursor(0,1);lcd.print(" + Port 7 ");
lcd.clear();
digitalWrite(pospuls,HIGH); // positieve puls aan Relay on
delay(pulsDuur); // Relay aan voor 1000ms
digitalWrite(pospuls,LOW); // positive puls uit Relay off
digitalWrite(cycleLED,LOW); // led off
lcd.clear();
}
else
{
Serial.print("\nRest van de deling "); Serial.print(minute() % 2); Serial.print(" - Minuten zijn een oneven.");
// Negative output settings Port Dig 6 LE01 - bruine draad.
// lcd.setCursor(0,1);lcd.print(" - Port 6 ");
//
lcd.clear();
digitalWrite(negpuls,HIGH); // negatieve puls Relay on
delay(pulsDuur); // wait
digitalWrite(negpuls,LOW); // drop puls - Relay off
digitalWrite(cycleLED,LOW); // led off
lcd.clear();
}
digitalWrite(pulseLED,LOW); //
digitalWrite(cycleLED,HIGH); //
// Serial.println("Pulse ended");
digitalWrite(negpuls,LOW); // negative puls - Relay off
digitalWrite(pospuls,LOW); // positive puls - Relay off
lcd.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void heartbeat()
{ digitalWrite(cycleLED,HIGH);
delay(10);
digitalWrite(cycleLED,LOW);
if (beatsec != second()) // display time in serial port every second
{if(timeStatus()== timeSet)
{Serial.print("RTC TIME : ");
// lcd.setCursor(12,0);lcd.print("RTC");
}
else
{Serial.print("RTC ERROR, use internal ---> ");
// lcd.setCursor(12,0);lcd.print("INT");
}
showClock();
}
beatsec=second(); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
bool getTime(const char *str)
{int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
bool getDate(const char *str)
{char Month[12];
int Day, Year;
uint8_t maandindex;
if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
for (maandindex = 0; maandindex < 12; maandindex++) {
if (strcmp(Month, Maandnaam[maandindex]) == 0) break;
}
if (maandindex >= 12) return false;
tm.Day = Day;
tm.Month = maandindex + 1;
tm.Year = CalendarYrToTm(Year);
return true;}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//Print an integer in "00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintI00(int val)
{
if (val < 10) Serial.print('0');
Serial.print(val, DEC);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Print an integer in ":00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintDigits(int val)
{
Serial.print(':');
if(val < 10) Serial.print('0');
Serial.print(val, DEC);
}
Om een uur vooruit te simuleren leg ik via een drukknop port 8 tegen de voedings -.
Nu zit ik met het volgende probleem.
- Code: Alles selecteren
// en nu moeten we nog de RTC klok een uur voortuit zetten zodat de Arduino de correcte tijd oppikt ...
setSyncProvider(RTC.get); // haal de huidige tijd van de RTC
Serial.print("\n Oude tm is : ");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
tm.Hour = hour()+1; // 1 uur bijtellen
tm.Minute = minute();
tm.Second = second();
tm.Day = day();
tm.Month = month();
tm.Year = year();
Serial.print("Nieuwe tm is : ");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
if (RTC.write(tm))
{Serial.print("RTC updated");
Serial.print(tm.Hour);Serial.print(":");
Serial.print(tm.Minute);Serial.print(":");
Serial.print(tm.Second);Serial.print("---");
Serial.print(tm.Day);Serial.print("/");
Serial.print(tm.Month);Serial.print("/");
Serial.print(tm.Year);Serial.println(".");
}
else
{Serial.println("RTC SYNC ERROR !");}
// Eens buiten deze lus gearriveerd, zal de klok nu gelijk lopen
Ik had bedacht dat deze code voor zou kunnen zorgen dat, nadat de één uur vooruit loop was doorlopen, ik de RTC zo gelijk kon zetten.
Die Serial.print() statements heb ik er ingezet om te kunnen achterhalen waar het fout gaat.
Maar in eens heeft de RTC een jaartal dat het huidige, + 18 is.
Waarom is dat?
Wat doe ik verkeerd?
grt Piet.
Re: Master voor een slave stationsklok.
ik zie je iets doen met utc-1, en 18 is 16+8=24 decimaal dus ergens maak je een rekenfout tussen hex en digitaal.
verder snap ik tm.hour=hour niet in getdate? en de nadere daarbij natuurlijk ook niet dat moet andersom staan.
verder snap ik tm.hour=hour niet in getdate? en de nadere daarbij natuurlijk ook niet dat moet andersom staan.
paul deelen
shooter@home.nl
shooter@home.nl
Re: Master voor een slave stationsklok.
Dat was even tijdelijk een hulp variabele local_t te vullen, vergeten weg te halen. Wordt verder nergens (meer) gebruikt.shooter schreef:ik zie je iets doen met utc-1,
Die moet je me ff uitleggen Paul.shooter schreef:en 18 is 16+8=24 decimaal dus ergens maak je een rekenfout tussen hex en digitaal.
Ik snap niet wat je bedoelt.
grt Piet
Re: Master voor een slave stationsklok.
18 hex de 1 is 16 en de 8 is 8 bij elkaar 24 decimaal
het eerste getal loopt van 0 tot F ofwel 0 tot 15 decimaal
de volgende is dan 16.
wij zijn gewend om met tietallig te werken maar de computer (en de RTC zeker werkt met 16tallig stelsel.
verder zag ik iets raars met tm.hour die een waarde krijgt maar dat kan niet.
het eerste getal loopt van 0 tot F ofwel 0 tot 15 decimaal
de volgende is dan 16.
wij zijn gewend om met tietallig te werken maar de computer (en de RTC zeker werkt met 16tallig stelsel.
verder zag ik iets raars met tm.hour die een waarde krijgt maar dat kan niet.
paul deelen
shooter@home.nl
shooter@home.nl
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 0 gasten