make dht22 errors unsigned int, so we don't wrap into negative
[Arduino] / rpi_promini / rpi_promini.ino
index 0cd74b3..38d318d 100644 (file)
@@ -5,16 +5,18 @@
   RPI pin  Arduino
   RXD      TXD
   TXD      RXD
-  GPIO6    RST
+  BCM25    RST
   GND      GND
   +5V      RAW
 
            2    433Mhz receive
-           3    433Mhz outdoor temperature sensor receiver
+//           3    433Mhz outdoor temperature sensor receiver # DISABLED
+           8    DHT22 (VCC from arduino VCC)
            10   433Mhz send
            11   DS18B20
-           13   513Mhz send
-
+           12   315Mhz send
+           13   status LED
+           
 */
 
 #include <RCSwitch.h>
@@ -29,17 +31,19 @@ OneWire oneWire(11);
 DallasTemperature sensors(&oneWire);
 
 
-// 513Mhz light sockets
+// 315Mhz light sockets
 #define TX_PIN 12
 #define LED_PIN 13
+#define LED_ON  digitalWrite(LED_PIN, HIGH);
+#define LED_OFF digitalWrite(LED_PIN, LOW);
 
 int int_0 = 300; // ms
 int int_1 = 900; // ms
 int wait  = 2000; // ms
-int repeat = 5; // times
+int repeat = 20; // times (5 times seem a little low for sensors which are more than 10m away)
 
-void send_513(char *code) {
-  Serial.print("send 513Mhz ");
+void send_315(char *code) {
+  Serial.print("send 315Mhz ");
   Serial.println(code);
   
   // we have to send same signal at least two times
@@ -60,208 +64,66 @@ void send_513(char *code) {
       delayMicroseconds(i2);
     }
 
+    digitalWrite(LED_PIN, LOW);
+
     delayMicroseconds(wait); // guess
   }
 
-  digitalWrite(LED_PIN, LOW);
-}
-
-
-// outdoor 433 MHz temperature sensor
-
-// Unknown 433Mhz weather sensor decoder. Untested in the real world.
-// http://arduino.cc/forum/index.php/topic,142871.msg1106336.html#msg1106336
-
-// __           ___       ___    ___
-//   |         |  |      |  |   |  |
-//   |_________|  |______|  |___|  |
-//
-//   |  Sync      |    1    |  0   |
-//   |  9780us    | 4420us  | 2410us
-//      9810        4410      2490
-
-// Defines
-#define DataBits0 4                                       // Number of data0 bits to expect
-#define DataBits1 32                                      // Number of data1 bits to expect
-#define allDataBits 36                                    // Number of data sum 0+1 bits to expect
-// isrFlags bit numbers
-#define F_HAVE_DATA 1                                     // 0=Nothing in read buffer, 1=Data in read buffer
-#define F_GOOD_DATA 2                                     // 0=Unverified data, 1=Verified (2 consecutive matching reads)
-#define F_CARRY_BIT 3                                     // Bit used to carry over bit shift from one long to the other
-#define F_STATE 7                                         // 0=Sync mode, 1=Data mode
-
-// uno: pin 2 = int.0 or pin 3 = int.1 see
-// http://arduino.cc/en/Reference/attachInterrupt
-#define ISR_PIN 3
-#define ISR_INT 1
-
-// Constants
-const unsigned long sync_MIN = 9600;                      // Minimum Sync time in micro seconds
-const unsigned long sync_MAX = 9900;
-
-const unsigned long bit1_MIN = 4200;
-const unsigned long bit1_MAX = 4600;
-
-const unsigned long bit0_MIN = 2200;
-const unsigned long bit0_MAX = 2600;
-
-const unsigned long glitch_Length = 300;                  // Anything below this value is a glitch and will be ignored.
-
-// Interrupt variables
-unsigned long fall_Time = 0;                              // Placeholder for microsecond time when last falling edge occured.
-unsigned long rise_Time = 0;                              // Placeholder for microsecond time when last rising edge occured.
-byte bit_Count = 0;                                       // Bit counter for received bits.
-unsigned long build_Buffer[] = {0,0};                     // Placeholder last data packet being received.
-volatile unsigned long read_Buffer[] = {0,0};             // Placeholder last full data packet read.
-volatile byte isrFlags = 0;                               // Various flag bits
-volatile unsigned long last_Buffer[] = {0,0};
-
-void PinChangeISR(){                                     // Pin 2 (Interrupt 0) service routine
-  unsigned long Time = micros();                          // Get current time
-  if (digitalRead(ISR_PIN) == LOW) {
-// Falling edge
-    if (Time > (rise_Time + glitch_Length)) {
-// Not a glitch
-      Time = micros() - fall_Time;                        // Subtract last falling edge to get pulse time.
-      if (bitRead(build_Buffer[1],31) == 1)
-        bitSet(isrFlags, F_CARRY_BIT);
-      else
-        bitClear(isrFlags, F_CARRY_BIT);
-
-      if (bitRead(isrFlags, F_STATE) == 1) {
-// Looking for Data
-        if ((Time > bit0_MIN) && (Time < bit0_MAX)) {
-// 0 bit
-          build_Buffer[1] = build_Buffer[1] << 1;
-          build_Buffer[0] = build_Buffer[0] << 1;
-          if (bitRead(isrFlags,F_CARRY_BIT) == 1)
-            bitSet(build_Buffer[0],0);
-          bit_Count++;
-        }
-        else if ((Time > bit1_MIN) && (Time < bit1_MAX)) {
-// 1 bit
-          build_Buffer[1] = build_Buffer[1] << 1;
-          bitSet(build_Buffer[1],0);
-          build_Buffer[0] = build_Buffer[0] << 1;
-          if (bitRead(isrFlags,F_CARRY_BIT) == 1)
-            bitSet(build_Buffer[0],0);
-          bit_Count++;
-        }
-        else {
-// Not a 0 or 1 bit so restart data build and check if it's a sync?
-          bit_Count = 0;
-          build_Buffer[0] = 0;
-          build_Buffer[1] = 0;
-          bitClear(isrFlags, F_GOOD_DATA);                // Signal data reads dont' match
-          bitClear(isrFlags, F_STATE);                    // Set looking for Sync mode
-          if ((Time > sync_MIN) && (Time < sync_MAX)) {
-            // Sync length okay
-            bitSet(isrFlags, F_STATE);                    // Set data mode
-          }
-        }
-        if (bit_Count >= allDataBits) {
-// All bits arrived
-          bitClear(isrFlags, F_GOOD_DATA);                // Assume data reads don't match
-          if (build_Buffer[0] == read_Buffer[0]) {
-            if (build_Buffer[1] == read_Buffer[1]) 
-              bitSet(isrFlags, F_GOOD_DATA);              // Set data reads match
-          }
-          read_Buffer[0] = build_Buffer[0];
-          read_Buffer[1] = build_Buffer[1];
-          last_Buffer[0] = build_Buffer[0];
-          last_Buffer[1] = build_Buffer[1];
-          bitSet(isrFlags, F_HAVE_DATA);                  // Set data available
-          bitClear(isrFlags, F_STATE);                    // Set looking for Sync mode
-digitalWrite(13,HIGH); // Used for debugging
-          build_Buffer[0] = 0;
-          build_Buffer[1] = 0;
-          bit_Count = 0;
-        }
-      }
-      else {
-// Looking for sync
-        if ((Time > sync_MIN) && (Time < sync_MAX)) {
-// Sync length okay
-          build_Buffer[0] = 0;
-          build_Buffer[1] = 0;
-          bit_Count = 0;
-          bitSet(isrFlags, F_STATE);                      // Set data mode
-digitalWrite(13,LOW); // Used for debugging
-        }
-      }
-      fall_Time = micros();                               // Store fall time
-    }
-  }
-  else {
-// Rising edge
-    if (Time > (fall_Time + glitch_Length)) {
-      // Not a glitch
-      rise_Time = Time;                                   // Store rise time
-    }
-  }
 }
 
 
+// DHT22
+#include "DHT.h"
+DHT dht;
 
-void serial_outdoor_dump(void) {
-    unsigned long myData0 = 0;
-    unsigned long myData1 = 0;
-
-    // We have at least 2 consecutive matching reads
-    myData0 = last_Buffer[0]; // first 4 bits
-    myData1 = last_Buffer[1]; // rest of 32 bits
-    bitClear(isrFlags,F_HAVE_DATA); // Flag we have read the data
+#include "RunningAverage.h"
 
-    Serial.print("temp=");
-    int temp = ( myData1 >> 8 ) & 0xFFF;
-    if ( temp & 0x800 ) temp = temp | 0xF000;
-    Serial.print(temp / 10.0, 1);
+RunningAverage temp_avg(10);
+RunningAverage hum_avg(10);
 
-    Serial.print(" humidity=");
-    Serial.print( myData1 & 0xFF );
-
-    byte b1 = ( myData1 >> 20 ); // second byte from received packet
-
-    Serial.print(" button=");
-    Serial.print( b1 & 0x04);
-
-    Serial.print(" battery=");
-    Serial.print( b1 & 0x08);
-
-    Serial.print(" channel=");
-    Serial.print( ( b1 & 0x03 ) + 1 );
-
-    Serial.print(" rid=");
-    Serial.println( myData1 >> 24 );
+// setup
 
+void help() {
+  Serial.print("# press buttons on remote or send AB where A = socket (0..9), B = state (0 = off, 1 = on)\nB00...00 (24 digits) to send binary\n");
 }
 
-
-
-// setup
-
 void setup() {
   Serial.begin(9600);
   mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2  
   mySwitch.enableTransmit(10); // with sender wired in receiving doesn't work, pin #10
+  mySwitch.setRepeatTransmit(repeat); // or change to be different for 433 and 315 MHz
 
   // DS18B20
   sensors.begin();
 
-  // outdoor temperature sensor
-  pinMode(13,OUTPUT); // Used for debugging
-  pinMode(ISR_PIN,INPUT);
-  attachInterrupt(ISR_INT,PinChangeISR,CHANGE);
+  // DHT22
+  dht.setup(8);
 
+    temp_avg.addValue( dht.getTemperature() );
+    hum_avg.addValue( dht.getHumidity() );
 
-  Serial.print("press buttons on remote or send AB where A = socket (0..9), B = state (0 = off, 1 = on)\nB00...00 (24 digits) to send binary\n");
 }
 
 int serial_pos = 0;
 char serial_data[2]; // socket (0-9), state (0-1)
-char binary_data[24];
+char binary_data[32];
+unsigned int dht22_errors = 0;
+
+unsigned long time = millis();
 
 void loop() {
+  if ( millis() - time > 2000 ) {
+    float t = dht.getTemperature();
+    if ( dht.getStatus() == 0 )
+      temp_avg.addValue( t );
+    else dht22_errors++;
+    float h = dht.getHumidity();
+    if ( dht.getStatus() == 0 )
+      hum_avg.addValue( h );
+    else dht22_errors++;
+    time = millis();
+  }
+
   if (mySwitch.available()) {
     Serial.print(mySwitch.getReceivedBitlength());
     Serial.print(" bits ");
@@ -270,6 +132,11 @@ void loop() {
   }
   if (Serial.available() > 0) {
      char input = Serial.read();
+
+     if (input == '?' || input == 'h') {
+       help();
+     } else
+
      if ( input == 'T' ) {
        Serial.print("DS18B20 temperature = ");
        sensors.requestTemperatures();
@@ -278,68 +145,103 @@ void loop() {
 
      if ( input == 'B' ) {
        Serial.readBytesUntil('\n', binary_data, sizeof(binary_data));
-       Serial.print("send B");
+       Serial.print("send B");
        Serial.println( binary_data );
+       LED_ON
        mySwitch.send( binary_data );
+       LED_OFF
+     } else
+
+     if ( input == 'R' ) {
+       Serial.readBytesUntil('\n', binary_data, sizeof(binary_data));
+       Serial.print("# send 315 binary ");
+       Serial.println( binary_data );
+       send_315( binary_data );
      } else
 
-    // light sockets at 513 Mhz
+    // light sockets at 315 Mhz
      if (input == 'a') {
-       send_513("1000100110110000000000010");
+       send_315("1000100110110000000000010");
      } else
      if (input == 'b') {
-       send_513("1011001001011111000000010");
+       send_315("1011001001011111000000010");
      } else
 
-     if (input == 'o') {
-       serial_outdoor_dump();
+     // DHT22
+     if (input == 'd') {
+       Serial.print("temperature=");
+       Serial.print(temp_avg.getAverage());
+       Serial.print(" humidity=");
+       Serial.print(hum_avg.getAverage());
+       Serial.print(" errors=");
+       Serial.println(dht22_errors);
      }
 
-     if ( input >= 0x30 && input <= 0x39 ) {
+     if ( input >= 0x30 && input <= 0x39 && serial_pos < 2 ) {
        input = input - 0x30; // ASCII to number
        serial_data[serial_pos++] = input;
      } else {     
-       Serial.print("ignore: ");
+       Serial.print("ignore: ");
        Serial.println(input, HEX);
      }
      
      if ( serial_pos == 2 ) {
-       Serial.print("socket: ");
+       Serial.print("switch=");
        Serial.print(serial_data[0], DEC);
-       Serial.print(" state");
+       Serial.print(" state=");
        Serial.println(serial_data[1] ? "on" : "off");
-       serial_pos = 0;
-       if ( serial_data[1] ) { // on
-         switch ( serial_data[0] ) {
+
+       byte on = serial_data[1];
+
+       LED_ON
+
+       // switches, 433 Mhz set of 3
+       switch ( serial_data[0] ) {
          case 1:
-           mySwitch.send("110101011101010000001100");
-           break;
+           on  ? mySwitch.send("110101011101010000001100")
+               : mySwitch.send("110101011101010000000011");
+          break;
          case 2:
-           mySwitch.send("110101010111010000001100");
+           on  ? mySwitch.send("110101010111010000001100")
+               : mySwitch.send("110101010111010000000011");
            break;
          case 3:
-           mySwitch.send("110101010101110000001100");
+           on  ? mySwitch.send("110101010101110000001100")
+               : mySwitch.send("110101010101110000000011");
            break;
-         default:
-           Serial.print("invalid switch on number ");
-           Serial.println(serial_data[0], DEC);
-         }
-       } else { // off
-         switch ( serial_data[0] ) {
-         case 1:
-           mySwitch.send("110101011101010000000011");
-           break;
-         case 2:
-           mySwitch.send("110101010111010000000011");
-           break;
-         case 3:
-           mySwitch.send("110101010101110000000011");
+         case 4:
+           on  ? mySwitch.send("001111110000000011000000")
+               : mySwitch.send("001111110000000000000000");
            break;
+         case 5:
+/*
+               cca. 320Mhz 4 channel 4.8A 220V relay
+
+               A       1101001010011010011100010
+               B       1101001010011010011101000
+               C       1101001010011010011100100
+               D       1101001010011010011110000
+               off     1101001010011010011111000
+               on      1101001010011010011100110
+*/
+               switch ( on ) {
+                       case '0': send_315( "1101001010011010011111000" );
+                       case '1': send_315( "1101001010011010011100110" );
+                       case 'A': send_315( "1101001010011010011100010" );
+                       case 'B': send_315( "1101001010011010011101000" );
+                       case 'C': send_315( "1101001010011010011100100" );
+                       case 'D': send_315( "1101001010011010011110000" );
+                       default:  Serial.println("# ERROR: use 0-off 1-on A B C D");
+               }
          default:
-           Serial.print("invalid switch off number ");
+           Serial.print("# invalid switch number ");
            Serial.println(serial_data[0], DEC);
-         }
-       }
+       }
+
+        LED_OFF
+
+       // reset for later
+       serial_pos = 0;
      }
   }
 }