Initial Program for MultiTech Dragonfly to communicate to PTC ThingWorx. Sensors are from Rohm version1
Dependencies: MbedJSONValue mbed mtsas
Fork of UUU_MultiTech_Dragonfly_Sprint by
Revision 0:a44e71488e1f, committed 2015-09-24
- Comitter:
- mfiore
- Date:
- Thu Sep 24 17:56:49 2015 +0000
- Child:
- 1:a049d113e250
- Commit message:
- first commit - mtsas doesn't play nice with rtos. think it's a serial irq + rtos issue
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MbedJSONValue.lib Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/samux/code/MbedJSONValue/#10a99cdf7846
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IKS01A1.lib Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/ST/code/X_NUCLEO_IKS01A1/#a91987e8cf51
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,312 @@ +/************************************************************************* + * 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"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#9d001ed5feec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4f6c30876dfa \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtsas.lib Thu Sep 24 17:56:49 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/MultiTech/code/mtsas/#1667a524c7a3