From e048e9c0bdf7dc1bcacbfd29102506af385eafd8 Mon Sep 17 00:00:00 2001 From: David Koch Date: Fri, 21 Dec 2018 17:00:51 +0100 Subject: [PATCH 1/8] Temporary WIP on irRepeatCodeDetection --- Esp32_radio/Esp32_radio.ino | 39 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 2766cdc..6576050 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -155,10 +155,10 @@ // Define (just one) type of display. See documentation. //#define BLUETFT // Works also for RED TFT 128x160 //#define OLED // 64x128 I2C OLED -//#define DUMMYTFT // Dummy display +#define DUMMYTFT // Dummy display //#define LCD1602I2C // LCD 1602 display with I2C backpack //#define ILI9341 // ILI9341 240*320 -#define NEXTION // Nextion display. Uses UART 2 (pin 16 and 17) +//#define NEXTION // Nextion display. Uses UART 2 (pin 16 and 17) // #include #include @@ -207,6 +207,7 @@ #define MQTT_SUBTOPIC "command" // Command to receive from MQTT // #define otaclient mp3client // OTA uses mp3client for connection to host +#define PIN_IR_DEBUG 21 //************************************************************************************************** // Forward declaration and prototypes of various functions. * @@ -357,7 +358,7 @@ SemaphoreHandle_t SPIsem = NULL ; // For exclusive SPI us hw_timer_t* timer = NULL ; // For timer char timetxt[9] ; // Converted timeinfo char cmd[130] ; // Command from MQTT or Serial -uint8_t tmpbuff[6000] ; // Input buffer for mp3 or data stream +uint8_t tmpbuff[6000] ; // Input buffer for mp3 or data stream QueueHandle_t dataqueue ; // Queue for mp3 datastream QueueHandle_t spfqueue ; // Queue for special functions qdata_struct outchunk ; // Data to queue @@ -1855,6 +1856,7 @@ void IRAM_ATTR isr_IR() uint32_t mask_in = 2 ; // Mask input for conversion uint16_t mask_out = 1 ; // Mask output for conversion + (*((volatile uint32_t *) (0x3ff44000 + 0x8 ))) ^= 1 << PIN_IR_DEBUG ; t1 = micros() ; // Get current time intval = t1 - t0 ; // Compute interval t0 = t1 ; // Save for next compare @@ -1888,6 +1890,7 @@ void IRAM_ATTR isr_IR() ir_locvalue = 0 ; // Reset decoding ir_loccount = 0 ; } + (*((volatile uint32_t *) (0x3ff44000 + 0xC))) ^= 1 << PIN_IR_DEBUG ; } @@ -2343,7 +2346,7 @@ bool connectwifi() } tftlog ( pfs ) ; // Show IP delay ( 3000 ) ; // Allow user to read this - tftlog ( "\f" ) ; // Select new page if NEXTION + tftlog ( "\f" ) ; // Select new page if NEXTION return ( localAP == false ) ; // Return result of connection } @@ -2402,7 +2405,7 @@ bool do_nextion_update ( uint32_t clength ) } k = otaclient.read ( tmpbuff, k ) ; // Read a number of bytes from the stream dbgprint ( "TFT file, read %d bytes", k ) ; - nxtserial->write ( tmpbuff, k ) ; + nxtserial->write ( tmpbuff, k ) ; while ( !nxtserial->available() ) // Any input seen? { delay ( 20 ) ; @@ -2433,7 +2436,7 @@ bool do_nextion_update ( uint32_t clength ) bool do_software_update ( uint32_t clength ) { bool res = false ; // Update result - + if ( Update.begin ( clength ) ) // Update possible? { dbgprint ( "Begin OTA update, length is %d", @@ -2485,7 +2488,7 @@ void update_software ( const char* lstmodkey, const char* updatehost, const char String line ; // Input header line String lstmod = "" ; // Last modified timestamp in NVS String newlstmod ; // Last modified from host - + updatereq = false ; // Clear update flag otastart() ; // Show something on screen stop_mp3client () ; // Stop input stream @@ -2523,7 +2526,7 @@ void update_software ( const char* lstmodkey, const char* updatehost, const char break ; // Yes, get the OTA started } // Check if the HTTP Response is 200. Any other response is an error. - if ( line.startsWith ( "HTTP/1.1" ) ) // + if ( line.startsWith ( "HTTP/1.1" ) ) // { if ( line.indexOf ( " 200 " ) < 0 ) { @@ -2542,7 +2545,7 @@ void update_software ( const char* lstmodkey, const char* updatehost, const char { dbgprint ( "No new version available" ) ; // No, show reason otaclient.flush() ; - return ; + return ; } if ( clength > 0 ) { @@ -2815,7 +2818,7 @@ String readprefs ( bool output ) String ( "/*******" ) ; } cmd = String ( "" ) ; // Do not analyze this - + } else if ( strstr ( key, "mqttpasswd" ) ) // Is it a MQTT password? { @@ -3007,7 +3010,7 @@ void scanserial2() dbgprint ( "NEXTION command seen %02X %s", cmd[0], cmd + 1 ) ; if ( cmd[0] == 0x70 ) // Button pressed? - { + { reply = analyzeCmd ( cmd + 1 ) ; // Analyze command and handle it dbgprint ( reply ) ; // Result for debugging } @@ -3452,6 +3455,17 @@ void setup() #if defined ( NEXTION ) dbgprint ( dtyp, "NEXTION" ) ; #endif + pinMode ( PIN_IR_DEBUG, OUTPUT ); // FOR IR TESTING + // digitalWrite ( PIN_IR_DEBUG, HIGH ); + // delay(100); + // digitalWrite( PIN_IR_DEBUG, LOW ); + // GPIO.out_w1ts = ( 1 << PIN_IR_DEBUG ); + // GPIO.out_w1tc = ( 1 << PIN_IR_DEBUG ); + (*((volatile uint32_t *) (0x3ff44000 + 0x8 ))) ^= 1 << PIN_IR_DEBUG ; + (*((volatile uint32_t *) (0x3ff44000 + 0xC))) ^= 1 << PIN_IR_DEBUG ; + // digitalWrite ( PIN_IR_DEBUG, HIGH ); + // digitalWrite ( PIN_IR_DEBUG, LOW ); + maintask = xTaskGetCurrentTaskHandle() ; // My taskhandle SPIsem = xSemaphoreCreateMutex(); ; // Semaphore for SPI bus pi = esp_partition_find ( ESP_PARTITION_TYPE_DATA, // Get partition iterator for @@ -4528,7 +4542,7 @@ void loop() if ( updatereq ) // Software update requested? { if ( displaytype == T_NEXTION ) // NEXTION in use? - { + { update_software ( "lstmodn", // Yes, update NEXTION image from remote image UPDATEHOST, TFTFILE ) ; } @@ -5682,4 +5696,3 @@ void spftask ( void * parameter ) } //vTaskDelete ( NULL ) ; // Will never arrive here } - From 9a57b10efbb291e292299f549b66fc82685a5c14 Mon Sep 17 00:00:00 2001 From: David Koch Date: Fri, 21 Dec 2018 17:02:25 +0100 Subject: [PATCH 2/8] Temporary WIP on irRepeatCodeDetection 2 --- Esp32_radio/Esp32_radio.ino | 63 +++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 6576050..5d016ce 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -209,6 +209,11 @@ #define otaclient mp3client // OTA uses mp3client for connection to host #define PIN_IR_DEBUG 21 +#define IR_READY 0 // FOR TESTING IR +#define IR_OVERFLOW 1 +#define IR_FRAME_READ 2 +#define IR_FRAME_READING 3 + //************************************************************************************************** // Forward declaration and prototypes of various functions. * //************************************************************************************************** @@ -398,9 +403,12 @@ int chunkcount = 0 ; // Counter for chunked String http_getcmd ; // Contents of last GET command String http_rqfile ; // Requested file bool http_reponse_flag = false ; // Response required -uint16_t ir_value = 0 ; // IR code -uint32_t ir_0 = 550 ; // Average duration of an IR short pulse -uint32_t ir_1 = 1650 ; // Average duration of an IR long pulse +static volatile uint16_t ir_value = 0 ; // IR code +static volatile uint32_t ir_pulses[400]; // FOR TESTING ir code interpretation +static volatile uint8_t ir_state = IR_READY; // FOR TESTING ir code interpretation +static volatile uint32_t ir_start_frame = 0; // FOR TESTING ir code interpretation +static volatile uint32_t ir_0 = 550 ; // Average duration of an IR short pulse +static volatile uint32_t ir_1 = 1650 ; // Average duration of an IR long pulse struct tm timeinfo ; // Will be filled by NTP server bool time_req = false ; // Set time requested bool SD_okay = false ; // True if SD card in place and readable @@ -1209,13 +1217,13 @@ void claimSPI ( const char* p ) while ( xSemaphoreTake ( SPIsem, ctry ) != pdTRUE ) // Claim SPI bus { - if ( count++ > 10 ) - { - dbgprint ( "SPI semaphore not taken within %d ticks by CPU %d, id %s", - count * ctry, - xPortGetCoreID(), - p ) ; - } +// if ( count++ > 10 ) +// { +// dbgprint ( "SPI semaphore not taken within %d ticks by CPU %d, id %s", +// count * ctry, +// xPortGetCoreID(), +// p ) ; +// } } } @@ -1852,6 +1860,7 @@ void IRAM_ATTR isr_IR() sv uint32_t t0 = 0 ; // To get the interval sv uint32_t ir_locvalue = 0 ; // IR code sv int ir_loccount = 0 ; // Length of code + sv uint16_t ir_pulsecount = 0; // FOR TESTING IR uint32_t t1, intval ; // Current time and interval since last change uint32_t mask_in = 2 ; // Mask input for conversion uint16_t mask_out = 1 ; // Mask output for conversion @@ -1860,6 +1869,22 @@ void IRAM_ATTR isr_IR() t1 = micros() ; // Get current time intval = t1 - t0 ; // Compute interval t0 = t1 ; // Save for next compare + + if ( ir_state == IR_FRAME_READING ) // FOR TESTING IR + { + ir_pulses[ ir_pulsecount++ ] = intval ; + ir_pulses[ ir_pulsecount ] = 0 ; // Mark last entry with 0 + if ( ir_pulsecount == 399 ) { + ir_state = IR_OVERFLOW ; + } + } + else if ( ir_state == IR_READY ) + { + ir_start_frame = t0 ; + ir_state = IR_FRAME_READING ; + ir_pulsecount = 0 ; + } + if ( ( intval > 300 ) && ( intval < 800 ) ) // Short pulse? { ir_locvalue = ir_locvalue << 1 ; // Shift in a "zero" bit @@ -3135,6 +3160,23 @@ void scanIR() } ir_value = 0 ; // Reset IR code received } + + if ( ( ir_state == IR_FRAME_READING ) && ( (micros() - ir_start_frame ) > 100000 ) ) // FOR TESTING IR + { + ir_state = IR_FRAME_READ ; + uint16_t n = 0; + dbgprint ( "IR Frame Details:") ; + while ( ir_pulses[ n ] ) + { + dbgprint( "Interval %3u : %5u", n, ir_pulses[ n ]); + } + ir_state = IR_READY ; + } + else if ( ir_state == IR_OVERFLOW ) + { + dbgprint ( "IR Frame Overflow-Error!" ) ; + ir_state = IR_READY ; + } } @@ -3689,6 +3731,7 @@ void setup() NULL, // parameter of the task 1, // priority of the task &xspftask ) ; // Task handle to keep track of created task + ir_pulses[0] = 0; // FOR TESTING IR } From 9a52b89a7187518f433e7ad204263a4e8bee9d21 Mon Sep 17 00:00:00 2001 From: David Koch Date: Sat, 29 Dec 2018 14:53:02 +0100 Subject: [PATCH 3/8] Temporary WIP on irRepeatCodeDetection 3, still not working --- Esp32_radio/Esp32_radio.ino | 81 ++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 5d016ce..9c0cf3a 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -214,6 +214,12 @@ #define IR_FRAME_READ 2 #define IR_FRAME_READING 3 +#define IR_IDLE 0 +#define IR_START 1 +#define IR_NORMAL 2 +#define IR_REPEAT 0xFFFF +#define PIN_IR_DEBUG 21 + //************************************************************************************************** // Forward declaration and prototypes of various functions. * //************************************************************************************************** @@ -404,6 +410,8 @@ String http_getcmd ; // Contents of last GET String http_rqfile ; // Requested file bool http_reponse_flag = false ; // Response required static volatile uint16_t ir_value = 0 ; // IR code +static volatile bool ir_repeat_flag = false ; // FOR TESTING ir repeat code +static volatile byte this_line_was_reached = 0 ; // FOR TESTING ir code interpretation static volatile uint32_t ir_pulses[400]; // FOR TESTING ir code interpretation static volatile uint8_t ir_state = IR_READY; // FOR TESTING ir code interpretation static volatile uint32_t ir_start_frame = 0; // FOR TESTING ir code interpretation @@ -1847,6 +1855,15 @@ void IRAM_ATTR timer100() } +void IRAM_ATTR morseDebug( int n ) +{ + for (int i=0; i 8750 ) && ( intval < 9250 ) ) // 9 ms start burst? { - ir_pulses[ ir_pulsecount++ ] = intval ; - ir_pulses[ ir_pulsecount ] = 0 ; // Mark last entry with 0 - if ( ir_pulsecount == 399 ) { - ir_state = IR_OVERFLOW ; - } + ir_state = IR_START ; + this_line_was_reached |= 0x01 ; + morseDebug( 3 ); } - else if ( ir_state == IR_READY ) - { - ir_start_frame = t0 ; - ir_state = IR_FRAME_READING ; - ir_pulsecount = 0 ; + else if ( ( intval > 4250 ) && ( intval > 4750 ) && ( ir_state == IR_START ) ) // 4,5 ms pause? + { + ir_state = IR_NORMAL ; // then normal code will follow + this_line_was_reached |= 0x02 ; + morseDebug( 4 ); + } + else if ( ( intval > 2000 ) && ( intval < 2500 ) && ( ir_state == IR_START ) ) // 2,25 ms pause? + { + ir_repeat_flag = true ; // this is a repeat code + ir_state = IR_IDLE ; // ready for next input + morseDebug( 5 ); } - - if ( ( intval > 300 ) && ( intval < 800 ) ) // Short pulse? + else if ( ( intval > 300 ) && ( intval < 800 ) && ( ir_state == IR_NORMAL) ) // Short pulse? { ir_locvalue = ir_locvalue << 1 ; // Shift in a "zero" bit ir_loccount++ ; // Count number of received bits ir_0 = ( ir_0 * 3 + intval ) / 4 ; // Compute average durartion of a short pulse + this_line_was_reached |= 0x04 ; + morseDebug( 1 ); } - else if ( ( intval > 1400 ) && ( intval < 1900 ) ) // Long pulse? + else if ( ( intval > 1400 ) && ( intval < 1900 ) && ( ir_state == IR_NORMAL ) ) // Long pulse? { ir_locvalue = ( ir_locvalue << 1 ) + 1 ; // Shift in a "one" bit ir_loccount++ ; // Count number of received bits ir_1 = ( ir_1 * 3 + intval ) / 4 ; // Compute average durartion of a short pulse + this_line_was_reached |= 0x08 ; + morseDebug( 2 ); } - else if ( ir_loccount == 65 ) // Value is correct after 65 level changes + else if ( ( ir_loccount == 65 ) && ( ir_state == IR_NORMAL ) ) // Value is correct after 65 level changes { + morseDebug( 6 ); + this_line_was_reached |= 0x10 ; while ( mask_in ) // Convert 32 bits to 16 bits { if ( ir_locvalue & mask_in ) // Bit set in pattern? @@ -1909,13 +1937,16 @@ void IRAM_ATTR isr_IR() mask_out <<= 1 ; // Shift output mask 1 position } ir_loccount = 0 ; // Ready for next input + ir_state = IR_IDLE ; } - else + else // Illegal intervall length ? { + morseDebug(10); + this_line_was_reached |= 0x20 ; ir_locvalue = 0 ; // Reset decoding ir_loccount = 0 ; + ir_state = IR_IDLE ; } - (*((volatile uint32_t *) (0x3ff44000 + 0xC))) ^= 1 << PIN_IR_DEBUG ; } @@ -3141,6 +3172,7 @@ void scanIR() char mykey[20] ; // For numerated key String val ; // Contents of preference entry const char* reply ; // Result of analyzeCmd + static uint16_t lastCode ; // Store last value for repeat code interpretation if ( ir_value ) // Any input? { @@ -3152,6 +3184,7 @@ void scanIR() ir_value, val.c_str() ) ; reply = analyzeCmd ( val.c_str() ) ; // Analyze command and handle it dbgprint ( reply ) ; // Result for debugging + lastCode = ir_value ; // Store this value for repeat code interpretation } else { @@ -3161,6 +3194,14 @@ void scanIR() ir_value = 0 ; // Reset IR code received } + if ( ir_repeat_flag ) { + dbgprint ( "...IR Repeat" ) ; // It doesn't make sense to repeat all types of codes. Actually only volume+/-. Maybe also preset+/-, but then a longer pause would be needed. + dbgprint ( " last code was:%04X", lastCode ); + dbgprint ( " line_reached code:%02X", this_line_was_reached ); + ir_repeat_flag = false; // Reset ir_repeat_flag + this_line_was_reached = 0 ; + } + if ( ( ir_state == IR_FRAME_READING ) && ( (micros() - ir_start_frame ) > 100000 ) ) // FOR TESTING IR { ir_state = IR_FRAME_READ ; @@ -3513,6 +3554,9 @@ void setup() pi = esp_partition_find ( ESP_PARTITION_TYPE_DATA, // Get partition iterator for ESP_PARTITION_SUBTYPE_ANY, // the NVS partition partname ) ; + + morseDebug( 10 ); + if ( pi ) { nvs = esp_partition_get ( pi ) ; // Get partition struct @@ -3553,6 +3597,7 @@ void setup() } dbgprint ( "GPIO%d is %s", pinnr, p ) ; } + readprogbuttons() ; // Program the free input pins SPI.begin ( ini_block.spi_sck_pin, // Init VSPI bus with default or modified pins ini_block.spi_miso_pin, From a9654444c20dfd3ef5b5ab38eca6821c163c1727 Mon Sep 17 00:00:00 2001 From: David Koch Date: Sun, 30 Dec 2018 18:24:35 +0100 Subject: [PATCH 4/8] WIP, now working IR repeat detection, interpretation still missing --- Esp32_radio/Esp32_radio.ino | 85 +++---------------------------------- 1 file changed, 7 insertions(+), 78 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 9c0cf3a..80869c9 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -207,18 +207,6 @@ #define MQTT_SUBTOPIC "command" // Command to receive from MQTT // #define otaclient mp3client // OTA uses mp3client for connection to host -#define PIN_IR_DEBUG 21 - -#define IR_READY 0 // FOR TESTING IR -#define IR_OVERFLOW 1 -#define IR_FRAME_READ 2 -#define IR_FRAME_READING 3 - -#define IR_IDLE 0 -#define IR_START 1 -#define IR_NORMAL 2 -#define IR_REPEAT 0xFFFF -#define PIN_IR_DEBUG 21 //************************************************************************************************** // Forward declaration and prototypes of various functions. * @@ -351,6 +339,8 @@ enum datamode_t { INIT = 1, HEADER = 2, DATA = 4, // State for datastream STOPREQD = 128, STOPPED = 256 } ; +enum ir_state_t { IR_READY, IR_START, IR_NORMAL } ; + // Global variables int DEBUG = 1 ; // Debug on/off int numSsid ; // Number of available WiFi networks @@ -411,10 +401,7 @@ String http_rqfile ; // Requested file bool http_reponse_flag = false ; // Response required static volatile uint16_t ir_value = 0 ; // IR code static volatile bool ir_repeat_flag = false ; // FOR TESTING ir repeat code -static volatile byte this_line_was_reached = 0 ; // FOR TESTING ir code interpretation -static volatile uint32_t ir_pulses[400]; // FOR TESTING ir code interpretation -static volatile uint8_t ir_state = IR_READY; // FOR TESTING ir code interpretation -static volatile uint32_t ir_start_frame = 0; // FOR TESTING ir code interpretation +static volatile uint8_t ir_state = IR_READY ; // FOR TESTING ir code interpretation static volatile uint32_t ir_0 = 550 ; // Average duration of an IR short pulse static volatile uint32_t ir_1 = 1650 ; // Average duration of an IR long pulse struct tm timeinfo ; // Will be filled by NTP server @@ -1854,16 +1841,6 @@ void IRAM_ATTR timer100() } } - -void IRAM_ATTR morseDebug( int n ) -{ - for (int i=0; i 8750 ) && ( intval < 9250 ) ) // 9 ms start burst? { ir_state = IR_START ; - this_line_was_reached |= 0x01 ; - morseDebug( 3 ); } - else if ( ( intval > 4250 ) && ( intval > 4750 ) && ( ir_state == IR_START ) ) // 4,5 ms pause? + else if ( ( intval > 4250 ) && ( intval < 4750 ) && ( ir_state == IR_START ) ) // 4,5 ms pause? { ir_state = IR_NORMAL ; // then normal code will follow - this_line_was_reached |= 0x02 ; - morseDebug( 4 ); } else if ( ( intval > 2000 ) && ( intval < 2500 ) && ( ir_state == IR_START ) ) // 2,25 ms pause? { ir_repeat_flag = true ; // this is a repeat code - ir_state = IR_IDLE ; // ready for next input - morseDebug( 5 ); + ir_state = IR_READY ; // ready for next input } else if ( ( intval > 300 ) && ( intval < 800 ) && ( ir_state == IR_NORMAL) ) // Short pulse? { ir_locvalue = ir_locvalue << 1 ; // Shift in a "zero" bit ir_loccount++ ; // Count number of received bits ir_0 = ( ir_0 * 3 + intval ) / 4 ; // Compute average durartion of a short pulse - this_line_was_reached |= 0x04 ; - morseDebug( 1 ); } else if ( ( intval > 1400 ) && ( intval < 1900 ) && ( ir_state == IR_NORMAL ) ) // Long pulse? { ir_locvalue = ( ir_locvalue << 1 ) + 1 ; // Shift in a "one" bit ir_loccount++ ; // Count number of received bits ir_1 = ( ir_1 * 3 + intval ) / 4 ; // Compute average durartion of a short pulse - this_line_was_reached |= 0x08 ; - morseDebug( 2 ); } else if ( ( ir_loccount == 65 ) && ( ir_state == IR_NORMAL ) ) // Value is correct after 65 level changes { - morseDebug( 6 ); - this_line_was_reached |= 0x10 ; while ( mask_in ) // Convert 32 bits to 16 bits { if ( ir_locvalue & mask_in ) // Bit set in pattern? @@ -1937,15 +1900,13 @@ void IRAM_ATTR isr_IR() mask_out <<= 1 ; // Shift output mask 1 position } ir_loccount = 0 ; // Ready for next input - ir_state = IR_IDLE ; + ir_state = IR_READY ; } else // Illegal intervall length ? { - morseDebug(10); - this_line_was_reached |= 0x20 ; ir_locvalue = 0 ; // Reset decoding ir_loccount = 0 ; - ir_state = IR_IDLE ; + ir_state = IR_READY ; } } @@ -3197,26 +3158,7 @@ void scanIR() if ( ir_repeat_flag ) { dbgprint ( "...IR Repeat" ) ; // It doesn't make sense to repeat all types of codes. Actually only volume+/-. Maybe also preset+/-, but then a longer pause would be needed. dbgprint ( " last code was:%04X", lastCode ); - dbgprint ( " line_reached code:%02X", this_line_was_reached ); ir_repeat_flag = false; // Reset ir_repeat_flag - this_line_was_reached = 0 ; - } - - if ( ( ir_state == IR_FRAME_READING ) && ( (micros() - ir_start_frame ) > 100000 ) ) // FOR TESTING IR - { - ir_state = IR_FRAME_READ ; - uint16_t n = 0; - dbgprint ( "IR Frame Details:") ; - while ( ir_pulses[ n ] ) - { - dbgprint( "Interval %3u : %5u", n, ir_pulses[ n ]); - } - ir_state = IR_READY ; - } - else if ( ir_state == IR_OVERFLOW ) - { - dbgprint ( "IR Frame Overflow-Error!" ) ; - ir_state = IR_READY ; } } @@ -3538,16 +3480,6 @@ void setup() #if defined ( NEXTION ) dbgprint ( dtyp, "NEXTION" ) ; #endif - pinMode ( PIN_IR_DEBUG, OUTPUT ); // FOR IR TESTING - // digitalWrite ( PIN_IR_DEBUG, HIGH ); - // delay(100); - // digitalWrite( PIN_IR_DEBUG, LOW ); - // GPIO.out_w1ts = ( 1 << PIN_IR_DEBUG ); - // GPIO.out_w1tc = ( 1 << PIN_IR_DEBUG ); - (*((volatile uint32_t *) (0x3ff44000 + 0x8 ))) ^= 1 << PIN_IR_DEBUG ; - (*((volatile uint32_t *) (0x3ff44000 + 0xC))) ^= 1 << PIN_IR_DEBUG ; - // digitalWrite ( PIN_IR_DEBUG, HIGH ); - // digitalWrite ( PIN_IR_DEBUG, LOW ); maintask = xTaskGetCurrentTaskHandle() ; // My taskhandle SPIsem = xSemaphoreCreateMutex(); ; // Semaphore for SPI bus @@ -3555,8 +3487,6 @@ void setup() ESP_PARTITION_SUBTYPE_ANY, // the NVS partition partname ) ; - morseDebug( 10 ); - if ( pi ) { nvs = esp_partition_get ( pi ) ; // Get partition struct @@ -3776,7 +3706,6 @@ void setup() NULL, // parameter of the task 1, // priority of the task &xspftask ) ; // Task handle to keep track of created task - ir_pulses[0] = 0; // FOR TESTING IR } From 154c07b11ae756b176008a7e99a61dac495d12af Mon Sep 17 00:00:00 2001 From: David Koch Date: Sun, 30 Dec 2018 20:42:51 +0100 Subject: [PATCH 5/8] Working Version with IR repeat code detection and interpretation --- Esp32_radio/Esp32_radio.ino | 61 ++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 80869c9..bc17741 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -399,11 +399,11 @@ int chunkcount = 0 ; // Counter for chunked String http_getcmd ; // Contents of last GET command String http_rqfile ; // Requested file bool http_reponse_flag = false ; // Response required -static volatile uint16_t ir_value = 0 ; // IR code -static volatile bool ir_repeat_flag = false ; // FOR TESTING ir repeat code -static volatile uint8_t ir_state = IR_READY ; // FOR TESTING ir code interpretation -static volatile uint32_t ir_0 = 550 ; // Average duration of an IR short pulse -static volatile uint32_t ir_1 = 1650 ; // Average duration of an IR long pulse +static volatile uint16_t ir_value = 0 ; // IR code +static volatile bool ir_repeat_flag = false ; // this gets true when ir repeat code is received +static volatile uint8_t ir_state = IR_READY ; // for ir code interpretation +static volatile uint32_t ir_0 = 550 ; // Average duration of an IR short pulse +static volatile uint32_t ir_1 = 1650 ; // Average duration of an IR long pulse struct tm timeinfo ; // Will be filled by NTP server bool time_req = false ; // Set time requested bool SD_okay = false ; // True if SD card in place and readable @@ -1854,7 +1854,6 @@ void IRAM_ATTR isr_IR() sv uint32_t t0 = 0 ; // To get the interval sv uint32_t ir_locvalue = 0 ; // IR code sv int ir_loccount = 0 ; // Length of code - sv uint16_t ir_pulsecount = 0; // FOR TESTING IR uint32_t t1, intval ; // Current time and interval since last change uint32_t mask_in = 2 ; // Mask input for conversion uint16_t mask_out = 1 ; // Mask output for conversion @@ -3134,32 +3133,64 @@ void scanIR() String val ; // Contents of preference entry const char* reply ; // Result of analyzeCmd static uint16_t lastCode ; // Store last value for repeat code interpretation + static int16_t repeatDelay ; // Stores the delay until the command gets repeated + static uint32_t nextRepeat ; // Stores the time for next repeat in millis + + if ( ir_repeat_flag && repeatDelay ) // It doesn't make sense to repeat all types of codes. Actually only volume+/-. Maybe also preset+/-, but then a longer pause would be needed. + if ( millis() > nextRepeat ) + { + dbgprint ( " now is time for next repeat (%d)", millis() ); + dbgprint ( " last code was:%04X", lastCode ); + ir_value = lastCode ; // We inject the last code, which will lead to a new setting of nextRepeat later + } + + ir_repeat_flag = false; // Reset ir_repeat_flag + } if ( ir_value ) // Any input? { sprintf ( mykey, "ir_%04X", ir_value ) ; // Form key in preferences if ( nvssearch ( mykey ) ) { - val = nvsgetstr ( mykey ) ; // Get the contents - dbgprint ( "IR code %04X received. Will execute %s", - ir_value, val.c_str() ) ; + val = nvsgetstr ( mykey ) ; // Get the content + + if ( val.indexOf('/') != -1 ) // Does the command contain a '/' ? + { + if ( ( val.indexOf('#') == -1 ) || ( val.indexOf('#') > val.indexOf('/') ) ) // '/' is not in the comment section + { + repeatDelay = val.substring( val.indexOf('/') + 1 ).toInt() ; // '/' delimits the repeat delay (in ms) if any + if ( repeatDelay < 0 ) + { + dbgprint ( "Error in IR command. Repeat delay can't be negative, set to zero: %s", val.c_str() ); + repeatDelay = 0 ; + } + val = val.substring( 0, val.indexOf('/') ) ; // Now that we know the repeat delay we trim it from the string + } + else + { + repeatDelay = 0 ; + } + } + else + { + repeatDelay = 0 ; // This command does not get repeated + } + + dbgprint ( "IR code %04X received. Will execute %s and repeat in %d ms if button is held longer.", + ir_value, val.c_str(), repeatDelay ) ; reply = analyzeCmd ( val.c_str() ) ; // Analyze command and handle it dbgprint ( reply ) ; // Result for debugging + nextRepeat = millis() + repeatDelay ; lastCode = ir_value ; // Store this value for repeat code interpretation } else { dbgprint ( "IR code %04X received, but not found in preferences! Timing %d/%d", ir_value, ir_0, ir_1 ) ; + repeatDelay = 0 ; // Deactivate repeat for unknown code } ir_value = 0 ; // Reset IR code received } - - if ( ir_repeat_flag ) { - dbgprint ( "...IR Repeat" ) ; // It doesn't make sense to repeat all types of codes. Actually only volume+/-. Maybe also preset+/-, but then a longer pause would be needed. - dbgprint ( " last code was:%04X", lastCode ); - ir_repeat_flag = false; // Reset ir_repeat_flag - } } From e22ace1baa8f0875784024660485aa7ec4923b03 Mon Sep 17 00:00:00 2001 From: David Koch Date: Sun, 30 Dec 2018 20:47:32 +0100 Subject: [PATCH 6/8] Updated version history --- Esp32_radio/Esp32_radio.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index bc17741..365f2fe 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -141,6 +141,7 @@ // 18-09-2018, ES: "uppreset" and "downpreset" for MP3 player. // 04-10-2018, ES: Fixed compile error OLED 64x128 display. // 09-10-2018, ES: Bug fix xSemaphoreTake. +// 30-12-2018, DK: Added support for NEC style IR repeat codes // // // Define the version number, also used for webserver as Last-Modified header and to From f2056ba32daa051f7186e3a7e91583b2fbcf332f Mon Sep 17 00:00:00 2001 From: David Koch Date: Sun, 30 Dec 2018 21:49:14 +0100 Subject: [PATCH 7/8] Reverted some commenting out that was necessary for debugging. --- Esp32_radio/Esp32_radio.ino | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 365f2fe..9e4c71b 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -1213,13 +1213,13 @@ void claimSPI ( const char* p ) while ( xSemaphoreTake ( SPIsem, ctry ) != pdTRUE ) // Claim SPI bus { -// if ( count++ > 10 ) -// { -// dbgprint ( "SPI semaphore not taken within %d ticks by CPU %d, id %s", -// count * ctry, -// xPortGetCoreID(), -// p ) ; -// } + if ( count++ > 10 ) + { + dbgprint ( "SPI semaphore not taken within %d ticks by CPU %d, id %s", + count * ctry, + xPortGetCoreID(), + p ) ; + } } } From 334f1e64a4911a492880348d556f51dc1044d030 Mon Sep 17 00:00:00 2001 From: David Koch Date: Mon, 31 Dec 2018 00:10:40 +0100 Subject: [PATCH 8/8] Forgot a { --- Esp32_radio/Esp32_radio.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/Esp32_radio/Esp32_radio.ino b/Esp32_radio/Esp32_radio.ino index 9e4c71b..8fbc711 100644 --- a/Esp32_radio/Esp32_radio.ino +++ b/Esp32_radio/Esp32_radio.ino @@ -3138,6 +3138,7 @@ void scanIR() static uint32_t nextRepeat ; // Stores the time for next repeat in millis if ( ir_repeat_flag && repeatDelay ) // It doesn't make sense to repeat all types of codes. Actually only volume+/-. Maybe also preset+/-, but then a longer pause would be needed. + { if ( millis() > nextRepeat ) { dbgprint ( " now is time for next repeat (%d)", millis() );