From 3f97f3f02ab65b0515137bd75520afaedea95a6e Mon Sep 17 00:00:00 2001 From: 135 Date: Sat, 27 Jul 2024 12:36:14 +0300 Subject: [PATCH] =?UTF-8?q?WIP=20=D0=BF=D0=BE=D0=BF=D1=8B=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=B5=D0=B1=D0=B0=D0=B6=D0=B8=D1=82=D1=8C=20PPS?= =?UTF-8?q?/SQW.=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD=D0=B0=20S?= =?UTF-8?q?WSerial=20(8,9)=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D1=8C=20Serial=20=D0=B8=20?= =?UTF-8?q?=D0=BD=D0=B0=20LCD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GPS_RTC_Clock.cpp | 2 +- GPS_RTC_Clock.h | 4 +- GPS_RTC_Clock.ino | 167 ++++++++++++++------------------------------ GPS_com.cpp | 58 +++++++++++---- RTC_com.cpp | 16 +++-- Serial_AdjustBaud.h | 10 ++- 6 files changed, 118 insertions(+), 139 deletions(-) diff --git a/GPS_RTC_Clock.cpp b/GPS_RTC_Clock.cpp index e79431a..47b885d 100644 --- a/GPS_RTC_Clock.cpp +++ b/GPS_RTC_Clock.cpp @@ -25,7 +25,7 @@ void GPS_RTC_Clock_setup() { RTC_setup(); GPS_setup(); TZ_setup(); - Serial.println("DEBUG[GPS_RTC_Clock_setup] done"); + //Serial.println("DEBUG[GPS_RTC_Clock_setup] done"); } void GPS_RTC_Clock_loop() { diff --git a/GPS_RTC_Clock.h b/GPS_RTC_Clock.h index 6918982..93e0f88 100644 --- a/GPS_RTC_Clock.h +++ b/GPS_RTC_Clock.h @@ -37,8 +37,8 @@ extern bool NewMin; // pass to main ino = minute ready to print extern bool NewHour; // pass to main ino = Hour ready to print extern time_t Loc_t; // pass to main ino = Local timestamp -extern volatile unsigned long tmr_SQW, tmr_PPS; -// call from main ino, GPS_RTC_Clock.h +extern volatile bool GPS_sec, RTC_sec; +extern unsigned long RTCMillis;// call from main ino, GPS_RTC_Clock.h void GPS_RTC_Clock_setup(); // call from main ino, GPS_RTC_Clock.h diff --git a/GPS_RTC_Clock.ino b/GPS_RTC_Clock.ino index e699e80..c2fbe47 100644 --- a/GPS_RTC_Clock.ino +++ b/GPS_RTC_Clock.ino @@ -9,12 +9,13 @@ #include // needed for Nano Every #include "GPS_RTC_Clock.h" -#include "LED_96x8_matrix.h" +//#include "LED_96x8_matrix.h" #include #include #include "Font_Chrono1.h" -#define pin_RTC_SQW 3; +#define pin_RTC_SQW 3 +#define DEBUG_PORT Serial SoftDMD dmd(2, 1); LiquidCrystal_I2C lcd(0x27, 16, 2); @@ -23,42 +24,12 @@ char TempBuf[5] = "99.9"; // demo value char HumiBuf[3] = "99"; // demo value unsigned long TMR_FPS; +long FPS; bool LCD_Simple_clock; +bool GPS_PPS_LCD, RTC_SQW_LCD; +volatile bool fGPS_PPS, fRTC_SQW; -void RTCtoLCD(bool ClockType = LCD_Simple_clock) { - if (!NewSec && !NewMin && !NewHour) return; - char Clock[9]; - char segment[3]; - char message[50]; - - if (ClockType) { - snprintf(Clock, sizeof(Clock), "%.2u:%.2u:%.2u", hour(Loc_t), minute(Loc_t), second(Loc_t)); - lcd.setCursor(0,0); - lcd.print(Clock); - } - else if (NewSec) { - snprintf(segment, sizeof(segment),"%.2u", second(Loc_t)); - lcd.setCursor(6, 0); - lcd.print(segment); - } - - if (NewMin) { - snprintf(segment, sizeof(segment),"%.2u", minute(Loc_t)); - lcd.setCursor(3, 0); - lcd.print(segment); - snprintf(segment, sizeof(segment),"%.2u", hour(Loc_t)); - lcd.setCursor(0, 0); - lcd.print(segment); - } - //Serial.print("DEBUG[RTCtoLCD] millis(): "); Serial.println(micros()); -// long drift = tmr_PPS - tmr_SQW; - //Serial.println("DEBUG[RTCtoLCD] Difference PPS - SQW: " + String(drift) + "[" + String(tmr_PPS) + "]" + "[" + String(tmr_SQW) + "]"); -// lcd.setCursor(15, 1); -// lcd.print((micros() - tmr_PPS < 2000000) ? "P" : "p"); // Выводим "P" или "p" на 16 позиции в зависимости от условия -// snprintf(message, sizeof(message), "micros: %d, tmr_PPS: %d", millis(), tmr_PPS); -// Serial.println(message); -} void setup() { // the setup function runs once when you press reset or power the board // LCD @@ -68,9 +39,9 @@ void setup() { // the setup function runs once when you lcd.setCursor(0,0); lcd.print("DEBUG[setup()]"); delay(500); - Serial.begin(19200); // = 9600, must be same as GPS for debug - Serial.println(); // flush serial - Serial.println("-Arduino Reboot-"); // debug + //Serial.begin(19200); // = 9600, must be same as GPS for debug + //Serial.println(); // flush serial + //Serial.println("-Arduino Reboot-"); // debug GPS_RTC_Clock_setup(); // first in setup //Matrix_setup(); // LED display @@ -90,94 +61,60 @@ void loop() { // the loop function runs over and over again forever // } GPS_RTC_Clock_loop(); // first in loop + RTCtoLCD(); - PrintSec(); - PrintHour(); chkFPS(); } ///////////////////// +void RTCtoLCD() { + if (GPS_sec) { + DEBUG_PORT.println("DEBUG[RTCtoLCD] GPS_sec"); + GPS_PPS_LCD = !GPS_PPS_LCD; + lcd.setCursor(2, 0); + lcd.print((GPS_PPS_LCD) ? " " : ":"); + } + if (RTC_sec) { + DEBUG_PORT.println("DEBUG[RTCtoLCD] RTC_sec"); + RTC_SQW_LCD = !RTC_SQW_LCD; + lcd.setCursor(5, 0); + lcd.print((RTC_SQW_LCD) ? " " : ":"); + } + //if (!GPS_sec and !RTC_sec) return; + if (!NewSec && !NewMin && !NewHour) return; + char Clock[9]; + char segment[3]; + char message[50]; + + if (NewSec) { + DEBUG_PORT.println("DEBUG[RTCtoLCD] newSec"); + DEBUG_PORT.println("DEBUG[RTCtoLCD] RTCMillis: " + String(RTCMillis)); + DEBUG_PORT.println("DEBUG[RTCtoLCD] RTC_sec: " + String(RTC_sec)); + DEBUG_PORT.println("DEBUG[RTCtoLCD] millis: " + String(millis())); + snprintf(segment, sizeof(segment),"%.2u", second(Loc_t)); + lcd.setCursor(6, 0); + lcd.print(segment); + } + + if (NewMin) { + snprintf(segment, sizeof(segment),"%.2u", minute(Loc_t)); + lcd.setCursor(3, 0); + lcd.print(segment); + snprintf(segment, sizeof(segment),"%.2u", hour(Loc_t)); + lcd.setCursor(0, 0); + lcd.print(segment); + } +} void chkFPS() { - int FPS; - if (millis() - TMR_FPS > 1000) { - Serial.println(TMR_FPS); - Serial.println(millis()); - TMR_FPS = millis(); - Serial.print("DEBUG[chkFPS] "); Serial.println(FPS); + if (micros() - TMR_FPS > 1000000) { + DEBUG_PORT.println("DEBUG[chkFPS] FPS: " + String(FPS)); + //DEBUG_PORT.println("DEBUG[chkFPS] TMR_FPS: " + String(TMR_FPS)); + TMR_FPS = micros(); FPS = 0; return; } FPS++; } - - - -void PrintSec() { // print time if new second - if (NewSec) { // - NewSec = false; // remove flag, do only once every sec - char startmarker = '<'; - char endmarker = '>'; - //Serial.print(startmarker); // for remote display via RS485 - //Serial.print(Loc_t); // for remote display via RS485 - //Serial.println(endmarker); // for remote display via RS485 - - char TimeBuf[9]; // time string buffer, max n-1 char - snprintf(TimeBuf, sizeof(TimeBuf), "%.2u:%.2u:%.2u", // https://cplusplus.com/reference/cstdio/printf/ - hour(Loc_t), minute(Loc_t), second(Loc_t)); // time 24h format - //Serial.print("Time: "); // debug - //Serial.println(TimeBuf); // debug - //Print_time_zone(TimeBuf); // print to LED Matrix - PrintMin(); - } -} - -void PrintMin() { - char TextBuf[12]; // date string buffer, max n-1 char - if (!DIP_Scroll()) { // print date only or 'scrolling' text - snprintf(TextBuf, sizeof(TextBuf), "%s %.2u %s", - dayShortStrLoc(weekday(Loc_t)), day(Loc_t), monthShortStrLoc(month(Loc_t))); // weekday, day, month - } else { // print 'scrolling' - /*** HowTo ****************************************************************** - print different info every few seconds, because of limited display space - define the amount of different text lines, must be at least 1 - define the amount of seconds each textline is displayed, must be at least 1 - define each text line, this may be duplicates of other text lines - *****************************************************************************/ - byte text_lines = 3; // amount of different text lines printed - byte text_timer = 5; // amount of seconds to next text - byte text_counter(((Loc_t / text_timer) % text_lines) + 1); // range = 1..n - if (text_counter == 1) { - snprintf(TextBuf, sizeof(TextBuf), "%.2u%s%u", - day(Loc_t), monthShortStrLoc(month(Loc_t)), year(Loc_t)); // day, month, year - } else if (text_counter == 2) { - snprintf(TextBuf, sizeof(TextBuf), "%s W%.2u", - dayShortStrLoc(weekday(Loc_t)), ISOWeekNumber(Loc_t)); // weekday, week - } else if (text_counter == 3) { - snprintf(TextBuf, sizeof(TextBuf), "%s*C %s%%", TempBuf, HumiBuf); // * = ° degrees char in fontClock - } else { - snprintf(TextBuf, sizeof(TextBuf), " Err "); - } - } - //Print_date_zone(TextBuf); // print to LED Matrix - - if (NewMin) { // print date if new minute - NewMin = false; // remove flag, do only once every min - char DateBuf[21]; // date string buffer, max n-1 char - // long date version - snprintf(DateBuf, sizeof(DateBuf), "%s %.2u-%s-%u W%.2u", - dayShortStrLoc(weekday(Loc_t)), day(Loc_t), monthShortStrLoc(month(Loc_t)), year(Loc_t), ISOWeekNumber(Loc_t)); - //Serial.print("Date long: "); // debug - //Serial.println(DateBuf); // debug - } -} - -void PrintHour() { // do if new hour - if (NewHour) { // - NewHour = false; // remove flag, do only once every hour - //Serial.println("bring out the Cuckoo ;-)"); // debug - } -} - //End diff --git a/GPS_com.cpp b/GPS_com.cpp index 19e07cf..19d31b6 100644 --- a/GPS_com.cpp +++ b/GPS_com.cpp @@ -23,12 +23,9 @@ static int pulse_count = 0; static time_t gps_seconds_t = 0; // GPS time static byte gps_sats = 0; volatile bool GPS_sec = false; // flag for GPS-PPS -volatile unsigned long tmr_PPS; // set interrupt flag void gps_interrupt() { - tmr_PPS = micros(); - Serial.print("DEBUG[INT] GPS interrupt: "); Serial.println(tmr_PPS); //Serial.print("DEBUG[INT] GPS interrupt "); Serial.println(micros()); GPS_sec = true; } @@ -42,8 +39,6 @@ gps_fix fix; // This holds on to the latest values //#define GPS_PORT_NAME "Serial" #define GPS_PORT_NAME "AltSoftSerial" -#define DEBUG_PORT Serial - /***** Notice ******************************************** Edit file \Arduino\libraries\NeoGPS\src\NMEAGPS_cfg.h UnComment line //#define NMEAGPS_PARSE_ZDA @@ -70,19 +65,54 @@ gps_fix fix; // This holds on to the latest values const long POSIX_Y2K_offset = 946684800; // = 10957 days = 30 years, NeoTime (GPS) & TimeLib (RTC) library use different Epoch year, 2000 & 1970 const long offset_28y = 883612800; // = 10227 days = 28 years, simple test for 2038 bug const long offset_26w = 15724800; // = 182 days = 26 weeks, simple test for timezone -const long offset_135 = 123456; // = 135 seconds, simple test for timezone const char baud19200 [] PROGMEM = "PUBX,41,1,3,3,19200,0"; +const char baud38400 [] PROGMEM = "PUBX,41,1,3,3,38400,0"; +const char GGA_off [] PROGMEM = "PUBX,40,GGA,0,0,0,0"; +const char GLL_off [] PROGMEM = "PUBX,40,GLL,0,0,0,0"; +const char GSA_off [] PROGMEM = "PUBX,40,GSA,0,0,0,0"; +const char GSV_off [] PROGMEM = "PUBX,40,GSV,0,0,0,0"; +const char VTG_off [] PROGMEM = "PUBX,40,VTG,0,0,0,0"; +const char RMC_off [] PROGMEM = "PUBX,40,RMC,0,0,0,0"; +const char ZDA_off [] PROGMEM = "PUBX,40,ZDA,0,0,0,0"; +const char RMC_on [] PROGMEM = "PUBX,40,RMC,0,1,0,0"; +const char ZDA_on [] PROGMEM = "PUBX,40,ZDA,0,1,0,0"; void GPS_setup() { + DEBUG_PORT.begin(38400); + DEBUG_PORT.println(F("DEBUG[GPS_setup()] start")); pinMode(GPS_PPS_PIN, INPUT_PULLUP); // enable pullup on interrupt pin attachInterrupt(digitalPinToInterrupt(GPS_PPS_PIN), gps_interrupt, RISING); // 100ms HIGH at start of second GPS_sec = false; - gpsPort.begin(9600); // set PC to same baudrate for debug messages - gps.send_P(&gpsPort, (const __FlashStringHelper *) baud19200); - gpsPort.flush(); + if (detRate(cfg_pin_GPS_Rx) != 38400) { + DEBUG_PORT.println(F("DEBUG[GPS_setup()] baudrate not 38400")); + gpsPort.begin(detRate(cfg_pin_GPS_Rx)); // set PC to same baudrate for debug messages + gps.send_P(&gpsPort, (const __FlashStringHelper *) baud38400); + gpsPort.flush(); + delay(100); + gpsPort.end(); + } + else + DEBUG_PORT.println(F("DEBUG[GPS_setup()] baudrate already 38400")); + gpsPort.begin(38400); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) GGA_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) GLL_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) GSA_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) GSV_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) VTG_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) RMC_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) ZDA_off); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) RMC_on); + delay(100); + gps.send_P(&gpsPort, (const __FlashStringHelper *) ZDA_on); delay(100); - gpsPort.end(); - gpsPort.begin(19200); GPS_ON(); } @@ -101,8 +131,6 @@ void GPS_PPS() { // do something on the flip of the GPS second if (gps_seconds_t != 0) { // do only if value is set // gps_seconds_t += offset_28y; // debug & testing only! // gps_seconds_t += offset_26w; // debug & testing only! - // gps_seconds_t += offset_135; - Serial.println("DEBUG[GPS_PPS] difference PPS - SQW: " + String(tmr_PPS - tmr_SQW)); SetRTC(gps_seconds_t); // sync RTC with GPS GPS_OFF(); } @@ -127,13 +155,13 @@ void GPS_ON() { gps_on = true; gps_seconds_t = 0; // make shure GPS serial is alive before setting pulse_count = 0; - Serial.println("GPS: ON"); // debug + //Serial.println("GPS: ON"); // debug } void GPS_OFF() { if (gps_on) { // only if NOT off gps_on = false; - Serial.println("GPS: OFF"); // debug + //Serial.println("GPS: OFF"); // debug } } diff --git a/RTC_com.cpp b/RTC_com.cpp index 40872c7..45a2a7f 100644 --- a/RTC_com.cpp +++ b/RTC_com.cpp @@ -8,9 +8,13 @@ #include // for all the 'standard' Arduino stuff #include // https://github.com/JChristensen/DS3232RTC #include // https://github.com/PaulStoffregen/Time [valid until year 2099, no 2038 bug] +#include "GPS_RTC_Clock.h" #include "RTC_com.h" #define cfg_pin_RTC_SQW 3; +#ifndef DEBUG_PORT +#define DEBUG_PORT Serial +#endif // add the static modifier to limit visibility of these variables to just this file static int ledPin_PPS = A6; // Pin for RTC PseudoPPS LED [analog PIN used as digital PIN] @@ -23,11 +27,9 @@ bool SyncErr = true; #include DS3232RTC myRTC(0x68); // cfg_ volatile bool RTC_sec = false; // flag for PseudoPPS -static unsigned long RTCMillis; // blinking timer -volatile unsigned long tmr_SQW; +unsigned long RTCMillis; // blinking timer void rtc_interrupt() { - tmr_SQW = micros(); //Serial.print("DEBUG[INT] RTC interrupt "); Serial.println(micros()); RTCMillis = millis(); RTC_sec = true; @@ -51,6 +53,9 @@ void RTC_setup() { void RTC_loop() { //Serial.println("DEBUG[RTC_loop()] Start"); if (RTC_sec) { // do after RTC PseudoPPS interrupt, without interrupt NO time/date to display + DEBUG_PORT.println("DEBUG[RTC_loop()] RTC_sec: " + String(RTC_sec)); + DEBUG_PORT.println("DEBUG[RTC_loop()] RTCMillis: " + String(RTCMillis)); + DEBUG_PORT.println("DEBUG[RTC_loop()] millis: " + String(millis())); RTC_sec = false; // clear flag digitalWrite(ledPin_PPS, LOW); // LED off time_t now_t = myRTC.get(); @@ -60,6 +65,9 @@ void RTC_loop() { } Sec_Flip(now_t); // pass current datetime from RTC in UTC } + else { + NewSec = false; + } if (millis() > (RTCMillis + 100)) { // do 100ms after PseudoPPS interrupt digitalWrite(ledPin_PPS, HIGH); // LED on } @@ -70,7 +78,7 @@ void SetRTC(time_t t) { last_sync_t = t; SyncErr = false; digitalWrite(ledPin_Sync, HIGH); // LED on - Serial.println("RTC set by GPS"); // debug + //Serial.println("RTC set by GPS"); // debug } //End \ No newline at end of file diff --git a/Serial_AdjustBaud.h b/Serial_AdjustBaud.h index 235c1c8..132577b 100644 --- a/Serial_AdjustBaud.h +++ b/Serial_AdjustBaud.h @@ -1,4 +1,6 @@ /** + * Serial_AdjustBaud + * * Функция для вычисления и возврата скорости передачи данных (baud rate) на основе полученного входного пина. * * @param recpin входной пин для определения скорости передачи данных @@ -6,13 +8,17 @@ * @return рассчитанная скорость передачи данных на основе измеренной ширины нулевого бита */ -long detRate(int recpin){ +long detRate(int recpin) { long baud, x, rate = 10000; + + pinMode(recpin, INPUT); // make sure serial in is a input pin + digitalWrite (recpin, HIGH); // pull up enabled just for noise protection + delay(100); // Цикл для измерения ширины нулевого бита for (int i = 0; i < 15; i++){ // Ожидание начала низкого бита - while(digitalRead(recpin) == 1) + while(digitalRead(recpin) == 1) {} x = pulseIn(recpin, LOW); // Измерение ширины следующего нулевого бита rate = x < rate ? x : rate; // Обновление минимальной ширины нулевого бита }