Home automation using Xbee radios
Dependencies: EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd
Diff: XbeeCommLib.cpp
- 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