Home automation using Xbee radios

Dependencies:   EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd

Link to Notebook Page

Revision:
10:de0be690b3c0
Parent:
9:4b1e3531dd00
Child:
11:03ff417d0d5d
diff -r 4b1e3531dd00 -r de0be690b3c0 main.cpp
--- a/main.cpp	Wed Dec 04 02:35:47 2013 +0000
+++ b/main.cpp	Fri Dec 06 07:05:49 2013 +0000
@@ -9,6 +9,7 @@
 0 = No connection
 1 = Light Control (Digital Output)
 2 = Motion Sense (Digital Input)
+3 = Button (Digital Input)
 
 */
 
@@ -21,6 +22,8 @@
 
 DigitalIn pb(p8);
 DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
 DigitalOut led4(LED4);
 
 Serial xbeeSerial(p9, p10);
@@ -29,25 +32,47 @@
 int dataCounter = 0;
 bool clear = false;
 
+
+int motionDetector0 = 1;
+int motionDetector1 = 1;
+
+int button0 = 1;
+int button1 = 1;
+
 //Create port variables
 float ReadTemperatureSensor0 = 0.0;
 float ReadTemperatureSensor1 = 0.0;
-int ReadMotionDetector0 = 1; //Motion detector is low-active
-int ReadMotionDetector1 = 1; //Motion detector is low-active
+float ReadTemperatureSensor2 = 0.0;
+
+int ReadMotionEnable0 = 0;
+int ReadMotionEnable1 = 0;
+int WriteMotionEnable0 = 0;
+int WriteMotionEnable1 = 0;
+
 int ReadLightSwitch0 = 0;
 int ReadLightSwitch1 = 0;
+int ReadLightSwitch2 = 0;
+
 int WriteLightSwitch0 = 0;
 int WriteLightSwitch1 = 0;
+int WriteLightSwitch2 = 0;
 
 //Make these variables accessible over RPC by attaching them to an RPCVariable
-RPCVariable<float> RPCTemperatureSensor0(&ReadTemperatureSensor0, "TemperatureSensor0");
-RPCVariable<float> RPCTemperatureSensor1(&ReadTemperatureSensor1, "TemperatureSensor1");
-RPCVariable<int> RPCMotionDetector0(&ReadMotionDetector0, "MotionDetector0");
-RPCVariable<int> RPCMotionDetector1(&ReadMotionDetector1, "MotionDetector1");
-RPCVariable<int> RPCReadLightSwitch0(&ReadLightSwitch0, "ReadLightSwitch0");
-RPCVariable<int> RPCReadLightSwitch1(&ReadLightSwitch1, "ReadLightSwitch1");
-RPCVariable<int> RPCWriteLightSwitch0(&WriteLightSwitch0, "WriteLightSwitch0");
-RPCVariable<int> RPCWriteLightSwitch1(&WriteLightSwitch1, "WriteLightSwitch1");
+RPCVariable<float> RPCTemperatureSensor0(&ReadTemperatureSensor0, "Temp0");
+//RPCVariable<float> RPCTemperatureSensor1(&ReadTemperatureSensor1, "Temp1");
+RPCVariable<float> RPCTemperatureSensor2(&ReadTemperatureSensor2, "Temp2");
+
+RPCVariable<int> RPCReadMotionEnable0(&ReadMotionEnable0, "RMotion0");
+RPCVariable<int> RPCReadMotionEnable1(&ReadMotionEnable1, "RMotion1");
+
+RPCVariable<int> RPCWriteMotionEnable0(&WriteMotionEnable0, "WMotion0");
+RPCVariable<int> RPCWriteMotionEnable1(&WriteMotionEnable1, "WMotion1");
+
+RPCVariable<int> RPCReadLightSwitch0(&ReadLightSwitch0, "RLight0");
+RPCVariable<int> RPCReadLightSwitch1(&ReadLightSwitch1, "RLight1");
+
+RPCVariable<int> RPCWriteLightSwitch0(&WriteLightSwitch0, "WLight0");
+RPCVariable<int> RPCWriteLightSwitch1(&WriteLightSwitch1, "WLight1");
 
 EthernetNetIf eth;  
 HTTPServer svr;
@@ -59,17 +84,19 @@
     unsigned int addrLow;         // lower  address of sensor
     unsigned short digitalData;
     unsigned short digitalDataOutput;
+    bool digitalDataValid;
+    bool firstDigitalData;
     int digitalType[10];
     float analogData[4];
     int analogType[4];
     float* analogRpcDataPointer[4];
-    int* digitalOutRpcDataPointer[10];
-    int* digitalInRpcDataPointer[10];
+    int* rpcDataPointer[10];
+    int* writeRpcDataPointer[10];
+    int* prevData[10];
     Timer* timerList[10];
     struct xbee * next;    // pointer to next struct
 };
 
-struct xbee *root;
 
 struct xbee xbeeList[3];
 int xbeeCount = 3;
@@ -77,7 +104,7 @@
 
 
 
-void xbeeSerialCallback() {
+void xbeeSerialHandler() {
     //printf("Xbee\n");
     if(clear){
         dataCounter = 0;
@@ -85,10 +112,10 @@
     }
     if(dataCounter < 500){
         while(xbeeSerial.readable() == true && dataCounter < 500){
-            led4 = 1;
+//            led4 = 1;
             data[dataCounter] = xbeeSerial.getc();
             dataCounter++;
-            led4 = 0;
+//            led4 = 0;
         }
     }
     else{
@@ -102,7 +129,7 @@
 
 int main() {
     
-    //xbeeSerial.attach(&xbeeSerialCallback);
+    //xbeeSerial.attach(&xbeeSerialHandler);
     
     printf("\n\nBeginning Setup\n");
     // Ethernet Setup
@@ -119,56 +146,50 @@
     // Show that the server is ready and listening
     svr.bind(80);
     printf("RPC Server Ready\n");
-  
-    /* This won't change, or we would lose the list in memory */
-    //struct xbee *root;
-    root = (struct xbee *) malloc( sizeof(struct xbee) );
-    root->next = NULL;
-    /* The node root points to has its next pointer equal to a null pointer 
-    set */
-    //struct xbee* xbee1;
-//    struct xbee* xbee2;
-//    struct xbee* xbee3;
-    
-//    printf("Beginning Xbee Radio Struct Setup\n");
-//    xbee1 = addnode(root, 0x0013a200, 0x4079d00b); //Router0
-//    xbee1->analogType[1] = 1;   //Analog Devices TMP36 Temp Sensor
-//    xbee1->digitalType[0] = 1;  //Light control (output)
-//    xbee1->digitalType[3] = 1;  //Motion sensor (input)
-//    xbee1->analogRpcDataPointer[1] = &ReadTemperatureSensor1;
-//    printf("xbee1 setup\n");
+
+
     xbeeList[0].addrHigh = 0x0013a200;
     xbeeList[0].addrLow = 0x4079d00b; //Router0
     xbeeList[0].analogType[1] = 1;   //Analog Devices TMP36 Temp Sensor
     xbeeList[0].digitalType[0] = 1;  //Light control (output)
     xbeeList[0].digitalType[2] = 2;  //Motion sensor (input)
+    xbeeList[0].digitalType[3] = 3;  //Button (input)
     xbeeList[0].analogRpcDataPointer[1] = &ReadTemperatureSensor0;
-//    printf("Xbee0: Storing RPC variable address %d\nStored address is %d\n", &ReadTemperatureSensor1, xbeeList[0].analogRpcDataPointer[1]);
-    xbeeList[0].digitalOutRpcDataPointer[0] = &ReadLightSwitch0;
-    xbeeList[0].digitalInRpcDataPointer[2] = &ReadMotionDetector0;
+    
+    xbeeList[0].rpcDataPointer[0] = &ReadLightSwitch0;
+    xbeeList[0].writeRpcDataPointer[0] = &WriteLightSwitch0;
+    
+    xbeeList[0].rpcDataPointer[2] = &ReadMotionEnable0;
+    xbeeList[0].writeRpcDataPointer[2] = &WriteMotionEnable0;
+    xbeeList[0].prevData[2] = &motionDetector0;
     Timer motionTimer0;
     xbeeList[0].timerList[2] = &motionTimer0;
-    
+    xbeeList[0].prevData[3] = &button0;
     
-//    xbee2 = addnode(root, 0x0013a200, 0x4079d023); //Router1
-//    xbee2->analogType[1] = 1;   //Analog Devices TMP36 Temp Sensor
-//    xbee2->digitalType[0] = 1;  //Light control (output)
-//    printf("xbee2 setup\n");
+
     xbeeList[1].addrHigh = 0x0013a200;
     xbeeList[1].addrLow = 0x4079d023; //Router1
-    xbeeList[1].analogType[1] = 1;   //Analog Devices TMP36 Temp Sensor
     xbeeList[1].digitalType[0] = 1;  //Light control (output)
     xbeeList[1].digitalType[2] = 2;  //Motion sensor (input)
-    xbeeList[1].analogRpcDataPointer[1] = &ReadTemperatureSensor1;
-//    printf("Xbee1: Storing RPC variable address %d\nStored address is %d\n", &ReadTemperatureSensor2, xbeeList[1].analogRpcDataPointer[1]);
-    xbeeList[1].digitalOutRpcDataPointer[0] = &ReadLightSwitch1;
-    xbeeList[1].digitalInRpcDataPointer[2] = &ReadMotionDetector1;
+    xbeeList[1].digitalType[3] = 3;  //Button (input)
+    
+    xbeeList[1].rpcDataPointer[0] = &ReadLightSwitch1;
+    xbeeList[1].writeRpcDataPointer[0] = &WriteLightSwitch1;
+    
+    xbeeList[1].rpcDataPointer[2] = &ReadMotionEnable1;
+    xbeeList[1].writeRpcDataPointer[2] = &WriteMotionEnable1;
+    xbeeList[1].prevData[2] = &motionDetector1;
     Timer motionTimer1;
     xbeeList[1].timerList[2] = &motionTimer1;
     
+    xbeeList[1].prevData[3] = &button1;
     
-    //xbee3 = addnode(root, 0, 3);
-//    xbee3->digitalType[3] = 1;  //Motion sensor (input)
+    
+    xbeeList[2].addrHigh = 0x0013a200;
+    xbeeList[2].addrLow = 0x406874c6; //Router2
+    xbeeList[2].analogType[1] = 1;   //Analog Devices TMP36 Temp Sensor
+    xbeeList[2].analogRpcDataPointer[1] = &ReadTemperatureSensor2;
+
     
     printf("Initialization finished\n\n");
      
@@ -179,10 +200,10 @@
     //Main program loop
     while(true){
         Net::poll();
-        xbeeSerialCallback();
+        xbeeSerialHandler();
         monitorXbee();
         compareDigitalReadWrite();
-        
+        monitorTimers();
         
         // TODO: Poll sensors and reset RPC variables. 
         
@@ -190,26 +211,11 @@
             led1 = !led1;
             tm.start();
             
-            monitorTimers();
+            
         }
     }
 }
 
-struct xbee* addnode(struct xbee* root, unsigned int addrHigh, unsigned int addrLow){
-    struct xbee* node;
-    node = root;
-    
-    if ( node != 0 ) {
-        while ( node->next != 0){
-            node = node->next;
-        }
-    }
-    node = (struct xbee *) malloc( sizeof(struct xbee) );
-    node->next = NULL;
-    node->addrHigh = addrHigh;
-    node->addrLow = addrLow;
-    return node;
-}
 
 
 int getDigitalValue(int i, short pins){
@@ -231,16 +237,14 @@
         default:
             return data;
     }
-//    return(data);
 }
 
 
 
-void digitalInputHandle(struct xbee* root, unsigned int addrHigh, unsigned int addrLow, unsigned short data){
-    //struct xbee* node;
-//    node = root;
-    
-    //printf("Digital input handler: Address: %x %x\nDigital Data = %d\n", addrHigh, addrLow, data);
+void digitalInputHandle(unsigned int addrHigh, unsigned int addrLow, unsigned short data){
+    if(DEBUG)
+        printf("Digital input handler: Address: %x %x\nDigital Data = %d\n", addrHigh, addrLow, data);
+    unsigned short tmp = data;
     
     for(int i = 0; i < xbeeCount; i++){
         if(xbeeList[i].addrHigh == addrHigh && xbeeList[i].addrLow == addrLow){
@@ -249,49 +253,36 @@
             //Place the digital data in the appropriate position in the struct
             xbeeList[i].digitalData = data;
             
-            //Need to update appropriate RPC variables
+            for(int j = 0; j < 10; j++){
+                if(xbeeList[i].digitalType[j] != 2){            //Make sure we don't overwrite the motion enable RPC variable
+                    //Update RPC variable, if present
+                    if(xbeeList[i].rpcDataPointer[j] != NULL){
+                        *xbeeList[i].rpcDataPointer[j] = tmp & 1;
+                        tmp = tmp >> 1;
+                    }
+                }
+            }
+            
+            //if(xbeeList[i].firstDigitalData == false && xbeeList[i].digitalDataValid == false){
+//                xbeeList[i].firstDigitalData = true;
+//            }else if(xbeeList[i].firstDigitalData == true && xbeeList[i].digitalDataValid == false){
+                xbeeList[i].digitalDataValid = true;
+            //    xbeeList[i].firstDigitalData = false;
+//            }
             break;
         }
         if(i == (xbeeCount - 1)){
             printf("No matching addresses found\n");
         }
     }
-    
-    
-    /*
-        Add code here to check for digital input changes.
-        This is important to be able to detect motion
-    */
-    
- 
-    /*if ( node != 0 ) {
-        while ( node->addrHigh != addrHigh){          
-           node = node->next;
-        }
-        while(node->addrLow !=addrLow){
-            node = node->next;
-        }
-    }
-    else {
-        printf("There is no node in the list");
-    }
-    
-    if(node != 0){
-        node->digitalData = data;
-    }
-    else{
-        printf("Node is not in the list");
-    }*/
-    
 }
 
 
-void analogInputHandle(struct xbee* root,unsigned int addrHigh, unsigned int addrLow, int index, float data){
-    //struct xbee* node;
-//    node = root;
+void analogInputHandle(unsigned int addrHigh, unsigned int addrLow, int index, float data){
     float analogData;
     
-    //printf("Analog input handler: Address: %x %x\nAnalog Index = %d  Analog Value = %f\n", addrHigh, addrLow, index, data);
+    if(DEBUG)
+        printf("Analog input handler: Address: %x %x\nAnalog Index = %d  Analog Value = %f\n", addrHigh, addrLow, index, data);
     
     if(index < 0){
         printf("ERROR: Analog input index is negative\n");
@@ -305,133 +296,130 @@
             if(DEBUG)
                 printf("Xbee %d radio address match\n", i);
             
-            //Place the analog data in the appropriate position in the struct
-            analogData = analogInputFormat(data, xbeeList[i].analogType[index]);
-            xbeeList[i].analogData[index] = analogData;
+            if(xbeeList[i].analogType[index]){      //Verify that analog input is actually enabled. If not, ignore the data
+            
+                //Place the analog data in the appropriate position in the struct
+                analogData = analogInputFormat(data, xbeeList[i].analogType[index]);
+                xbeeList[i].analogData[index] = analogData;
             
-            if(xbeeList[i].analogRpcDataPointer[index] != NULL){
-                //Also push the analog data to the RPC variable
-                *xbeeList[i].analogRpcDataPointer[index] = analogData;
-                //printf("Storing value %f into RPC pointer. Value stored is %f\n", analogData, *xbeeList[i].analogRpcDataPointer[index]);
-            }else
-                printf("No valid RPC variable found\n");
+                if(xbeeList[i].analogRpcDataPointer[index] != NULL){
+                    //Also push the analog data to the RPC variable
+                    *xbeeList[i].analogRpcDataPointer[index] = analogData;
+                    //printf("Storing value %f into RPC pointer. Value stored is %f\n", analogData, *xbeeList[i].analogRpcDataPointer[index]);
+                }else
+                    printf("No valid RPC variable found\n");
+            }
             break;
         }
         if(i == (xbeeCount - 1)){
             printf("No matching addresses found\n");
         }
     }
-    
-    
-    
-    
-    
-    
-    
-    /*if ( node != 0 ) {
-        printf("Comparing addrHigh %x to %x\n", node->addrHigh, addrHigh);
-        while ( node->addrHigh != addrHigh){
-            if(node->next != NULL){
-                node = node->next;
-            }else{
-                printf("Reached end of search with no addrHigh match\n");
-                break;
-            }
-            printf("Comparing addrHigh %x to %x\n", node->addrHigh, addrHigh);
-        }
-    
-        printf("Comparing addrLow %x to %x\n", node->addrLow, addrLow);
-        while(node->addrLow != addrLow){
-            if(node->next != NULL){
-                node = node->next;
-            }else{
-                printf("Reached end of search with no addrLow match\n");
-                break;
-            }
-            printf("Comparing addrLow %x to %x\n", node->addrLow, addrLow);
-        }
-    }else {
-        printf("There is no node in the list");
-    }
-    
-    if(node != 0 && index >= 0){
-        //Place the analog data in the appropriate position in the struct
-        analogData = analogInputFormat(data, node->analogType[index]);
-        node->analogData[index] = analogData;
-        
-        if(node->analogRpcDataPointer[index] != NULL){
-            //Also push the analog data to the RPC variable
-            *node->analogRpcDataPointer[index] = analogData;
-            printf("Storing value %f into RPC pointer. Value stored is %f\n", analogData, *node->analogRpcDataPointer[index]);
-        }
-    }
-    else{
-        printf("Node is not in the list");
-    }*/
 }
 
 
-
+/*
+    This is bad code
+    I need to replace this
+    
+    Possibly change name to monitorRpcValues
+*/
 
 void compareDigitalReadWrite(){
     int mask = 1;
     int i, digiIndex;
-    int rpcValue = 0;
-    int digiValue = 0;
+    bool rpcValue = false;
+    bool pinValue = false;
     
     for(i = 0; i < xbeeCount; i++){ //Loop through all xbees
         mask = 1;
         
-        for(digiIndex = 0; digiIndex < 10; digiIndex++){    //Loop through all digital inputs to see if they do not match the corresponding RPC variable
-            
-            if(xbeeList[i].digitalType[digiIndex] == 1){    //Is this digital I/O a light control (digital output)?
+        if(xbeeList[i].digitalDataValid){
+        
+            for(digiIndex = 0; digiIndex < 10; digiIndex++){    //Loop through all digital inputs to see if they do not match the corresponding RPC variable
                 
-                if(*xbeeList[i].digitalOutRpcDataPointer[digiIndex])
-                    rpcValue = 1;
+                if(xbeeList[i].digitalData & mask)
+                    pinValue = true;
                 else
-                    rpcValue = 0;
+                    pinValue = false;
+                
                 
-                if((xbeeList[i].digitalData & mask) != rpcValue){
-                    printf("Xbee%d: Digital output %d = %d doesn't match RPC variable = %d  Updating Xbee...\n", i, digiIndex, xbeeList[i].digitalData & mask, rpcValue);
-                    //This means that the digital output is in the incorrect state
-                    //Therefore write out the RPC state to the radio
-                    digitalWriteXbee(xbeeList[i].addrHigh, xbeeList[i].addrLow, digiIndex, rpcValue);
-                    //printf("Old digitalData = %d\t", xbeeList[i].digitalData);
-                    xbeeList[i].digitalData = (xbeeList[i].digitalData & ~mask) | (rpcValue << digiIndex); //Update the digitalData value with the new output value
-                    //printf("Updated digitalData = %d, mask = %d, rpcValue = %d, digiIndex = %d\n", xbeeList[i].digitalData, mask, rpcValue, digiIndex);
-                }
-                //Otherwise, it matches
-            }
-            
-            if(xbeeList[i].digitalType[digiIndex] == 2){    //Is this digital I/O a motion detector (digital input)?
-                digiValue = (xbeeList[i].digitalData & mask);
-                
-                //Get the RPC value
-                if(*xbeeList[i].digitalInRpcDataPointer[digiIndex])
-                    rpcValue = 1;
-                else
-                    rpcValue = 0;
+                //Check for both the motion enable value changes as well as actual motion sensor activations
+                if(xbeeList[i].digitalType[digiIndex] == 2){    //Is this digital I/O a motion detector (digital input)?
                     
-                if(digiValue != rpcValue){  //This means there has been a state change, either motion detected, or sensor returning to normal
-                    
-                    if(digiValue == 0 || rpcValue == 0){     //Motion detected
-                    
-//                        printf("Motion detected on Xbee%d\n", i);
-                        //if(digiValue)
-//                            rpcValue = 1;
-//                        else
-//                            rpcValue = 0;
-
-                        rpcValue = 1;
-                        *xbeeList[i].digitalInRpcDataPointer[digiIndex] = rpcValue;
-                    
-                        *xbeeList[i].digitalOutRpcDataPointer[0] = 1;   //Turn on the light
-                        xbeeList[i].timerList[digiIndex]->start();       //Restart timer
+                    if(xbeeList[i].writeRpcDataPointer[digiIndex] != NULL && xbeeList[i].rpcDataPointer[digiIndex] != NULL){
+                        
+                        //Determine if user changed value of motion enable. If so, update read RPC variable
+                        if(*xbeeList[i].writeRpcDataPointer[digiIndex] != *xbeeList[i].rpcDataPointer[digiIndex]){  
+                            *xbeeList[i].rpcDataPointer[digiIndex] = *xbeeList[i].writeRpcDataPointer[digiIndex];
+                        }
+                        
+                        if(*xbeeList[i].rpcDataPointer[digiIndex]){ //Is motion enabled?
+                            if(pinValue != *xbeeList[i].prevData[digiIndex]){  //See if the motion detection pin has changed value
+                                if(pinValue == 0){  //Motion has been detected
+                                    //turn on the light & restart timer
+                                    printf("Xbee%d: Motion detected\n", i);
+                                    *xbeeList[i].writeRpcDataPointer[0] = 1;
+                                    xbeeList[i].timerList[digiIndex]->start();
+                                }
+                                //update motion detector value with new state
+                                *xbeeList[i].prevData[digiIndex] = pinValue;
+                            }   
+                        }   
                     }
                 }
                 
+                
+                //Check for button state if present
+                if(xbeeList[i].digitalType[digiIndex] == 3){    //Is this digital I/O a button (digital input)?
+                    if(xbeeList[i].prevData[digiIndex] != NULL){
+                        if(pinValue != *xbeeList[i].prevData[digiIndex]){  //See if the button pin has changed value
+                            if(pinValue == 0){  //Button press detected
+                                
+                                if(xbeeList[i].rpcDataPointer[0] != NULL){
+                                    if(*xbeeList[i].rpcDataPointer[0])
+                                        rpcValue = true;
+                                    else
+                                        rpcValue = false;
+                                }
+                                        
+                                //turn the light on or off
+                                printf("Xbee%d: Button pressed\n", i);
+                                if(rpcValue)
+                                    *xbeeList[i].writeRpcDataPointer[0] = 0;
+                                else
+                                    *xbeeList[i].writeRpcDataPointer[0] = 1;
+                            }
+                            //update value with new state
+                            *xbeeList[i].prevData[digiIndex] = pinValue;
+                        }
+                    }
+                }
+                
+                
+                if(xbeeList[i].digitalType[digiIndex] == 1){    //Is this digital I/O a light control (digital output)?
+                    
+                    if(xbeeList[i].writeRpcDataPointer[digiIndex] != NULL){
+                        if(*xbeeList[i].writeRpcDataPointer[digiIndex])
+                            rpcValue = true;
+                        else
+                            rpcValue = false;
+                        
+                        if(pinValue != rpcValue){
+                            if(DEBUG)
+                                printf("Xbee%d: Writing %d to digital output %d\n", i, rpcValue, digiIndex);
+                            //This means that the digital output is in the incorrect state, Therefore write out the RPC state to the radio
+                            digitalWriteXbee(xbeeList[i].addrHigh, xbeeList[i].addrLow, digiIndex, rpcValue);
+                            xbeeList[i].digitalData = (xbeeList[i].digitalData & ~mask) | (rpcValue << digiIndex); //Update the digitalData value with the new output value                    
+                        }
+                        //Otherwise, it matches
+                        if(xbeeList[i].rpcDataPointer[digiIndex] != NULL)
+                            *xbeeList[i].rpcDataPointer[digiIndex] = rpcValue; //Update the read RPC variable to reflect the actual value
+                    }
+                }
+                
+                mask = mask << 1;
             }
-            mask = mask << 1;
         }
     }
 }
@@ -440,11 +428,17 @@
 
 void monitorTimers(){
 
-    for(int i = 0; i < xbeeCount; i++){                             //Loop through  all xbees
-        for(int digiIndex = 0; digiIndex < 10; digiIndex++){        //Loop through all digital I/O
-            if(xbeeList[i].digitalType[digiIndex] == 2){            //See if I/O is a motion detector input
-                if(xbeeList[i].timerList[digiIndex]->read() > 15){   //Check if timer has expired
-                    *xbeeList[i].digitalOutRpcDataPointer[0] = 0;   //If timer has expired, turn light off
+    for(int i = 0; i < xbeeCount; i++){                                     //Loop through  all xbees
+        for(int digiIndex = 0; digiIndex < 10; digiIndex++){                //Loop through all digital I/O
+            if(xbeeList[i].digitalType[digiIndex] == 2){                    //See if I/O is a motion detector input
+                if(xbeeList[i].rpcDataPointer[digiIndex] != NULL){          //Make sure RPC value is valid
+                    if(*xbeeList[i].rpcDataPointer[digiIndex]){             //Check if motion detection is enabled
+                        if(xbeeList[i].timerList[digiIndex]->read() > 15){  //Check if timer has expired
+                            if(xbeeList[i].rpcDataPointer[0] != NULL)
+                                *xbeeList[i].writeRpcDataPointer[0] = 0;         //If timer has expired, turn light off
+                        }
+                        
+                    }
                 }
             }
         }