From e14a43fbf214786e677d9a53de630fcb1a2738d3 Mon Sep 17 00:00:00 2001 From: Philipp Gahtow Date: Mon, 27 Jun 2022 09:58:07 +0200 Subject: [PATCH] Update 6.1.0 --- DCCPacketScheduler.cpp | 69 ++++++++++++++++++++++++++++++++++-------- DCCPacketScheduler.h | 14 ++++----- DDCHardware_config.h | 4 +-- library.properties | 2 +- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/DCCPacketScheduler.cpp b/DCCPacketScheduler.cpp index 62c6825..9a9f10f 100644 --- a/DCCPacketScheduler.cpp +++ b/DCCPacketScheduler.cpp @@ -63,7 +63,15 @@ volatile uint16_t current_cv = 0; //cv that we are working on volatile uint8_t current_cv_value = 0; //value that is read volatile uint8_t current_cv_bit = 0xFF; //bit that will be read - 0xFF = ready, nothing to read! uint8_t cv_read_count = 0; //count number of cv read -bool current_ack_read = false; + +#define NON_PROG_OP 0x00 +#define WAIT_FOR_ACK 0x01 +#define ACK_DETECTED 0x02 +#define ACK_READ_SUCCESS 0x10 +#define ACK_READ_FAIL 0xFF +uint8_t current_ack_status = NON_PROG_OP; + //current_ack_read = false; +unsigned long ack_start_time = 0; #if defined(ESP32) extern hw_timer_t * timer; @@ -1095,12 +1103,46 @@ void DCCPacketScheduler::update(void) { if ((current_packet_service > 0) && (current_packet_service < 0xFF)) { if (notifyCurrentSence) { //get the Base rail current uint16_t current_load_now = notifyCurrentSence(); - if ( ( (current_load_now < (LASTVAmpSence + ACK_SENCE_DIFF)) && (current_load_now > (LASTVAmpSence - ACK_SENCE_DIFF)) ) || (current_load_now > (LASTVAmpSence + ACK_SENCE_VALUE)) ) { - COUNTVAmpSence++; - if (COUNTVAmpSence > ACK_SENCE_TIME) - current_ack_read = true; //ACK from decoder + + if (current_packet_service == (0xFF - ProgRepeat)) { //first packet - base current! + //get base current voltage: + if (current_ack_status != WAIT_FOR_ACK) { + LASTVAmpSence = current_load_now; //store the last value + current_ack_status = WAIT_FOR_ACK; + #if defined(PROG_DEBUG) + Serial.print(current_load_now); + Serial.print(":"); + #endif + } + } + else { + //current load detect: + if ((current_load_now > (LASTVAmpSence + ACK_SENCE_VALUE))) { + if (current_ack_status == WAIT_FOR_ACK) { + current_ack_status = ACK_DETECTED; + ack_start_time = micros(); + #if defined(PROG_DEBUG) + Serial.print(current_load_now); + Serial.print(";"); + #endif + + } + } + else { + if (current_ack_status == ACK_DETECTED) { + if ( ((micros() - ack_start_time) / 1000) >= ACK_SENCE_MIN) { + if ( ((micros() - ack_start_time) / 1000) <= ACK_SENCE_MAX) { //sec. + current_ack_status = ACK_READ_SUCCESS; + } + else current_ack_status = ACK_READ_FAIL; + } + else current_ack_status = WAIT_FOR_ACK; + #if defined(PROG_DEBUG) + Serial.print((micros() - ack_start_time) / 1000); + #endif + } + } } - LASTVAmpSence = current_load_now; //store the last value } //ENDE notify function } //ENDE Service-Mode operation @@ -1142,10 +1184,11 @@ void DCCPacketScheduler::update(void) { //Send Start Reset Packets: opsDecoderReset(RSTsRepeat); //send first a Reset Start Packet ops_programmming_queue.readPacket(&p); + ack_start_time = micros(); break; } case ProgACKRead: { #if defined(PROG_DEBUG) - if (current_ack_read == true) //ACK from decoder + if (current_ack_status == ACK_READ_SUCCESS) //ACK from decoder Serial.print("A"); else Serial.print("x"); if (COUNTVAmpSence < 10) @@ -1160,7 +1203,7 @@ void DCCPacketScheduler::update(void) { switch (ProgMode) { case ProgModeBit: //Check Bit Status - if (current_ack_read == true) //CV read....? + if (current_ack_status == ACK_READ_SUCCESS) //CV read....? bitWrite(current_cv_value,current_cv_bit,1); //ACK, so bit is 'one'! else bitWrite(current_cv_value,current_cv_bit,0); //no ACK => 'zero'! current_cv_bit++; //get next bit @@ -1179,13 +1222,13 @@ void DCCPacketScheduler::update(void) { break; case ProgModeBitVerify: { #if defined(PROG_DEBUG) - if (current_ack_read == true) + if (current_ack_status == ACK_READ_SUCCESS) Serial.println(); #endif current_cv_bit = 0; //reset ProgMode = ProgModeBit; //Check CV Value - if (current_ack_read == true) + if (current_ack_status == ACK_READ_SUCCESS) ProgState = ProgSuccess; else { //Read again... @@ -1216,13 +1259,13 @@ void DCCPacketScheduler::update(void) { } break; } case ProgModeByteVerify: - if (current_ack_read == true) + if (current_ack_status == ACK_READ_SUCCESS) ProgState = ProgSuccess; else ProgState = ProgFail; break; case ProgModeByte: //Check Byte Status - if (current_ack_read == true) + if (current_ack_status == ACK_READ_SUCCESS) ProgState = ProgSuccess; else { #if defined(PROG_DEBUG) @@ -1245,7 +1288,7 @@ void DCCPacketScheduler::update(void) { opsDecoderReset(RSTsRepeat); //send Reset start Packet -> wait if we get a next Service Mode packet! else opsDecoderReset(RSTcRepeat); //send Reset continue Packet ops_programmming_queue.readPacket(&p); - current_ack_read = false; //reset ACK information + current_ack_status = NON_PROG_OP; //reset ACK information break; } case ProgBitRead: { //Read CV in Bit-Mode: diff --git a/DCCPacketScheduler.h b/DCCPacketScheduler.h index db00f98..b61eff6 100644 --- a/DCCPacketScheduler.h +++ b/DCCPacketScheduler.h @@ -1,5 +1,5 @@ /* - * DCC Waveform Generator v6.0.1 + * DCC Waveform Generator v6.1.0 * * Author: Philipp Gahtow digitalmoba@arcor.de * Don Goodman-Wilson dgoodman@artificial-science.org @@ -79,6 +79,7 @@ * - change ACK detection and add state machine for CV direct * - add function bit control from F29...F32767 * - add function setExtAccessoryPos + * - add timing to ACK detection */ #ifndef __DCCCOMMANDSTATION_H__ @@ -90,15 +91,14 @@ //#define PROG_DEBUG //Serial output of Prog Informaton #if defined(ESP8266) //ESP8266 or WeMos D1 mini -#define ACK_SENCE_VALUE 10 //WeMos has a voltage divider for 3.1 Volt -> we not want to modify the board! -#define ACK_SENCE_DIFF 0 //Differenz beim Konstanten Strom am Gleis (Abweichung +/-) -#define ACK_SENCE_TIME 2 //Dauer bis ein ACK erkannt wird +#define ACK_SENCE_VALUE 4 //WeMos has a voltage divider for 3.1 Volt -> we not want to modify the board! #else -#define ACK_SENCE_VALUE 90 //Value = 200 for use with AREF = 1.1 Volt analog Refence Voltage; (Value = 15 for AREF = 5.0 Volt) -#define ACK_SENCE_DIFF 33 //Differenz beim Konstanten Strom am Gleis (Abweichung +/-) -#define ACK_SENCE_TIME 8 //Dauer bis ein ACK erkannt wird +#define ACK_SENCE_VALUE 30 //value difference #endif +#define ACK_SENCE_MIN 3 //min ACK length in ms +#define ACK_SENCE_MAX 14 //max ACK length in ms + //read value again if verify fails: #define CV_BIT_MAX_TRY_READ 4 //times to try in Bit-Mode #define CV_BYTE_MAX_TRY_READ 1 //times to try in Byte-Mode diff --git a/DDCHardware_config.h b/DDCHardware_config.h index 98e3195..e6c4eb1 100644 --- a/DDCHardware_config.h +++ b/DDCHardware_config.h @@ -92,8 +92,8 @@ Dauer des Teil-Nullbits: t ≥ 100 µs, normal: 116µs //TIM_DIV1 = 0 -> 80MHz (80 ticks/us - 104857.588us max) //TIM_DIV16 = 1 -> 5MHz (5 ticks/us - 1677721.4us max) //TIM_DIV256 = 3 -> 312.5Khz (1 tick = 3.2us - 26843542.4us max) -#define half_one_count 2080 // 145 //29usec pulse 2280 -#define one_count 4160 // 290 - Calls every 58µs 4580 +#define half_one_count 2080 // 145 //29usec pulse old:2280 new:2080 +#define one_count 4160 // 290 - Calls every 58µs old:4580 new:4160 #define zero_high_count 7920 // 500 - Calls every 100µs #define zero_low_count 7920 // 500 // Calls every 100µs #define DCC_ESP_TIMER_DIV TIM_DIV1 diff --git a/library.properties b/library.properties index 20406fe..d1e423a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=DCCInterfaceMaster -version=6.0.1 +version=6.1.0 author=Philipp Gahtow maintainer=Philipp Gahtow sentence=Enables NMRA DCC Communication