Home automation using Xbee radios

Dependencies:   EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd

Link to Notebook Page

Revision:
7:15cbbbe6105c
diff -r 230c1ec1c9bb -r 15cbbbe6105c XbeeCommLib.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XbeeCommLib.cpp	Tue Nov 26 06:16:25 2013 +0000
@@ -0,0 +1,159 @@
+
+#include "XbeeCommLib.h"
+
+float getAnalogVoltage(int analogInputIndex, int totalPacketBytes, int digitalSampleBytes){
+    int index = 19 + digitalSampleBytes + analogInputIndex*2;
+    if(index > (totalPacketBytes+1)) //+1 because each analog sample is 2 bytes
+        return 0;
+    else
+        return ((data[index] << 8 | data[index  + 1]) / 1023.0) * 1.2;
+}
+
+void digitalWriteXbee(unsigned int addrHigh, unsigned int addrLow, int outputIndex, bool value){
+    unsigned char dataToSend[40];
+    int counter = 0;
+    int i = 0;
+    int addrSum = 0;
+    unsigned char data = 0;
+
+    led3 = 1;
+    
+    printf(" - Sending...");
+    
+    dataToSend[counter++] = 0x7E;   // Start of packet
+    dataToSend[counter++] = 0x0;    // Length MSB (always 0)
+    dataToSend[counter++] = 0x10;   // Length LSB
+    dataToSend[counter++] = 0x17;   //0x17 =  command request
+    dataToSend[counter++] = 0x0;    // Frame ID (no reply needed)
+
+    // Send the 64 bit destination address
+    for(i = 3; i > -1; i--){
+        dataToSend[counter++] = (addrHigh >> 8*i) & 0xFF;
+        addrSum += (addrHigh >> 8*i) & 0xFF;
+    }
+    for(i = 3; i > -1; i--){
+        dataToSend[counter++] = (addrLow >> 8*i) & 0xFF;
+        addrSum += (addrLow >> 8*i) & 0xFF;
+    }
+    
+    dataToSend[counter++] = 0xFF;   // Destination Network
+    dataToSend[counter++] = 0xFE;   // (Set to 0xFFFE if unknown)
+    dataToSend[counter++] = 0x02;   // Set to 0x02 to apply these changes
+    dataToSend[counter++] = 'D';    // AT Command: D0
+    dataToSend[counter++] = '0' + outputIndex;
+    
+    if(value == true)
+        data = 5;   // Set digital output to be 5 (Digital Out HIGH)
+    else
+        data = 4;   // Set digital output to be 4 (LOW)
+    dataToSend[counter++] = data;
+        
+    
+    //long checksum = 0x17 + addrHigh + addrLow +0xFF + 0xFE + 0x02 + 'D' + '0' + data; //Sum - data = 0x488
+    long checksum = 0x17 + addrSum + 0xFF + 0xFE + 0x02 + 'D' + '0' + outputIndex + data; //Sum - data = 0x488
+
+    dataToSend[counter++] = 0xFF - (checksum & 0xFF);
+    
+    dataToSend[counter] = '\0';
+
+    
+    for(int i=0; i < counter; i++){
+        xbee1.putc(dataToSend[i]);
+        //printf("%x ", dataToSend[i]);
+    }
+    
+    printf("Sent\n");
+    
+    led3 = 0;
+}
+
+
+
+
+void monitorXbee(){
+    int minimumInputBytes = 20; //20 is minimum number of bytes. 19 for bytes 0-18 and 1 for the checksum! There will be more if there is digital or analog input data
+    static int digitalInBytes = 0;
+    static int analogInBytes = 0;
+    static int totalPacketBytes = 0;
+    int i = 0;
+    static bool lengthCalculated = false;
+    
+    float tempF = 0;
+    
+    
+    if(dataCounter > 0){                // Do we have any input data at all?
+        if(data[0] == 0x7E){            // Valid start byte?
+            if(dataCounter > 3){
+                if(data[3] !=  0x92)
+                    clear = true;
+                else{
+                    if(dataCounter > 18 && lengthCalculated == false){       // Make sure we have both the digital and analog channel masks.
+                        
+                        // Check if there are any pins set as digital input
+                        // The  masking on data[16] is b/c we're only using 3 out of the 8 bits
+                        if((data[16] & 0x1C) | data[17]){
+                            digitalInBytes = 2;
+                        }
+                        
+                        // Check if there are any enabled analog input pins
+                        for(i = 0; i < 4; i++){
+                            if( ((data[18] & 0xF) >> i) & 1 ){
+                                analogInBytes += 2;
+                            }
+                        }
+                        totalPacketBytes = minimumInputBytes + digitalInBytes + analogInBytes;
+                        //printf("%d digital in bytes\t%d analog in bytes\n", digitalInBytes, analogInBytes);
+                        //printf("Have %d of %d total bytes\n", dataCounter, totalPacketBytes);
+                        lengthCalculated = true;
+                    }
+                    
+                    if(lengthCalculated && (dataCounter == totalPacketBytes)){
+                        //Do packet handling here...
+                        
+                        if(analogInBytes){
+                            float tmp;
+                            tmp =  green;
+                            green = blue;
+                            blue = tmp;
+                            
+                            tempF = getAnalogVoltage(0, totalPacketBytes, digitalInBytes) * 100;
+                            printf("Temp %0.2fF\n", tempF);
+                            lcd.cls();
+                            lcd.locate(0,5);
+                            lcd.printf("Remote Temp %0.2fF\n", tempF);
+                            lcd.locate(0,15);
+                            tempF = (float)sensor.read() * (9.0/5.0) + 32;
+                            lcd.printf("Local Temp %.2fF\n", tempF);
+                        }
+                        
+                        if(digitalInBytes){
+                            int digitalMask = (data[16] << 8) | data[17];
+                            int digitalData = (data[19] << 8) | data[20];
+                            for(i = 0; i < 10; i++){
+                                if(digitalMask & 1){
+                                    printf("Digital Input %d is %d\n", i, digitalData & 1);
+                                }
+                                digitalMask = digitalMask >> 1;
+                                digitalData = digitalData >> 1;
+                            }
+                        }
+                        
+                        //printf("*******Temp = %f\n", (data[19] << 8 | data[20])/1023.0 * 120);
+                        
+                        dataCounter = 0;
+                        clear = true;
+                        lengthCalculated = false;
+                        digitalInBytes = 0;
+                        analogInBytes = 0;
+                        totalPacketBytes = 0;
+                    }
+                }
+            }
+        }
+        else{
+            // Not a valid start byte so reset
+            clear = true;
+            lengthCalculated = false;
+        }
+    }
+}
\ No newline at end of file