dcf77.cpp bugfixes and now finalized

This commit is contained in:
Klaus K Wilting 2019-02-04 23:42:17 +01:00
parent 8d01b651bb
commit 82489524d3
3 changed files with 53 additions and 37 deletions

View File

@ -6,7 +6,7 @@
; ---> SELECT TARGET PLATFORM HERE! <--- ; ---> SELECT TARGET PLATFORM HERE! <---
[platformio] [platformio]
env_default = generic ;env_default = generic
;env_default = ebox ;env_default = ebox
;env_default = eboxtube ;env_default = eboxtube
;env_default = heltec ;env_default = heltec
@ -15,7 +15,7 @@ env_default = generic
;env_default = ttgov2 ;env_default = ttgov2
;env_default = ttgov21old ;env_default = ttgov21old
;env_default = ttgov21new ;env_default = ttgov21new
;env_default = ttgobeam env_default = ttgobeam
;env_default = ttgofox ;env_default = ttgofox
;env_default = lopy ;env_default = lopy
;env_default = lopy4 ;env_default = lopy4
@ -33,7 +33,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
release_version = 1.7.152 release_version = 1.7.152
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
debug_level = 0 debug_level = 4
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA ; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
upload_protocol = esptool upload_protocol = esptool
;upload_protocol = custom ;upload_protocol = custom

View File

@ -25,6 +25,8 @@ uint8_t DCFtimeframe[DCF77_FRAME_SIZE];
// initialize and configure DCF77 output // initialize and configure DCF77 output
int dcf77_init(void) { int dcf77_init(void) {
BitsPending = false;
pinMode(HAS_DCF77, OUTPUT); pinMode(HAS_DCF77, OUTPUT);
digitalWrite(HAS_DCF77, HIGH); digitalWrite(HAS_DCF77, HIGH);
@ -42,9 +44,13 @@ int dcf77_init(void) {
ESP_LOGD(TAG, "Starting DCF pulse..."); ESP_LOGD(TAG, "Starting DCF pulse...");
dcfCycle = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec dcfCycle = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec
timerAttachInterrupt(dcfCycle, &DCF77IRQ, true); timerAttachInterrupt(dcfCycle, &DCF77IRQ, true);
timerAlarmWrite(dcfCycle, 2000, true); // 100ms cycle timerAlarmWrite(dcfCycle, 1000, true); // 100ms cycle
// wait until beginning of next minute, then start DCF pulse
do {
delay(2);
} while (second());
timerAlarmEnable(dcfCycle); timerAlarmEnable(dcfCycle);
xTaskNotify(DCF77Task, 0, eNoAction);
return 1; // success return 1; // success
@ -100,62 +106,69 @@ void generateTimeframe(time_t t) {
DCFtimeframe[59] = dcf_off; DCFtimeframe[59] = dcf_off;
// !! missing code here for leap second !! // !! missing code here for leap second !!
// for debug: print the DCF77 frame buffer /*
char out[DCF77_FRAME_SIZE + 1]; // for debug: print the DCF77 frame buffer
uint8_t i; char out[DCF77_FRAME_SIZE + 1];
for (i = 0; i < DCF77_FRAME_SIZE; i++) { uint8_t i;
out[i] = DCFtimeframe[i] + '0'; // convert int digit to printable ascii for (i = 0; i < DCF77_FRAME_SIZE; i++) {
} out[i] = DCFtimeframe[i] + '0'; // convert int digit to printable ascii
out[DCF77_FRAME_SIZE] = '\0'; // string termination char }
ESP_LOGD(TAG, "DCF Timeframe = %s", out); out[DCF77_FRAME_SIZE] = '\0'; // string termination char
ESP_LOGD(TAG, "DCF Timeframe = %s", out);
*/
} }
// called every 100msec by hardware time // helper function to convert gps date/time into time_t
time_t nextMinute(time_t t) {
tmElements_t tm;
breakTime(t, tm);
tm.Minute++;
tm.Second = 0;
return makeTime(tm);
}
// called every 100msec by hardware timer to pulse out DCF signal
void DCF_Out() { void DCF_Out() {
static uint8_t bit = 0; static uint8_t bit = 0;
static uint8_t pulse = 0; static uint8_t pulse = 0;
if (!BitsPending) { if (!BitsPending) {
// prepare next frame to send // prepare frame for next minute to send
generateTimeframe(now()); generateTimeframe(nextMinute(now()));
// start blinking symbol on display and kick off timer
BitsPending = true; BitsPending = true;
// wait until next minute, then kick off hardware timer and first DCF pulse
do {
delay(2);
} while (second());
} }
// ticker out current frame // ticker out current DCF frame
while (BitsPending) { if (BitsPending) {
switch (pulse++) { switch (pulse++) {
case 0: // start of second -> start of timeframe for logic signal case 0: // start of second -> start of timeframe for logic signal
if (DCFtimeframe[bit] != dcf_off) if (DCFtimeframe[bit] != dcf_off)
digitalWrite(HAS_DCF77, LOW); digitalWrite(HAS_DCF77, LOW);
return; break;
case 1: // 100ms after start of second -> end of timeframe for logic 0 case 1: // 100ms after start of second -> end of timeframe for logic 0
if (DCFtimeframe[bit] == dcf_zero) if (DCFtimeframe[bit] == dcf_zero)
digitalWrite(HAS_DCF77, HIGH); digitalWrite(HAS_DCF77, HIGH);
return; break;
case 2: // 200ms after start of second -> end of timeframe for logic 1 case 2: // 200ms after start of second -> end of timeframe for logic 1
digitalWrite(HAS_DCF77, HIGH); digitalWrite(HAS_DCF77, HIGH);
return; break;
case 9: // last pulse before next second starts case 9: // last pulse before next second starts
pulse = 0; pulse = 0;
if (bit++ != DCF77_FRAME_SIZE) if (bit++ == (DCF77_FRAME_SIZE - 1)) // end of DCF77 frame (59th second)
return; {
else { // end of DCF77 frame (59th second)
bit = 0; bit = 0;
BitsPending = false; BitsPending = false;
}; };
break; break;
}; // switch }; // switch
}; // while }; // if
} // DCF_Out() } // DCF_Out()
@ -179,8 +192,8 @@ void dcf77_loop(void *pvParameters) {
DCF_Out(); DCF_Out();
} }
BitsPending = false; // stop blink in display BitsPending = false; // stop blink in display, should never be reached
vTaskDelete(DCF77Task); // shoud never be reached vTaskDelete(DCF77Task);
} // dcf77_loop() } // dcf77_loop()
#endif // HAS_DCF77 #endif // HAS_DCF77

View File

@ -24,16 +24,19 @@
// enable only if device has these sensors, otherwise comment these lines // enable only if device has these sensors, otherwise comment these lines
// BME680 sensor on I2C bus // BME680 sensor on I2C bus
//#define HAS_BME SDA, SCL #define HAS_BME SDA, SCL
//#define BME_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !! #define BME_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !!
// display (if connected) // display (if connected)
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
//#define MY_OLED_SDA SDA #define MY_OLED_SDA SDA
//#define MY_OLED_SCL SCL #define MY_OLED_SCL SCL
//#define MY_OLED_RST U8X8_PIN_NONE #define MY_OLED_RST U8X8_PIN_NONE
//#define DISPLAY_FLIP 1 // use if display is rotated //#define DISPLAY_FLIP 1 // use if display is rotated
// Settings for DCF77 interface
#define HAS_DCF77 GPIO_NUM_13
// user defined sensors (if connected) // user defined sensors (if connected)
//#define HAS_SENSORS 1 // comment out if device has user defined sensors //#define HAS_SENSORS 1 // comment out if device has user defined sensors