Pārlūkot izejas kodu

Added some receiver code

Thomas Chef 2 gadi atpakaļ
vecāks
revīzija
c2d8f5de80
8 mainītis faili ar 398 papildinājumiem un 1 dzēšanām
  1. 2 0
      main/config.h
  2. 8 1
      main/main.c
  3. 79 0
      main/receiver.c
  4. 13 0
      main/receiver.h
  5. 121 0
      main/rxTimer.c
  6. 18 0
      main/rxTimer.h
  7. 146 0
      main/toshiba_ir.c
  8. 11 0
      main/toshiba_ir.h

+ 2 - 0
main/config.h

@@ -15,5 +15,7 @@
 
 #define ONE_WIRE_BUS_IO           GPIO_NUM_26   // Temp sensors
 
+#define GPIO_RX_DATA       16       // IR Receiver
+
 
 #endif

+ 8 - 1
main/main.c

@@ -5,6 +5,8 @@
 #include "wifi.h"
 #include "mqtt.h"
 #include "readTemps.h"
+#include "rxTimer.h"
+#include "receiver.h"
 
 
 // Chip info:
@@ -17,7 +19,10 @@ void app_main(void)
     ESP_LOGI("MAIN", "IRTransceiver ESP32. Core:%d",xPortGetCoreID());
 
     // Wait for stable environment
-    vTaskDelay(2000.0 / portTICK_PERIOD_MS);
+    vTaskDelay(1000.0 / portTICK_PERIOD_MS);
+
+
+    rxTimerInit();          // First we start the Timer (which samples Rx and handles uS-delays)
 
 #ifdef ENABLE_DS18B20
     initTempReadings();
@@ -31,6 +36,8 @@ void app_main(void)
     mqtt_init();
 #endif
 
+    initReceiver();         // Init receiver-task
+
     TickType_t vLastWakeTime = xTaskGetTickCount();
 
     // Do an initial delay to make the different tasks to work out of sync to each other (not send all data at same time)

+ 79 - 0
main/receiver.c

@@ -0,0 +1,79 @@
+#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 "receiver.h"
+#include "rxTimer.h"
+#include "toshiba_ir.h"
+#include "wifi.h"
+
+uint32_t dataArr[1000];
+uint32_t dataArrIdx = 0;
+
+static int convertToSignedTemp(unsigned int value)
+{
+
+	//int signValue;
+
+	return ( (value >> 11) == 0 )? value : ((-1 ^ 0xFFF) | value);
+}
+
+void receiverTask(void *pvParameter)
+{
+    ESP_LOGI("RX", "Receiver task starting.");
+    uint32_t width;
+
+
+    while (1) {
+
+        while( xQueueReceive( rxQueue, &width, portMAX_DELAY ) == pdTRUE ) {
+
+            /*dataArr[dataArrIdx++] = width;
+            if( dataArrIdx == 1000 ) dataArrIdx=0;
+
+            // Receive the Toshiba IR
+            int64_t data = nextPulseToshiba_ir(width);
+            if( data != -1 ) {
+
+                int value      = convertToSignedTemp( data & 0xFFF );
+                unsigned char id         = (data>>12) & 0x007;
+
+                ESP_LOGI("RX", "ClasO:  <TR%08llX> %u               %4.1f",data,id, (float)value/10);
+
+                //sprintf(dataStr,"<TR%08llX>",data);
+#ifdef WIFI_ENABLED
+                sendUDPMessage(dataStr, true);
+#endif
+            }
+            */
+
+
+        }
+    }
+    vTaskDelete(NULL);
+}
+
+void initReceiver() {
+
+    gpio_pad_select_gpio(GPIO_RX_DATA);
+    gpio_set_direction(GPIO_RX_DATA, GPIO_MODE_INPUT);
+
+    //ClasO_ResetDecoder();
+            
+    ESP_LOGI("RX", "Receiver has been initialized.");
+
+    xTaskCreatePinnedToCore(&receiverTask, "receiverTask", 8192, NULL, tskIDLE_PRIORITY + 5, NULL, 0);
+}

+ 13 - 0
main/receiver.h

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

+ 121 - 0
main/rxTimer.c

@@ -0,0 +1,121 @@
+#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 "config.h"
+
+
+static intr_handle_t s_timer_handle;
+
+static bool timerTaskIsDone = false;
+
+static volatile uint32_t tenUsCounter = 0;  
+
+QueueHandle_t rxQueue = NULL;
+
+static uint32_t millisCnt=0;
+
+uint32_t millis() { return millisCnt; }
+
+
+static void timer_tg0_isr(void* arg)
+{
+    static uint32_t subMillisCounter=100;
+
+    if( subMillisCounter-- == 0 ) {
+        millisCnt++;
+        subMillisCounter=100;
+    }
+
+    tenUsCounter++;
+
+    static uint8_t currValue = 0;
+  
+    static uint16_t samples = 0;
+    static uint16_t newSamples = 0;
+    
+    // Sample the pin value
+    uint8_t value = (uint8_t)gpio_get_level(GPIO_RX_DATA);
+
+    if( value == currValue ) {
+        samples++;
+        samples+=newSamples;
+        newSamples=0;
+    }
+    else {
+        newSamples++;
+    }
+    
+    if( newSamples == 6 ) {
+
+        const uint32_t dataToSend = samples * 10;
+
+        //if( disableRx == false ) {
+            xQueueSend( rxQueue, &dataToSend, 0 );
+        //}
+        
+        samples = newSamples;
+        newSamples = 0;
+        currValue = value;    
+    }
+
+    //Reset irq and set for next time
+    TIMERG1.int_clr_timers.t1 = 1;
+    TIMERG1.hw_timer[1].config.alarm_en = 1;
+}
+
+static void timerSetupTask(void *pvParameter)
+{
+    rxQueue = xQueueCreate( 1000, sizeof( uint32_t ) );
+
+    timer_config_t config = {
+        .alarm_en = true,				//Alarm Enable
+        .counter_en = false,			//If the counter is enabled it will start incrementing / decrementing immediately after calling timer_init()
+        .intr_type = TIMER_INTR_LEVEL,	//Is interrupt is triggered on timer’s alarm (timer_intr_mode_t)
+        .counter_dir = TIMER_COUNT_UP,	//Does counter increment or decrement (timer_count_dir_t)
+        .auto_reload = true,			//If counter should auto_reload a specific initial value on the timer’s alarm, or continue incrementing or decrementing.
+        .divider = 8   				//Divisor of the incoming 160 MHz (12.5nS) APB_CLK clock. E.g. 800 = 10uS per timer tick
+    };
+
+    timer_init(TIMER_GROUP_1, TIMER_1, &config);
+    timer_set_counter_value(TIMER_GROUP_1, TIMER_1, 0);
+    timer_set_alarm_value(TIMER_GROUP_1, TIMER_1, 100);     // Here we set the ISR-Value
+    timer_enable_intr(TIMER_GROUP_1, TIMER_1);
+    timer_isr_register(TIMER_GROUP_1, TIMER_1, &timer_tg0_isr, NULL, 0, &s_timer_handle);
+
+    timer_start(TIMER_GROUP_1, TIMER_1);
+
+    
+
+    timerTaskIsDone = true;
+    vTaskDelete(NULL);
+}
+
+void rxTimerInit()
+{
+    xTaskCreatePinnedToCore(&timerSetupTask, "timerSetupTask", 8192, NULL, tskIDLE_PRIORITY + 2, NULL, 1);
+
+    // Wait until task has finished
+    while(timerTaskIsDone == false) vTaskDelay( 50 / portTICK_PERIOD_MS );
+
+    ESP_LOGI("rxTimer", "10uS Timer has been started.");
+}
+
+void delayMicroseconds(uint32_t delay)
+{
+	volatile uint32_t endtime = tenUsCounter + ((uint32_t)delay / 10);
+
+	while( tenUsCounter < endtime ) ;
+}

+ 18 - 0
main/rxTimer.h

@@ -0,0 +1,18 @@
+#ifndef __RX_TIMER__
+#define __RX_TIMER__
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/queue.h"
+#include <stdint.h>
+
+void rxTimerInit();
+
+void delayMicroseconds(uint32_t delay);
+
+extern QueueHandle_t rxQueue;
+
+uint32_t millis();
+
+
+
+#endif

+ 146 - 0
main/toshiba_ir.c

@@ -0,0 +1,146 @@
+#include "toshiba_ir.h"
+#include <stdint.h>
+#include <stdio.h>
+#include "esp_log.h"
+#include "rxTimer.h"
+
+enum
+{
+    UNKNOWN,
+    T0,
+    T1,
+    T2,
+    T3,
+    TEMP1_OK,
+    DONE
+};
+
+static uint8_t rx_state = UNKNOWN;
+
+static uint64_t sensor_data;
+static uint32_t rx_numBits;
+
+
+void Toshiba_ir_ResetDecoder()
+{
+    sensor_data = 0;
+    rx_numBits = 0;
+    rx_state = UNKNOWN;
+}
+
+static void addBit(uint8_t value)
+{
+
+    rx_numBits++;
+    sensor_data = (sensor_data << 1) + (value & 0x01);
+
+    rx_state = TEMP1_OK;
+}
+
+#define START_PULSE_MIN (3880-200)
+#define START_PULSE_MAX (4010+200)
+
+#define T0_PULSE_MIN (380-100)
+#define T0_PULSE_MAX (520+100)
+
+#define SHORT_PULSE_MIN (890-100)
+#define SHORT_PULSE_MAX (990+100)
+
+#define LONG_PULSE_MIN (1880-150)
+#define LONG_PULSE_MAX (1980+150)
+
+
+static int32_t rx_decode(uint32_t width)
+{
+    switch (rx_state) {
+        case UNKNOWN: // Start of frame
+            if ( START_PULSE_MIN <= width && width <= START_PULSE_MAX )
+            {
+                rx_state = T0;
+            }
+            else
+            {
+                return -1; // error, reset
+            }
+            break;
+
+        case T0: // First half of pulse : HIGH around 230us
+
+            if (rx_numBits == 32)
+            { // end of frame
+                rx_state = DONE;
+                sensor_data = (sensor_data >> 8); // Mask away some bits at the end
+                return 1;
+            }
+            else if( T0_PULSE_MIN <= width && width <= T0_PULSE_MAX )
+            {
+                rx_state = T1;
+            }
+            else
+            {
+                if (rx_numBits == 0 && START_PULSE_MIN <= width && width <= START_PULSE_MAX )
+                {
+                    rx_state = T0;
+                }
+                else
+                {
+                    return -1; // error, reset
+                }
+            }
+            break;
+
+        case T1:
+            if( SHORT_PULSE_MIN <= width && width <= SHORT_PULSE_MAX )
+            {
+                addBit(0);
+            }
+            else if( LONG_PULSE_MIN <= width && width <= LONG_PULSE_MAX )
+            {
+                addBit(1);
+            }
+            else
+            {
+                return -1; // error, reset
+            }
+            rx_state = T0;
+            break;
+    }
+    return 0;
+}
+
+int64_t nextPulseToshiba_ir(uint32_t width)
+{
+    static int64_t previous_data = 0;
+    static uint32_t old_time=0;
+    static uint32_t now;
+    int64_t retVal = -1;
+
+    if (width > 0)
+    {
+        if (rx_state != DONE)
+        {
+            switch (rx_decode(width))
+            {
+            case -1:
+                Toshiba_ir_ResetDecoder();
+                break;
+            case 1:
+                rx_state = DONE;
+                break;
+            }
+        }
+    }
+    if (rx_state == DONE) {
+        now = millis();
+
+        if( sensor_data != previous_data || (now > (old_time+1000)) ) {
+            previous_data = sensor_data;
+            retVal = sensor_data;
+            
+        }
+        old_time = now;
+        Toshiba_ir_ResetDecoder();
+    }
+    
+    return retVal;
+}

+ 11 - 0
main/toshiba_ir.h

@@ -0,0 +1,11 @@
+#ifndef __TOSHIBA_IR__
+#define __TOSHIBA_IR__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+void Toshiba_ir_ResetDecoder ();
+
+int64_t nextPulseToshiba_ir(uint32_t width);
+
+#endif