Home automation using Xbee radios
Dependencies: EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd
XbeeCommLib.cpp
- Committer:
- chrisisthefish
- Date:
- 2013-12-09
- Revision:
- 11:03ff417d0d5d
- Parent:
- 10:de0be690b3c0
File content as of revision 11:03ff417d0d5d:
#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; } } }