浏览代码

Fixes + Added ESIC (No RX though..)

Thomas Chef 5 年之前
父节点
当前提交
e830bc5479
共有 10 个文件被更改,包括 321 次插入15 次删除
  1. 1 0
      main/CMakeLists.txt
  2. 248 0
      main/Sensors/esic.c
  3. 11 0
      main/Sensors/esic.h
  4. 28 1
      main/Sensors/nexa.c
  5. 2 2
      main/Sensors/proovesmartSensor.c
  6. 4 2
      main/main.c
  7. 9 8
      main/nexaTransmit.c
  8. 16 0
      main/receiver.c
  9. 1 1
      main/rxTimer.c
  10. 1 1
      main/udp_client.h

+ 1 - 0
main/CMakeLists.txt

@@ -1,5 +1,6 @@
 idf_component_register(SRCS "main.c" "led.c" "rxTimer.c" "transceiver.c" "receiver.c"
                         "Sensors/ClasOSensor.c" "Sensors/proovesmartSensor.c" "Sensors/nexa.c" "Sensors/oregon.c"
+                        "Sensors/esic.c"
                         "nexaTransmit.c"
                         "wifi.c" "udp_client.c"
                     INCLUDE_DIRS ".")

+ 248 - 0
main/Sensors/esic.c

@@ -0,0 +1,248 @@
+#include "esic.h"
+#include <stdint.h>
+#include <stdio.h>
+#include "esp_log.h"
+#include "../rxTimer.h"
+#include "../led.h"
+
+/**
+**********************************************************************************
+* TEMP 3
+* ESIC WT450H
+
+    +---+   +---+   +-------+       +  high
+    |   |   |   |   |       |       |
+    |   |   |   |   |       |       |
+    +   +---+   +---+       +-------+  low
+    
+    ^       ^       ^       ^       ^  clock cycle
+    |   1   |   1   |   0   |   0   |  translates as
+    
+    Each transmission is 36 bits long (i.e. 72 ms)
+
+	.short_width = 976,  // half-bit width 976 us
+    .long_width  = 1952, // bit width 1952 us
+    
+    Data is transmitted in pure binary values, NOT BCD-coded.
+    
+    Example transmission (House 1, Channel 1, RH 59 %, Temperature 23.5 �C)
+    1100 00010011001110110100100110011000
+    
+    b00 - b03  (4 bits): Constant, 1100, probably preamble
+    b04 - b07  (4 bits): House code (here: 0001 = HC 1)
+    b08 - b09  (2 bits): Channel code - 1 (here 00 = CC 1)
+    b10 - b12  (3 bits): Constant, 110
+    b13 - b19  (7 bits): Relative humidity (here 0111011 = 59 %)
+    b20 - b34 (15 bits): Temperature (see below)
+    b35 - b35  (1 bit) : Parity (xor of all bits should give 0)
+    
+    The temperature is transmitted as (temp + 50.0) * 128,
+    which equals (temp * 128) + 6400. Adding 50.0 �C makes
+    all values positive, an unsigned 15 bit integer where the
+    first 8 bits correspond to the whole part of the temperature
+    (here 01001001, decimal 73, substract 50 = 23).
+    Remaining 7 bits correspond to the fractional part.
+    
+    To avoid floating point calculations I store the raw temperature value
+    as a signed integer in the variable esicTemp, then transform it to
+    actual temperature * 10 using "esicTemp = (esicTemp - 6400) * 10 / 128",
+    where 6400 is the added 50 times 128.
+    When reporting the temperature I simply print "esicTemp / 10" (integer division,
+    no fraction), followed by a decimal point and "esicTemp % 10" (remainder, which
+    equals first fractional decimal digit).
+      
+    Summary of bit fields:
+    1100 0001 00 110 0111011 010010011001100 0
+     c1   hc  cc  c2    rh          t        p
+     
+    c1, c2 = constant field 1 and 2
+    hc, cc = house code and channel code
+    rh, t  = relative humidity, temperature
+    p      = parity bit 1111111111111110
+**********************************************************************************
+*/
+
+
+
+volatile unsigned long long temp3_x_data;
+
+
+void ESIC_ResetDecoder() {
+	temp3_x_data = 0;
+}
+
+#define NO_OF_PULSES 60
+#define max(a,b) (((a)>(b))?(a):(b))
+#define isShortPulse(width)  (((long_pulse/2)-maxDiff) <= width && width <= ((long_pulse/2)+maxDiff))
+#define isLongPulse(width)  ((long_pulse-maxDiff) <= width && width <= (long_pulse+maxDiff))
+
+unsigned int temp3_pulses[NO_OF_PULSES];
+
+
+static int long_pulse = 1955;
+static int maxDiff = 300;
+
+static void storePulses(unsigned int inWidth) {
+
+	int i;
+
+	// Shift pulses down
+	for(i=1;i<NO_OF_PULSES;i++) {
+		temp3_pulses[i-1] = temp3_pulses[i];
+	}
+
+	temp3_pulses[NO_OF_PULSES-1] = inWidth;
+}
+
+static void sweepForNoise() {
+
+	// If we have a short pulse in position 2
+	// Then add together pos 1,2 and 3 if they are a valid pulse
+	// This way we can handle one single noise pulse in a real pulse
+	if( temp3_pulses[NO_OF_PULSES-2] < ((long_pulse/2)-maxDiff) ) {
+
+		int totPulse = temp3_pulses[NO_OF_PULSES-1]+temp3_pulses[NO_OF_PULSES-2]+temp3_pulses[NO_OF_PULSES-3];
+		
+		if( isShortPulse(totPulse) || isLongPulse(totPulse) ) {
+			
+			// Store new pulse in last position
+			temp3_pulses[NO_OF_PULSES-1] = totPulse;
+
+			// Move everything up again
+			for(int i=NO_OF_PULSES-2;i>1;i--) {
+				temp3_pulses[i] = temp3_pulses[i-2];
+			}
+			temp3_pulses[0] = 0;
+			temp3_pulses[1] = 0;
+		}
+	}
+}
+
+
+/*static void adjustTiming() {
+
+	int p1 = temp3_pulses[NO_OF_PULSES-8];
+	int p2 = temp3_pulses[NO_OF_PULSES-7];
+	int p3 = temp3_pulses[NO_OF_PULSES-6];
+	int p4 = temp3_pulses[NO_OF_PULSES-5];
+	int p5 = temp3_pulses[NO_OF_PULSES-4];
+	int p6 = temp3_pulses[NO_OF_PULSES-3];
+	int p7 = temp3_pulses[NO_OF_PULSES-2];
+	int p8 = temp3_pulses[NO_OF_PULSES-1];
+
+	// Check max differance between the short pulses
+	int sh_mean = (p1+p2+p3+p4) / 4;
+	int sh_max_diff = max(max(abs(p1-sh_mean),abs(p2-sh_mean)),max(abs(p3-sh_mean),abs(p4-sh_mean)));
+
+	// Check max differance between the long pulses
+	int long_mean = (p5+p6+p7+p8) / 4;
+	int long_max_diff = max(max(abs(p5-long_mean),abs(p6-long_mean)),max(abs(p7-long_mean),abs(p8-long_mean)));
+
+	if( sh_max_diff < maxDiff && long_max_diff < maxDiff ) {
+
+		int mean = (long_mean + sh_mean)/2;
+		if( long_mean > (mean+maxDiff) && sh_mean < (mean-maxDiff) ) {
+			if( abs(long_mean - (sh_mean*2)) < maxDiff ) {
+				long_pulse = (long_mean + sh_mean*2)/2;
+				maxDiff = long_mean / 15;
+			}
+		}
+	}
+}*/
+
+// The latest/newest pulse is at the end of the array [59]
+// This ([59]) is the latest bit in the bit-stream from the transmitter
+// This is way we input the bits at a high position and shift them towards lower values
+// So..start reading backwards and working towards the first/highest bits
+static int checkPulsePattern() {
+
+	int i = NO_OF_PULSES-1;	// Start reading from the last received (end of array)
+	int b = 0;
+
+	unsigned long long code = 0;
+
+	while( i >= 0 ) {
+
+		int combWidth = temp3_pulses[i] + temp3_pulses[i-1];
+
+		if( isLongPulse(temp3_pulses[i]) ) {
+			b++;
+			i-=1;
+			code = code >> 1;
+		}
+		else if( isShortPulse(temp3_pulses[i]) && isShortPulse(temp3_pulses[i-1]) ) {
+			b++;
+			i-=2;
+			code = ((code >> 1) | 0x200000000);
+		}
+		else if( isLongPulse( combWidth ) ) {
+			b++;
+			i-=2;
+			code = ((code >> 1) | 0x200000000);
+		}
+		else {
+			return -1;
+		}
+		if( b == 34 ) {
+/*
+		0000 0001 00 110 0101000 010010110101000 1
+AND:    0011 1111 00 111 0000000 000000000000000 0  = 001111110011100000000000000000000000 = 0x3F3800000
+RES:    0000 0001 00 110 0000000 000000000000000 0  = 000000010011000000000000000000000000 = 0x013000000
+
+		Summary of bit fields:
+		1100 0001 00 110 0111011 010010011001100 0
+		 c1   hc  cc  c2    rh          t        p
+		 */
+			if( (code & 0x3F3800000) == 0x013000000 ) {
+
+				temp3_x_data = (code&0xFFFFFFFF);
+				// Check parity
+				int even=0;
+				unsigned long long data = temp3_x_data;
+				for(int i=0;i<32;i++) {
+					if( data & 1 ) even++;
+					data >>= 1;
+				}
+				if( even % 2 != 0 ) {
+					return -1;
+				}
+				// A correct code has been received
+				//printf("Code received: %llu on row:%d\n",(code&0xFFFFFFFF),row_no);
+				return 1;
+				
+			}
+			else {
+				return -1;
+			}
+		}
+	}
+	return 0;
+}
+
+static int temp3decode (unsigned int inWidth) {
+
+	int width = inWidth; //preProcessPulses(inWidth);
+
+	if( width == -1 ) return -1;
+	if( width == 0 ) return 0;
+
+	storePulses(inWidth);
+	sweepForNoise();
+	//adjustTiming();
+	return checkPulsePattern();
+}
+
+int64_t nextPulseESICSensor(uint32_t width) {
+  
+  volatile static int result;
+  
+  if( width > 0 ) {
+    if( temp3_x_data == 0 ) {
+      
+      result = temp3decode(width);
+
+    }
+  }
+  
+  return (temp3_x_data > 0);
+}

+ 11 - 0
main/Sensors/esic.h

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

+ 28 - 1
main/Sensors/nexa.c

@@ -4,6 +4,24 @@
 #include "../rxTimer.h"
 #include "../led.h"
 
+typedef struct {
+    uint32_t max;
+    uint32_t min;
+    uint32_t cnt;
+    uint32_t total;
+} debug_data_t;
+
+static debug_data_t debug_data = { 0,99999,0,0 };
+static debug_data_t debug_data_tot = { 0,99999,0,0 };
+
+#define DEBUG_WIDTH_FUNC() { \
+                    if( width > debug_data.max ) debug_data.max = width; \
+                    if( width < debug_data.min ) debug_data.min = width; \
+                    debug_data.total += width; \
+                    debug_data.cnt++; \
+                }
+
+
 #define FACTOR 9
 #define CONV(a) ((((a)*FACTOR) / 100) + (a))
 
@@ -25,6 +43,9 @@ void NEXA_resetDecoder () {
 	rx_numBits = 0;
 	x_2ndbit = false;
 	rx_state = UNKNOWN;
+
+    debug_data.max = 0;
+    debug_data.min = 99999;
 }
 
 static void addBit (uint8_t value) {
@@ -72,6 +93,7 @@ static int rx_decode(uint32_t width) {
 
             if ( 155 <= width && width <= 305 ) {
                 rx_state = T1;
+
             }
             else {
                 if( rx_numBits == 0 && 2240 <= width && width <= 3540 ) {
@@ -87,7 +109,8 @@ static int rx_decode(uint32_t width) {
             if ( 240 <= width && width <= 440 ) {
                 addBit(0);
             } else if ( (1410-300) <= width && width <= (1410+300) ) {
-                //debug_width = width;
+                DEBUG_WIDTH_FUNC();
+
                 addBit(1);
             } else if( rx_numBits == 64 ) {	// end of frame
                 rx_state = DONE;
@@ -128,6 +151,10 @@ int64_t nextPulseNEXA(uint32_t width)
     }
     if (rx_state == DONE) {
         now = millis();
+        if( debug_data.max > debug_data_tot.max ) debug_data_tot.max = debug_data.max;
+        if( debug_data.min < debug_data_tot.min ) debug_data_tot.min = debug_data.min;
+        //printf("OREGON DEbug min,max:%u %u\n",debug_data_tot.min,debug_data_tot.max);
+
         if( sensor_data != previous_data || (now > (old_time+1000)) ) {
             previous_data = sensor_data;
             retVal = sensor_data;

+ 2 - 2
main/Sensors/proovesmartSensor.c

@@ -13,8 +13,8 @@ typedef struct {
     uint32_t total;
 } debug_data_t;
 
-debug_data_t debug_data = { 0,99999,0,0 };
-debug_data_t debug_data_tot = { 0,99999,0,0 };
+static debug_data_t debug_data = { 0,99999,0,0 };
+static debug_data_t debug_data_tot = { 0,99999,0,0 };
 
 #define DEBUG_WIDTH_FUNC() { \
                     if( width > debug_data.max ) debug_data.max = width; \

+ 4 - 2
main/main.c

@@ -77,10 +77,12 @@ void app_main(void)
         }
 
         if( c == '0' ) {
-            sendNexaCode(0x4C90AD81);
+            //sendNexaCode(0x1B5C1DA0);
+            sendNexaCode(0x2A37C840);
         }
         if( c == '1' ) {
-            sendNexaCode(0x4C90AD91);
+            //sendNexaCode(0x1B5C1DB0);
+            sendNexaCode(0x2A37C850);   // Volvo: ON
         }
     }
 }

+ 9 - 8
main/nexaTransmit.c

@@ -34,10 +34,10 @@ QueueHandle_t nexaTxQueue = NULL;
 // <NT01995090>
 
 // Timing for NEXA Remote controls
-#define HIGH_PULSE     230
-#define LOW_PULSE_0    340
-#define LOW_PULSE_1   1410
-#define SYNC_PULSE    2890
+#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() {
@@ -90,8 +90,8 @@ static void sendNexaCodeNo(uint32_t orig_code) {
         code = (code << 1);
       }
       
-      sendStop();    
-      
+      sendStop();   
+
     }
 
     trcvSwitch2receive();
@@ -124,7 +124,8 @@ static void nexaTxTask(void *pvParameter)
     while (1)
     {
         while( xQueueReceive( nexaTxQueue, &data, portMAX_DELAY ) == pdTRUE ) {
-          sendNexaCodeNo(data);
+            sendNexaCodeNo(data);
+            vTaskDelay(200 / portTICK_PERIOD_MS);   // Wait a while between transmits
         }
     }
     vTaskDelete(NULL);
@@ -134,5 +135,5 @@ void initNexaTransmit() {
 
   nexaTxQueue = xQueueCreate( 20, sizeof( uint32_t ) );
 
-  xTaskCreatePinnedToCore(&nexaTxTask, "nexaTxTask", 8192, NULL, tskIDLE_PRIORITY + 2, NULL, 0);
+  xTaskCreatePinnedToCore(&nexaTxTask, "nexaTxTask", 8192, NULL, tskIDLE_PRIORITY + 10, NULL, 1);
 }

+ 16 - 0
main/receiver.c

@@ -22,6 +22,7 @@
 #include "Sensors/proovesmartSensor.h"
 #include "Sensors/nexa.h"
 #include "Sensors/oregon.h"
+#include "Sensors/esic.h"
 #include "led.h"
 #include "udp_client.h"
 #include "wifi.h"
@@ -124,8 +125,23 @@ void receiverTask(void *pvParameter)
                 strncpy(ch_data,ch_data_p, sizeof(ch_data));
                 ESP_LOGI("RX", "OREGON: <RR%s> %6.4f cm2", ch_data, total );
 
+#ifdef WIFI_ENABLED
+                sprintf(dataStr,"<RR%s>\n",ch_data);
+                sendUDPMessage(dataStr);
+#endif
+
                 Oregon_ResetDecoder();
             }
+
+            // ESIC (Fridge / Freezer Sensors)
+            if( nextPulseESICSensor(width) ) {
+
+                ESP_LOGE("RX", "NO WAY");
+     
+                
+                    ESIC_ResetDecoder();          
+                    blinkTheLED();      
+            }
         }
     }
     vTaskDelete(NULL);

+ 1 - 1
main/rxTimer.c

@@ -117,5 +117,5 @@ void delayMicroseconds(uint32_t delay)
 {
 	volatile uint32_t endtime = tenUsCounter + ((uint32_t)delay / 10);
 
-	while( tenUsCounter < endtime ) taskYIELD();
+	while( tenUsCounter < endtime ) ;
 }

+ 1 - 1
main/udp_client.h

@@ -1,7 +1,7 @@
 #ifndef __UDP_CLIENT__
 #define __UDP_CLIENT__
 
-#define UDP_QUEUE_OBJ_LENGTH 25
+#define UDP_QUEUE_OBJ_LENGTH 30
 
 void udpClientInit();