Demo starter application to connect WiGo to NSP and expose on-board sensors

Dependencies:   NVIC_set_all_priorities cc3000_hostdriver_mbedsocket mbed nsdl_lib TEMT6200 TSI Wi-Go_eCompass_Lib_V3 WiGo_BattCharger

This is the mbed project for the IoT World Hackathon event, June 17th and 18th in Palo Also.

The setup instructions for participants are at the Setup page of this wiki:

http://mbed.org/teams/MBED_DEMOS/code/IoT_World_Hackathon_WiGo_NSP_Demo/wiki/Setup-Guide-for-the-IoT-World-Hackathon

main.cpp

Committer:
michaeljkoster
Date:
2014-06-14
Revision:
4:727f1aeb717a
Parent:
0:07581223f90c
Child:
16:d6812604cf92

File content as of revision 4:727f1aeb717a:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mbed.h"
#include "cc3000.h"
#include "main.h"
#include "TCPSocketConnection.h"
#include "TCPSocketServer.h"
#include "nsdl_support.h"

using namespace mbed_cc3000;

tUserFS user_info;

/* cc3000 module declaration specific for user's board. Check also init() */
#if (MY_BOARD == WIGO)

#include "I2C_busreset.h"
#include "defLED.h"
#include "TSISensor.h"
#include "TEMT6200.h"
#include "WiGo_BattCharger.h"
#include "MMA8451Q.h"
#include "MAG3110.h"
#include "MPL3115A2.h"
#include "Wi-Go_eCompass_Lib_V3.h"
#include "demo.h"
#include "doTCPIP.h"
#include "run_exosite.h"

#define FCOUNTSPERG  4096.0F // sensor specific: MMA8451 provide 4096 counts / g in 2g mode
#define FCOUNTSPERUT   10.0F // sensor specific: MAG3110 provide 10 counts / uT

#define BATT_0          0.53
#define BATT_100        0.63

DigitalOut ledr (LED_RED);
DigitalOut ledg (LED_GREEN);
DigitalOut ledb (LED_BLUE);
DigitalOut led1 (PTB8);
DigitalOut led2 (PTB9);
DigitalOut led3 (PTB10);

cc3000 wifi(PTA16, PTA13, PTD0, SPI(PTD2, PTD3, PTC5), "", "", NONE, true);

TCPSocketConnection socket;

Serial pc(USBTX, USBRX);

// Slide sensor
TSISensor tsi;

// Systick
Ticker systick;

// Ambient light sensor : PTD5 = enable, PTB0 = analog input
TEMT6200 ambi(PTD5, PTB0);

//Wi-Go battery charger control
WiGo_BattCharger Batt(CHRG_EN1, CHRG_EN2, CHRG_SNS_EN, CHRG_SNS, CHRG_POK, CHRG_CHG);

// Accelerometer
#define MMA8451_I2C_ADDRESS (0x1d<<1)
MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);

// Magnetometer
#define MAG3110_I2C_ADDRESS (0x0e<<1)
MAG3110 mag(PTE0, PTE1, MAG3110_I2C_ADDRESS);

// altimeter-Pressure-Temperature (apt)
#define MPL3115A2_I2C_ADDRESS (0x60<<1)
MPL3115A2 apt( PTE0, PTE1, MPL3115A2_I2C_ADDRESS);

volatile int secondFlag;
volatile int HsecondFlag;
unsigned int seconds;
unsigned int compass_type;
unsigned short adc_sample3;
float fcountperg = 1.0F / FCOUNTSPERG;
float fcountperut = 1.0F / FCOUNTSPERUT;
volatile unsigned char newData;
volatile int server_running;
axis6_t axis6;
int do_mDNS = 0;
//Device name - used for Smart config in order to stop the Smart phone configuration process
char DevServname[] = "CC3000";

void initLEDs(void)
{
    RED_OFF;
    GREEN_OFF;
    BLUE_OFF;
    LED_D1_OFF;
    LED_D2_OFF;
    LED_D3_OFF;
}

void GreenStop(void)
{
    RED_OFF; GREEN_OFF; BLUE_OFF;
    while(1)
    {
        GREEN_ON;
        secondFlag = 0;
        while(!secondFlag);
        GREEN_OFF;
        secondFlag = 0;
        while(!secondFlag);
    }
}

void accel_read(void)
{
    signed short resultx, resulty, resultz;
    if(acc.isDataAvailable())
    {
        resultx = acc.readReg(0x01)<<8;
        resultx |= acc.readReg(0x02);
        resultx = resultx >> 2;
        resulty = acc.readReg(0x03)<<8;
        resulty |= acc.readReg(0x04);
        resulty = resulty >> 2;
        resultz = acc.readReg(0x05)<<8;
        resultz |= acc.readReg(0x06);
        resultz = resultz >> 2;
        if(compass_type == NED_COMPASS)
        {
            axis6.acc_x = resultx;
            axis6.acc_y = -1 * resulty; // multiple by -1 to compensate for PCB layout
            axis6.acc_z = resultz;
        }
        if(compass_type == ANDROID_COMPASS)
        {
            axis6.acc_x = resulty; // 
            axis6.acc_y = -1 * resultx;
            axis6.acc_z = resultz;
        }
        if(compass_type == WINDOWS_COMPASS)
        {
            axis6.acc_x = -1 * resulty; // 
            axis6.acc_y = resultx;
            axis6.acc_z = resultz;
        }
        axis6.fax = axis6.acc_x;
        axis6.fay = axis6.acc_y;
        axis6.faz = axis6.acc_z;
        axis6.fGax = axis6.fax * fcountperg;
        axis6.fGay = axis6.fay * fcountperg;
        axis6.fGaz = axis6.faz * fcountperg;                    
    }
}        

void readTempAlt(void) // We don't use the fractional data
{
    unsigned char raw_data[2];
    if(apt.getAltimeterRaw(&raw_data[0]))
        axis6.alt = ((raw_data[0] << 8) | raw_data[1]);
    if(apt.getTemperatureRaw(&raw_data[0]))
        axis6.temp = raw_data[0];
}

void readCompass( void )
{
    if(mag.isDataAvailable())
    {
        uint8_t  mx_msb, my_msb, mz_msb;
        uint8_t  mx_lsb, my_lsb, mz_lsb;

        mx_msb = mag.readReg(0x01);
        mx_lsb = mag.readReg(0x02);
        my_msb = mag.readReg(0x03);
        my_lsb = mag.readReg(0x04);
        mz_msb = mag.readReg(0x05);
        mz_lsb = mag.readReg(0x06);

        if(compass_type == NED_COMPASS)
        {
            axis6.mag_y = (((mx_msb << 8) | mx_lsb));      // x & y swapped to compensate for PCB layout
            axis6.mag_x = (((my_msb << 8) | my_lsb));
            axis6.mag_z = (((mz_msb << 8) | mz_lsb));
        }
        if(compass_type == ANDROID_COMPASS)
        {
            axis6.mag_x = (((mx_msb << 8) | mx_lsb));
            axis6.mag_y = (((my_msb << 8) | my_lsb));
            axis6.mag_z = -1 * (((mz_msb << 8) | mz_lsb)); // negate to reverse axis of Z to conform to Android coordinate system
        }
        if(compass_type == WINDOWS_COMPASS)
        {
            axis6.mag_x = (((mx_msb << 8) | mx_lsb));
            axis6.mag_y = (((my_msb << 8) | my_lsb));
            axis6.mag_z = -1 * (((mz_msb << 8) | mz_lsb));
        }
        axis6.fmx = axis6.mag_x;
        axis6.fmy = axis6.mag_y;
        axis6.fmz = axis6.mag_z;
        axis6.fUTmx = axis6.fmx * fcountperut;
        axis6.fUTmy = axis6.fmy * fcountperut;
        axis6.fUTmz = axis6.fmz * fcountperut;
    }
}   

void axis6Print(void)
{
    char *compass_points[9] = {"North", "N-East", "East", "S-East", "South", "S-West", "West", "N-West", "North"};
    signed short compass_bearing = (axis6.compass + 23) / 45;
    printf("Compass : Roll=%-d  Pitch=%-d  Yaw=%-d [%s]\r\n", axis6.roll, axis6.pitch, axis6.yaw, compass_points[compass_bearing]);
    printf("Accel   : X= %1.2f, Y= %1.2f, Z= %1.2f\r\n", axis6.fGax, axis6.fGay, axis6.fGaz);
    printf("Magneto : X= %3.1f, Y= %3.1f, Z= %3.1f\r\n\r\n", axis6.fUTmx, axis6.fUTmy, axis6.fUTmz);
}

void set_dir_LED(void)
{
    RED_OFF; GREEN_OFF; BLUE_OFF;
    
    if((axis6.compass >= 353) || (axis6.compass <= 7))
    {
        GREEN_ON;
    }
    else
    {
        GREEN_OFF;
    }
    if(((axis6.compass >= 348) && (axis6.compass <= 357)) || ((axis6.compass >= 3) && (axis6.compass <= 12)))
    {
        BLUE_ON;
    }
    else
    {
        BLUE_OFF;
    }
    if((axis6.compass >= 348) || (axis6.compass <= 12)) return;
    if(((axis6.compass >= 268) && (axis6.compass <= 272)) || ((axis6.compass >= 88) && (axis6.compass <= 92)))
    {
        RED_ON;
        return;
    }
    if((axis6.compass >= 178) && (axis6.compass <= 182))
    {
        BLUE_ON;
        RED_ON;
        return;
    }
}

void SysTick_Handler(void)
{
    static unsigned int ttt = 1;
    int ts;
    ts = ttt & 0x1;
    if(ts == 0)
    {
        accel_read();
        readCompass();
    }
    if(ts == 1)
    {
        run_eCompass();
        newData = 1; // a general purpose flag for things that need to synch to the ISR
        axis6.timestamp++;
        if(!server_running) set_dir_LED(); // Set the LEDs based on direction when nothing else is usng them
    }
    if(ttt == 50)
    {
        LED_D1_ON;
        if(seconds && (seconds < 15)) calibrate_eCompass();
        readTempAlt();
        axis6.light = ambi.readRaw(); // Light Sensor    
        HsecondFlag = 1; // A general purpose flag for things that need to happen every 500ms   
    }
    if(ttt >= 100)
    {
        LED_D1_OFF;
        ttt = 1;  
        calibrate_eCompass();
        Batt.sense_en(1);
        adc_sample3 = Batt.level(); 
        Batt.sense_en(0);
        secondFlag = 1; // A general purpose flag for things that need to happen once a second
        HsecondFlag = 1;
        seconds++;
        if(!(seconds & 0x1F)) do_mDNS = 1;          
    } else ttt++;
}
/*void SysTick_Handler(void)
{
    static unsigned int ttt = 1;
    int ts;
    ts = ttt & 0x3;
    if(ts == 2) readCompass();
    if(ts == 1) accel_read();
    if(ts == 3)
    {
        run_eCompass();
        newData = 1; // a general purpose flag for things that need to synch to the ISR
        axis6.timestamp++;
        if(!server_running) set_dir_LED(); // Set the LEDs based on direction when nothing else is usng them
    }
    if(ttt == 100)//systick = 0.005 : 100 - systick = 0.025 : 20
    {
        LED_D1_ON;
        if(seconds && (seconds < 15)) calibrate_eCompass();
        readTempAlt();
        axis6.light = ambi.readRaw(); // Light Sensor    
        HsecondFlag = 1; // A general purpose flag for things that need to happen every 500ms   
    }
    if(ttt >= 200)//systick = 0.005 : 200 - systick = 0.025 : 40
    {
        LED_D1_OFF;
        ttt = 1;  
        calibrate_eCompass();
        Batt.sense_en(1);
        adc_sample3 = Batt.level(); 
        Batt.sense_en(0);
        secondFlag = 1; // A general purpose flag for things that need to happen once a second
        HsecondFlag = 1;
        seconds++;
        if(!(seconds & 0x1F)) do_mDNS = 1;
    } else ttt++;
}*/

#elif (MY_BOARD == WIFI_DIPCORTEX)
cc3000 wifi(p28, p27, p30, SPI(p21, p14, p37), PIN_INT0_IRQn);
Serial pc(UART_TX, UART_RX);
#else

#endif

#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
  const uint8_t smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36};
#else
  const uint8_t smartconfigkey = 0;
#endif

/**
 *  \brief Print cc3000 information
 *  \param none
 *  \return none
 */
void print_cc3000_info() {
    uint8_t myMAC[8];
    uint8_t spVER[5];
    wifi._nvmem.read_sp_version(spVER);
    printf("SP Version (TI) : %d %d %d %d %d\r\n", spVER[0], spVER[1], spVER[2], spVER[3], spVER[4]);
    printf("MAC address + cc3000 info \r\n");
    wifi.get_user_file_info((uint8_t *)&user_info, sizeof(user_info));
    wifi.get_mac_address(myMAC);
    printf(" MAC address %02x:%02x:%02x:%02x:%02x:%02x \r\n \r\n", myMAC[0], myMAC[1], myMAC[2], myMAC[3], myMAC[4], myMAC[5]);

    printf(" FTC        %i \r\n",user_info.FTC);
    printf(" PP_version %i.%i \r\n",user_info.PP_version[0], user_info.PP_version[1]);
    printf(" SERV_PACK  %i.%i \r\n",user_info.SERV_PACK[0], user_info.SERV_PACK[1]);
    printf(" DRV_VER    %i.%i.%i \r\n",user_info.DRV_VER[0], user_info.DRV_VER[1], user_info.DRV_VER[2]);
    printf(" FW_VER     %i.%i.%i \r\n",user_info.FW_VER[0], user_info.FW_VER[1], user_info.FW_VER[2]);
}

/**
 *  \brief Connect to SSID with a timeout
 *  \param ssid     Name of SSID
 *  \param key      Password
 *  \param sec_mode Security mode
 *  \return none
 */
void connect_to_ssid(char *ssid, char *key, unsigned char sec_mode) {
    printf("Connecting to SSID: %s. Timeout is 10s. \r\n",ssid);
    if (wifi.connect_to_AP((uint8_t *)ssid, (uint8_t *)key, sec_mode) == true) {
        printf(" Connected. \r\n");
    } else {
        printf(" Connection timed-out (error). Please restart. \r\n");
        while(1);
  }
}

/**
 *  \brief Connect to SSID without security
 *  \param ssid Name of SSID
 *  \return none
 */
void connect_to_ssid(char *ssid) {
    wifi.connect_open((uint8_t *)ssid);
}

/**
 *  \brief First time configuration
 *  \param none
 *  \return none
 */
void do_FTC(void) {
    printf("Running First Time Configuration \r\n");
    wifi.start_smart_config(smartconfigkey);
    while (wifi.is_dhcp_configured() == false) {
         wait_ms(500);
         printf("Waiting for dhcp to be set. \r\n");
    }
    user_info.FTC = 1;
    wifi.set_user_file_info((uint8_t *)&user_info, sizeof(user_info));
    wifi._wlan.stop();
    printf("FTC finished. \r\n");
}

/**
 *  \brief TCP server demo
 *  \param  none
 *  \return int
 */
int main() {
    int loop;
    int temp;
    unsigned int oldseconds;

    //Board dependent init
    init();

    // Initalize global variables
    axis6.packet_id = 1;
    axis6.timestamp = 0;
    axis6.acc_x = 0;
    axis6.acc_y = 0;
    axis6.acc_z = 0;
    axis6.mag_x = 0;
    axis6.mag_y = 0;
    axis6.mag_z = 0;
    axis6.roll = 0;
    axis6.pitch = 0;
    axis6.yaw = 0;
    axis6.compass = 0;      
    axis6.alt = 0;
    axis6.temp = 0;
    axis6.light = 0;
    compass_type = ANDROID_COMPASS;
    seconds = 0;
    server_running = 1;
    newData = 0;    
    secondFlag = 0;
    HsecondFlag = 0;
    GREEN_ON;

    // Unlock I2C bus if blocked by a device
    I2C_busreset();

    pc.baud(115200);

    // set current to 500mA since we're turning on the Wi-Fi
    Batt.init(CHRG_500MA);

    //Init LEDs
    initLEDs();
    // Read the Magnetometer a couple of times to initalize
    for(loop=0 ; loop < 5 ; loop++)
    {
        temp = mag.readReg(0x01);
        temp = mag.readReg(0x02);
        temp = mag.readReg(0x03);
        temp = mag.readReg(0x04);
        temp = mag.readReg(0x05);
        temp = mag.readReg(0x06);
        wait_ms(50);
    }

    init_eCompass();

    // Start Ticker
    systick.attach(&SysTick_Handler, 0.01);
    // Trigger a WLAN device
    wifi.init();
    //wifi.start(0);
    printf("CC3000 Wi-Go IOT ARM Sensinode demo.\r\n");
    print_cc3000_info();
    server_running = 1;
    newData = 0;    
    GREEN_ON;

    if(!user_info.FTC)
    {
        do_FTC(); // Call First Time Configuration if SmartConfig has not been run
        printf("Please restart your board. \r\n");
        GreenStop();
    }

    // Wait for slider touch
    printf("\r\nUse the slider to start an application.\r\n");
    printf("Releasing the slider for more than 3 seconds\r\nwill start the chosen application.\r\n");
    printf("Touching the slider within the 3 seconds\r\ntimeframe allows you to re-select an application.\r\n");
    printf("\r\nThe RGB LED indicates the selection:\r\n");
    printf("ORANGE - Erase all profiles.\r\n");
    printf("PURPLE - Force SmartConfig.\r\n");
    printf("BLUE   - Webserver displaying live sensor data.\r\n");
    printf("RED    - ARM Sensinode LWM2M client.\r\n");
    printf("GREEN  - Android sensor fusion app.\r\n");
    while( tsi.readPercentage() == 0 )
    {
        RED_ON;
        wait(0.2);
        RED_OFF;
        wait(0.2);
    }
    RED_OFF;

    oldseconds = seconds;
    loop = 100;
    temp = 0;
    // Read slider as long as it is touched.
    // If released for more than 3 seconds, exit
    while((loop != 0) || ((seconds - oldseconds) < 3))
    {
        loop = tsi.readPercentage() * 100;
        if(loop != 0)
        {
            oldseconds = seconds;
            temp = loop;
        }
        if(temp > 80)
        {
             RED_ON; GREEN_ON; BLUE_OFF; //Orange
        }
        else if(temp > 60)
        {
             RED_ON; GREEN_OFF; BLUE_ON; //Purple
        }
        else if(temp > 40)
        {
            RED_OFF; GREEN_OFF; BLUE_ON; //Blue
        }
        else if(temp > 20)
        {
            RED_ON; GREEN_OFF; BLUE_OFF; //Red
        }
        else
        {
            RED_OFF; GREEN_ON; BLUE_OFF; //Green
        }
    }
    RED_OFF; GREEN_OFF; BLUE_OFF;

    // Execute the user selected application
    if(temp > 80) // Erase all profiles
    {
        server_running = 1;
        RED_OFF; GREEN_OFF; BLUE_OFF;
        printf("\r\nErasing all wireless profiles. \r\n");
        wifi.delete_profiles();
        wifi.stop();
        printf("Finished. Please restart your board. \r\n");
        GreenStop();
    }

    if(temp > 60) // Force SmartConfig
    {
        server_running = 1;
        RED_OFF; GREEN_OFF; BLUE_OFF;
        printf("\r\nStarting Smart Config configuration. \r\n");
        wifi.start_smart_config(smartconfigkey);
        while (wifi.is_dhcp_configured() == false)
        {
            wait_ms(500);
            printf("Waiting for dhcp to be set. \r\n");
        }
        printf("Finished. Please restart your board. \r\n");
        GreenStop();
    }

    RED_OFF; GREEN_OFF; BLUE_OFF; 

    printf("\r\nAttempting SSID Connection. \r\n");
    if (wifi.connect() == -1) {
        printf("Failed to connect. Please verify connection details and try again. \r\n");
    } else {
        printf("Connected - IP address: %s \r\n",wifi.getIPAddress());
    }
    LED_D3_ON;

    server_running = 0;
        
    // Start the selected application
    if(temp > 40) // Run Webserver
    {
        compass_type = NED_COMPASS;
        init_eCompass();
        seconds = 0;
        demo_wifi_main();
    }
    if(temp > 20) // Sensinode LWM2M client
    {
        compass_type = NED_COMPASS;
        init_eCompass();
        seconds = 0;
        server_running = 1;
        nsdl_run();
    }
    if(temp <= 20)
    {
        init_eCompass();
        seconds = 0;
        // Run TCP/IP Connection to host - Sensor Fusion App
        runTCPIPserver();
    }
}