Home automation using Xbee radios

Dependencies:   EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd

Link to Notebook Page

Revision:
8:e32fcca16102
Child:
9:4b1e3531dd00
diff -r ae3cbcf75d78 -r e32fcca16102 XbeeCommLib.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XbeeCommLib.cpp	Mon Dec 02 22:25:29 2013 +0000
@@ -0,0 +1,176 @@
+#include "XbeeCommLib.h"
+
+
+float getAnalogVoltage(int startingPacket, int analogIndex, int totalPacketBytes){
+    int dataIndex = startingPacket + analogIndex*2;
+    if(dataIndex > (totalPacketBytes+1)) //+1 because each analog sample is 2 bytes
+        return 0;
+    else
+        return ((data[dataIndex] << 8 | data[dataIndex  + 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++){
+        xbeeSerial.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 analogData = 0;
+    int addrHigh = 0;
+    int addrLow = 0;
+    int startingPacket = 0;
+    int analogPortNumbers[4];
+    int analogCount = 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...
+                        
+                        //Determine source address
+                        for(i = 0; i < 4; i++){
+                            addrHigh = addrHigh | (data[4 + i] << (3-i)*8);
+                            addrLow = addrLow | (data[8 + i] << (3-i)*8);
+                            
+                            //Hijack this loop to initialize the analogPortNumbers array
+                            analogPortNumbers[i] = -1;
+                        }    
+                        
+                        if(analogInBytes){
+                            //Figure out where the analog bytes start
+                            if(digitalInBytes)
+                                startingPacket = 21;
+                            else
+                                startingPacket = 19;
+                            
+                            //Determine how many analog inputs are active, and which pins they use
+                            for(i = 0; i < 4; i++){
+                                if( ((data[18] & 0xF) >> i) & 1 ){
+                                    analogPortNumbers[analogCount] = i;
+                                    analogCount++;
+                                }
+                            }
+                            
+                            //Decode analog data and push into appropriate struct
+                            for(i = 0; i < analogCount; i++){
+                                analogData = getAnalogVoltage(startingPacket, i, totalPacketBytes);
+                                analogInputHandle(root, addrHigh, addrLow, analogPortNumbers[i], analogData);
+                            }
+                        }
+                        
+                        if(digitalInBytes){
+                            //unsigned short digitalMask = (data[16] << 8) | data[17];
+                            unsigned short digitalData = (data[19] << 8) | data[20];
+                            
+                            digitalInputHandle(root, addrHigh, addrLow, digitalData);
+                        }
+                        
+                        dataCounter = 0;
+                        clear = true;
+                        lengthCalculated = false;
+                        digitalInBytes = 0;
+                        analogInBytes = 0;
+                        totalPacketBytes = 0;
+                    }
+                }
+            }
+        }
+        else{
+            // Not a valid start byte so reset
+            clear = true;
+            lengthCalculated = false;
+            dataCounter = 0;
+        }
+    }
+}
\ No newline at end of file