123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <sys/time.h>
- #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 <stddef.h>
- #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.
- * ***************************************************************************/
- // <NT01995080>
- // <NT01995090>
- // 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", "<NT%08lX> + Dim:%u",(unsigned long int)orig_code, dim_level);
- else
- ESP_LOGI("NEXA TX", "<NT%08lX>",(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: <NT4C90AD91>
- 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,"<NT%08lX>",(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,"<NT%08lX>",(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);
- }
|