Code for the IOT wirless sensors demo. Including the NFC communications for setting up the sensor.
Dependencies: AppNearMe_MuNFC_PN532 RHT03 mbed xbee_lib
main.cpp@0:c3b76a463a8b, 2012-08-30 (annotated)
- Committer:
- tristanjph
- Date:
- Thu Aug 30 12:43:33 2012 +0000
- Revision:
- 0:c3b76a463a8b
First commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tristanjph | 0:c3b76a463a8b | 1 | /* Copyright (c) 2012 Tristan Hughes, MIT License |
tristanjph | 0:c3b76a463a8b | 2 | * |
tristanjph | 0:c3b76a463a8b | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
tristanjph | 0:c3b76a463a8b | 4 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
tristanjph | 0:c3b76a463a8b | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
tristanjph | 0:c3b76a463a8b | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
tristanjph | 0:c3b76a463a8b | 7 | * furnished to do so, subject to the following conditions: |
tristanjph | 0:c3b76a463a8b | 8 | * |
tristanjph | 0:c3b76a463a8b | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
tristanjph | 0:c3b76a463a8b | 10 | * substantial portions of the Software. |
tristanjph | 0:c3b76a463a8b | 11 | * |
tristanjph | 0:c3b76a463a8b | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
tristanjph | 0:c3b76a463a8b | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
tristanjph | 0:c3b76a463a8b | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
tristanjph | 0:c3b76a463a8b | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
tristanjph | 0:c3b76a463a8b | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
tristanjph | 0:c3b76a463a8b | 17 | */ |
tristanjph | 0:c3b76a463a8b | 18 | |
tristanjph | 0:c3b76a463a8b | 19 | /*------INCLUDES-----*/ |
tristanjph | 0:c3b76a463a8b | 20 | #include "mbed.h" |
tristanjph | 0:c3b76a463a8b | 21 | #include "RHT03.h" |
tristanjph | 0:c3b76a463a8b | 22 | #include "MuNFC.h" |
tristanjph | 0:c3b76a463a8b | 23 | #include "xbee.h" |
tristanjph | 0:c3b76a463a8b | 24 | |
tristanjph | 0:c3b76a463a8b | 25 | /*------Definitions----*/ |
tristanjph | 0:c3b76a463a8b | 26 | #define SLEEP_TIME 30 //Time to wait between reading and sending data |
tristanjph | 0:c3b76a463a8b | 27 | #define SENSOR_PACKET 2 //Tells the NFC app device is a sensor |
tristanjph | 0:c3b76a463a8b | 28 | #define LOCATION_PRECISION 100000 //The accuracy of the devices location |
tristanjph | 0:c3b76a463a8b | 29 | |
tristanjph | 0:c3b76a463a8b | 30 | /*------Pins------*/ |
tristanjph | 0:c3b76a463a8b | 31 | DigitalOut red(p30); |
tristanjph | 0:c3b76a463a8b | 32 | DigitalOut green(p29); |
tristanjph | 0:c3b76a463a8b | 33 | DigitalOut pswitch(p21); |
tristanjph | 0:c3b76a463a8b | 34 | AnalogIn light(p15); |
tristanjph | 0:c3b76a463a8b | 35 | DigitalIn pir(p16); |
tristanjph | 0:c3b76a463a8b | 36 | DigitalIn setup(p14); |
tristanjph | 0:c3b76a463a8b | 37 | DigitalOut led_alive(LED1); |
tristanjph | 0:c3b76a463a8b | 38 | DigitalOut led_progress(LED2); |
tristanjph | 0:c3b76a463a8b | 39 | DigitalOut led_ok(LED3); |
tristanjph | 0:c3b76a463a8b | 40 | DigitalOut led_failed(LED4); |
tristanjph | 0:c3b76a463a8b | 41 | Serial pc1(USBTX, USBRX); |
tristanjph | 0:c3b76a463a8b | 42 | |
tristanjph | 0:c3b76a463a8b | 43 | /*-----Globals-----*/ |
tristanjph | 0:c3b76a463a8b | 44 | char send_data[202]; |
tristanjph | 0:c3b76a463a8b | 45 | int cur_temp,cur_hum,device_serial[8]; |
tristanjph | 0:c3b76a463a8b | 46 | float cur_light; |
tristanjph | 0:c3b76a463a8b | 47 | int cur_pir; |
tristanjph | 0:c3b76a463a8b | 48 | int nfc_setup = 0; |
tristanjph | 0:c3b76a463a8b | 49 | Ticker val_check; |
tristanjph | 0:c3b76a463a8b | 50 | |
tristanjph | 0:c3b76a463a8b | 51 | /*-----Class Init-----*/ |
tristanjph | 0:c3b76a463a8b | 52 | MuNFC nfc("000000053Tfi0RwY", 1, p11, p12, p13, p19, p18); |
tristanjph | 0:c3b76a463a8b | 53 | xbee xbee_1(p9,p10,p25); |
tristanjph | 0:c3b76a463a8b | 54 | |
tristanjph | 0:c3b76a463a8b | 55 | |
tristanjph | 0:c3b76a463a8b | 56 | /*-----A class of useful functions for use with NFC----*/ |
tristanjph | 0:c3b76a463a8b | 57 | class sr_configuration |
tristanjph | 0:c3b76a463a8b | 58 | { |
tristanjph | 0:c3b76a463a8b | 59 | public: |
tristanjph | 0:c3b76a463a8b | 60 | sr_configuration( const uint8_t* ieee_address ) { |
tristanjph | 0:c3b76a463a8b | 61 | memcpy( this->ieee_address, ieee_address, 8 ); |
tristanjph | 0:c3b76a463a8b | 62 | } |
tristanjph | 0:c3b76a463a8b | 63 | |
tristanjph | 0:c3b76a463a8b | 64 | void hexPrint(const char* name, uint8_t* buf, int len) { |
tristanjph | 0:c3b76a463a8b | 65 | printf("%s: ", name); |
tristanjph | 0:c3b76a463a8b | 66 | for(int i = 0; i < len; i++) { |
tristanjph | 0:c3b76a463a8b | 67 | printf("%02x ", buf[i]); |
tristanjph | 0:c3b76a463a8b | 68 | } |
tristanjph | 0:c3b76a463a8b | 69 | printf("\r\n"); |
tristanjph | 0:c3b76a463a8b | 70 | } |
tristanjph | 0:c3b76a463a8b | 71 | |
tristanjph | 0:c3b76a463a8b | 72 | void prettyPrint() { |
tristanjph | 0:c3b76a463a8b | 73 | printf("Name: %s\r\n", name); |
tristanjph | 0:c3b76a463a8b | 74 | hexPrint("IEEE Address", ieee_address, 8); |
tristanjph | 0:c3b76a463a8b | 75 | hexPrint("Gateway IEEE Address", gw_ieee_address, 8); |
tristanjph | 0:c3b76a463a8b | 76 | hexPrint("Gateway Security Key", gw_security_key, 16); |
tristanjph | 0:c3b76a463a8b | 77 | printf("Location: Lat.: %d.%05d; Long.: %d.%05d\r\n", |
tristanjph | 0:c3b76a463a8b | 78 | location[0]/LOCATION_PRECISION, (location[0] - (location[0]/LOCATION_PRECISION)*LOCATION_PRECISION ), |
tristanjph | 0:c3b76a463a8b | 79 | location[1]/LOCATION_PRECISION, (location[1] - (location[1]/LOCATION_PRECISION)*LOCATION_PRECISION ) ); |
tristanjph | 0:c3b76a463a8b | 80 | } |
tristanjph | 0:c3b76a463a8b | 81 | |
tristanjph | 0:c3b76a463a8b | 82 | char name[24]; |
tristanjph | 0:c3b76a463a8b | 83 | uint8_t ieee_address[8]; |
tristanjph | 0:c3b76a463a8b | 84 | uint8_t gw_ieee_address[8]; |
tristanjph | 0:c3b76a463a8b | 85 | uint8_t gw_security_key[16]; |
tristanjph | 0:c3b76a463a8b | 86 | uint32_t location[2]; //lat*100000, long*100000 |
tristanjph | 0:c3b76a463a8b | 87 | }; |
tristanjph | 0:c3b76a463a8b | 88 | |
tristanjph | 0:c3b76a463a8b | 89 | const uint8_t address[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //setting the IEEE address to 0 |
tristanjph | 0:c3b76a463a8b | 90 | sr_configuration config(address); |
tristanjph | 0:c3b76a463a8b | 91 | |
tristanjph | 0:c3b76a463a8b | 92 | //Encode call back for NFC |
tristanjph | 0:c3b76a463a8b | 93 | void encode_cb(TLVList* tlv, void *) |
tristanjph | 0:c3b76a463a8b | 94 | { |
tristanjph | 0:c3b76a463a8b | 95 | tlv->putUInt8( SENSOR_PACKET ); //First uint8_t is packet type |
tristanjph | 0:c3b76a463a8b | 96 | tlv->putString(config.name); |
tristanjph | 0:c3b76a463a8b | 97 | tlv->putArray(config.ieee_address, 8); |
tristanjph | 0:c3b76a463a8b | 98 | tlv->putArray(config.gw_ieee_address, 8); |
tristanjph | 0:c3b76a463a8b | 99 | tlv->putArray(config.gw_security_key, 16); |
tristanjph | 0:c3b76a463a8b | 100 | tlv->putUInt32(config.location[0]); |
tristanjph | 0:c3b76a463a8b | 101 | tlv->putUInt32(config.location[1]); |
tristanjph | 0:c3b76a463a8b | 102 | } |
tristanjph | 0:c3b76a463a8b | 103 | |
tristanjph | 0:c3b76a463a8b | 104 | //Decode callback for NFC |
tristanjph | 0:c3b76a463a8b | 105 | void decode_cb(TLVList* tlv, void *) |
tristanjph | 0:c3b76a463a8b | 106 | { |
tristanjph | 0:c3b76a463a8b | 107 | TLVList::TLVType t; |
tristanjph | 0:c3b76a463a8b | 108 | |
tristanjph | 0:c3b76a463a8b | 109 | if(tlv->getNext() != UINT8) { |
tristanjph | 0:c3b76a463a8b | 110 | return; |
tristanjph | 0:c3b76a463a8b | 111 | } |
tristanjph | 0:c3b76a463a8b | 112 | if(tlv->getUInt8() == SENSOR_PACKET) { //First uint8_t is packet type |
tristanjph | 0:c3b76a463a8b | 113 | if(tlv->getNext() != STRING) { |
tristanjph | 0:c3b76a463a8b | 114 | return; |
tristanjph | 0:c3b76a463a8b | 115 | } |
tristanjph | 0:c3b76a463a8b | 116 | tlv->getString(config.name, 23); |
tristanjph | 0:c3b76a463a8b | 117 | |
tristanjph | 0:c3b76a463a8b | 118 | if(tlv->getNext() != UINT8_ARRAY) { |
tristanjph | 0:c3b76a463a8b | 119 | return; |
tristanjph | 0:c3b76a463a8b | 120 | } |
tristanjph | 0:c3b76a463a8b | 121 | //tlv->getArray(config.ieee_address, 8); //IEEE address is ignored |
tristanjph | 0:c3b76a463a8b | 122 | |
tristanjph | 0:c3b76a463a8b | 123 | if(tlv->getNext() != UINT8_ARRAY) { |
tristanjph | 0:c3b76a463a8b | 124 | return; |
tristanjph | 0:c3b76a463a8b | 125 | } |
tristanjph | 0:c3b76a463a8b | 126 | tlv->getArray(config.gw_ieee_address, 8); |
tristanjph | 0:c3b76a463a8b | 127 | |
tristanjph | 0:c3b76a463a8b | 128 | if(tlv->getNext() != UINT8_ARRAY) { |
tristanjph | 0:c3b76a463a8b | 129 | return; |
tristanjph | 0:c3b76a463a8b | 130 | } |
tristanjph | 0:c3b76a463a8b | 131 | tlv->getArray(config.gw_security_key, 16); |
tristanjph | 0:c3b76a463a8b | 132 | |
tristanjph | 0:c3b76a463a8b | 133 | t = tlv->getNext(); |
tristanjph | 0:c3b76a463a8b | 134 | if( (t != UINT32) && (t != UINT8) ) { |
tristanjph | 0:c3b76a463a8b | 135 | return; |
tristanjph | 0:c3b76a463a8b | 136 | } |
tristanjph | 0:c3b76a463a8b | 137 | config.location[0] = tlv->getUInt32(); |
tristanjph | 0:c3b76a463a8b | 138 | |
tristanjph | 0:c3b76a463a8b | 139 | t = tlv->getNext(); |
tristanjph | 0:c3b76a463a8b | 140 | if( (t != UINT32) && (t != UINT8) ) { |
tristanjph | 0:c3b76a463a8b | 141 | return; |
tristanjph | 0:c3b76a463a8b | 142 | } |
tristanjph | 0:c3b76a463a8b | 143 | config.location[1] = tlv->getUInt32(); |
tristanjph | 0:c3b76a463a8b | 144 | } |
tristanjph | 0:c3b76a463a8b | 145 | nfc_setup = 1; |
tristanjph | 0:c3b76a463a8b | 146 | } |
tristanjph | 0:c3b76a463a8b | 147 | |
tristanjph | 0:c3b76a463a8b | 148 | //NFC event call back (sets LED's on mbed) |
tristanjph | 0:c3b76a463a8b | 149 | void event_cb(NFCEvent event, void*) |
tristanjph | 0:c3b76a463a8b | 150 | { |
tristanjph | 0:c3b76a463a8b | 151 | switch(event) { |
tristanjph | 0:c3b76a463a8b | 152 | case NFC_TRANSACTION_STARTED: |
tristanjph | 0:c3b76a463a8b | 153 | led_progress=1; |
tristanjph | 0:c3b76a463a8b | 154 | led_ok=0; |
tristanjph | 0:c3b76a463a8b | 155 | led_failed=0; |
tristanjph | 0:c3b76a463a8b | 156 | break; |
tristanjph | 0:c3b76a463a8b | 157 | case NFC_TRANSACTION_SUCCESSFUL: |
tristanjph | 0:c3b76a463a8b | 158 | led_progress=0; |
tristanjph | 0:c3b76a463a8b | 159 | led_ok=1; |
tristanjph | 0:c3b76a463a8b | 160 | led_failed=0; |
tristanjph | 0:c3b76a463a8b | 161 | break; |
tristanjph | 0:c3b76a463a8b | 162 | case NFC_TRANSACTION_FAILED: |
tristanjph | 0:c3b76a463a8b | 163 | led_progress=0; |
tristanjph | 0:c3b76a463a8b | 164 | led_ok=0; |
tristanjph | 0:c3b76a463a8b | 165 | led_failed=1; |
tristanjph | 0:c3b76a463a8b | 166 | break; |
tristanjph | 0:c3b76a463a8b | 167 | } |
tristanjph | 0:c3b76a463a8b | 168 | } |
tristanjph | 0:c3b76a463a8b | 169 | |
tristanjph | 0:c3b76a463a8b | 170 | //Reads values from Sensors |
tristanjph | 0:c3b76a463a8b | 171 | void read_values(void) |
tristanjph | 0:c3b76a463a8b | 172 | { |
tristanjph | 0:c3b76a463a8b | 173 | int attempts=0; |
tristanjph | 0:c3b76a463a8b | 174 | red = 1; |
tristanjph | 0:c3b76a463a8b | 175 | pswitch = 0; //Power up the sensor network |
tristanjph | 0:c3b76a463a8b | 176 | RHT03 humtemp(p22); //Intalise the RHT03 Class |
tristanjph | 0:c3b76a463a8b | 177 | wait(1); //Wait to let the powersupply stablise |
tristanjph | 0:c3b76a463a8b | 178 | cur_light = light*100; //Read the value of the light sensor *100 to make into percentage |
tristanjph | 0:c3b76a463a8b | 179 | while(attempts <= 10 ) { |
tristanjph | 0:c3b76a463a8b | 180 | wait(2); |
tristanjph | 0:c3b76a463a8b | 181 | if(humtemp.readData() == RHT_ERROR_NONE) attempts = 20; //Read the RHT03 will have 20 attempts to read correclty |
tristanjph | 0:c3b76a463a8b | 182 | attempts++; |
tristanjph | 0:c3b76a463a8b | 183 | } |
tristanjph | 0:c3b76a463a8b | 184 | if(humtemp.getHumidity()>0) { //Used to detect if a valid reading has occured |
tristanjph | 0:c3b76a463a8b | 185 | cur_temp = (int)humtemp.getTemperatureC(); //Read current temp |
tristanjph | 0:c3b76a463a8b | 186 | cur_hum = (int)humtemp.getHumidity(); //Read current humidity |
tristanjph | 0:c3b76a463a8b | 187 | } |
tristanjph | 0:c3b76a463a8b | 188 | |
tristanjph | 0:c3b76a463a8b | 189 | cur_pir = pir; //Read the current PIR value |
tristanjph | 0:c3b76a463a8b | 190 | green=1; |
tristanjph | 0:c3b76a463a8b | 191 | wait_ms(1); |
tristanjph | 0:c3b76a463a8b | 192 | sprintf(send_data,"%x,%2d,%2d,%03.0f,%i; \0",device_serial,cur_temp,cur_hum,cur_light,cur_pir); //Formated data string |
tristanjph | 0:c3b76a463a8b | 193 | xbee_1.SendData(send_data); //Send the data to the Xbee |
tristanjph | 0:c3b76a463a8b | 194 | wait(5); //Give the Xbee time to send the data |
tristanjph | 0:c3b76a463a8b | 195 | green = 0; |
tristanjph | 0:c3b76a463a8b | 196 | red = 0; |
tristanjph | 0:c3b76a463a8b | 197 | pswitch = 1; //Power the sensors/Xbee down |
tristanjph | 0:c3b76a463a8b | 198 | } |
tristanjph | 0:c3b76a463a8b | 199 | |
tristanjph | 0:c3b76a463a8b | 200 | |
tristanjph | 0:c3b76a463a8b | 201 | //Request NFC setup data (called if setup pin=0) |
tristanjph | 0:c3b76a463a8b | 202 | void get_setup(void) |
tristanjph | 0:c3b76a463a8b | 203 | { |
tristanjph | 0:c3b76a463a8b | 204 | pswitch = 0; //Power sensors and NFC up |
tristanjph | 0:c3b76a463a8b | 205 | wait(2); //Let powersupply stabalise |
tristanjph | 0:c3b76a463a8b | 206 | memcpy(config.ieee_address,device_serial,8); //Coppy device serial into ieee_address for encode_cb |
tristanjph | 0:c3b76a463a8b | 207 | |
tristanjph | 0:c3b76a463a8b | 208 | nfc.encode(encode_cb, NULL); //Register the encode callback function |
tristanjph | 0:c3b76a463a8b | 209 | nfc.decode(decode_cb, NULL); //Register the decode callback function |
tristanjph | 0:c3b76a463a8b | 210 | nfc.event(event_cb, NULL); //Register the event callback function |
tristanjph | 0:c3b76a463a8b | 211 | |
tristanjph | 0:c3b76a463a8b | 212 | bool ret = nfc.init(); //Initalise the NFC |
tristanjph | 0:c3b76a463a8b | 213 | if(ret) { |
tristanjph | 0:c3b76a463a8b | 214 | //printf("\nAppNearMe/MuNFC stack initialized\n"); |
tristanjph | 0:c3b76a463a8b | 215 | |
tristanjph | 0:c3b76a463a8b | 216 | } else { |
tristanjph | 0:c3b76a463a8b | 217 | //printf("Could not initialize stack\n"); |
tristanjph | 0:c3b76a463a8b | 218 | while(1) { |
tristanjph | 0:c3b76a463a8b | 219 | green = !green; |
tristanjph | 0:c3b76a463a8b | 220 | red = !red; |
tristanjph | 0:c3b76a463a8b | 221 | wait_ms(500); //Flash both LED's if NFC isn't initalised |
tristanjph | 0:c3b76a463a8b | 222 | } |
tristanjph | 0:c3b76a463a8b | 223 | } |
tristanjph | 0:c3b76a463a8b | 224 | |
tristanjph | 0:c3b76a463a8b | 225 | red = 1; |
tristanjph | 0:c3b76a463a8b | 226 | |
tristanjph | 0:c3b76a463a8b | 227 | while(nfc_setup==0) { //While the decode callback hasn't been called poll the NFC |
tristanjph | 0:c3b76a463a8b | 228 | nfc.poll(100); |
tristanjph | 0:c3b76a463a8b | 229 | } |
tristanjph | 0:c3b76a463a8b | 230 | red = 0; |
tristanjph | 0:c3b76a463a8b | 231 | green = 1; |
tristanjph | 0:c3b76a463a8b | 232 | led_ok = 0; |
tristanjph | 0:c3b76a463a8b | 233 | xbee_1.ConfigMode(); //Enable config mode on Xbee |
tristanjph | 0:c3b76a463a8b | 234 | xbee_1.SetKey((int*)config.gw_security_key); //Set the security key of the Xbee |
tristanjph | 0:c3b76a463a8b | 235 | xbee_1.WriteSettings(); //Save the settings to the Xbee |
tristanjph | 0:c3b76a463a8b | 236 | xbee_1.ExitConfigMode(); //Exit config |
tristanjph | 0:c3b76a463a8b | 237 | |
tristanjph | 0:c3b76a463a8b | 238 | pswitch = 1; //power down the sensors/NFC |
tristanjph | 0:c3b76a463a8b | 239 | wait(1); |
tristanjph | 0:c3b76a463a8b | 240 | green = 0; |
tristanjph | 0:c3b76a463a8b | 241 | } |
tristanjph | 0:c3b76a463a8b | 242 | |
tristanjph | 0:c3b76a463a8b | 243 | int main() |
tristanjph | 0:c3b76a463a8b | 244 | { |
tristanjph | 0:c3b76a463a8b | 245 | setup.mode(PullUp); |
tristanjph | 0:c3b76a463a8b | 246 | xbee_1.ConfigMode(); //Enable config mode on Xbee |
tristanjph | 0:c3b76a463a8b | 247 | xbee_1.GetSerial(device_serial); //Read the Xbee's serial number |
tristanjph | 0:c3b76a463a8b | 248 | xbee_1.ExitConfigMode(); //Exit config mode |
tristanjph | 0:c3b76a463a8b | 249 | if(setup == 0) get_setup(); //Call setup if setup=0 |
tristanjph | 0:c3b76a463a8b | 250 | pswitch=1; //make sure sensors are powered down |
tristanjph | 0:c3b76a463a8b | 251 | red=1; |
tristanjph | 0:c3b76a463a8b | 252 | wait(1); |
tristanjph | 0:c3b76a463a8b | 253 | green=1; |
tristanjph | 0:c3b76a463a8b | 254 | red=0; |
tristanjph | 0:c3b76a463a8b | 255 | wait(1); |
tristanjph | 0:c3b76a463a8b | 256 | green=0; |
tristanjph | 0:c3b76a463a8b | 257 | read_values(); //Read sensor values |
tristanjph | 0:c3b76a463a8b | 258 | val_check.attach(&read_values,SLEEP_TIME); //Read sesnor data every SLEEP_TIME seconds |
tristanjph | 0:c3b76a463a8b | 259 | while(1) { |
tristanjph | 0:c3b76a463a8b | 260 | |
tristanjph | 0:c3b76a463a8b | 261 | } |
tristanjph | 0:c3b76a463a8b | 262 | return 1; |
tristanjph | 0:c3b76a463a8b | 263 | } |