Demonstration for connecting Multitech mDot/mDotbox to the Telit devicewise platform.

Dependencies:   DOGS102 GpsParser ISL29011 MMA845x MPL3115A2 MTS-Serial NCP5623B mDot_X_NUCLEO_IKS01A1 libmDot-mbed5

Committer:
pferland
Date:
Tue May 16 16:45:05 2017 +0000
Revision:
2:fc20e16833af
Parent:
1:de9172a990bd
Corrected missing loop delay

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pferland 0:5a7579045f49 1 /*================================================================================
pferland 0:5a7579045f49 2 *
pferland 0:5a7579045f49 3 * CLASIFICATION: **** PUBLIC RELEASE AS-IS APPLICATION EXAMPLE ****
pferland 0:5a7579045f49 4 *
pferland 0:5a7579045f49 5 * SOURCE FILE NAME: main.cpp
pferland 0:5a7579045f49 6 *
pferland 0:5a7579045f49 7 * DESCRIPTIVE NAME: MBED Source for MultiTech mDot, EVB, and MDOT-BOX Devices
pferland 0:5a7579045f49 8 *
pferland 0:5a7579045f49 9 * COPYRIGHT: Copyright 2014-2017, Telit
pferland 0:5a7579045f49 10 *
pferland 0:5a7579045f49 11 * LICENSED MATERIAL - PROGRAM PROPERTY OF TELIT
pferland 0:5a7579045f49 12 * REFER TO TELIT COPYRIGHT INSTRUCTION
pferland 0:5a7579045f49 13 *
pferland 0:5a7579045f49 14 ** WEB SITE: www.telit.com
pferland 0:5a7579045f49 15 *
pferland 0:5a7579045f49 16 * WRITTEN BY: Eliott Fersko and John Keever
pferland 0:5a7579045f49 17 *
pferland 0:5a7579045f49 18 * DATE: April 17, 2017
pferland 0:5a7579045f49 19 *
pferland 0:5a7579045f49 20 * VERSION: 1.02
pferland 0:5a7579045f49 21 *
pferland 0:5a7579045f49 22 * FUNCTION: Provide working example for LoRa 'Sensor-to-Cloud'
pferland 0:5a7579045f49 23 * Demonstration using MultiTech LoRa Starter Kit and
pferland 0:5a7579045f49 24 * Telit Data and Cloud Platform Services Offerings
pferland 0:5a7579045f49 25 *
pferland 0:5a7579045f49 26 * SOURCE FILE TYPE: MBED C++
pferland 0:5a7579045f49 27 *
pferland 0:5a7579045f49 28 * FUNCTIONS/ENTRY POINTS: main
pferland 0:5a7579045f49 29 *
pferland 0:5a7579045f49 30 * INPUT = None.
pferland 0:5a7579045f49 31 * OUTPUT = None.
pferland 0:5a7579045f49 32 *
pferland 0:5a7579045f49 33 * EXIT-NORMAL = N/A
pferland 0:5a7579045f49 34 * EXIT-ERROR = N/A
pferland 0:5a7579045f49 35 *
pferland 0:5a7579045f49 36 * EXTERNAL REFERENCES = None.
pferland 0:5a7579045f49 37 *
pferland 0:5a7579045f49 38 * EXTERNAL FUNCTIONS = None.
pferland 0:5a7579045f49 39 *
pferland 0:5a7579045f49 40 * CONTROL BLOCKS = None.
pferland 0:5a7579045f49 41 *
pferland 0:5a7579045f49 42 *================================================================================*/
pferland 0:5a7579045f49 43 /* LEGAL DISCLAIMER */
pferland 0:5a7579045f49 44 /*================================================================================
pferland 0:5a7579045f49 45
pferland 0:5a7579045f49 46 Redistribution and use in source and binary forms, with or without
pferland 0:5a7579045f49 47 modification, are permitted provided that the following conditions
pferland 0:5a7579045f49 48 are met:
pferland 0:5a7579045f49 49
pferland 0:5a7579045f49 50 Neither the name of ILS Technology nor Telit nor the names of its
pferland 0:5a7579045f49 51 contributors may be used to endorse or promote products derived
pferland 0:5a7579045f49 52 from this software without specific prior written permission.
pferland 0:5a7579045f49 53
pferland 0:5a7579045f49 54 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
pferland 0:5a7579045f49 55 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
pferland 0:5a7579045f49 56 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
pferland 0:5a7579045f49 57 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
pferland 0:5a7579045f49 58 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
pferland 0:5a7579045f49 59 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
pferland 0:5a7579045f49 60 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
pferland 0:5a7579045f49 61 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
pferland 0:5a7579045f49 62 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
pferland 0:5a7579045f49 63 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
pferland 0:5a7579045f49 64 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pferland 0:5a7579045f49 65
pferland 0:5a7579045f49 66 *================================================================================*/
pferland 0:5a7579045f49 67 /* CHANGE LOG */
pferland 0:5a7579045f49 68 /*================================================================================*/
pferland 0:5a7579045f49 69 /* |Changed | | */
pferland 0:5a7579045f49 70 /* Date | by |Version ID| Comments */
pferland 0:5a7579045f49 71 /*----------+--------+----------+-------------------------------------------------*/
pferland 0:5a7579045f49 72 /*04-12-2017|JEK |V1.00 |Original Version - mDot, EVB, MDOT-BOX */
pferland 0:5a7579045f49 73 /*04-14-2017|JEK |V1.01 |Added IRQ Handlers - SW1/SW2 (Threads?) */
pferland 0:5a7579045f49 74 /*04-17-2017|JEK |V1.02 |Added Binary LoRa Payload Message Framing Type */
pferland 0:5a7579045f49 75 /*04-24-2017|EMF |V1.03 |Updated Libraries */
pferland 0:5a7579045f49 76 /*05-10-2017|EMF |V1.04 |Added support for ST-Micro MEMS Sensor Shield */
pferland 0:5a7579045f49 77 /*================================================================================*/
pferland 0:5a7579045f49 78 /*NOTE: Please keep the change log up to date!!! */
pferland 0:5a7579045f49 79 /*================================================================================*/
pferland 0:5a7579045f49 80
pferland 0:5a7579045f49 81 #include "mbed.h"
pferland 0:5a7579045f49 82 #include "MMA845x.h"
pferland 0:5a7579045f49 83 #include "MPL3115A2.h"
pferland 0:5a7579045f49 84 #include "ISL29011.h"
pferland 0:5a7579045f49 85 #include "NCP5623B.h"
pferland 0:5a7579045f49 86 #include "DOGS102.h"
pferland 0:5a7579045f49 87 #include "font_6x8.h"
pferland 0:5a7579045f49 88 #include "MultiTech_Logo.h"
pferland 0:5a7579045f49 89 #include "mDot.h"
pferland 0:5a7579045f49 90 #include "rtos.h"
pferland 0:5a7579045f49 91 #include "GPSPARSER.h"
pferland 0:5a7579045f49 92 #include "MTSSerial.h"
pferland 0:5a7579045f49 93 #include "x_nucleo_iks01a1.h"
pferland 0:5a7579045f49 94
pferland 0:5a7579045f49 95 #include <cmath>
pferland 0:5a7579045f49 96 #include <string>
pferland 0:5a7579045f49 97 #include <vector>
pferland 0:5a7579045f49 98 #include <ctime>
pferland 0:5a7579045f49 99 #include <Ticker.h>
pferland 0:5a7579045f49 100
pferland 0:5a7579045f49 101 #define CALL_METH(obj, meth, param, ret) ((obj == NULL) ? \
pferland 0:5a7579045f49 102 ((*(param) = (ret)), 0) : \
pferland 0:5a7579045f49 103 ((obj)->meth(param)) \
pferland 0:5a7579045f49 104 )
pferland 0:5a7579045f49 105
pferland 0:5a7579045f49 106
pferland 0:5a7579045f49 107 enum LED1_COLOR {
pferland 0:5a7579045f49 108 RED = 0,
pferland 0:5a7579045f49 109 GREEN = 1
pferland 0:5a7579045f49 110 };
pferland 0:5a7579045f49 111
pferland 0:5a7579045f49 112 namespace {
pferland 0:5a7579045f49 113 const int MS_INTERVALS = 1000;
pferland 0:5a7579045f49 114 }
pferland 0:5a7579045f49 115
pferland 0:5a7579045f49 116 /*
pferland 0:5a7579045f49 117 * union for converting from 32-bit to 4 8-bit values
pferland 0:5a7579045f49 118 */
pferland 0:5a7579045f49 119 union convert32 {
pferland 0:5a7579045f49 120 int32_t f_s; // convert from signed 32 bit int
pferland 0:5a7579045f49 121 uint32_t f_u; // convert from unsigned 32 bit int
pferland 0:5a7579045f49 122 uint8_t t_u[4]; // convert to 8 bit unsigned array
pferland 0:5a7579045f49 123 };
pferland 0:5a7579045f49 124
pferland 0:5a7579045f49 125 typedef struct {
pferland 0:5a7579045f49 126 int32_t AXIS_X;
pferland 0:5a7579045f49 127 int32_t AXIS_Y;
pferland 0:5a7579045f49 128 int32_t AXIS_Z;
pferland 0:5a7579045f49 129 } AxesRaw_TypeDef;
pferland 0:5a7579045f49 130
pferland 0:5a7579045f49 131
pferland 0:5a7579045f49 132 /*
pferland 0:5a7579045f49 133 * union for converting from 16- bit to 2 8-bit values
pferland 0:5a7579045f49 134 */
pferland 0:5a7579045f49 135 union convert16 {
pferland 0:5a7579045f49 136 int16_t f_s; // convert from signed 16 bit int
pferland 0:5a7579045f49 137 uint16_t f_u; // convert from unsigned 16 bit int
pferland 0:5a7579045f49 138 uint8_t t_u[2]; // convert to 8 bit unsigned array
pferland 0:5a7579045f49 139 };
pferland 0:5a7579045f49 140
pferland 0:5a7579045f49 141 //DigitalIn mDot02(PA_2); // GPIO/UART_TX
pferland 0:5a7579045f49 142 //DigitalOut mDot03(PA_3); // GPIO/UART_RX
pferland 0:5a7579045f49 143 //DigitalIn mDot04(PA_6); // GPIO/SPI_MISO
pferland 0:5a7579045f49 144 //DigitalIn mDot06(PA_8); // GPIO/I2C_SCL
pferland 0:5a7579045f49 145 //DigitalIn mDot07(PC_9); // GPIO/I2C_SDA
pferland 0:5a7579045f49 146
pferland 0:5a7579045f49 147 InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB
pferland 0:5a7579045f49 148 InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB
pferland 0:5a7579045f49 149
pferland 0:5a7579045f49 150 //DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI
pferland 0:5a7579045f49 151
pferland 0:5a7579045f49 152 InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB
pferland 0:5a7579045f49 153 DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D
pferland 0:5a7579045f49 154 InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB
pferland 0:5a7579045f49 155 InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB
pferland 0:5a7579045f49 156 DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB
pferland 0:5a7579045f49 157
pferland 0:5a7579045f49 158 // DigitalIn mDot18(PA_5); // GPIO/SPI_SCK
pferland 0:5a7579045f49 159 // DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off
pferland 0:5a7579045f49 160 // AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB
pferland 0:5a7579045f49 161
pferland 0:5a7579045f49 162 Serial debugUART(PA_9, PA_10); // mDot debug UART
pferland 0:5a7579045f49 163 MTSSerial mDotUART(PA_2,PA_3); // mDot external UART mDot02 and mDot03
pferland 0:5a7579045f49 164 I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7
pferland 0:5a7579045f49 165 SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18
pferland 0:5a7579045f49 166 AnalogIn current_sensor(PB_1); // EVB - GPIO - Current Sensor Analog Input
pferland 0:5a7579045f49 167
pferland 0:5a7579045f49 168 /* **** replace these values with the proper public or private network settings ****
pferland 0:5a7579045f49 169 * config_network_nameand config_network_pass are for private networks.
pferland 0:5a7579045f49 170 */
pferland 0:5a7579045f49 171
pferland 0:5a7579045f49 172 //static std::string config_network_name = "telitlora";
pferland 0:5a7579045f49 173 //static std::string config_network_pass = "telitpass";
pferland 0:5a7579045f49 174 //static uint8_t config_frequency_sub_band = 7;
pferland 0:5a7579045f49 175
pferland 0:5a7579045f49 176
pferland 0:5a7579045f49 177
pferland 0:5a7579045f49 178 static volatile bool timer_irq_triggered = false;
pferland 0:5a7579045f49 179 static volatile bool ff_irq_triggered = false;
pferland 0:5a7579045f49 180
pferland 1:de9172a990bd 181 static std::string config_network_name = "MTCDT-19186797";
pferland 1:de9172a990bd 182 static std::string config_network_pass = "MTCDT-19186797";
pferland 0:5a7579045f49 183 static uint8_t config_frequency_sub_band = 1;
pferland 0:5a7579045f49 184
pferland 0:5a7579045f49 185 /* config_app_id and config_app_key are for public networks.
pferland 0:5a7579045f49 186 static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
pferland 0:5a7579045f49 187 std::vector<uint8_t> config_app_id;
pferland 0:5a7579045f49 188 static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
pferland 0:5a7579045f49 189 std::vector<uint8_t> config_app_key;
pferland 0:5a7579045f49 190 */
pferland 0:5a7579045f49 191
pferland 0:5a7579045f49 192 uint8_t result;
pferland 0:5a7579045f49 193 uint8_t data;
pferland 0:5a7579045f49 194 uint8_t sf_val = mDot::SF_7;
pferland 0:5a7579045f49 195 uint8_t pwr_val = 11; // dBm
pferland 0:5a7579045f49 196 uint8_t swp_pwr;
pferland 0:5a7579045f49 197 uint8_t swp_sf;
pferland 0:5a7579045f49 198
pferland 0:5a7579045f49 199 // max size of text string for 6x8 font. Set to 12 if using 8x8 font
pferland 0:5a7579045f49 200 char txtstr[17];
pferland 0:5a7579045f49 201
pferland 0:5a7579045f49 202 int32_t mdot_ret;
pferland 0:5a7579045f49 203 int32_t join_delay;
pferland 0:5a7579045f49 204
pferland 0:5a7579045f49 205 osThreadId mainThreadID;
pferland 0:5a7579045f49 206
pferland 0:5a7579045f49 207 // flags for push button debounce code
pferland 0:5a7579045f49 208 bool pb1_low = false;
pferland 0:5a7579045f49 209 bool pb2_low = false;
pferland 0:5a7579045f49 210 bool toggle_text = false;
pferland 0:5a7579045f49 211 bool sw1_state = false;
pferland 0:5a7579045f49 212 bool sw2_state = false;
pferland 0:5a7579045f49 213
pferland 0:5a7579045f49 214 uint32_t num_whole;
pferland 0:5a7579045f49 215 uint16_t num_frac;
pferland 0:5a7579045f49 216
pferland 0:5a7579045f49 217 uint32_t pressure;
pferland 0:5a7579045f49 218 double current;
pferland 0:5a7579045f49 219
pferland 0:5a7579045f49 220 bool exit_program = false;
pferland 0:5a7579045f49 221
pferland 0:5a7579045f49 222 //EVB sensor variables
pferland 0:5a7579045f49 223 MMA845x_DATA accel_data;
pferland 0:5a7579045f49 224 MPL3115A2_DATA baro_data;
pferland 0:5a7579045f49 225 uint16_t lux_data;
pferland 0:5a7579045f49 226 MMA845x* evbAccel;
pferland 0:5a7579045f49 227 MPL3115A2* evbBaro;
pferland 0:5a7579045f49 228 ISL29011* evbAmbLight;
pferland 0:5a7579045f49 229 NCP5623B* evbBackLight;
pferland 0:5a7579045f49 230 DOGS102* evbLCD;
pferland 0:5a7579045f49 231
pferland 0:5a7579045f49 232 //MEMS sensor variables
pferland 0:5a7579045f49 233 float TEMPERATURE_Value;
pferland 0:5a7579045f49 234 float HUMIDITY_Value;
pferland 0:5a7579045f49 235 float PRESSURE_Value;
pferland 0:5a7579045f49 236 float PRESSURE_Temp_Value;
pferland 0:5a7579045f49 237 AxesRaw_TypeDef MAG_Value;
pferland 0:5a7579045f49 238 AxesRaw_TypeDef ACC_Value;
pferland 0:5a7579045f49 239 AxesRaw_TypeDef GYR_Value;
pferland 0:5a7579045f49 240 char buffer1[32];
pferland 0:5a7579045f49 241 char buffer2[32];
pferland 0:5a7579045f49 242 char buffer3[32];
pferland 0:5a7579045f49 243 char buffer4[32];
pferland 0:5a7579045f49 244 unsigned int ret = 0;
pferland 0:5a7579045f49 245
pferland 0:5a7579045f49 246 mDot* mdot_radio;
pferland 0:5a7579045f49 247 Mutex mdot_mutex;
pferland 0:5a7579045f49 248
pferland 0:5a7579045f49 249 //MEMS shield sensor variables
pferland 0:5a7579045f49 250 //static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance();
pferland 0:5a7579045f49 251 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
pferland 0:5a7579045f49 252 static Ticker ticker;
pferland 0:5a7579045f49 253
pferland 0:5a7579045f49 254
pferland 0:5a7579045f49 255 GyroSensor *memsGyro;
pferland 0:5a7579045f49 256 MotionSensor *memsAccel;
pferland 0:5a7579045f49 257 MagneticSensor *memsMag;
pferland 0:5a7579045f49 258 HumiditySensor *memsHumidity;
pferland 0:5a7579045f49 259 PressureSensor *memsPressure;
pferland 0:5a7579045f49 260 TempSensor *memsTemp1;
pferland 0:5a7579045f49 261 TempSensor *memsTemp2;
pferland 0:5a7579045f49 262
pferland 0:5a7579045f49 263
pferland 0:5a7579045f49 264 GPSPARSER* mdot_gps;
pferland 0:5a7579045f49 265
pferland 0:5a7579045f49 266 convert32 convertl;
pferland 0:5a7579045f49 267 convert16 converts;
pferland 0:5a7579045f49 268
pferland 0:5a7579045f49 269 void pb1ISR(void);
pferland 0:5a7579045f49 270 void pb2ISR(void);
pferland 0:5a7579045f49 271 void pb1_debounce(void const *args);
pferland 0:5a7579045f49 272 void pb2_debounce(void const *args);
pferland 0:5a7579045f49 273
pferland 0:5a7579045f49 274 MPL3115A2* resetBaro(const MPL3115A2* oldBaro);
pferland 0:5a7579045f49 275 void log_error(mDot* dot, const char* msg, int32_t retval);
pferland 0:5a7579045f49 276 int32_t sendString(const std::string text);
pferland 0:5a7579045f49 277 bool writeValueOrError();
pferland 0:5a7579045f49 278
pferland 0:5a7579045f49 279 const int FAIL_MAX=15;
pferland 0:5a7579045f49 280 int failtime=FAIL_MAX;
pferland 0:5a7579045f49 281 int cycle_cnt = 0;
pferland 0:5a7579045f49 282
pferland 0:5a7579045f49 283 char sensor_text[64];
pferland 0:5a7579045f49 284 char lora_temp_string[16];
pferland 0:5a7579045f49 285 char lora_alt_string[16];
pferland 0:5a7579045f49 286 char lora_press_string[16];
pferland 0:5a7579045f49 287 char lora_light_string[16];
pferland 0:5a7579045f49 288 char lora_current_string[16];
pferland 0:5a7579045f49 289 char lora_humid_string[16];
pferland 0:5a7579045f49 290
pferland 0:5a7579045f49 291 bool bHasGPS = false;
pferland 0:5a7579045f49 292 bool bHasACC = false;
pferland 0:5a7579045f49 293 bool bHasLCD = false;
pferland 0:5a7579045f49 294
pferland 0:5a7579045f49 295 /*** Helper Functions ------------------------------------------------------------ ***/
pferland 0:5a7579045f49 296 /* print floats & doubles */
pferland 0:5a7579045f49 297 static char *printDouble(char* str, double v, int decimalDigits=2)
pferland 0:5a7579045f49 298 {
pferland 0:5a7579045f49 299 int i = 1;
pferland 0:5a7579045f49 300 int intPart, fractPart;
pferland 0:5a7579045f49 301 int len;
pferland 0:5a7579045f49 302 char *ptr;
pferland 0:5a7579045f49 303
pferland 0:5a7579045f49 304 /* prepare decimal digits multiplicator */
pferland 0:5a7579045f49 305 for (;decimalDigits!=0; i*=10, decimalDigits--);
pferland 0:5a7579045f49 306
pferland 0:5a7579045f49 307 /* calculate integer & fractinal parts */
pferland 0:5a7579045f49 308 intPart = (int)v;
pferland 0:5a7579045f49 309 fractPart = (int)((v-(double)(int)v)*i);
pferland 0:5a7579045f49 310
pferland 0:5a7579045f49 311 /* fill in integer part */
pferland 0:5a7579045f49 312 sprintf(str, "%i.", intPart);
pferland 0:5a7579045f49 313
pferland 0:5a7579045f49 314 /* prepare fill in of fractional part */
pferland 0:5a7579045f49 315 len = strlen(str);
pferland 0:5a7579045f49 316 ptr = &str[len];
pferland 0:5a7579045f49 317
pferland 0:5a7579045f49 318 /* fill in leading fractional zeros */
pferland 0:5a7579045f49 319 for (i/=10;i>1; i/=10, ptr++) {
pferland 0:5a7579045f49 320 if(fractPart >= i) break;
pferland 0:5a7579045f49 321 *ptr = '0';
pferland 0:5a7579045f49 322 }
pferland 0:5a7579045f49 323
pferland 0:5a7579045f49 324 /* fill in (rest of) fractional part */
pferland 0:5a7579045f49 325 sprintf(ptr, "%i", fractPart);
pferland 0:5a7579045f49 326
pferland 0:5a7579045f49 327 return str;
pferland 0:5a7579045f49 328 }
pferland 0:5a7579045f49 329 /*===================================================================================
pferland 0:5a7579045f49 330 Main Program Logic - Entry
pferland 0:5a7579045f49 331 ===================================================================================*/
pferland 0:5a7579045f49 332 int main()
pferland 0:5a7579045f49 333 {
pferland 0:5a7579045f49 334 std::vector<uint8_t> mdot_data;
pferland 0:5a7579045f49 335 std::vector<uint8_t> mdot_EUI;
pferland 0:5a7579045f49 336 uint16_t i = 0;
pferland 0:5a7579045f49 337 uint8_t id1 = 0;
pferland 0:5a7579045f49 338
pferland 0:5a7579045f49 339 debugUART.baud(9600);
pferland 0:5a7579045f49 340
pferland 0:5a7579045f49 341 printf ("Starting Application...\r\n");
pferland 0:5a7579045f49 342
pferland 0:5a7579045f49 343 mainThreadID = osThreadGetId();
pferland 0:5a7579045f49 344
pferland 0:5a7579045f49 345 printf("Begin I2C/SPI Device Initialization...\r\n");
pferland 0:5a7579045f49 346
pferland 0:5a7579045f49 347
pferland 0:5a7579045f49 348 // Use Magnetometer As MEMS sensor shield Enumeration...
pferland 0:5a7579045f49 349
pferland 0:5a7579045f49 350 memsMag = mems_expansion_board->magnetometer;
pferland 0:5a7579045f49 351 CALL_METH(memsMag, ReadID, &id1, 0x0);
pferland 0:5a7579045f49 352 printf("Magnetometer ID value = %i \n\r", id1);
pferland 0:5a7579045f49 353
pferland 0:5a7579045f49 354 //chcek for default magnetomter ID 61...
pferland 0:5a7579045f49 355 if(id1 == 61)
pferland 0:5a7579045f49 356 {
pferland 0:5a7579045f49 357 printf("Magnetometer Found - MEMS sensor shield detected...\r\n");
pferland 0:5a7579045f49 358 bHasACC = true;
pferland 0:5a7579045f49 359
pferland 0:5a7579045f49 360 // Initialize Integrated Sensors...
pferland 0:5a7579045f49 361 printf("Instantiate Magnetometer...\r\n");
pferland 0:5a7579045f49 362 memsMag = mems_expansion_board->magnetometer;
pferland 0:5a7579045f49 363
pferland 0:5a7579045f49 364 printf("Instantiate Accelerometer...\r\n");
pferland 0:5a7579045f49 365 memsAccel = mems_expansion_board->GetAccelerometer();
pferland 0:5a7579045f49 366
pferland 0:5a7579045f49 367 printf("Instantiate Gyroscope...\r\n");
pferland 0:5a7579045f49 368 memsGyro = mems_expansion_board->GetGyroscope();
pferland 0:5a7579045f49 369
pferland 0:5a7579045f49 370 printf("Instantiate Barometric Pressure Sensor...\r\n");
pferland 0:5a7579045f49 371 memsPressure = mems_expansion_board->pt_sensor;
pferland 0:5a7579045f49 372
pferland 0:5a7579045f49 373 printf("Instantiate Temperature Pressure Sensor...\r\n");
pferland 0:5a7579045f49 374 //memsTemp1 = mems_expansion_board->ht_sensor;
pferland 0:5a7579045f49 375 memsTemp2 = mems_expansion_board->pt_sensor;
pferland 0:5a7579045f49 376
pferland 0:5a7579045f49 377 printf("Instantiate Humidity Sensor...\r\n");
pferland 0:5a7579045f49 378 memsHumidity = mems_expansion_board->ht_sensor;
pferland 0:5a7579045f49 379
pferland 0:5a7579045f49 380 }
pferland 0:5a7579045f49 381
pferland 0:5a7579045f49 382
pferland 0:5a7579045f49 383 else
pferland 0:5a7579045f49 384 {
pferland 0:5a7579045f49 385 printf("No Magnetometer Found...\r\n");
pferland 0:5a7579045f49 386 // Use Accelerometer As MDOT-BOX/EVB Enumeration...
pferland 0:5a7579045f49 387 printf("Instantiate Accelerometer...\r\n");
pferland 0:5a7579045f49 388 evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS);
pferland 0:5a7579045f49 389
pferland 0:5a7579045f49 390 printf("Accelerometer Status = %d\r\n", evbAccel->getStatus());
pferland 0:5a7579045f49 391 printf("Accelerometer who_am_i value = %x \n\r", evbAccel->getWhoAmI());
pferland 0:5a7579045f49 392
pferland 0:5a7579045f49 393 if( (evbAccel->getStatus() == 1) && (evbAccel->getWhoAmI() == 0) )
pferland 0:5a7579045f49 394 {
pferland 0:5a7579045f49 395 printf("No Accelerometer Found - Basic mDot, Not MDOT-BOX or EVB...\r\n");
pferland 0:5a7579045f49 396 }
pferland 0:5a7579045f49 397
pferland 0:5a7579045f49 398 else
pferland 0:5a7579045f49 399 {
pferland 0:5a7579045f49 400 printf("Accelerometer Found - Either MDOT-BOX or EVB...\r\n");
pferland 0:5a7579045f49 401 bHasACC = true;
pferland 0:5a7579045f49 402
pferland 0:5a7579045f49 403 // Initialize Integrated Sensors...
pferland 0:5a7579045f49 404 printf("Instantiate Barometric Pressure Sensor...\r\n");
pferland 0:5a7579045f49 405 evbBaro = new MPL3115A2(mDoti2c); // Setup Barometric Sensor
pferland 0:5a7579045f49 406 printf("Barometric Sensor Status = %d\r\n", evbBaro->getStatus());
pferland 0:5a7579045f49 407 printf("Barometer who_am_i check = %d\r\n", evbBaro->testWhoAmI());
pferland 0:5a7579045f49 408 printf("Barometer who_am_i check = %s\r\n", evbBaro->testWhoAmI() ? "TRUE" : "FALSE");
pferland 0:5a7579045f49 409
pferland 0:5a7579045f49 410 if( evbBaro->getStatus() == 0 ) printf("No Barometric Sensor...\r\n");
pferland 0:5a7579045f49 411
pferland 0:5a7579045f49 412 printf("Instantiate Ambient Light Sensor...\r\n");
pferland 0:5a7579045f49 413 evbAmbLight = new ISL29011(mDoti2c); // Setup Ambient Light Sensor
pferland 0:5a7579045f49 414
pferland 0:5a7579045f49 415 // Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz
pferland 0:5a7579045f49 416 // Normal oversample mode, High pass filter off
pferland 0:5a7579045f49 417 evbAccel->setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF );
pferland 0:5a7579045f49 418
pferland 0:5a7579045f49 419 // Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition.
pferland 0:5a7579045f49 420 // and a sample taken every second when in active mode
pferland 0:5a7579045f49 421 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
pferland 0:5a7579045f49 422
pferland 0:5a7579045f49 423 // Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution, and 16000 lux range
pferland 0:5a7579045f49 424 evbAmbLight->setMode(ISL29011::ALS_CONT);
pferland 0:5a7579045f49 425 evbAmbLight->setResolution(ISL29011::ADC_16BIT);
pferland 0:5a7579045f49 426 evbAmbLight->setRange(ISL29011::RNG_16000);
pferland 0:5a7579045f49 427
pferland 0:5a7579045f49 428 // Set the accelerometer for active mode
pferland 0:5a7579045f49 429 evbAccel->activeMode();
pferland 0:5a7579045f49 430
pferland 0:5a7579045f49 431 // Clear the min-max registers in the Barometric Sensor
pferland 0:5a7579045f49 432 evbBaro->clearMinMaxRegs();
pferland 0:5a7579045f49 433
pferland 0:5a7579045f49 434 // Support Integrated LCD Display
pferland 0:5a7579045f49 435 bHasLCD = true;
pferland 0:5a7579045f49 436
pferland 0:5a7579045f49 437 printf("Instantiate BackLight and LCD Display...\r\n");
pferland 0:5a7579045f49 438 evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip
pferland 0:5a7579045f49 439
pferland 0:5a7579045f49 440 evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD Display
pferland 0:5a7579045f49 441
pferland 0:5a7579045f49 442 printf("Font Table Address: %p\r\n",&font_6x8);
pferland 0:5a7579045f49 443 printf("Bitmap Logo Address: %p\r\n",&MultiTech_Logo);
pferland 0:5a7579045f49 444
pferland 0:5a7579045f49 445 // Setup and display logo on LCD
pferland 0:5a7579045f49 446 evbLCD->startUpdate();
pferland 0:5a7579045f49 447 evbLCD->writeBitmap(0,0,MultiTech_Logo);
pferland 0:5a7579045f49 448
pferland 0:5a7579045f49 449 sprintf(txtstr,"MTDOT-EVB");
pferland 0:5a7579045f49 450 evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 451 sprintf(txtstr,"Sensor Demo");
pferland 0:5a7579045f49 452 evbLCD->writeText(18,4,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 453
pferland 0:5a7579045f49 454 evbLCD->endUpdate();
pferland 0:5a7579045f49 455
pferland 0:5a7579045f49 456 printf("Setup PushButton Interface Handlers...\r\n");
pferland 0:5a7579045f49 457
pferland 0:5a7579045f49 458 printf("Launching Debounce Threads...\r\n");
pferland 0:5a7579045f49 459 Thread thread_1(pb1_debounce);
pferland 0:5a7579045f49 460 Thread thread_2(pb2_debounce);
pferland 0:5a7579045f49 461 printf("Debounce Threads Launched...\r\n");
pferland 0:5a7579045f49 462
pferland 0:5a7579045f49 463 printf("Set SW1/SW2 IRQs...\r\n");
pferland 0:5a7579045f49 464 // Setup SW1 as Data rate and power out select
pferland 0:5a7579045f49 465 mDot08.disable_irq();
pferland 0:5a7579045f49 466 mDot08.fall(&pb1ISR);
pferland 0:5a7579045f49 467
pferland 0:5a7579045f49 468 // need to call this function after rise or fall because rise/fall sets mode to PullNone
pferland 0:5a7579045f49 469 mDot08.mode(PullUp);
pferland 0:5a7579045f49 470 mDot08.enable_irq();
pferland 0:5a7579045f49 471
pferland 0:5a7579045f49 472 // Setup SW2 as send PING
pferland 0:5a7579045f49 473 mDot09.disable_irq();
pferland 0:5a7579045f49 474 mDot09.fall(&pb2ISR);
pferland 0:5a7579045f49 475
pferland 0:5a7579045f49 476 // need to call this function after rise or fall because rise/fall sets mode to PullNone
pferland 0:5a7579045f49 477 mDot09.mode(PullUp);
pferland 0:5a7579045f49 478 mDot09.enable_irq();
pferland 0:5a7579045f49 479
pferland 0:5a7579045f49 480 // Setting other InterruptIn pins with Pull Ups
pferland 0:5a7579045f49 481 mDot12.mode(PullUp);
pferland 0:5a7579045f49 482 mDot15.mode(PullUp);
pferland 0:5a7579045f49 483 mDot16.mode(PullUp);
pferland 0:5a7579045f49 484
pferland 0:5a7579045f49 485 printf("SW1/SW2 IRQs Set...\r\n");
pferland 0:5a7579045f49 486 }
pferland 0:5a7579045f49 487 }
pferland 0:5a7579045f49 488
pferland 0:5a7579045f49 489 printf("I2C/SPI Device Initialization Complete...\r\n");
pferland 0:5a7579045f49 490
pferland 0:5a7579045f49 491 printf("\r\nSetup mDot Radio Communications...\r\n");
pferland 0:5a7579045f49 492
pferland 0:5a7579045f49 493 // get a mDot handle
pferland 0:5a7579045f49 494 mdot_radio = mDot::getInstance();
pferland 0:5a7579045f49 495
pferland 0:5a7579045f49 496 if (mdot_radio)
pferland 0:5a7579045f49 497 {
pferland 0:5a7579045f49 498 // reset to default config so we know what state we're in
pferland 0:5a7579045f49 499 mdot_mutex.lock(); // lock mdot before setting configuration
pferland 0:5a7579045f49 500 mdot_radio->resetConfig();
pferland 0:5a7579045f49 501
pferland 0:5a7579045f49 502 // Setting up LED1 as activity LED
pferland 0:5a7579045f49 503 mdot_radio->setActivityLedPin(PB_0);
pferland 0:5a7579045f49 504 mdot_radio->setActivityLedEnable(true);
pferland 0:5a7579045f49 505
pferland 0:5a7579045f49 506 // Read node ID
pferland 0:5a7579045f49 507 mdot_EUI = mdot_radio->getDeviceId();
pferland 0:5a7579045f49 508 printf("mDot EUI = ");
pferland 0:5a7579045f49 509
pferland 0:5a7579045f49 510 for(i=0; i<mdot_EUI.size(); i++) {
pferland 0:5a7579045f49 511 printf("%02x ", mdot_EUI[i]);
pferland 0:5a7579045f49 512 }
pferland 0:5a7579045f49 513 printf("\r\n");
pferland 0:5a7579045f49 514
pferland 0:5a7579045f49 515 // Setting up the mDot with network information.
pferland 0:5a7579045f49 516
pferland 0:5a7579045f49 517 // This call sets up private or public mode on the MTDOT. Set the function to true if
pferland 0:5a7579045f49 518 // connecting to a public network
pferland 0:5a7579045f49 519 printf("Setting Private Network Mode...\r\n");
pferland 0:5a7579045f49 520 if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 521 log_error(mdot_radio, "ERROR: Failed to set Public Network Mode", mdot_ret);
pferland 0:5a7579045f49 522 }
pferland 0:5a7579045f49 523
pferland 0:5a7579045f49 524 // Frequency sub-band is valid for NAM only and for Private networks should be set to a value
pferland 0:5a7579045f49 525 // between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
pferland 0:5a7579045f49 526 // This function can be commented out for EU networks
pferland 0:5a7579045f49 527 printf("Setting Frequency Sub-Band...\r\n");
pferland 0:5a7579045f49 528 if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 529 log_error(mdot_radio, "ERROR: Failed to set Frequency Sub-Band", mdot_ret);
pferland 0:5a7579045f49 530 }
pferland 0:5a7579045f49 531
pferland 0:5a7579045f49 532 // Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm
pferland 0:5a7579045f49 533 printf("Setting TX Power Level to %2d dBm...\r\n", pwr_val);
pferland 0:5a7579045f49 534 if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 535 log_error(mdot_radio, "ERROR: Failed to set TX Power Level", mdot_ret);
pferland 0:5a7579045f49 536 }
pferland 0:5a7579045f49 537
pferland 0:5a7579045f49 538 // Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_10
pferland 0:5a7579045f49 539 printf("Setting TX data rate to SF_7...\r\n");
pferland 0:5a7579045f49 540 if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 541 log_error(mdot_radio, "ERROR: Failed to set TX Data Rate", mdot_ret);
pferland 0:5a7579045f49 542 }
pferland 0:5a7579045f49 543
pferland 0:5a7579045f49 544 // Configure Pushbutton Display Labels...
pferland 0:5a7579045f49 545 sprintf(txtstr,"SF=%2d PWR=%2d",sf_val,pwr_val);
pferland 0:5a7579045f49 546 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 547 printf("%s\r\n",txtstr);
pferland 0:5a7579045f49 548
pferland 0:5a7579045f49 549
pferland 0:5a7579045f49 550 // Setting Packet ACK to 1 try.
pferland 0:5a7579045f49 551
pferland 0:5a7579045f49 552 printf("Setting Packet Retry to 1...\r\n");
pferland 0:5a7579045f49 553 if ((mdot_ret = mdot_radio->setAck(1)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 554 log_error(mdot_radio, "ERROR: Failed to set Packet Retry\r\n", mdot_ret);
pferland 0:5a7579045f49 555 }
pferland 0:5a7579045f49 556
pferland 0:5a7579045f49 557
pferland 0:5a7579045f49 558 // setNetworkName is used for private networks.
pferland 0:5a7579045f49 559 // Use setNetworkID(AppID) for public networks
pferland 0:5a7579045f49 560
pferland 0:5a7579045f49 561 // config_app_id.assign(app_id,app_id+7);
pferland 0:5a7579045f49 562
pferland 0:5a7579045f49 563 printf("Setting Network Name...\r\n");
pferland 0:5a7579045f49 564 if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 565 // if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 566 log_error(mdot_radio, "ERROR: Failed to set Network Name", mdot_ret);
pferland 0:5a7579045f49 567 }
pferland 0:5a7579045f49 568
pferland 0:5a7579045f49 569 // setNetworkPassphrase is used for private networks
pferland 0:5a7579045f49 570 // Use setNetworkKey for public networks
pferland 0:5a7579045f49 571
pferland 0:5a7579045f49 572 // config_app_key.assign(app_key,app_key+15);
pferland 0:5a7579045f49 573
pferland 0:5a7579045f49 574 printf("Setting Network Password...\r\n");
pferland 0:5a7579045f49 575 if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 576 // if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 577 log_error(mdot_radio, "ERROR: Failed to set Network Password", mdot_ret);
pferland 0:5a7579045f49 578 }
pferland 0:5a7579045f49 579
pferland 0:5a7579045f49 580 mdot_mutex.unlock(); // unlock mdot mutex before join attempt so SW1 can work
pferland 0:5a7579045f49 581
pferland 0:5a7579045f49 582 // attempt to join the network
pferland 0:5a7579045f49 583 printf("Joining LoRa Network...\r\n");
pferland 0:5a7579045f49 584 do {
pferland 0:5a7579045f49 585 mdot_mutex.lock(); // lock mdot mutex before join attempt
pferland 0:5a7579045f49 586 mdot_ret = mdot_radio->joinNetwork();
pferland 0:5a7579045f49 587 mdot_mutex.unlock(); // unlock mdot mutex after join attempt so SW1 can work
pferland 0:5a7579045f49 588
pferland 0:5a7579045f49 589 if (mdot_ret != mDot::MDOT_OK)
pferland 0:5a7579045f49 590 {
pferland 0:5a7579045f49 591 log_error(mdot_radio,"ERROR: Failed to Join Network:", mdot_ret);
pferland 0:5a7579045f49 592
pferland 0:5a7579045f49 593 if (toggle_text)
pferland 0:5a7579045f49 594 sprintf(txtstr," > Join Failed <");
pferland 0:5a7579045f49 595 else
pferland 0:5a7579045f49 596 sprintf(txtstr," < Join Failed >");
pferland 0:5a7579045f49 597
pferland 0:5a7579045f49 598 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 599
pferland 0:5a7579045f49 600 if (mdot_radio->getFrequencyBand() == mDot::FB_868)
pferland 0:5a7579045f49 601 {
pferland 0:5a7579045f49 602 join_delay = mdot_radio->getNextTxMs();
pferland 0:5a7579045f49 603 }
pferland 0:5a7579045f49 604 else
pferland 0:5a7579045f49 605 {
pferland 0:5a7579045f49 606 join_delay = 10;
pferland 0:5a7579045f49 607 }
pferland 0:5a7579045f49 608 printf("Join Delay = %lu\r\n",join_delay);
pferland 0:5a7579045f49 609 osDelay(join_delay + 1);
pferland 0:5a7579045f49 610 toggle_text = !toggle_text;
pferland 0:5a7579045f49 611 }
pferland 0:5a7579045f49 612
pferland 0:5a7579045f49 613 /*
pferland 0:5a7579045f49 614 * Setting TX power and Data Rate for radio just in case user requested by SW2
pferland 0:5a7579045f49 615 */
pferland 0:5a7579045f49 616 mdot_mutex.lock(); // lock mdot mutex before setting change
pferland 0:5a7579045f49 617 mdot_radio->setTxPower(pwr_val);
pferland 0:5a7579045f49 618 mdot_radio->setTxDataRate(sf_val);
pferland 0:5a7579045f49 619 mdot_mutex.unlock(); // unlock mdot mutex after settings change so SW1 can work
pferland 0:5a7579045f49 620
pferland 0:5a7579045f49 621 } while (mdot_ret != mDot::MDOT_OK);
pferland 0:5a7579045f49 622
pferland 0:5a7579045f49 623 printf("Successfully Joined LoRa Network...\r\n");
pferland 0:5a7579045f49 624
pferland 0:5a7579045f49 625 sprintf(txtstr,"*Network Joined*");
pferland 0:5a7579045f49 626 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 627
pferland 0:5a7579045f49 628 }
pferland 0:5a7579045f49 629 else
pferland 0:5a7579045f49 630 {
pferland 0:5a7579045f49 631 printf("ERROR: Unable to Join LoRa Network...\r\n");
pferland 0:5a7579045f49 632 sprintf(txtstr,"Radio Init Failed!");
pferland 0:5a7579045f49 633 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 634 printf("%s\r\n",txtstr);
pferland 0:5a7579045f49 635 exit(1);
pferland 0:5a7579045f49 636 }
pferland 0:5a7579045f49 637
pferland 0:5a7579045f49 638 // Check for MDOT-BOX Configuration (GPS)
pferland 0:5a7579045f49 639
pferland 0:5a7579045f49 640 if( bHasACC && bHasLCD )
pferland 0:5a7579045f49 641 {
pferland 0:5a7579045f49 642 printf("Instantiate GPS...\r\n");
pferland 0:5a7579045f49 643 mdot_gps = new GPSPARSER(&mDotUART);
pferland 0:5a7579045f49 644
pferland 0:5a7579045f49 645 if(!mdot_gps->gpsDetected())
pferland 0:5a7579045f49 646 {
pferland 0:5a7579045f49 647 printf(">>>> No GPS Detected... Not an MDOT-BOX, EVB Identified\r\n");
pferland 0:5a7579045f49 648
pferland 0:5a7579045f49 649 sprintf(txtstr,"*No GPS Detected*");
pferland 0:5a7579045f49 650 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 651 }
pferland 0:5a7579045f49 652 else
pferland 0:5a7579045f49 653 {
pferland 0:5a7579045f49 654 // main_single = main_sweep = false;
pferland 0:5a7579045f49 655 do
pferland 0:5a7579045f49 656 {
pferland 0:5a7579045f49 657 // osSignalWait(0x10, 2000);
pferland 0:5a7579045f49 658 if (mdot_gps->getLockStatus())
pferland 0:5a7579045f49 659 {
pferland 0:5a7579045f49 660 sprintf(txtstr,"!!GPS locked!!");
pferland 0:5a7579045f49 661 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 662 printf("%s \r\n",txtstr);
pferland 0:5a7579045f49 663 }
pferland 0:5a7579045f49 664 else
pferland 0:5a7579045f49 665 {
pferland 0:5a7579045f49 666 if (toggle_text)
pferland 0:5a7579045f49 667 sprintf(txtstr," > no GPS lock <");
pferland 0:5a7579045f49 668 else
pferland 0:5a7579045f49 669 sprintf(txtstr," < no GPS lock >");
pferland 0:5a7579045f49 670
pferland 0:5a7579045f49 671 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 672 printf("%s \r\n",txtstr);
pferland 0:5a7579045f49 673 toggle_text = !toggle_text;
pferland 0:5a7579045f49 674 }
pferland 0:5a7579045f49 675 } while ( !(mdot_gps->getLockStatus()) );
pferland 0:5a7579045f49 676 }
pferland 0:5a7579045f49 677 }
pferland 0:5a7579045f49 678
pferland 0:5a7579045f49 679 printf("Initialization/Configuration Completed...\r\n");
pferland 0:5a7579045f49 680
pferland 0:5a7579045f49 681 osDelay(1500);
pferland 0:5a7579045f49 682 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
pferland 0:5a7579045f49 683
pferland 0:5a7579045f49 684 // sets LED2 to 50% max current
pferland 0:5a7579045f49 685 if( bHasLCD ) evbBackLight->setLEDCurrent(16);
pferland 0:5a7579045f49 686
pferland 0:5a7579045f49 687
pferland 0:5a7579045f49 688 // Check for PB1 press during network join attempt
pferland 0:5a7579045f49 689 /*
pferland 0:5a7579045f49 690 if (exit_program)
pferland 0:5a7579045f49 691 {
pferland 0:5a7579045f49 692 printf("PB1 Pressed, Exiting Program...\r\n");
pferland 0:5a7579045f49 693 if( bHasLCD ) evbLCD->clearBuffer();
pferland 0:5a7579045f49 694 sprintf(txtstr,"Exiting Program");
pferland 0:5a7579045f49 695 if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 696 exit(1);
pferland 0:5a7579045f49 697 }
pferland 0:5a7579045f49 698 */
pferland 0:5a7579045f49 699
pferland 0:5a7579045f49 700 // Enter Main Data Acquisition Loop...
pferland 0:5a7579045f49 701 printf("Processing Data Acquisition Scan Loop...\r\n");
pferland 0:5a7579045f49 702
pferland 0:5a7579045f49 703 i = 0;
pferland 0:5a7579045f49 704 cycle_cnt = 100;
pferland 0:5a7579045f49 705
pferland 0:5a7579045f49 706 if( bHasLCD ) evbLCD->clearBuffer();
pferland 0:5a7579045f49 707
pferland 0:5a7579045f49 708 do
pferland 0:5a7579045f49 709 {
pferland 0:5a7579045f49 710 //EVB
pferland 0:5a7579045f49 711 if( bHasACC && bHasLCD )
pferland 0:5a7579045f49 712 {
pferland 0:5a7579045f49 713 // Check Accelerometer XYZ data ready bit to see if acquisition complete
pferland 0:5a7579045f49 714 failtime = FAIL_MAX;
pferland 0:5a7579045f49 715 do
pferland 0:5a7579045f49 716 {
pferland 0:5a7579045f49 717 osDelay(100); // allows other threads to process
pferland 0:5a7579045f49 718 result = evbAccel->getStatus();
pferland 0:5a7579045f49 719 failtime--;
pferland 0:5a7579045f49 720 } while ((result & MMA845x::XYZDR) == 0 && failtime > 0);
pferland 0:5a7579045f49 721
pferland 0:5a7579045f49 722 if (failtime==0)
pferland 0:5a7579045f49 723 {
pferland 0:5a7579045f49 724 evbBaro=resetBaro(evbBaro);
pferland 0:5a7579045f49 725 continue;
pferland 0:5a7579045f49 726 }
pferland 0:5a7579045f49 727
pferland 0:5a7579045f49 728 // Retrieve and print out accelerometer data
pferland 0:5a7579045f49 729 accel_data = evbAccel->getXYZ();
pferland 0:5a7579045f49 730 sprintf(txtstr, "Accel-X = %d", accel_data._x);
pferland 0:5a7579045f49 731 evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 732 sprintf(txtstr, "Accel-Y = %d", accel_data._y);
pferland 0:5a7579045f49 733 evbLCD->writeText(0,1,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 734 sprintf(txtstr, "Accel-Z = %d", accel_data._z );
pferland 0:5a7579045f49 735 evbLCD->writeText(0,2,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 736
pferland 0:5a7579045f49 737 // Trigger a Barometric Pressure Reading
pferland 0:5a7579045f49 738 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
pferland 0:5a7579045f49 739 evbBaro->triggerOneShot();
pferland 0:5a7579045f49 740
pferland 0:5a7579045f49 741 // Test Barometer Device, Check to see if acquisition is complete
pferland 0:5a7579045f49 742 failtime=FAIL_MAX;
pferland 0:5a7579045f49 743 do
pferland 0:5a7579045f49 744 {
pferland 0:5a7579045f49 745 osDelay(100); // allows other threads to process
pferland 0:5a7579045f49 746 result = evbBaro->getStatus();
pferland 0:5a7579045f49 747 failtime--;
pferland 0:5a7579045f49 748 } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 );
pferland 0:5a7579045f49 749
pferland 0:5a7579045f49 750 if(failtime==0)
pferland 0:5a7579045f49 751 {
pferland 0:5a7579045f49 752 evbBaro=resetBaro(evbBaro);
pferland 0:5a7579045f49 753 continue;
pferland 0:5a7579045f49 754 }
pferland 0:5a7579045f49 755
pferland 0:5a7579045f49 756 // Retrieve and Display Barometric Pressure
pferland 0:5a7579045f49 757 pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value
pferland 0:5a7579045f49 758 num_whole = pressure >> 2; // 18 bit integer significant
pferland 0:5a7579045f49 759 num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit
pferland 0:5a7579045f49 760
pferland 0:5a7579045f49 761 // If failtime reached 0 , indicates that the result might be junk.
pferland 0:5a7579045f49 762 sprintf(txtstr,"Press=%ld.%01d Pa", num_whole, num_frac/10);
pferland 0:5a7579045f49 763
pferland 0:5a7579045f49 764 pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value
pferland 0:5a7579045f49 765 num_whole = pressure >> 2; // 18 bit integer significant
pferland 0:5a7579045f49 766 num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit
pferland 0:5a7579045f49 767
pferland 0:5a7579045f49 768 writeValueOrError(); // will write to lorapresstring and txtstr
pferland 0:5a7579045f49 769
pferland 0:5a7579045f49 770 // Trigger a Altitude reading
pferland 0:5a7579045f49 771 // evbBaro->setAltitudeCalib(101);
pferland 0:5a7579045f49 772 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
pferland 0:5a7579045f49 773 // evbBaro->setAltitudeCalib(101);
pferland 0:5a7579045f49 774 evbBaro->triggerOneShot();
pferland 0:5a7579045f49 775
pferland 0:5a7579045f49 776 // Test barometer device status to see if acquisition is complete
pferland 0:5a7579045f49 777 failtime=FAIL_MAX;
pferland 0:5a7579045f49 778 do
pferland 0:5a7579045f49 779 {
pferland 0:5a7579045f49 780 osDelay(100); // allows other threads to process
pferland 0:5a7579045f49 781 result = evbBaro->getStatus();
pferland 0:5a7579045f49 782 failtime--;
pferland 0:5a7579045f49 783 } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 );
pferland 0:5a7579045f49 784
pferland 0:5a7579045f49 785 if (failtime==0)
pferland 0:5a7579045f49 786 {
pferland 0:5a7579045f49 787 evbBaro=resetBaro(evbBaro);
pferland 0:5a7579045f49 788 continue;
pferland 0:5a7579045f49 789 }
pferland 0:5a7579045f49 790
pferland 0:5a7579045f49 791 // Retrieve and Display Altimeter Reading
pferland 0:5a7579045f49 792 baro_data = evbBaro->getAllData(false);
pferland 0:5a7579045f49 793 baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value
pferland 0:5a7579045f49 794 num_whole = baro_data._baro / 16; // 18 bit signed significant integer (JEK Added 60 as SWAG Offset for Boca)
pferland 0:5a7579045f49 795 num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit
pferland 0:5a7579045f49 796 sprintf(txtstr,"Alti=%ld.%03d m", num_whole, num_frac);
pferland 0:5a7579045f49 797 sprintf(lora_alt_string,"%ld.%03d", num_whole, num_frac);
pferland 0:5a7579045f49 798 evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 799
pferland 0:5a7579045f49 800 // Retrieve and Display Temperature Reading
pferland 0:5a7579045f49 801 num_whole = baro_data._temp / 16; // 8 bit signed significant integer
pferland 0:5a7579045f49 802 num_frac = (baro_data._temp & 0x0F) * 625 / 100; // 4 bit fractional .0625 per bit
pferland 0:5a7579045f49 803 sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac);
pferland 0:5a7579045f49 804 sprintf(lora_temp_string,"%ld.%03d", num_whole, num_frac);
pferland 0:5a7579045f49 805 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 806
pferland 0:5a7579045f49 807 // Retrieve and Display Ambient Light Level
pferland 0:5a7579045f49 808 lux_data = evbAmbLight->getData();
pferland 0:5a7579045f49 809 num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit
pferland 0:5a7579045f49 810 num_frac = lux_data * 24 % 100;
pferland 0:5a7579045f49 811 sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac );
pferland 0:5a7579045f49 812 sprintf(lora_light_string, "%ld.%02d", num_whole, num_frac );
pferland 0:5a7579045f49 813 evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 814
pferland 0:5a7579045f49 815 // Retrieve and Display Current Sensor Level (EVB Analog Input)
pferland 0:5a7579045f49 816 current = (double) current_sensor * 65535.0;
pferland 0:5a7579045f49 817 sprintf(lora_current_string, "%d", (int) current);
pferland 0:5a7579045f49 818
pferland 0:5a7579045f49 819 // Handle Pushbutton #1 (SW1) - This should be handled by the 'pb1_debounce' thread.
pferland 0:5a7579045f49 820 if( pb1_low )
pferland 0:5a7579045f49 821 {
pferland 0:5a7579045f49 822 sw1_state = !sw1_state;
pferland 0:5a7579045f49 823 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,0); // enable LED2 on EVB and set to 0% PWM
pferland 0:5a7579045f49 824
pferland 0:5a7579045f49 825 sprintf(txtstr,"PB1 Press-SW1: %d", sw1_state);
pferland 0:5a7579045f49 826 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 827 printf("%s \r\n",txtstr);
pferland 0:5a7579045f49 828
pferland 0:5a7579045f49 829 pb1_low = false;
pferland 0:5a7579045f49 830 }
pferland 0:5a7579045f49 831
pferland 0:5a7579045f49 832 // Handle Pushbutton #2 (SW2) - This should be handled by the 'pb2_debounce' thread.
pferland 0:5a7579045f49 833 if( pb2_low )
pferland 0:5a7579045f49 834 {
pferland 0:5a7579045f49 835 sw2_state = !sw2_state;
pferland 0:5a7579045f49 836 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
pferland 0:5a7579045f49 837
pferland 0:5a7579045f49 838 sprintf(txtstr,"PB2 Press-SW2: %d", sw2_state);
pferland 0:5a7579045f49 839 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 840 printf("%s \r\n",txtstr);
pferland 0:5a7579045f49 841
pferland 0:5a7579045f49 842 pb2_low = false;
pferland 0:5a7579045f49 843 }
pferland 0:5a7579045f49 844 }
pferland 0:5a7579045f49 845 //MEMS
pferland 0:5a7579045f49 846 else if(!bHasLCD && bHasACC)
pferland 0:5a7579045f49 847 {
pferland 0:5a7579045f49 848
pferland 0:5a7579045f49 849 std::vector<uint8_t> tx_data;
pferland 0:5a7579045f49 850
pferland 0:5a7579045f49 851
pferland 0:5a7579045f49 852 // Payload structure for mydevices cayenne:
pferland 0:5a7579045f49 853 // 1 byte Data1 ID
pferland 0:5a7579045f49 854 // 1 Byte Data1 Type
pferland 0:5a7579045f49 855 // N Bytes Data1
pferland 0:5a7579045f49 856 // 1 byte data 2 ID
pferland 0:5a7579045f49 857 // 1 byte data 2 type
pferland 0:5a7579045f49 858 // n Bytes data 2
pferland 0:5a7579045f49 859 // ...
pferland 0:5a7579045f49 860
pferland 0:5a7579045f49 861 // formats:
pferland 0:5a7579045f49 862 // Temperature sensor:
pferland 0:5a7579045f49 863 /*
pferland 0:5a7579045f49 864 * IPSO: 3303
pferland 0:5a7579045f49 865 * LPP 103
pferland 0:5a7579045f49 866 * HEX: 67
pferland 0:5a7579045f49 867 * Data size: 2
pferland 0:5a7579045f49 868 * Resolution: 0.1 degres C
pferland 0:5a7579045f49 869
pferland 0:5a7579045f49 870 * Humidity sensor
pferland 0:5a7579045f49 871 * IPSO: 3304
pferland 0:5a7579045f49 872 * LPP: 104
pferland 0:5a7579045f49 873 * Hex: 68
pferland 0:5a7579045f49 874 * Datasize: 1
pferland 0:5a7579045f49 875 * Resolution: 0.5% unsigned
pferland 0:5a7579045f49 876
pferland 0:5a7579045f49 877 * Barometer/pressure sensor
pferland 0:5a7579045f49 878 * IPSO: 3315
pferland 0:5a7579045f49 879 * LPP: 115
pferland 0:5a7579045f49 880 * Hex: 73
pferland 0:5a7579045f49 881 * Datasize: 2
pferland 0:5a7579045f49 882 * Resolution 0.1hPa unsigned MSB
pferland 0:5a7579045f49 883
pferland 0:5a7579045f49 884 * Accelerometer
pferland 0:5a7579045f49 885 * IPSO: 3313
pferland 0:5a7579045f49 886 * LPP: 113
pferland 0:5a7579045f49 887 * Hex: 71
pferland 0:5a7579045f49 888 * Data size: 6
pferland 0:5a7579045f49 889 * Resolution: 0.001G signed MSB per axis
pferland 0:5a7579045f49 890
pferland 0:5a7579045f49 891 * Gyrometer
pferland 0:5a7579045f49 892 * IPSO: 3334
pferland 0:5a7579045f49 893 * LPP: 134
pferland 0:5a7579045f49 894 * Hex: 86
pferland 0:5a7579045f49 895 * Data size: 6
pferland 0:5a7579045f49 896 * Resolution: 0.01 degrees/s signed msb per axis
pferland 0:5a7579045f49 897 */
pferland 0:5a7579045f49 898
pferland 0:5a7579045f49 899 //temp floats
pferland 0:5a7579045f49 900 float temp_value, humid_value, pressure_value;
pferland 0:5a7579045f49 901 int16_t int_temp_value, int_humid_value, int_pressure_value;
pferland 0:5a7579045f49 902
pferland 0:5a7579045f49 903 // HTS221 Humidity sensor
pferland 0:5a7579045f49 904
pferland 0:5a7579045f49 905 ret |= (!CALL_METH(memsTemp1, GetTemperature, &temp_value, 0.0f) ? 0x0 : 0x1);
pferland 0:5a7579045f49 906 ret |= (!CALL_METH(memsHumidity, GetHumidity, &humid_value, 0.0f) ? 0x0 : 0x2);;
pferland 0:5a7579045f49 907
pferland 0:5a7579045f49 908 /*
pferland 0:5a7579045f49 909 //serialize data and append to packet
pferland 0:5a7579045f49 910 // Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit
pferland 0:5a7579045f49 911 tx_data.push_back(uint8_t(1)); // data id
pferland 0:5a7579045f49 912 tx_data.push_back(uint8_t(0x67)); // data type - temp
pferland 0:5a7579045f49 913 int_temp_value = floor(temp_value*10 + 0.5f);
pferland 0:5a7579045f49 914 tx_data.push_back(uint8_t( 0xFF & (int_temp_value >> 8)));
pferland 0:5a7579045f49 915 tx_data.push_back(uint8_t(0xFF & int_temp_value));
pferland 0:5a7579045f49 916
pferland 0:5a7579045f49 917
pferland 0:5a7579045f49 918 tx_data.push_back(uint8_t(2)); // data id
pferland 0:5a7579045f49 919 tx_data.push_back(uint8_t(0x68)); // data type - humidity
pferland 0:5a7579045f49 920 int_humid_value = floor(humid_value * 2.0f + 0.5f);
pferland 0:5a7579045f49 921 tx_data.push_back(uint8_t(0xFF & int_humid_value ));
pferland 0:5a7579045f49 922 */
pferland 0:5a7579045f49 923
pferland 0:5a7579045f49 924 ret |= (!CALL_METH(memsPressure, GetPressure, &pressure_value, 0.0f) ? 0x0 : 0x4);;
pferland 0:5a7579045f49 925
pferland 0:5a7579045f49 926 /*
pferland 0:5a7579045f49 927 // pressure is reported in mbar, cayenne wants it in 0.1 hPa
pferland 0:5a7579045f49 928 // 1mbar = 1 hPa
pferland 0:5a7579045f49 929 int_pressure_value = floor(pressure_value * 100.0f + 0.5f);
pferland 0:5a7579045f49 930
pferland 0:5a7579045f49 931 tx_data.push_back(uint8_t(3)); // data id
pferland 0:5a7579045f49 932 tx_data.push_back(uint8_t(0x73)); // data type - pressure
pferland 0:5a7579045f49 933 int_pressure_value = floor(pressure_value / 0.1f + 0.5f);
pferland 0:5a7579045f49 934 tx_data.push_back(uint8_t(0xFF & (int_pressure_value >> 8)));
pferland 0:5a7579045f49 935 tx_data.push_back(uint8_t(0xFF & int_pressure_value));
pferland 0:5a7579045f49 936 */
pferland 0:5a7579045f49 937
pferland 0:5a7579045f49 938 // Get accelerometer data
pferland 0:5a7579045f49 939 int32_t accel_vector[3];
pferland 0:5a7579045f49 940 // returns in mG
pferland 0:5a7579045f49 941 memsAccel->Get_X_Axes(accel_vector);
pferland 0:5a7579045f49 942
pferland 0:5a7579045f49 943 /*
pferland 0:5a7579045f49 944 tx_data.push_back(uint8_t(4)); // data id
pferland 0:5a7579045f49 945 tx_data.push_back(uint8_t(0x71)); // data type - accelerometer
pferland 0:5a7579045f49 946 for(int i=0; i<3; i++) {
pferland 0:5a7579045f49 947 tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8);
pferland 0:5a7579045f49 948 tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
pferland 0:5a7579045f49 949 }
pferland 0:5a7579045f49 950 */
pferland 0:5a7579045f49 951
pferland 0:5a7579045f49 952 // Get gyro data
pferland 0:5a7579045f49 953 int32_t gyro_vector[3];
pferland 0:5a7579045f49 954 memsGyro->Get_G_Axes(gyro_vector);
pferland 0:5a7579045f49 955
pferland 0:5a7579045f49 956 /*
pferland 0:5a7579045f49 957 // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
pferland 0:5a7579045f49 958 tx_data.push_back(uint8_t(5)); //data id
pferland 0:5a7579045f49 959 tx_data.push_back(uint8_t(0x86)); // data type - gyrometer
pferland 0:5a7579045f49 960 for(int i=0; i<3; i++) {
pferland 0:5a7579045f49 961 gyro_vector[i] /= 10;
pferland 0:5a7579045f49 962 tx_data.push_back(uint8_t(0xFF & (gyro_vector[i] >> 8)));
pferland 0:5a7579045f49 963 tx_data.push_back(uint8_t(0xFF & gyro_vector[i]));
pferland 0:5a7579045f49 964 }
pferland 0:5a7579045f49 965 */
pferland 0:5a7579045f49 966
pferland 0:5a7579045f49 967 // Get magnetometer data
pferland 0:5a7579045f49 968 int32_t mag_vector[3];
pferland 0:5a7579045f49 969 memsMag->Get_M_Axes(mag_vector);
pferland 0:5a7579045f49 970 // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
pferland 0:5a7579045f49 971
pferland 0:5a7579045f49 972 /*
pferland 0:5a7579045f49 973 tx_data.push_back(uint8_t(5)); //data id
pferland 0:5a7579045f49 974 tx_data.push_back(uint8_t(0x99)); // data type - mangetometer
pferland 0:5a7579045f49 975 for(int i=0; i<3; i++) {
pferland 0:5a7579045f49 976 mag_vector[i] /= 10;
pferland 0:5a7579045f49 977 tx_data.push_back(uint8_t(0xFF & (mag_vector[i] >> 8)));
pferland 0:5a7579045f49 978 tx_data.push_back(uint8_t(0xFF & mag_vector[i]));
pferland 0:5a7579045f49 979 }
pferland 0:5a7579045f49 980 */
pferland 0:5a7579045f49 981
pferland 0:5a7579045f49 982
pferland 0:5a7579045f49 983 //send_data(tx_data);
pferland 0:5a7579045f49 984
pferland 0:5a7579045f49 985 //---------------------------------------------------------------------------
pferland 0:5a7579045f49 986 // Verbose Text Format: Least Data Payload, Most Human Readible
pferland 0:5a7579045f49 987 //---------------------------------------------------------------------------
pferland 0:5a7579045f49 988
pferland 0:5a7579045f49 989 /*
pferland 0:5a7579045f49 990 if(!bHasLCD && bHasACC)
pferland 0:5a7579045f49 991 {
pferland 0:5a7579045f49 992
pferland 0:5a7579045f49 993 sprintf(sensor_text, "accel-x:%d|accel-y:%d|accel-z:%d|gyro-x:%d|gyro-y:%d|gyro-z:%d|mag-x:%d|mag-y:%d|mag-x:%d|press:%s|temp:%s|humid:%s",
pferland 0:5a7579045f49 994 accel_vector[0],
pferland 0:5a7579045f49 995 accel_vector[1],
pferland 0:5a7579045f49 996 accel_vector[2],
pferland 0:5a7579045f49 997 gyro_vector[0],
pferland 0:5a7579045f49 998 gyro_vector[1],
pferland 0:5a7579045f49 999 gyro_vector[2],
pferland 0:5a7579045f49 1000 mag_vector[0],
pferland 0:5a7579045f49 1001 mag_vector[1],
pferland 0:5a7579045f49 1002 mag_vector[2],
pferland 0:5a7579045f49 1003 printDouble(buffer3, pressure_value),
pferland 0:5a7579045f49 1004 printDouble(buffer1, temp_value),
pferland 0:5a7579045f49 1005 printDouble(buffer2, humid_value));
pferland 0:5a7579045f49 1006 }
pferland 0:5a7579045f49 1007 else
pferland 0:5a7579045f49 1008 {
pferland 0:5a7579045f49 1009 sprintf(sensor_text, "accel-x:%d|accel-y:%d|accel-z:%d|press:%s|alti:%s|temp:%s|light:%s|moist:%s",
pferland 0:5a7579045f49 1010 accel_data._x,
pferland 0:5a7579045f49 1011 accel_data._y,
pferland 0:5a7579045f49 1012 accel_data._z,
pferland 0:5a7579045f49 1013 lora_press_string,
pferland 0:5a7579045f49 1014 lora_alt_string,
pferland 0:5a7579045f49 1015 lora_temp_string,
pferland 0:5a7579045f49 1016 lora_light_string,
pferland 0:5a7579045f49 1017 lora_current_string);
pferland 0:5a7579045f49 1018
pferland 0:5a7579045f49 1019 }
pferland 0:5a7579045f49 1020
pferland 0:5a7579045f49 1021
pferland 0:5a7579045f49 1022 if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) {
pferland 0:5a7579045f49 1023 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
pferland 0:5a7579045f49 1024 } else {
pferland 0:5a7579045f49 1025 printf("Ok, Successfully Sent Data to Gateway...\r\n");
pferland 0:5a7579045f49 1026 }
pferland 0:5a7579045f49 1027 */
pferland 0:5a7579045f49 1028
pferland 2:fc20e16833af 1029 if( cycle_cnt > 30 )
pferland 2:fc20e16833af 1030 {
pferland 2:fc20e16833af 1031 sprintf(txtstr,"Transmitting... ");
pferland 2:fc20e16833af 1032 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 1033
pferland 0:5a7579045f49 1034
pferland 2:fc20e16833af 1035 //---------------------------------------------------------------------------
pferland 2:fc20e16833af 1036 // Byte Vector Format: More Data Payload, Less Human Readible
pferland 2:fc20e16833af 1037 //---------------------------------------------------------------------------
pferland 2:fc20e16833af 1038
pferland 2:fc20e16833af 1039 if(!bHasLCD && bHasACC)
pferland 2:fc20e16833af 1040 {
pferland 2:fc20e16833af 1041
pferland 2:fc20e16833af 1042 sprintf(sensor_text, "ax:%d,ay:%d,az:%d,gx:%d,gy:%d,gz:%d,mx:%d,my:%d,mz:%d,p:%s,t:%s,h:%s",
pferland 2:fc20e16833af 1043 accel_vector[0],
pferland 2:fc20e16833af 1044 accel_vector[1],
pferland 2:fc20e16833af 1045 accel_vector[2],
pferland 2:fc20e16833af 1046 gyro_vector[0],
pferland 2:fc20e16833af 1047 gyro_vector[1],
pferland 2:fc20e16833af 1048 gyro_vector[2],
pferland 2:fc20e16833af 1049 mag_vector[0],
pferland 2:fc20e16833af 1050 mag_vector[1],
pferland 2:fc20e16833af 1051 mag_vector[2],
pferland 2:fc20e16833af 1052 printDouble(buffer3, pressure_value),
pferland 2:fc20e16833af 1053 printDouble(buffer1, temp_value),
pferland 2:fc20e16833af 1054 printDouble(buffer2, humid_value));
pferland 2:fc20e16833af 1055 }
pferland 2:fc20e16833af 1056
pferland 2:fc20e16833af 1057 else
pferland 2:fc20e16833af 1058 {
pferland 2:fc20e16833af 1059 sprintf(sensor_text, "x:%d,y:%d,z:%d,p:%s,al:%s,t:%s,l:%s,c:%s",
pferland 2:fc20e16833af 1060 accel_data._x,
pferland 2:fc20e16833af 1061 accel_data._y,
pferland 2:fc20e16833af 1062 accel_data._z,
pferland 2:fc20e16833af 1063 lora_press_string,
pferland 2:fc20e16833af 1064 lora_alt_string,
pferland 2:fc20e16833af 1065 lora_temp_string,
pferland 2:fc20e16833af 1066 lora_light_string,
pferland 2:fc20e16833af 1067 lora_current_string);
pferland 2:fc20e16833af 1068 }
pferland 2:fc20e16833af 1069
pferland 2:fc20e16833af 1070 if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) {
pferland 2:fc20e16833af 1071 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
pferland 2:fc20e16833af 1072 } else {
pferland 2:fc20e16833af 1073 printf("Ok, Successfully Sent Data to Gateway...\r\n");
pferland 2:fc20e16833af 1074 }
pferland 2:fc20e16833af 1075
pferland 2:fc20e16833af 1076 /*
pferland 2:fc20e16833af 1077 //---------------------------------------------------------------------------
pferland 2:fc20e16833af 1078 // Binary Encoded Format: Most Data Payload, Not Human Readible
pferland 2:fc20e16833af 1079 //---------------------------------------------------------------------------
pferland 2:fc20e16833af 1080 mdot_data.clear();
pferland 2:fc20e16833af 1081 mdot_data.push_back(0x0E); // key for Current Acceleration 3-Axis Value
pferland 2:fc20e16833af 1082 converts.f_s = accel_data._x *4; // shift data 2 bits while retaining sign
pferland 2:fc20e16833af 1083 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value
pferland 2:fc20e16833af 1084 converts.f_s = accel_data._y * 4; // shift data 2 bits while retaining sign
pferland 2:fc20e16833af 1085 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value
pferland 2:fc20e16833af 1086 converts.f_s = accel_data._z * 4; // shift data 2 bits while retaining sign
pferland 2:fc20e16833af 1087 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value
pferland 2:fc20e16833af 1088 mdot_data.push_back(0x08); // key for Current Pressure Value
pferland 2:fc20e16833af 1089 convertl.f_u = pressure; // pressure data is 20 bits unsigned
pferland 2:fc20e16833af 1090 mdot_data.push_back(convertl.t_u[2]);
pferland 2:fc20e16833af 1091 mdot_data.push_back(convertl.t_u[1]);
pferland 2:fc20e16833af 1092 mdot_data.push_back(convertl.t_u[0]);
pferland 2:fc20e16833af 1093 mdot_data.push_back(0x05); // key for Current Ambient Light Value
pferland 2:fc20e16833af 1094 converts.f_u = lux_data; // data is 16 bits unsigned
pferland 2:fc20e16833af 1095 mdot_data.push_back(converts.t_u[1]);
pferland 2:fc20e16833af 1096 mdot_data.push_back(converts.t_u[0]);
pferland 2:fc20e16833af 1097 mdot_data.push_back(0x0B); // key for Current Temperature Value
pferland 2:fc20e16833af 1098 converts.f_s = baro_data._temp; // temperature is signed 12 bit
pferland 2:fc20e16833af 1099 mdot_data.push_back(converts.t_u[1]);
pferland 2:fc20e16833af 1100 mdot_data.push_back(converts.t_u[0]);
pferland 2:fc20e16833af 1101
pferland 2:fc20e16833af 1102 if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) {
pferland 2:fc20e16833af 1103 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
pferland 2:fc20e16833af 1104 } else {
pferland 2:fc20e16833af 1105 printf("Ok, Successfully Sent Data to Gateway...\r\n");
pferland 2:fc20e16833af 1106 }
pferland 2:fc20e16833af 1107
pferland 2:fc20e16833af 1108 */
pferland 2:fc20e16833af 1109
pferland 2:fc20e16833af 1110 osDelay(500);
pferland 2:fc20e16833af 1111 sprintf(txtstr,"Scanning... ");
pferland 2:fc20e16833af 1112 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 2:fc20e16833af 1113 cycle_cnt = 0;
pferland 0:5a7579045f49 1114 }
pferland 0:5a7579045f49 1115 }
pferland 0:5a7579045f49 1116
pferland 0:5a7579045f49 1117 osDelay(1000);
pferland 0:5a7579045f49 1118 cycle_cnt++;
pferland 0:5a7579045f49 1119
pferland 0:5a7579045f49 1120 // Put Thread to Sleep for 30 Seconds...
pferland 0:5a7579045f49 1121 // osDelay(30000);
pferland 0:5a7579045f49 1122
pferland 0:5a7579045f49 1123 } while(i < 86400);
pferland 0:5a7579045f49 1124
pferland 0:5a7579045f49 1125 printf("End of Data Collection Cycle (24 Hours) - Ending Application, GoodBye...\r\n");
pferland 0:5a7579045f49 1126
pferland 0:5a7579045f49 1127 if( bHasLCD ) evbLCD->clearBuffer();
pferland 0:5a7579045f49 1128 sprintf(txtstr,"Exiting Program");
pferland 0:5a7579045f49 1129 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 1130 }
pferland 0:5a7579045f49 1131
pferland 0:5a7579045f49 1132 /*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/
pferland 0:5a7579045f49 1133 /* Called in interrupt context, therefore just set a trigger variable */
pferland 0:5a7579045f49 1134 static void timer_irq(void) {
pferland 0:5a7579045f49 1135 timer_irq_triggered = true;
pferland 0:5a7579045f49 1136 }
pferland 0:5a7579045f49 1137
pferland 0:5a7579045f49 1138 /* Called in interrupt context, therefore just set a trigger variable */
pferland 0:5a7579045f49 1139 static void ff_irq(void) {
pferland 0:5a7579045f49 1140 ff_irq_triggered = true;
pferland 0:5a7579045f49 1141
pferland 0:5a7579045f49 1142 /* Disable IRQ until handled */
pferland 0:5a7579045f49 1143 mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ();
pferland 0:5a7579045f49 1144 }
pferland 0:5a7579045f49 1145
pferland 0:5a7579045f49 1146
pferland 0:5a7579045f49 1147 /*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/
pferland 0:5a7579045f49 1148 /* Handle Free Fall Interrupt
pferland 0:5a7579045f49 1149 (here we are in "normal" context, i.e. not in IRQ context)
pferland 0:5a7579045f49 1150 */
pferland 0:5a7579045f49 1151 static void handle_ff_irq(void) {
pferland 0:5a7579045f49 1152 printf("\nFree Fall Detected!\n\n");
pferland 0:5a7579045f49 1153
pferland 0:5a7579045f49 1154 /* Re-enable IRQ */
pferland 0:5a7579045f49 1155 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ();
pferland 0:5a7579045f49 1156 }
pferland 0:5a7579045f49 1157
pferland 0:5a7579045f49 1158 /*===================================================================================
pferland 0:5a7579045f49 1159 Send String Payload to Conduit Gateway
pferland 0:5a7579045f49 1160 ===================================================================================*/
pferland 0:5a7579045f49 1161 int32_t sendString(const std::string text)
pferland 0:5a7579045f49 1162 {
pferland 0:5a7579045f49 1163 int32_t ret;
pferland 0:5a7579045f49 1164 if (mdot_radio->getNextTxMs() != 0)
pferland 0:5a7579045f49 1165 {
pferland 0:5a7579045f49 1166 printf("Sending in %lu ms...\r\n", mdot_radio->getNextTxMs());
pferland 0:5a7579045f49 1167 return false;
pferland 0:5a7579045f49 1168 }
pferland 0:5a7579045f49 1169
pferland 0:5a7579045f49 1170 printf("Sending: '%s'\r\n", text.c_str());
pferland 0:5a7579045f49 1171 std::vector<uint8_t> data(text.begin(), text.end());
pferland 0:5a7579045f49 1172 if ((ret = mdot_radio->send(data, 1)) != mDot::MDOT_OK)
pferland 0:5a7579045f49 1173 {
pferland 0:5a7579045f49 1174 log_error(mdot_radio, "ERROR: Failed to Send Data", ret);
pferland 0:5a7579045f49 1175 }
pferland 0:5a7579045f49 1176
pferland 0:5a7579045f49 1177 return ret;
pferland 0:5a7579045f49 1178 }
pferland 0:5a7579045f49 1179
pferland 0:5a7579045f49 1180 /*===================================================================================
pferland 0:5a7579045f49 1181 Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread
pferland 0:5a7579045f49 1182 ===================================================================================*/
pferland 0:5a7579045f49 1183 void pb1ISR(void)
pferland 0:5a7579045f49 1184 {
pferland 0:5a7579045f49 1185 pb1_low = true;
pferland 0:5a7579045f49 1186 }
pferland 0:5a7579045f49 1187
pferland 0:5a7579045f49 1188 /*===================================================================================
pferland 0:5a7579045f49 1189 Pushbutton Debounce - Debounces pb1 PB1 changes SW1 State Value (Sets LED Off)
pferland 0:5a7579045f49 1190 ===================================================================================*/
pferland 0:5a7579045f49 1191 void pb1_debounce(void const *args)
pferland 0:5a7579045f49 1192 {
pferland 0:5a7579045f49 1193 printf("Thread pb1_debounce started...\r\n");
pferland 0:5a7579045f49 1194
pferland 0:5a7579045f49 1195 while(true)
pferland 0:5a7579045f49 1196 {
pferland 0:5a7579045f49 1197 // if( pb1_low && (mDot08 == 0))
pferland 0:5a7579045f49 1198 if( pb1_low )
pferland 0:5a7579045f49 1199 {
pferland 0:5a7579045f49 1200 sprintf(txtstr,"PB1 Pressed...");
pferland 0:5a7579045f49 1201 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 1202 printf("%s\r\n",txtstr);
pferland 0:5a7579045f49 1203
pferland 0:5a7579045f49 1204 pb1_low = false;
pferland 0:5a7579045f49 1205 }
pferland 0:5a7579045f49 1206
pferland 0:5a7579045f49 1207 Thread::wait(50);
pferland 0:5a7579045f49 1208 }
pferland 0:5a7579045f49 1209 }
pferland 0:5a7579045f49 1210
pferland 0:5a7579045f49 1211 /*===================================================================================
pferland 0:5a7579045f49 1212 Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread
pferland 0:5a7579045f49 1213 ===================================================================================*/
pferland 0:5a7579045f49 1214 void pb2ISR(void)
pferland 0:5a7579045f49 1215 {
pferland 0:5a7579045f49 1216 pb2_low = true;
pferland 0:5a7579045f49 1217 }
pferland 0:5a7579045f49 1218
pferland 0:5a7579045f49 1219 /*===================================================================================
pferland 0:5a7579045f49 1220 Pushbutton Debounce - Debounces pb2 PB2 changes SW2 State Value (Sets LED On)
pferland 0:5a7579045f49 1221 ===================================================================================*/
pferland 0:5a7579045f49 1222 void pb2_debounce(void const *args)
pferland 0:5a7579045f49 1223 {
pferland 0:5a7579045f49 1224 printf("Thread pb2_debounce started...\r\n");
pferland 0:5a7579045f49 1225
pferland 0:5a7579045f49 1226 while(true)
pferland 0:5a7579045f49 1227 {
pferland 0:5a7579045f49 1228 // if( pb2_low && (mDot09 == 1))
pferland 0:5a7579045f49 1229 if( pb2_low )
pferland 0:5a7579045f49 1230 {
pferland 0:5a7579045f49 1231 sprintf(txtstr,"PB2 Pressed...");
pferland 0:5a7579045f49 1232 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 1233 printf("%s \r\n",txtstr);
pferland 0:5a7579045f49 1234
pferland 0:5a7579045f49 1235 pb2_low = false;
pferland 0:5a7579045f49 1236 }
pferland 0:5a7579045f49 1237
pferland 0:5a7579045f49 1238 Thread::wait(50);
pferland 0:5a7579045f49 1239 }
pferland 0:5a7579045f49 1240 }
pferland 0:5a7579045f49 1241
pferland 0:5a7579045f49 1242 /*===================================================================================
pferland 0:5a7579045f49 1243 Display Value/Error String of Barometric Pressure Sensor
pferland 0:5a7579045f49 1244 ===================================================================================*/
pferland 0:5a7579045f49 1245 bool writeValueOrError()
pferland 0:5a7579045f49 1246 {
pferland 0:5a7579045f49 1247 bool res;
pferland 0:5a7579045f49 1248
pferland 0:5a7579045f49 1249 if (failtime==0)
pferland 0:5a7579045f49 1250 {
pferland 0:5a7579045f49 1251 sprintf(lora_press_string, "%s", "--.--");
pferland 0:5a7579045f49 1252 sprintf(txtstr, "%s", "--.--");
pferland 0:5a7579045f49 1253 if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr, strlen(txtstr));
pferland 0:5a7579045f49 1254 res=false;
pferland 0:5a7579045f49 1255 }
pferland 0:5a7579045f49 1256 else
pferland 0:5a7579045f49 1257 {
pferland 0:5a7579045f49 1258 sprintf(lora_press_string, "%ld.%02d", num_whole, num_frac);
pferland 0:5a7579045f49 1259 if( bHasLCD ) evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr));
pferland 0:5a7579045f49 1260 res=true;
pferland 0:5a7579045f49 1261 }
pferland 0:5a7579045f49 1262
pferland 0:5a7579045f49 1263 return res;
pferland 0:5a7579045f49 1264 }
pferland 0:5a7579045f49 1265
pferland 0:5a7579045f49 1266 /*===================================================================================
pferland 0:5a7579045f49 1267 Resets Barometric Pressure Sensor
pferland 0:5a7579045f49 1268 ===================================================================================*/
pferland 0:5a7579045f49 1269 MPL3115A2* resetBaro(const MPL3115A2* oldBaro)
pferland 0:5a7579045f49 1270 {
pferland 0:5a7579045f49 1271 delete oldBaro;
pferland 0:5a7579045f49 1272 MPL3115A2* baro = new MPL3115A2(mDoti2c);
pferland 0:5a7579045f49 1273 baro->testWhoAmI();
pferland 0:5a7579045f49 1274
pferland 0:5a7579045f49 1275 printf("Resetting barometer.. %x \n\r", baro->getStatus() );
pferland 0:5a7579045f49 1276 baro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
pferland 0:5a7579045f49 1277 evbBaro->clearMinMaxRegs();
pferland 0:5a7579045f49 1278
pferland 0:5a7579045f49 1279 return baro;
pferland 0:5a7579045f49 1280 }
pferland 0:5a7579045f49 1281
pferland 0:5a7579045f49 1282 /*===================================================================================
pferland 0:5a7579045f49 1283 Print clear text verion of mDot/EVB errors
pferland 0:5a7579045f49 1284 ===================================================================================*/
pferland 0:5a7579045f49 1285 void log_error(mDot* dot, const char* msg, int32_t retval)
pferland 0:5a7579045f49 1286 {
pferland 0:5a7579045f49 1287 printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
pferland 0:5a7579045f49 1288 }