Demo using a Nimbelink Skywire cellular modem paired with ST Nucleo. This demo reads several sensors and reports them to a Freeboard dashboard using dweet.io from Buglabs
Dependencies: LIS3DH LM75B LPS331 hts221 mbed
Fork of Skywire_Demo by
main.cpp
00001 /* main.cpp */ 00002 /* v3.0 00003 * Copyright (C) 2016 nimbelink.com, MIT License 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00006 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00007 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00008 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in all copies or 00012 * substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00015 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00016 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00017 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00019 */ 00020 00021 /* 00022 * DESCRIPTION 00023 * This code updated sensor data on the Nimbelink ST Development Kit (NL-AB-ST-NCL) and sends 00024 * the information to www.dweet.io using the Thingname "DeviceID". That information can be 00025 * viewed using a Freeboard at www.freeboard.io (account required). Depending on your 00026 * ST Development Kit version, clone the following freeboard: 00027 * Rev A (Legacy): https://freeboard.io/board/jqlneI 00028 * Rev B (Current): https://freeboard.io/board/LhnbrX 00029 * 00030 * Please consult the wiki for more information 00031 */ 00032 00033 /* 00034 * INSTRUCTIONS FOR USING THIS CODE 00035 * 1. Under the "DEFINE THE SKYWIRE MODEM" section of the code, uncomment the modem that you 00036 * are using to enable to proper setup and features of your Skywire modem. 00037 * 00038 * NOTE: Make sure the other Skywire modems listed are commented out. 00039 * 00040 * 2. Change the "DeviceID" to a unique identifier for your Nucleo board. One recommendation 00041 * would be to use the MEID/IMEI of your Skywire Modem. 00042 * 00043 * 3. If applicable, change the APN for your Skywire Modem. 00044 */ 00045 00046 #include "mbed.h" 00047 #include "LPS331.h" 00048 #include "LIS3DH.h" 00049 #include "LM75B.h" 00050 #include "hts221.h" 00051 #include <string> 00052 00053 /* 00054 * DEFINE THE SKYWIRE MODEM 00055 * Uncomment only the modem that you are using. 00056 * Make sure only one modem is uncommented! 00057 */ 00058 //#define NL_SW_1xRTT_V // Verizon 2G Modem - CE910-DUAL 00059 //#define NL_SW_1xRTT_S // Sprint 2G Modem - CE910-DUAL 00060 //#define NL_SW_1xRTT_A // Aeris 2G Modem - CE910-DUAL 00061 //#define NL_SW_GPRS // AT&T/T-Mobile 2G Modem 00062 //#define NL_SW_EVDO_V // Verizon 3G Modem 00063 //#define NL_SW_EVDO_A // Aeris 3G Modem 00064 //#define NL_SW_HSPAP // AT&T/T-Mobile 3G Modem 00065 //#define NL_SW_HSPAPG // AT&T/T-Mobile 3G Modem w/ GPS 00066 //#define NL_SW_HSPAPE // GSM 3G Modem, EU 00067 //#define NL_SW_LTE_TSVG // Verizon 4G LTE Modem 00068 //#define NL_SW_LTE_TNAG // AT&T/T-Mobile 4G LTE Modem 00069 //#define NL_SW_LTE_TEUG // GSM 4G LTE Modem, EU 00070 //#define NL_SW_LTE_GELS3 // VZW LTE Cat 1 Modem 00071 00072 /* --CHANGE THIS FOR YOUR SETUP-- */ 00073 #define DeviceID "yourDeviceIDhere" //Freeboard DweetIO unique ID 00074 00075 /* --CHANGE THIS FOR YORU SETUP (IF APPLICABLE)-- */ 00076 #if defined NL_SW_HSPAP || defined NL_SW_HSPAPG || defined NL_SW_HSPAPE || defined NL_SW_LTE_TSVG || defined NL_SW_LTE_TNAG || defined NL_SW_LTE_TEUG || defined NL_SW_LTE_GELS3 00077 std::string APN = "yourAPNhere"; 00078 #endif 00079 00080 DigitalOut myled(LED1); // Main LED 00081 DigitalOut skywire_en(PA_6); // Skywire Enable 00082 DigitalOut skywire_rts(PA_7); // Skywire Send 00083 DigitalOut green_LED(PA_1); // Green LED 00084 DigitalOut red_LED(PA_4); // Red LED 00085 DigitalOut blue_LED(PB_0); // Blue LED 00086 00087 AnalogIn photo_trans(PA_0); // Photo Transistor 00088 AnalogIn pot(PC_0); // Potentiometer 00089 DigitalIn button1(PB_3); // Button 1 00090 DigitalIn button2(PC_1); // Button 2 00091 00092 Serial skywire(PA_9,PA_10); // Serial comms to Skywire 00093 Serial debug_pc(USBTX, USBRX); // USB connection to PC 00094 00095 I2C i2c(PB_9,PB_8); // Setup I2C bus for sensors 00096 bool sw1; // Boolean to check if button 1 is pressed 00097 bool sw2; // Boolean to check if button 2 is pressed 00098 00099 LPS331 pressure(i2c); // Pressure Sensor 00100 LM75B LM75_temp(PB_9,PB_8); // Temp Sensor 00101 // Accelerometer 00102 LIS3DH accel(i2c, LIS3DH_V_CHIP_ADDR, LIS3DH_DR_NR_LP_100HZ, LIS3DH_FS_2G); 00103 HTS221 humidity(PB_9, PB_8); // Humidity Sensor 00104 00105 // char array for reading from Skywire 00106 char str[255]; 00107 00108 // Variables for GPS 00109 float latitude; 00110 float longitude; 00111 int number; 00112 00113 // Variables for UART comms 00114 volatile int rx_in=0; 00115 volatile int rx_out=0; 00116 const int buffer_size = 600; 00117 char rx_buffer[buffer_size+1]; 00118 char rx_line[buffer_size]; 00119 00120 // Interrupt for the Skywire 00121 void Skywire_Rx_interrupt() 00122 { 00123 // Loop just in case more than one character is in UART's receive FIFO buffer 00124 // Stop if buffer full 00125 while ((skywire.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { 00126 rx_buffer[rx_in] = skywire.getc(); 00127 rx_in = (rx_in + 1) % buffer_size; 00128 } 00129 return; 00130 } 00131 00132 // Function to blink LEDs for debugging 00133 // NOTE: Currently not used 00134 void blink_leds(int num) 00135 { 00136 for (int i = 0; i < num; i++) { 00137 blue_LED = 0; 00138 wait(0.5); 00139 blue_LED = 1; 00140 wait(0.5); 00141 } 00142 } 00143 00144 // Read line from the UART 00145 void read_line() 00146 { 00147 int i; 00148 i = 0; 00149 // Start Critical Section - don't interrupt while changing global buffer variables 00150 __disable_irq(); 00151 // Loop reading rx buffer characters until end of line character 00152 while ((i==0) || (rx_line[i-1] != '\n')) { 00153 // Wait if buffer empty 00154 if (rx_in == rx_out) { 00155 // End Critical Section - need to allow rx interrupt to get new characters for buffer 00156 __enable_irq(); 00157 while (rx_in == rx_out) { 00158 } 00159 // Start Critical Section - don't interrupt while changing global buffer variables 00160 __disable_irq(); 00161 } 00162 rx_line[i] = rx_buffer[rx_out]; 00163 i++; 00164 rx_out = (rx_out + 1) % buffer_size; 00165 } 00166 // End Critical Section 00167 __enable_irq(); 00168 rx_line[i-1] = 0; 00169 return; 00170 } 00171 00172 // Wait for specific response 00173 int WaitForResponse(char* response, int num) 00174 { 00175 do { 00176 read_line(); 00177 debug_pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line); 00178 } while (strncmp(rx_line, response, num)); 00179 return 0; 00180 } 00181 00182 int main() 00183 { 00184 float axis[3]; 00185 float press; 00186 float temp; 00187 float humi; 00188 float dummy_temp; 00189 00190 // Setup serial comms with Skywire and PC 00191 debug_pc.baud(115200); 00192 skywire.baud(115200); 00193 debug_pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock); 00194 skywire.attach(&Skywire_Rx_interrupt, Serial::RxIrq); 00195 00196 // Turn on blue LED 00197 green_LED = 0; 00198 red_LED = 0; 00199 blue_LED = 1; 00200 00201 skywire_rts=0; 00202 myled=0; 00203 debug_pc.printf("Starting Demo...\r\n"); 00204 debug_pc.printf("Waiting for Skywire to Boot...\r\n"); 00205 00206 //Enable Skywire 00207 skywire_en=0; 00208 wait(2); 00209 skywire_en=1; 00210 wait(2); 00211 skywire_en=0; 00212 00213 myled=1; 00214 00215 // Wait for modem to initialize 00216 // Wait time is different for each modem 00217 #if defined NL_SW_LTE_GELS3 00218 wait(60); 00219 #elif defined NL_SW_LTE_TSVG || defined NL_SW_LTE_TNAG || defined NL_SW_LTE_TEUG 00220 wait(15); 00221 #else 00222 wait(5); 00223 #endif 00224 00225 // Start temp reading 00226 LM75_temp.open(); 00227 00228 //Turn off echo 00229 // Helps with checking responses from Skywire 00230 debug_pc.printf("Turning off echo...\r\n"); 00231 skywire.printf("ATE0\r\n"); 00232 WaitForResponse("OK", 2); 00233 00234 // Turn on DNS Response Caching 00235 // Used on the Telit-based Skywires 00236 #if !defined NL_SW_LTE_GELS3 00237 debug_pc.printf("Turning on DNS Cacheing to improve speed..."); 00238 skywire.printf("AT#CACHEDNS=1\r\n"); 00239 WaitForResponse("OK", 2); 00240 #endif 00241 00242 debug_pc.printf("Connecting to Network...\r\n"); 00243 // get IP address 00244 #if defined NL_SW_LTE_GELS3 00245 // The last parameter in AT+SQNSCFG sets the timeout if transmit buffer is not full 00246 // Time is in hundreds of ms: so, a value of 5 = 500ms 00247 debug_pc.printf("Configuring context part 1...\r\n"); 00248 skywire.printf("AT+SQNSCFG=3,3,300,90,600,5\r\n"); 00249 WaitForResponse("OK", 2); 00250 wait(1); 00251 debug_pc.printf("Configuring context part 2...\r\n"); 00252 skywire.printf("AT+CGDCONT=3,\"IP\",\"vzwinternet\"\r\n"); 00253 WaitForResponse("OK", 2); 00254 wait(1); 00255 debug_pc.printf("Activating context...\r\n"); 00256 skywire.printf("AT+CGACT=1,3\r\n"); 00257 #elif defined NL_SW_LTE_TSVG 00258 // The last parameter in AT#SCFG sets the timeout if transmit buffer is not full 00259 // Time is in hundreds of ms: so, a value of 5 = 500 ms 00260 skywire.printf("AT#SCFG=3,3,300,90,600,5\r\n"); 00261 WaitForResponse("OK", 2); 00262 wait(1); 00263 skywire.printf("AT+CGDCONT=3,\"IP\",\"%s\"\r\n", APN); 00264 WaitForResponse("OK", 2); 00265 wait(1); 00266 skywire.printf("AT#SGACT=3,1\r\n"); 00267 WaitForResponse("#SGACT", 6); 00268 #else 00269 // The last parameter in AT#SCFG sets the timeout if transmit buffer is not full 00270 // Time is in hundreds of ms: so, a value of 5 = 500 ms 00271 skywire.printf("AT#SCFG=1,1,300,90,600,5\r\n"); 00272 WaitForResponse("OK", 2); 00273 skywire.printf("AT#SGACT=1,1\r\n"); 00274 WaitForResponse("#SGACT", 6); 00275 #endif 00276 WaitForResponse("OK", 2); 00277 00278 // Get triangulation data 00279 // NOTE: This only works on the below modems! 00280 #if defined NL_SW_1xRTT_V || defined NL_SW_1xRTT_S || defined NL_SW_1xRTT_A || defined NL_SW_GPRS || defined NL_SW_EVDO_V || defined NL_SW_EVDO_A || defined NL_SW_HSPAP || defined NL_SW_HSPAPG || defined NL_SW_HSPAPE 00281 //get location approximation from cell tower information 00282 skywire.printf("AT#AGPSSND\r\n"); 00283 WaitForResponse("#AGPSRING:", 10); 00284 sscanf(rx_line, "%s %d,%f,%f,", str, &number, &latitude, &longitude); 00285 debug_pc.printf("Location: Latt:%f, Long:%f\r\n", latitude, longitude); 00286 #endif 00287 00288 red_LED = 0; 00289 blue_LED = 0; 00290 green_LED = 1; 00291 00292 while(1) { 00293 // Green on to indicate code position 00294 // Start of loop. Either entered loop for the first time or just sent to dweet.io 00295 red_LED = 0; 00296 blue_LED = 0; 00297 green_LED = 1; 00298 // connect to dweet.io 00299 #if defined NL_SW_LTE_GELS3 00300 skywire.printf("AT+SQNSD=3,0,80,\"dweet.io\"\r\n"); 00301 #elif defined NL_SW_LTE_TSVG 00302 skywire.printf("AT#SD=3,0,80,\"dweet.io\"\r\n"); 00303 #else 00304 skywire.printf("AT#SD=1,0,80,\"dweet.io\"\r\n"); 00305 #endif 00306 WaitForResponse("CONNECT", 7); 00307 00308 00309 // Update the sensors 00310 temp = (float)LM75_temp; 00311 //temp = (temp * 9)/5 + 32; // convert C to F 00312 debug_pc.printf("Temp = %.3f\r\n", temp); 00313 press=(float)pressure.value() / 4096; 00314 debug_pc.printf("Pressure = %.3f\r\n", press); 00315 humidity.ReadTempHumi(&dummy_temp, &humi); 00316 debug_pc.printf("Humidity = %.3f\r\n", humi); 00317 accel.read_data(axis); 00318 debug_pc.printf("Accel = %.3f, %.3f, %.3f\r\n", axis[0], axis[1], axis[2]); 00319 00320 wait(1); 00321 00322 // Check buttons for presses 00323 if (button1 == 0) 00324 sw1 = 0; 00325 else 00326 sw1 = 1; 00327 if (button2 == 0) 00328 sw2 = 0; 00329 else 00330 sw2 = 1; 00331 00332 // Green on to indicate code position: 00333 // Sensors updated, have not sent to dweet.io 00334 red_LED = 1; 00335 green_LED = 0; 00336 blue_LED = 0; 00337 00338 debug_pc.printf("Sending information...\r\n"); 00339 // Report the sensor data to dweet.io 00340 skywire.printf("POST /dweet/for/%s?temp=%.3f&p=%.3f&X=%.3f&Y=%.3f&Z=%.3f&La=%f&Lo=%f&sw1=%d&sw2=%d&pot=%.3f&photo=%.3f&humidity=%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, press, axis[0], axis[1], axis[2], latitude, longitude, sw1, sw2, (pot * 3), (photo_trans * 100), humi); 00341 00342 // Blue on to indicate code position 00343 // Data sent to dweet 00344 red_LED = 0; 00345 green_LED = 0; 00346 blue_LED = 1; 00347 00348 // Wait for response from dweet.io 00349 #if defined NL_SW_LTE_GELS3 00350 WaitForResponse("OK", 2); 00351 wait(1); 00352 #else 00353 WaitForResponse("NO CARRIER", 10); 00354 #endif 00355 } 00356 }
Generated on Tue Jul 12 2022 20:03:35 by 1.7.2