Exosite Collaberation ALS int .

Dependencies:   MbedJSONValue mbed mtsas

Fork of UUU_MultiTech_Dragonfly_Sprint_SF by Paul Jaeger

main.cpp

Committer:
mfiore
Date:
2015-09-24
Revision:
0:a44e71488e1f
Child:
1:a049d113e250

File content as of revision 0:a44e71488e1f:

/*************************************************************************
 * Dragonfly Example program for 2015 AT&T Government Solutions Hackathon
 * 
 * The following hardware is required to successfully run this program:
 *   - MultiTech UDK2 (4" square white PCB with Arduino headers, antenna
 *     connector, micro USB ports, and 40-pin connector for Dragonfly)
 *   - MultiTech Dragonfly (1"x2" green PCB with Telit radio)
 *   - Seeed Studio Base Shield
 *   - Grove moisture sensor (to connect to Base Shield)
 *   - Grove button (to connect to Base Shield)
 *   - MEMs Inertial and Environmental Nucleo Expansion board (LSM6DS0
 *     3-axis accelerometer + 3-axis gyroscope, LIS3MDL 3-axis
 *     magnetometer, HTS221 humidity and temperature sensor and LPS25HB
 *     pressure sensor)
 *
 * What this program does:
 *   - reads data from all sensors on MEMs board and moisture sensor on a
 *     periodic basis
 *   - prints all sensor data to debug port on a periodic basis
 *   - optionally send a SMS containing sensor data when the Grove Button
 *     is pushed (phone number must be configured)
 *   - optionally send sensor data to AT&T M2X cloud platform (user must
 *     create own M2X account and configure a device) if sensor data
 *     crosses established thresholds
 *
 * Setup:
 *   - Correctly insert SIM card into Dragonfly
 *   - Seat the Dragonfly on the UDK2 board
 *   - Connect an antenna to the connector on the Dragonfly labled "M"
 *   - Stack the Base Shield on the UDK2 Arduino headers
 *   - Connect the Grove button to the D8 socket on the Base Shield
 *   - Connect the Grove moisture sensor to the A0 socket on the Base
 *     Shield
 *   - Stack the MEMs board on top of the Base Shield
 *   - Plug in the power cable
 *   - Plug a micro USB cable into the port below and slightly to the
 *     left of the Dragonfly (NOT the port on the Dragonfly)
 *
 * Go have fun and make something cool!
 *
 ************************************************************************/
 
#include "mbed.h"
#include "rtos.h"
#include "mtsas.h"
#include "x_nucleo_iks01a1.h"
#include "MbedJSONValue.h"
#include <string>

// Debug serial port
static Serial debug(USBTX, USBRX);

// MTSSerialFlowControl - serial link between processor and radio
static MTSSerialFlowControl io(SERIAL_TX, SERIAL_RX, SERIAL_RTS, SERIAL_CTS);

// Cellular - radio object for cellular operations (SMS, TCP, etc)
Cellular* radio;

// APN associated with SIM card
//static const std::string apn = "";
static const std::string apn = "b2b.tmobile.com";

// Phone number to send SMS messages to
//static const std::string phone_number = "1xxxxxxxxxx";
static const std::string phone_number = "19524062053";

// handle to MEMs board object
static X_NUCLEO_IKS01A1* mems = X_NUCLEO_IKS01A1::Instance();

// Moisture sensor
AnalogIn moisture_sensor(A0);

// Button
DigitalIn button(D8);

// variables for sensor data
float temp_celsius;
float temp_fahrenheit;
float humidity_percent;
float pressure_mbar;
float moisture_percent;
int32_t mag_mgauss[3];
int32_t acc_mg[3];
int32_t gyro_mdps[3];

// mutexes
Mutex data_mutex;
Mutex mtsas_mutex;

// misc variables
static char wall_of_dash[] = "--------------------------------------------------";
bool radio_ok = false;
static int thp_interval_ms = 2000;
static int motion_interval_ms = 250;
static int print_interval_ms = 5000;
int debug_baud = 115200;

// function prototypes
bool init_mtsas();
void sensor_thread(void const* args);
void print_thread(void const* args);
void sms_thread(void const* args);
void read_temperature();
void read_humidity();
void read_pressure();
void read_moisture();
void read_magnetometer();
void read_accelerometer();
void read_gyroscope();
void button_irq();

// main
int main() {
    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
    debug.baud(debug_baud);
    logInfo("starting...");
    
    radio_ok = init_mtsas();
    if (! radio_ok)
        logError("MTSAS init failed");
    else
        logInfo("MTSAS is ok");
    
    Thread sensors(sensor_thread);
    Thread prints(print_thread);
    Thread sms(sms_thread);
    
    while (true) {
    }
}

// init functions
bool init_mtsas() {
    io.baud(115200);
    
    mtsas_mutex.lock();
    radio = CellularFactory::create(&io);
    mtsas_mutex.unlock();
    if (! radio)
        return false;
        
    mtsas_mutex.lock();
    Code ret = radio->setApn(apn);
    mtsas_mutex.unlock();
    if (ret != MTS_SUCCESS)
        return false;
        
    return true;
}

// thread "main" functions
void sensor_thread(void const* args) {
    Timer thp_timer;
    Timer motion_timer;
    
    thp_timer.start();
    motion_timer.start();
    while (true) {
        if (motion_timer.read_ms() > motion_interval_ms) {
            read_magnetometer();
            read_accelerometer();
            read_gyroscope();
            motion_timer.reset();
        }
        
        if (thp_timer.read_ms() > thp_interval_ms) {
            read_temperature();
            read_humidity();
            read_pressure();
            thp_timer.reset();
        }
        
        Thread::wait(100);
    }
}

void print_thread(void const* args) {
    Timer print_timer;
    
    print_timer.start();
    while (true) {
        if (print_timer.read_ms() > print_interval_ms) {
            data_mutex.lock();
            logDebug("%s", wall_of_dash);
            logDebug("SENSOR DATA");
            logDebug("temperature: %f C\t%f F", temp_celsius, temp_fahrenheit);
            logDebug("humidity: %f%%",  humidity_percent);
            logDebug("pressure: %f mbar", pressure_mbar);
            logDebug("moisture: %f%%", moisture_percent);
            logDebug("magnetometer:\r\n\tx: %ld\ty: %ld\tz: %ld\tmgauss", mag_mgauss[0], mag_mgauss[1], mag_mgauss[2]);
            logDebug("accelerometer:\r\n\tx: %ld\ty: %ld\tz: %ld\tmg", acc_mg[0], acc_mg[1], acc_mg[2]);
            logDebug("gyroscope:\r\n\tx: %ld\ty: %ld\tz: %ld\tmdps", gyro_mdps[0], gyro_mdps[1], gyro_mdps[2]);
            logDebug("%s", wall_of_dash);
            data_mutex.unlock();
            print_timer.reset();
        }
        
        Thread::wait(1000);
    }
}

void sms_thread(void const* args) {
    while (true) {
        if (button) {
            logInfo("Button was pressed");
            if (radio_ok) {
                MbedJSONValue sms_json;
                string sms_str;
                
                sms_json["temp_C"] = temp_celsius;
                sms_json["temp_F"] = temp_fahrenheit;
                sms_json["humidity_percent"] = humidity_percent;
                sms_json["pressure_mbar"] = pressure_mbar;
                sms_json["moisture_percent"] = moisture_percent;
                sms_json["mag_mgauss"]["x"] = mag_mgauss[0];
                sms_json["mag_mgauss"]["y"] = mag_mgauss[1];
                sms_json["mag_mgauss"]["z"] = mag_mgauss[2];
                sms_json["acc_mg"]["x"] = acc_mg[0];
                sms_json["acc_mg"]["y"] = acc_mg[1];
                sms_json["acc_mg"]["z"] = acc_mg[2];
                sms_json["gyro_mdps"]["x"] = gyro_mdps[0];
                sms_json["gyro_mdps"]["y"] = gyro_mdps[1];
                sms_json["gyro_mdps"]["z"] = gyro_mdps[2];
                
                sms_str = "SENSOR DATA: ";
                sms_str += sms_json.serialize();
                
                logDebug("sending SMS to %s:\r\n%s", phone_number.c_str(), sms_str.c_str());
                mtsas_mutex.lock();
                Code ret = radio->sendSMS(phone_number, sms_str);
                mtsas_mutex.unlock();
                if (ret != MTS_SUCCESS)
                    logError("sending SMS failed");
            }
        }
        
        Thread::wait(200);
    }
}

// Sensor data acquisition functions
void read_temperature() {
    int ret;
    
    data_mutex.lock();
    ret = mems->ht_sensor->GetTemperature(&temp_celsius);
    data_mutex.unlock();
    if (ret)
        logError("reading temp (C) failed");
        
    data_mutex.lock();
    ret = mems->ht_sensor->GetFahrenheit(&temp_fahrenheit);
    data_mutex.unlock();
    if (ret)
        logError("reading temp (F) failed");
}

void read_humidity() {
    int ret;
    
    data_mutex.lock();
    ret = mems->ht_sensor->GetHumidity(&humidity_percent);
    data_mutex.unlock();
    if (ret)
        logError("reading humidity failed");
}

void read_pressure() {
    int ret;
    
    data_mutex.lock();
    ret = mems->pt_sensor->GetPressure(&pressure_mbar);
    data_mutex.unlock();
    if (ret)
        logError("reading pressure failed");
}

void read_moisture() {
    data_mutex.lock();
    moisture_percent = moisture_sensor;
    data_mutex.unlock();
}

void read_magnetometer() {
    int ret;
    
    data_mutex.lock();
    ret = mems->magnetometer->Get_M_Axes(mag_mgauss);
    data_mutex.unlock();
    if (ret)
        logError("reading magnetometer failed");
}

void read_accelerometer() {
    int ret;
    
    data_mutex.lock();
    ret = mems->GetAccelerometer()->Get_X_Axes(acc_mg);
    data_mutex.unlock();
    if (ret)
        logError("reading accelerometer failed");
}

void read_gyroscope() {
    int ret;
    
    data_mutex.lock();
    ret = mems->GetGyroscope()->Get_G_Axes(gyro_mdps);
    data_mutex.unlock();
    if (ret)
        logError("reading gyroscope failed");
}