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 Paul Jaeger

Files at this revision

API Documentation at this revision

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

MbedJSONValue.lib Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_IKS01A1.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mtsas.lib Show annotated file Show diff for this revision Revisions of this file
--- /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