#include #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_sleep.h" #include "esp_log.h" #include "driver/uart.h" #include "driver/rtc_io.h" #include "esp_intr_alloc.h" #include "esp_attr.h" #include "driver/timer.h" #include #include "esp_intr_alloc.h" #include "transceiver.h" #include "rxTimer.h" #include "led.h" #include "udp_client.h" #include "nexaTransmit.h" QueueHandle_t nexaTxQueue = NULL; /***************************************************************************** * Nexa : http://elektronikforumet.com/wiki/index.php/RF_Protokoll_-_Nexa_sj%C3%A4lvl%C3%A4rande * "1" = 295 µs hög och 170 µs låg * "0" = 295 µs hög och 920 µs låg * Etta skickas som 10 och Nolla som 01 * Dessa siffror från web-sidan stämmer inte med den Nexa-kontroll som jag har. * Jag har rättat dessa med siffror från verkligheten. Finns i define's nedan. * * --------------------------------------------------------------------------- * From: https://github.com/TheCarlG/NexaCtrl/blob/master/NexaCtrl.cpp * * bits 0-25: the group code - a 26bit number assigned to controllers. * bit 26: group flag * bit 27: on/off/dim flag * bits 28-31: the device code - 4bit number. * bits 32-35: the dim level - 4bit number. * * The extra 4 dim bits are optional and used for setting absolute dim level * Normally the on/off-bit is transmitted as a normal On=10, Off=01, but when * including a dim-level the on/off-bit is transmitted as 00 * * Dim levels are 0-15. 0=Lowest dim, 15=100% * 0 is not off. A separate off needs to be sent to turn the light off. * ***************************************************************************/ // // // Timing for NEXA Remote controls #define HIGH_PULSE 260 #define LOW_PULSE_0 310 #define LOW_PULSE_1 1330 #define SYNC_PULSE 2720 #define STOP_PULSE 10000 static void send1() { trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_1); // 1 trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_0 ); // 0 } static void send0() { trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_0 ); // 0 trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_1); // 1 } // Special 00-bit used when including 4 dim bits last in message static void send00() { trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_0 ); // 0 trcvSendHighLowPulse( HIGH_PULSE, LOW_PULSE_0); // 0 } static void sendSync() { trcvSendHighLowPulse( HIGH_PULSE, SYNC_PULSE ); } static void sendStop() { trcvSendHighLowPulse( HIGH_PULSE, STOP_PULSE ); } static void sendNexaCodeNo(uint32_t orig_code, bool send_dim, uint8_t dim_level) { uint32_t code=0; int32_t i; int32_t loop; if( send_dim == true ) ESP_LOGI("NEXA TX", " + Dim:%u",(unsigned long int)orig_code, dim_level); else ESP_LOGI("NEXA TX", "",(unsigned long int)orig_code); blinkTheLED(); if( 1 ) { trcvSwitch2transmit(); for( loop=5; loop>0; loop--) { code = orig_code; sendSync(); for(i=0; i < 32; i++) { // Bit 27 is the on/off/dim-bit // Check if we should send it as a special dim-bit if( i == 27 && send_dim == true ) { send00(); } else { // Normal on/off control if( code & 0x80000000 ) send1(); else send0(); } code = (code << 1); } code = dim_level; // Check if we should send 4 extra dim-bits at the end if( send_dim == true ) { for(i=0; i < 4; i++) { if( code & 0x00000008 ) send1(); else send0(); code = (code << 1); } } sendStop(); } trcvSwitch2receive(); } } /** * Public interface for sending a NEXA Code */ void sendNexaCode(uint32_t data, bool send_dim, uint8_t dim_level ) { nexaCodeData_t txData; txData.data = data; txData.send_dim = send_dim; txData.dim_level = dim_level; if( nexaTxQueue != NULL ) xQueueSend( nexaTxQueue, &txData, 0 ); } // Public interface for sending a NEXA Code in string format. For example: void sendNexaCodeStr(char *str) { const uint32_t now = millis(); static char oldData[40]; static uint32_t oldDataTime = 0; // Check if we have a retransmission of exactly the same data within 250mS // If we have a identical re-transmission, then skip that one if( ((now - oldDataTime) < 250) && strncmp(str,oldData,40)==0 ) { ESP_LOGW("NEXA TX", "Retransm: %10d mS",now - oldDataTime); oldDataTime = now; return; } strncpy(oldData,str,40); oldDataTime = now; char diffLevel = '\0'; // 0-F = 0-15 Dim-level if( strlen(str) == 13 && str[0] == '<' && str[12] == '>' ) { diffLevel = str[11]; // 0-F = 0-15 Dim-level str[11] = '>'; str[12] = '\0'; } if( strlen(str) == 12 && str[0] == '<' && str[11] == '>' ) { uint32_t code; bool send_dim = (diffLevel == '\0') ? false : true; uint8_t dim_level = (send_dim == true) ? diffLevel - '0' : 0; sscanf((const char *)str,"",(long unsigned int *)&code); sendNexaCode(code, send_dim, dim_level); } } // GIT ESP32 Before: 0ae960f2fe92de1ee9c7c624b7115d06faca119e static void nexaTxTask(void *pvParameter) { ESP_LOGI("NEXA TX", "Task started."); nexaCodeData_t txData; while (1) { while( xQueueReceive( nexaTxQueue, &txData, portMAX_DELAY ) == pdTRUE ) { sendNexaCodeNo(txData.data, txData.send_dim, txData.dim_level); // Do the radio-transmission // Forward the NEXA code to the next transceiver char strCode[20]; sprintf(strCode,"",(unsigned long int)txData.data); forwardNEXAMessage(strCode); vTaskDelay(200 / portTICK_PERIOD_MS); // Wait a while between transmits } } vTaskDelete(NULL); } void initNexaTransmit() { nexaTxQueue = xQueueCreate( 20, sizeof( nexaCodeData_t ) ); xTaskCreatePinnedToCore(&nexaTxTask, "nexaTxTask", 8192, NULL, tskIDLE_PRIORITY + 10, NULL, 1); }