Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MbedJSONValue mbed mtsas
Fork of UUU_MultiTech_Dragonfly_Sprint_SF by
Diff: main.cpp
- Revision:
- 0:a44e71488e1f
- Child:
- 1:a049d113e250
--- /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");
+}
