Jelajahi Sumber

TX and RX of Toshiba MQTT Data works.

Thomas Chef 2 tahun lalu
induk
melakukan
584489d879
7 mengubah file dengan 100 tambahan dan 22 penghapusan
  1. 4 3
      main/config.h
  2. 39 4
      main/mqtt.c
  3. 24 3
      main/receiver.c
  4. 1 2
      main/receiver.h
  5. 1 1
      main/rxTimer.c
  6. 30 9
      main/toshiba_ir.c
  7. 1 0
      main/toshiba_ir.h

+ 4 - 3
main/config.h

@@ -6,15 +6,16 @@
 #define SW_VERSION "1.0"
 
 // These defines configures which code to generate (to save download time during development)
-//#define WIFI_ENABLED
-//#define MQTT_ENABLED
+#define WIFI_ENABLED
+#define MQTT_ENABLED
 //#define ENABLE_DS18B20
 
 #define MQTT_DEBUG              // Add an extra debug string to the topic-string
 
 #define ONE_WIRE_BUS_IO           GPIO_NUM_16   // Temp sensors
 
-#define GPIO_RX_DATA              GPIO_NUM_26   // IR Receiver
+#define GPIO_IR_RX_DATA              GPIO_NUM_26   // IR Receiver
+#define GPIO_IR_TX_DATA              GPIO_NUM_25   // IR Transmitter
 
 
 #endif

+ 39 - 4
main/mqtt.c

@@ -31,6 +31,8 @@
 #include "mqtt_client.h"
 
 #include "wifi.h"
+#include "receiver.h"
+#include "toshiba_ir.h"
 
 static const char *TAG = "MQTT";
 
@@ -52,7 +54,7 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
         case MQTT_EVENT_CONNECTED:
             connected = true;
             ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
-            msg_id = esp_mqtt_client_subscribe(client, "#", 0);
+            msg_id = esp_mqtt_client_subscribe(client, "hall/ac/ir_cmd_tx", 0);
             ESP_LOGI(TAG, "Sent subscribe successful, msg_id=%d", msg_id);
             break;
         case MQTT_EVENT_DISCONNECTED:
@@ -70,9 +72,42 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
             ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
             break;
         case MQTT_EVENT_DATA:
-            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
-            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
-            printf("DATA=%.*s\r\n", event->data_len, event->data);
+            ESP_LOGI(TAG, "MQTT_EVENT_DATA Topic: <%.*s>", event->topic_len, event->topic);
+            //printf("DATA=%.*s\r\n", event->data_len, event->data);
+            if( strncmp(event->topic,"hall/ac/ir_cmd_tx",event->topic_len) == 0 ) {
+
+                uint8_t data[kToshibaNumberOfBytes];
+
+                if( event->data_len != kToshibaNumberOfBytes*2 ) {
+                    ESP_LOGE("MQTT","Wrong length in MQTT-data %u",event->data_len);
+                    break;
+                }
+                
+                bool exitRx = false;
+                for(uint8_t i=0;i<kToshibaNumberOfBytes*2;i++) {
+                    const unsigned char c = event->data[i];
+                    if( c<'0' || c>'F' || (c>'9' && c<'A') ) {
+                        ESP_LOGE("MQTT","Wrong chars in MQTT-data");
+                        exitRx = true;
+                        break;
+                    }
+                }
+                if( exitRx ) break;
+                
+                char *cp = event->data;
+                for(uint8_t i=0;i<kToshibaNumberOfBytes;i++) {
+                    int n = sscanf(cp, "%02X", (unsigned int*)&data[i]);
+                    if( n != 1 ) {
+                        ESP_LOGE("MQTT","Wrong chars (sscanf) in MQTT-data");
+                        break;
+                    }
+                    cp+=2;
+                }
+
+                ESP_LOGI("MQTT","Received a Toshiba IR Code for transmit");
+
+                xQueueSend( toshibaTxQueue, &data, 0 );
+            }
             break;
         case MQTT_EVENT_ERROR:
             ESP_LOGI(TAG, "MQTT_EVENT_ERROR");

+ 24 - 3
main/receiver.c

@@ -5,6 +5,8 @@
 #include <sys/time.h>
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
+#include "freertos/queue.h"
+#include "driver/gpio.h"
 #include "esp_sleep.h"
 #include "esp_log.h"
 #include "driver/uart.h"
@@ -19,20 +21,33 @@
 #include "rxTimer.h"
 #include "toshiba_ir.h"
 #include "wifi.h"
+#include "mqtt.h"
+
 
 uint32_t dataArr[1000];
 uint32_t dataArrIdx = 0;
 
+QueueHandle_t toshibaTxQueue = NULL;
+
+
+
 
 
 void receiverTask(void *pvParameter)
 {
     ESP_LOGI("RX", "Receiver task starting.");
     uint32_t width;
+    uint8_t data[kToshibaNumberOfBytes];
 
 
     while (1) {
 
+        while( xQueueReceive( toshibaTxQueue, data, portMAX_DELAY ) == pdTRUE ) {
+
+            ESP_LOGI("TOSHIBA","Received a TX from MQTT");
+            sendToshibaIRCode(data);
+        }
+
         while( xQueueReceive( rxQueue, &width, portMAX_DELAY ) == pdTRUE ) {
 
             //ESP_LOGI("D", "%u", width);
@@ -66,10 +81,16 @@ void receiverTask(void *pvParameter)
 
 void initReceiver() {
 
-    gpio_pad_select_gpio(GPIO_RX_DATA);
-    gpio_set_direction(GPIO_RX_DATA, GPIO_MODE_INPUT);
+    gpio_pad_select_gpio(GPIO_IR_RX_DATA);
+    gpio_set_direction(GPIO_IR_RX_DATA, GPIO_MODE_INPUT);
+
+    gpio_pad_select_gpio(GPIO_IR_TX_DATA);
+    gpio_set_direction(GPIO_IR_TX_DATA, GPIO_MODE_OUTPUT);
+    gpio_set_level(GPIO_IR_TX_DATA, 0);
+
+    Toshiba_ir_ResetDecoder();
 
-    //ClasO_ResetDecoder();
+    toshibaTxQueue = xQueueCreate( 5, kToshibaNumberOfBytes );
             
     ESP_LOGI("RX", "Receiver has been initialized.");
 

+ 1 - 2
main/receiver.h

@@ -1,13 +1,12 @@
 #ifndef __RECEIVER__
 #define __RECEIVER__
 
-
-
 void initReceiver();
 
 extern uint32_t dataArr[1000];
 extern uint32_t dataArrIdx;
 
+extern QueueHandle_t toshibaTxQueue;
 
 
 #endif

+ 1 - 1
main/rxTimer.c

@@ -47,7 +47,7 @@ static void timer_tg0_isr(void* arg)
     static uint16_t newSamples = 0;
     
     // Sample the pin value
-    uint8_t value = (uint8_t)gpio_get_level(GPIO_RX_DATA);
+    uint8_t value = (uint8_t)gpio_get_level(GPIO_IR_RX_DATA);
 
     if( value == currValue ) {
         samples++;

+ 30 - 9
main/toshiba_ir.c

@@ -4,6 +4,7 @@
 #include "esp_log.h"
 #include "rxTimer.h"
 #include <string.h>
+#include "config.h"
 
 uint8_t xorBytes(const uint8_t * const start, const uint16_t length);
 
@@ -31,20 +32,40 @@ uint8_t xorBytes(const uint8_t * const start, const uint16_t length);
  */
 
 // Toshiba A/C
-const uint16_t kToshibaAcHdrMark = 4400;
-const uint16_t kToshibaAcHdrSpace = 4480;
-const uint16_t kToshibaAcBitMark = 530;
-const uint16_t kToshibaAcOneSpace = 1600;
-const uint16_t kToshibaAcZeroSpace = 530;
-// Some models have a different inter-message gap.
-// See: https://github.com/crankyoldgit/IRremoteESP8266/issues/1420
-const uint16_t kToshibaAcMinGap = 4600;    // WH-UB03NJ remote
-const uint16_t kToshibaAcUsualGap = 7400;  // Others
+const uint32_t kToshibaAcHdrMark = 4420;
+const uint32_t kToshibaAcHdrSpace = 4450;
+const uint32_t kToshibaAcBitMark = 570;
+const uint32_t kToshibaAcOneSpace = 1600;
+const uint32_t kToshibaAcZeroSpace = 510;
+const uint32_t kToshibaAcUsualGap = 7960;  // Others
 
 
 uint8_t data[kToshibaNumberOfBytes];            // Temp data during rx
 uint8_t dataTransfer[kToshibaNumberOfBytes];    // Send as pointer to receiver
 
+void sendToshibaIRCode(uint8_t *data) {
+
+    gpio_set_level(GPIO_IR_TX_DATA, 1);
+    delayMicroseconds(kToshibaAcHdrMark);
+    gpio_set_level(GPIO_IR_TX_DATA, 0);
+    delayMicroseconds(kToshibaAcHdrSpace);
+
+    for(uint8_t b=0;b<kToshibaNumberOfBits;b++) {
+        const uint8_t byteNo = b / 8;
+        const uint8_t shiftBits = b % 8;
+        gpio_set_level(GPIO_IR_TX_DATA, 1);
+        delayMicroseconds(kToshibaAcBitMark);
+
+        gpio_set_level(GPIO_IR_TX_DATA, 0);
+        const uint8_t bit_data = (1u << (7-shiftBits)) & data[byteNo];
+        delayMicroseconds( bit_data ? kToshibaAcOneSpace : kToshibaAcZeroSpace );
+    }
+    gpio_set_level(GPIO_IR_TX_DATA, 1);
+    delayMicroseconds(kToshibaAcHdrMark);
+    gpio_set_level(GPIO_IR_TX_DATA, 0);
+    delayMicroseconds(kToshibaAcUsualGap);
+}
+
 enum
 {
     UNKNOWN,

+ 1 - 0
main/toshiba_ir.h

@@ -7,6 +7,7 @@
 void Toshiba_ir_ResetDecoder ();
 
 uint8_t* nextPulseToshiba_ir(uint32_t width);
+void sendToshibaIRCode(uint8_t *data);
 
 #define kToshibaNumberOfBits 72
 #define kToshibaNumberOfBytes (kToshibaNumberOfBits/8)