Home automation using Xbee radios

Dependencies:   EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd

Link to Notebook Page

XbeeCommLib.cpp

Committer:
chrisisthefish
Date:
2013-11-26
Revision:
7:15cbbbe6105c

File content as of revision 7:15cbbbe6105c:


#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;
        }
    }
}