Home automation using Xbee radios
Dependencies: EthernetNetIf HTTPServer RPCInterface mbed C12832_lcd
main.cpp@8:e32fcca16102, 2013-12-02 (annotated)
- Committer:
- chrisisthefish
- Date:
- Mon Dec 02 22:25:29 2013 +0000
- Revision:
- 8:e32fcca16102
- Parent:
- 5:ae3cbcf75d78
- Child:
- 9:4b1e3531dd00
Re-added Chris' Xbee communication code.; ; Integrated Hai's digital and analog handling code with the Xbee packet decoder code so that we handle incoming packets correctly.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
chrisisthefish | 8:e32fcca16102 | 1 | /* |
chrisisthefish | 8:e32fcca16102 | 2 | |
chrisisthefish | 8:e32fcca16102 | 3 | Analog Types: |
chrisisthefish | 8:e32fcca16102 | 4 | 0 = No connection |
chrisisthefish | 8:e32fcca16102 | 5 | 1 = Analog Devices TMP36 Temperature Sensor |
chrisisthefish | 8:e32fcca16102 | 6 | |
chrisisthefish | 8:e32fcca16102 | 7 | |
chrisisthefish | 8:e32fcca16102 | 8 | Digital Types: |
chrisisthefish | 8:e32fcca16102 | 9 | 0 = No connection |
chrisisthefish | 8:e32fcca16102 | 10 | 1 = Light Control (Digital Output) |
chrisisthefish | 8:e32fcca16102 | 11 | 2 = Motion Sense (Digital Input) |
chrisisthefish | 8:e32fcca16102 | 12 | |
chrisisthefish | 8:e32fcca16102 | 13 | */ |
chrisisthefish | 8:e32fcca16102 | 14 | |
chrisisthefish | 8:e32fcca16102 | 15 | |
chrisisthefish | 0:c498b8bcfc46 | 16 | #include "mbed.h" |
mmujica6 | 5:ae3cbcf75d78 | 17 | #include "EthernetNetIf.h" |
mmujica6 | 5:ae3cbcf75d78 | 18 | #include "HTTPServer.h" |
mmujica6 | 5:ae3cbcf75d78 | 19 | #include "SerialRPCInterface.h" |
chrisisthefish | 8:e32fcca16102 | 20 | #include "XbeeCommLib.h" |
chrisisthefish | 0:c498b8bcfc46 | 21 | |
hpham33 | 2:9503a713b648 | 22 | DigitalIn pb(p8); |
hpham33 | 2:9503a713b648 | 23 | |
chrisisthefish | 8:e32fcca16102 | 24 | Serial xbeeSerial(p9, p10); |
chrisisthefish | 8:e32fcca16102 | 25 | C12832_LCD lcd; |
chrisisthefish | 8:e32fcca16102 | 26 | |
chrisisthefish | 8:e32fcca16102 | 27 | unsigned char data[500]; |
chrisisthefish | 8:e32fcca16102 | 28 | int dataCounter = 0; |
chrisisthefish | 8:e32fcca16102 | 29 | bool clear = false; |
hpham33 | 2:9503a713b648 | 30 | |
mmujica6 | 5:ae3cbcf75d78 | 31 | //Create port variables |
mmujica6 | 5:ae3cbcf75d78 | 32 | float ReadTemperatureSensor1; |
mmujica6 | 5:ae3cbcf75d78 | 33 | float ReadTemperatureSensor2; |
mmujica6 | 5:ae3cbcf75d78 | 34 | int ReadMotionDetector1; |
mmujica6 | 5:ae3cbcf75d78 | 35 | int ReadMotionDetector2; |
mmujica6 | 5:ae3cbcf75d78 | 36 | int ReadLightSwitch1; |
mmujica6 | 5:ae3cbcf75d78 | 37 | int ReadLightSwitch2; |
mmujica6 | 5:ae3cbcf75d78 | 38 | int WriteLightSwitch1; |
mmujica6 | 5:ae3cbcf75d78 | 39 | int WriteLightSwitch2; |
mmujica6 | 5:ae3cbcf75d78 | 40 | |
mmujica6 | 5:ae3cbcf75d78 | 41 | //Make these variables accessible over RPC by attaching them to an RPCVariable |
mmujica6 | 5:ae3cbcf75d78 | 42 | RPCVariable<float> RPCTemperatureSensor1(&ReadTemperatureSensor1, "TemperatureSensor1"); |
mmujica6 | 5:ae3cbcf75d78 | 43 | RPCVariable<float> RPCTemperatureSensor2(&ReadTemperatureSensor2, "TemperatureSensor2"); |
mmujica6 | 5:ae3cbcf75d78 | 44 | RPCVariable<int> RPCMotionDetector1(&ReadMotionDetector1, "MotionDetector1"); |
mmujica6 | 5:ae3cbcf75d78 | 45 | RPCVariable<int> RPCMotionDetector2(&ReadMotionDetector2, "MotionDetector2"); |
mmujica6 | 5:ae3cbcf75d78 | 46 | RPCVariable<int> RPCReadLightSwitch1(&ReadLightSwitch1, "ReadLightSwitch1"); |
mmujica6 | 5:ae3cbcf75d78 | 47 | RPCVariable<int> RPCReadLightSwitch2(&ReadLightSwitch2, "ReadLightSwitch2"); |
mmujica6 | 5:ae3cbcf75d78 | 48 | RPCVariable<int> RPCWriteLightSwitch1(&WriteLightSwitch1, "WriteLightSwitch1"); |
mmujica6 | 5:ae3cbcf75d78 | 49 | RPCVariable<int> RPCWriteLightSwitch2(&WriteLightSwitch2, "WriteLightSwitch2"); |
mmujica6 | 5:ae3cbcf75d78 | 50 | |
mmujica6 | 5:ae3cbcf75d78 | 51 | EthernetNetIf eth; |
mmujica6 | 5:ae3cbcf75d78 | 52 | HTTPServer svr; |
hpham33 | 2:9503a713b648 | 53 | |
chrisisthefish | 8:e32fcca16102 | 54 | |
chrisisthefish | 8:e32fcca16102 | 55 | |
hpham33 | 2:9503a713b648 | 56 | struct xbee { // radio prototype with addresss, location, pointer to sensor list |
hpham33 | 2:9503a713b648 | 57 | unsigned int addrHigh; // upper 16 bits address of sensor |
hpham33 | 2:9503a713b648 | 58 | unsigned int addrLow; // lower address of sensor |
hpham33 | 2:9503a713b648 | 59 | unsigned short digitalData; |
hpham33 | 2:9503a713b648 | 60 | unsigned short digitalDataOutput; |
hpham33 | 2:9503a713b648 | 61 | int digitalType[10]; |
hpham33 | 2:9503a713b648 | 62 | float analogData[4]; |
hpham33 | 2:9503a713b648 | 63 | int analogType[4]; |
hpham33 | 2:9503a713b648 | 64 | struct xbee * next; // pointer to next struct |
hpham33 | 2:9503a713b648 | 65 | }; |
hpham33 | 2:9503a713b648 | 66 | |
chrisisthefish | 8:e32fcca16102 | 67 | struct xbee *root; |
chrisisthefish | 8:e32fcca16102 | 68 | |
chrisisthefish | 8:e32fcca16102 | 69 | |
chrisisthefish | 8:e32fcca16102 | 70 | |
chrisisthefish | 8:e32fcca16102 | 71 | |
chrisisthefish | 8:e32fcca16102 | 72 | void xbeeSerialCallback() { |
chrisisthefish | 8:e32fcca16102 | 73 | if(clear){ |
chrisisthefish | 8:e32fcca16102 | 74 | dataCounter = 0; |
chrisisthefish | 8:e32fcca16102 | 75 | clear = false; |
chrisisthefish | 8:e32fcca16102 | 76 | } |
chrisisthefish | 8:e32fcca16102 | 77 | if(dataCounter < 500){ |
chrisisthefish | 8:e32fcca16102 | 78 | while(xbeeSerial.readable() == true && dataCounter < 500){ |
chrisisthefish | 8:e32fcca16102 | 79 | data[dataCounter] = xbeeSerial.getc(); |
chrisisthefish | 8:e32fcca16102 | 80 | dataCounter++; |
chrisisthefish | 8:e32fcca16102 | 81 | } |
chrisisthefish | 8:e32fcca16102 | 82 | } |
chrisisthefish | 8:e32fcca16102 | 83 | else{ |
chrisisthefish | 8:e32fcca16102 | 84 | printf("Serial data buffer overflow. Resetting buffer...\n"); |
chrisisthefish | 8:e32fcca16102 | 85 | dataCounter = 0; |
chrisisthefish | 8:e32fcca16102 | 86 | data[dataCounter] = xbeeSerial.getc(); |
chrisisthefish | 8:e32fcca16102 | 87 | } |
chrisisthefish | 8:e32fcca16102 | 88 | } |
chrisisthefish | 8:e32fcca16102 | 89 | |
chrisisthefish | 8:e32fcca16102 | 90 | |
chrisisthefish | 0:c498b8bcfc46 | 91 | |
chrisisthefish | 0:c498b8bcfc46 | 92 | int main() { |
chrisisthefish | 8:e32fcca16102 | 93 | |
chrisisthefish | 8:e32fcca16102 | 94 | xbeeSerial.attach(&xbeeSerialCallback); |
chrisisthefish | 8:e32fcca16102 | 95 | |
chrisisthefish | 8:e32fcca16102 | 96 | // Ethernet Setup |
chrisisthefish | 8:e32fcca16102 | 97 | EthernetErr ethErr = eth.setup(); |
chrisisthefish | 8:e32fcca16102 | 98 | if(ethErr) |
chrisisthefish | 8:e32fcca16102 | 99 | { |
mmujica6 | 5:ae3cbcf75d78 | 100 | printf("Error %d in setup.\n", ethErr); |
mmujica6 | 5:ae3cbcf75d78 | 101 | return -1; |
chrisisthefish | 8:e32fcca16102 | 102 | } |
chrisisthefish | 8:e32fcca16102 | 103 | printf("Setup OK\n"); |
chrisisthefish | 8:e32fcca16102 | 104 | |
chrisisthefish | 8:e32fcca16102 | 105 | // Add RPCHandler |
chrisisthefish | 8:e32fcca16102 | 106 | svr.addHandler<RPCHandler>("/rpc"); |
chrisisthefish | 8:e32fcca16102 | 107 | |
chrisisthefish | 8:e32fcca16102 | 108 | // Show that the server is ready and listening |
chrisisthefish | 8:e32fcca16102 | 109 | svr.bind(80); |
chrisisthefish | 8:e32fcca16102 | 110 | printf("Listening...\n"); |
mmujica6 | 5:ae3cbcf75d78 | 111 | |
chrisisthefish | 8:e32fcca16102 | 112 | /* This won't change, or we would lose the list in memory */ |
chrisisthefish | 8:e32fcca16102 | 113 | //struct xbee *root; |
hpham33 | 2:9503a713b648 | 114 | root->next = NULL; |
hpham33 | 2:9503a713b648 | 115 | /* The node root points to has its next pointer equal to a null pointer |
chrisisthefish | 8:e32fcca16102 | 116 | set */ |
chrisisthefish | 8:e32fcca16102 | 117 | struct xbee* xbee1; |
chrisisthefish | 8:e32fcca16102 | 118 | struct xbee* xbee2; |
chrisisthefish | 8:e32fcca16102 | 119 | struct xbee* xbee3; |
chrisisthefish | 8:e32fcca16102 | 120 | |
chrisisthefish | 8:e32fcca16102 | 121 | xbee1 = addnode(root, 0x0013a200, 0x4079d00b); //Router0 |
chrisisthefish | 8:e32fcca16102 | 122 | xbee1->analogType[1] = 1; //Analog Devices TMP36 Temp Sensor |
chrisisthefish | 8:e32fcca16102 | 123 | xbee1->digitalType[0] = 1; //Light control (output) |
chrisisthefish | 8:e32fcca16102 | 124 | xbee1->digitalType[3] = 1; //Motion sensor (input) |
chrisisthefish | 8:e32fcca16102 | 125 | |
chrisisthefish | 8:e32fcca16102 | 126 | xbee2 = addnode(root, 0x0013a200, 0x4079d023); //Router1 |
chrisisthefish | 8:e32fcca16102 | 127 | xbee2->analogType[1] = 1; //Analog Devices TMP36 Temp Sensor |
chrisisthefish | 8:e32fcca16102 | 128 | xbee2->digitalType[0] = 1; //Light control (output) |
chrisisthefish | 8:e32fcca16102 | 129 | |
chrisisthefish | 8:e32fcca16102 | 130 | xbee3 = addnode(root, 0, 3); |
chrisisthefish | 8:e32fcca16102 | 131 | xbee3->digitalType[3] = 1; //Motion sensor (input) |
chrisisthefish | 8:e32fcca16102 | 132 | |
mmujica6 | 5:ae3cbcf75d78 | 133 | |
chrisisthefish | 8:e32fcca16102 | 134 | // TODO: Read sensors and set RPC variables to initial values |
mmujica6 | 5:ae3cbcf75d78 | 135 | |
chrisisthefish | 8:e32fcca16102 | 136 | //Main program loop |
chrisisthefish | 8:e32fcca16102 | 137 | while(true){ |
chrisisthefish | 8:e32fcca16102 | 138 | Net::poll(); |
chrisisthefish | 8:e32fcca16102 | 139 | monitorXbee(); |
chrisisthefish | 8:e32fcca16102 | 140 | // TODO: Poll sensors and reset RPC variables. |
chrisisthefish | 8:e32fcca16102 | 141 | } |
hpham33 | 2:9503a713b648 | 142 | } |
hpham33 | 2:9503a713b648 | 143 | |
chrisisthefish | 8:e32fcca16102 | 144 | struct xbee* addnode(struct xbee* root, unsigned int addrhigh, unsigned int addrlow){ |
chrisisthefish | 8:e32fcca16102 | 145 | struct xbee* node; |
chrisisthefish | 8:e32fcca16102 | 146 | node = root; |
chrisisthefish | 8:e32fcca16102 | 147 | |
hpham33 | 2:9503a713b648 | 148 | if ( node != 0 ) { |
chrisisthefish | 8:e32fcca16102 | 149 | while ( node->next != 0){ |
chrisisthefish | 8:e32fcca16102 | 150 | node = node->next; |
hpham33 | 2:9503a713b648 | 151 | } |
chrisisthefish | 0:c498b8bcfc46 | 152 | } |
chrisisthefish | 8:e32fcca16102 | 153 | node = (struct xbee *) malloc( sizeof(struct xbee) ); |
chrisisthefish | 8:e32fcca16102 | 154 | node->next = NULL; |
chrisisthefish | 8:e32fcca16102 | 155 | node->addrHigh = addrhigh; |
chrisisthefish | 8:e32fcca16102 | 156 | node->addrLow = addrlow; |
chrisisthefish | 8:e32fcca16102 | 157 | return node; |
hpham33 | 2:9503a713b648 | 158 | } |
chrisisthefish | 8:e32fcca16102 | 159 | |
chrisisthefish | 8:e32fcca16102 | 160 | |
chrisisthefish | 8:e32fcca16102 | 161 | int getDigitalValue(int i, short pins){ |
chrisisthefish | 8:e32fcca16102 | 162 | return ((pins>>i)&1); |
hpham33 | 2:9503a713b648 | 163 | } |
hpham33 | 2:9503a713b648 | 164 | |
chrisisthefish | 8:e32fcca16102 | 165 | |
chrisisthefish | 8:e32fcca16102 | 166 | float analogInputFormat(float data, int type){ |
chrisisthefish | 8:e32fcca16102 | 167 | // Incoming data is in volts: |
chrisisthefish | 8:e32fcca16102 | 168 | // Example: data = 0.7 -> 0.7 Volts |
chrisisthefish | 8:e32fcca16102 | 169 | |
chrisisthefish | 8:e32fcca16102 | 170 | switch (type){ |
chrisisthefish | 8:e32fcca16102 | 171 | case 1: //Analog Devices TMP36 Temp Sensor: 1 deg F per 10mV |
chrisisthefish | 8:e32fcca16102 | 172 | return data * 100; //Multiply voltage by 100 to get Temperature |
chrisisthefish | 8:e32fcca16102 | 173 | case 2: |
chrisisthefish | 8:e32fcca16102 | 174 | return data; |
chrisisthefish | 8:e32fcca16102 | 175 | case 3: |
chrisisthefish | 8:e32fcca16102 | 176 | return data; |
chrisisthefish | 8:e32fcca16102 | 177 | default: |
chrisisthefish | 8:e32fcca16102 | 178 | return data; |
chrisisthefish | 8:e32fcca16102 | 179 | } |
chrisisthefish | 8:e32fcca16102 | 180 | // return(data); |
chrisisthefish | 8:e32fcca16102 | 181 | } |
chrisisthefish | 8:e32fcca16102 | 182 | |
chrisisthefish | 8:e32fcca16102 | 183 | |
chrisisthefish | 8:e32fcca16102 | 184 | |
chrisisthefish | 8:e32fcca16102 | 185 | void digitalInputHandle(struct xbee* root, unsigned int addrhigh, unsigned int addrlow, unsigned short data){ |
chrisisthefish | 8:e32fcca16102 | 186 | struct xbee* node; |
chrisisthefish | 8:e32fcca16102 | 187 | node = root; |
hpham33 | 2:9503a713b648 | 188 | |
hpham33 | 2:9503a713b648 | 189 | if ( node != 0 ) { |
chrisisthefish | 8:e32fcca16102 | 190 | while ( node->addrHigh != addrhigh){ |
hpham33 | 2:9503a713b648 | 191 | node = node->next; |
hpham33 | 3:c4bec8e7cc07 | 192 | } |
chrisisthefish | 8:e32fcca16102 | 193 | while(node->addrLow !=addrlow){ |
chrisisthefish | 8:e32fcca16102 | 194 | node = node->next; |
chrisisthefish | 8:e32fcca16102 | 195 | } |
hpham33 | 2:9503a713b648 | 196 | } |
hpham33 | 4:6091cb494e73 | 197 | else { |
chrisisthefish | 8:e32fcca16102 | 198 | printf("There is no node in the list"); |
hpham33 | 4:6091cb494e73 | 199 | } |
chrisisthefish | 8:e32fcca16102 | 200 | |
chrisisthefish | 8:e32fcca16102 | 201 | if(node != 0){ |
chrisisthefish | 8:e32fcca16102 | 202 | node->digitalData = data; |
hpham33 | 4:6091cb494e73 | 203 | } |
hpham33 | 4:6091cb494e73 | 204 | else{ |
chrisisthefish | 8:e32fcca16102 | 205 | printf("Node is not in the list"); |
chrisisthefish | 8:e32fcca16102 | 206 | } |
chrisisthefish | 8:e32fcca16102 | 207 | |
chrisisthefish | 8:e32fcca16102 | 208 | |
chrisisthefish | 8:e32fcca16102 | 209 | /* |
chrisisthefish | 8:e32fcca16102 | 210 | Add code here to check for digital input changes. |
chrisisthefish | 8:e32fcca16102 | 211 | This is important to be able to detect motion |
chrisisthefish | 8:e32fcca16102 | 212 | */ |
chrisisthefish | 8:e32fcca16102 | 213 | |
chrisisthefish | 8:e32fcca16102 | 214 | |
hpham33 | 2:9503a713b648 | 215 | } |
chrisisthefish | 8:e32fcca16102 | 216 | |
chrisisthefish | 8:e32fcca16102 | 217 | |
hpham33 | 2:9503a713b648 | 218 | void analogInputHandle(struct xbee* root,unsigned int addrhigh, unsigned int addrlow, int index, float data){ |
chrisisthefish | 8:e32fcca16102 | 219 | struct xbee* node; |
chrisisthefish | 8:e32fcca16102 | 220 | node = root; |
chrisisthefish | 8:e32fcca16102 | 221 | |
chrisisthefish | 8:e32fcca16102 | 222 | if(index < 0){ |
chrisisthefish | 8:e32fcca16102 | 223 | printf("ERROR: Analog input index is negative\n"); |
chrisisthefish | 8:e32fcca16102 | 224 | } |
chrisisthefish | 8:e32fcca16102 | 225 | |
hpham33 | 2:9503a713b648 | 226 | if ( node != 0 ) { |
chrisisthefish | 8:e32fcca16102 | 227 | while ( node->addrHigh != addrhigh){ |
chrisisthefish | 8:e32fcca16102 | 228 | node = node->next; |
chrisisthefish | 8:e32fcca16102 | 229 | } |
chrisisthefish | 8:e32fcca16102 | 230 | |
chrisisthefish | 8:e32fcca16102 | 231 | while(node->addrLow != addrlow){ |
chrisisthefish | 8:e32fcca16102 | 232 | node = node->next; |
hpham33 | 2:9503a713b648 | 233 | } |
hpham33 | 4:6091cb494e73 | 234 | }else { |
chrisisthefish | 8:e32fcca16102 | 235 | printf("There is no node in the list"); |
hpham33 | 2:9503a713b648 | 236 | } |
chrisisthefish | 8:e32fcca16102 | 237 | |
chrisisthefish | 8:e32fcca16102 | 238 | if(node != 0 && index >= 0){ |
chrisisthefish | 8:e32fcca16102 | 239 | node->analogData[index] = analogInputFormat(data, node->analogType[index]); |
chrisisthefish | 8:e32fcca16102 | 240 | } |
chrisisthefish | 8:e32fcca16102 | 241 | else{ |
chrisisthefish | 8:e32fcca16102 | 242 | printf("Node is not in the list"); |
chrisisthefish | 8:e32fcca16102 | 243 | } |
hpham33 | 2:9503a713b648 | 244 | } |