Home automation using Xbee radios

Dependencies:   EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd

Link to Notebook Page

XbeeCommLib.cpp

Committer:
chrisisthefish
Date:
2013-12-06
Revision:
10:de0be690b3c0
Parent:
9:4b1e3531dd00

File content as of revision 10:de0be690b3c0:

#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;
    
    if(DEBUG)
        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]);
    }
    
    if(DEBUG)
        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?
            led4 = 1;
            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...
                        
                        /*printf("Printing packet - %d bytes:\n", dataCounter);
                        for(i = 0; i < dataCounter; i++){
                            printf("%x\n", data[i]);
                        }
                        printf("End of packet\n");*/
                        
                        
                        //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(DEBUG)
                            printf("\n\nReceived packet from %x %x\n", addrHigh, addrLow);
                        
                        if(analogInBytes){
                            //if(DEBUG)
//                                printf("Analog Data Present\n");
                            //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
//                            printf("Analog inputs ");
                            for(i = 0; i < 4; i++){
                                if( ((data[18] & 0xF) >> i) & 1 ){
//                                    printf("%d ", i);
                                    analogPortNumbers[analogCount] = i;
                                    analogCount++;
                                }
                            }
//                            printf("active\n");
                            
                            if(DEBUG)
                                printf("%d Ananlog inputs total\n", analogCount);
                            
                            //Decode analog data and push into appropriate struct
                            for(i = 0; i < analogCount; i++){
                                analogData = getAnalogVoltage(startingPacket, i, totalPacketBytes);
                                if(DEBUG)
                                    printf("Analog Data Input Index %d = %f\n", analogPortNumbers[i], analogData);
                                analogInputHandle(addrHigh, addrLow, analogPortNumbers[i], analogData);
                            }
                        }
                        
                        if(digitalInBytes){
                            //if(DEBUG)
//                                printf("Digital Data Present\n");
//                            unsigned short digitalMask = (data[16] << 8) | data[17];
                            unsigned short digitalData = (data[19] << 8) | data[20];
                            
                            if(digitalData < 1024){
                                digitalInputHandle(addrHigh, addrLow, digitalData);
                                //printf("Digital Mask = %x\nDigital Data = %x\n", digitalMask, digitalData);
                            }
                        }
                        
                        dataCounter = 0;
                        clear = true;
                        lengthCalculated = false;
                        digitalInBytes = 0;
                        analogInBytes = 0;
                        totalPacketBytes = 0;
                        led4 = 0;
                    }
                }
            }
        }
        else{
            // Not a valid start byte so reset
            clear = true;
            lengthCalculated = false;
            dataCounter = 0;
            led4 = 0;
        }
    }
}