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

Committer:
tristanjph
Date:
2012-08-30
Revision:
0:c3b76a463a8b

File content as of revision 0:c3b76a463a8b:

/* Copyright (c) 2012 Tristan Hughes, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*------INCLUDES-----*/
#include "mbed.h"
#include "RHT03.h"
#include "MuNFC.h"
#include "xbee.h"

/*------Definitions----*/
#define SLEEP_TIME 30 //Time to wait between reading and sending data
#define SENSOR_PACKET 2 //Tells the NFC app device is a sensor
#define LOCATION_PRECISION 100000 //The accuracy of the devices location

/*------Pins------*/
DigitalOut red(p30);
DigitalOut green(p29);
DigitalOut pswitch(p21);
AnalogIn light(p15);
DigitalIn pir(p16);
DigitalIn setup(p14);
DigitalOut led_alive(LED1);
DigitalOut led_progress(LED2);
DigitalOut led_ok(LED3);
DigitalOut led_failed(LED4);
Serial pc1(USBTX, USBRX);

/*-----Globals-----*/
char send_data[202];
int cur_temp,cur_hum,device_serial[8];
float cur_light;
int cur_pir;
int nfc_setup = 0;
Ticker val_check;

/*-----Class Init-----*/
MuNFC nfc("000000053Tfi0RwY", 1, p11, p12, p13, p19, p18);
xbee xbee_1(p9,p10,p25);


/*-----A class of useful functions for use with NFC----*/
class sr_configuration
{
public:
    sr_configuration( const uint8_t* ieee_address ) {
        memcpy( this->ieee_address, ieee_address, 8 );
    }

    void hexPrint(const char* name, uint8_t* buf, int len) {
        printf("%s: ", name);
        for(int i = 0; i < len; i++) {
            printf("%02x ", buf[i]);
        }
        printf("\r\n");
    }

    void prettyPrint() {
        printf("Name: %s\r\n", name);
        hexPrint("IEEE Address", ieee_address, 8);
        hexPrint("Gateway IEEE Address", gw_ieee_address, 8);
        hexPrint("Gateway Security Key", gw_security_key, 16);
        printf("Location: Lat.: %d.%05d; Long.: %d.%05d\r\n",
               location[0]/LOCATION_PRECISION, (location[0] - (location[0]/LOCATION_PRECISION)*LOCATION_PRECISION ),
               location[1]/LOCATION_PRECISION, (location[1] - (location[1]/LOCATION_PRECISION)*LOCATION_PRECISION ) );
    }

    char name[24];
    uint8_t ieee_address[8];
    uint8_t gw_ieee_address[8];
    uint8_t gw_security_key[16];
    uint32_t location[2]; //lat*100000, long*100000
};

const uint8_t address[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //setting the IEEE address to 0
sr_configuration config(address);

//Encode call back for NFC
void encode_cb(TLVList* tlv, void *)
{
    tlv->putUInt8( SENSOR_PACKET ); //First uint8_t is packet type
    tlv->putString(config.name);
    tlv->putArray(config.ieee_address, 8);
    tlv->putArray(config.gw_ieee_address, 8);
    tlv->putArray(config.gw_security_key, 16);
    tlv->putUInt32(config.location[0]);
    tlv->putUInt32(config.location[1]);
}

//Decode callback for NFC
void decode_cb(TLVList* tlv, void *)
{
    TLVList::TLVType t;

    if(tlv->getNext() != UINT8) {
        return;
    }
    if(tlv->getUInt8() == SENSOR_PACKET) { //First uint8_t is packet type
        if(tlv->getNext() != STRING) {
            return;
        }
        tlv->getString(config.name, 23);

        if(tlv->getNext() != UINT8_ARRAY) {
            return;
        }
        //tlv->getArray(config.ieee_address, 8); //IEEE address is ignored

        if(tlv->getNext() != UINT8_ARRAY) {
            return;
        }
        tlv->getArray(config.gw_ieee_address, 8);

        if(tlv->getNext() != UINT8_ARRAY) {
            return;
        }
        tlv->getArray(config.gw_security_key, 16);

        t = tlv->getNext();
        if( (t != UINT32) && (t != UINT8) ) {
            return;
        }
        config.location[0] = tlv->getUInt32();

        t = tlv->getNext();
        if( (t != UINT32) && (t != UINT8) ) {
            return;
        }
        config.location[1] = tlv->getUInt32();
    }
    nfc_setup = 1;
}

//NFC event call back (sets LED's on mbed)
void event_cb(NFCEvent event, void*)
{
    switch(event) {
        case NFC_TRANSACTION_STARTED:
            led_progress=1;
            led_ok=0;
            led_failed=0;
            break;
        case NFC_TRANSACTION_SUCCESSFUL:
            led_progress=0;
            led_ok=1;
            led_failed=0;
            break;
        case NFC_TRANSACTION_FAILED:
            led_progress=0;
            led_ok=0;
            led_failed=1;
            break;
    }
}

//Reads values from Sensors
void read_values(void)
{
    int attempts=0;
    red = 1;
    pswitch = 0; //Power up the sensor network
    RHT03 humtemp(p22); //Intalise the RHT03 Class
    wait(1); //Wait to let the powersupply stablise
    cur_light = light*100; //Read the value of the light sensor *100 to make into percentage
    while(attempts <= 10 ) {
        wait(2);
        if(humtemp.readData() == RHT_ERROR_NONE) attempts = 20; //Read the RHT03 will have 20 attempts to read correclty
        attempts++;
    }
    if(humtemp.getHumidity()>0) { //Used to detect if a valid reading has occured
        cur_temp = (int)humtemp.getTemperatureC(); //Read current temp
        cur_hum = (int)humtemp.getHumidity(); //Read current humidity
    }

    cur_pir = pir; //Read the current PIR value
    green=1;
    wait_ms(1);
    sprintf(send_data,"%x,%2d,%2d,%03.0f,%i; \0",device_serial,cur_temp,cur_hum,cur_light,cur_pir); //Formated data string
    xbee_1.SendData(send_data); //Send the data to the Xbee
    wait(5); //Give the Xbee time to send the data
    green = 0;
    red = 0;
    pswitch = 1; //Power the sensors/Xbee down
}


//Request NFC setup data (called if setup pin=0)
void get_setup(void)
{
    pswitch = 0; //Power sensors and NFC up
    wait(2); //Let powersupply stabalise
    memcpy(config.ieee_address,device_serial,8); //Coppy device serial into ieee_address for encode_cb

    nfc.encode(encode_cb, NULL); //Register the encode callback function
    nfc.decode(decode_cb, NULL); //Register the decode callback function
    nfc.event(event_cb, NULL); //Register the event callback function

    bool ret = nfc.init(); //Initalise the NFC
    if(ret) {
        //printf("\nAppNearMe/MuNFC stack initialized\n");

    } else {
       //printf("Could not initialize stack\n");
        while(1) {
            green = !green;
            red = !red;
            wait_ms(500); //Flash both LED's if NFC isn't initalised
        }
    }

    red = 1;

    while(nfc_setup==0) { //While the decode callback hasn't been called poll the NFC
        nfc.poll(100);
    }
    red = 0;
    green = 1;
    led_ok = 0;
    xbee_1.ConfigMode(); //Enable config mode on Xbee
    xbee_1.SetKey((int*)config.gw_security_key); //Set the security key of the Xbee
    xbee_1.WriteSettings(); //Save the settings to the Xbee
    xbee_1.ExitConfigMode(); //Exit config

    pswitch = 1; //power down the sensors/NFC
    wait(1);
    green = 0;
}

int main()
{
    setup.mode(PullUp);
    xbee_1.ConfigMode(); //Enable config mode on Xbee
    xbee_1.GetSerial(device_serial); //Read the Xbee's serial number
    xbee_1.ExitConfigMode(); //Exit config mode
    if(setup == 0) get_setup(); //Call setup if setup=0
    pswitch=1; //make sure sensors are powered down
    red=1;
    wait(1);
    green=1;
    red=0;
    wait(1);
    green=0;
    read_values(); //Read sensor values
    val_check.attach(&read_values,SLEEP_TIME); //Read sesnor data every SLEEP_TIME seconds
    while(1) {

    }
    return 1;
}