![](/media/cache/group/NimbeLink_Logo.png.50x50_q85.png)
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
Getting Started Guide
- Set the JP5 jumper to E5V on the Nucleo
- Place the Skywire Shield onto the Nucleo as pictured
- Place the Skywire modem onto the Shield as picture and attach the antenna U.FL coax cable as pictured
- Plug the 12V wall supply into the Skywire Shield
- Go to https://freeboard.io/ and create a user account
- Once you are logged into your Freeboard account, go to https://freeboard.io/board/PJI272 and clone the dashboard by clicking the CLONE link in the lower right corner
- Old Revision of dashboard is here https://freeboard.io/board/jqlneI
- Old Revision of dashboard is here https://freeboard.io/board/jqlneI
- The new dashboard will show up on you account list under My Freeboards, you can then edit the name to whatever you like
- Under the Datasources tab on the dashboard, click the skywire link
- Change the THING NAME field to a unique string, we recommended using the MEID or IMEI on the Skywire Modem, but it could be anything you want.
- Next, Import the Skywire_Demo program into the online compiler
- Open main.cpp. Starting at Line 58, there is a list of Skywire Modems. Uncomment the Skywire Modem that you are using. Make sure only one Skywire Modem is uncommented:
main.cpp
/* * DEFINE THE SKYWIRE MODEM * Uncomment only the modem that you are using. * Make sure only one modem is uncommented! */ //#define NL_SW_1xRTT_V // Verizon 2G Modem - CE910-DUAL //#define NL_SW_1xRTT_S // Sprint 2G Modem - CE910-DUAL //#define NL_SW_1xRTT_A // Aeris 2G Modem - CE910-DUAL //#define NL_SW_GPRS // AT&T/T-Mobile 2G Modem //#define NL_SW_EVDO_V // Verizon 3G Modem //#define NL_SW_EVDO_A // Aeris 3G Modem //#define NL_SW_HSPAP // AT&T/T-Mobile 3G Modem //#define NL_SW_HSPAPG // AT&T/T-Mobile 3G Modem w/ GPS //#define NL_SW_HSPAPE // GSM 3G Modem, EU //#define NL_SW_LTE_TSVG // Verizon 4G LTE Modem //#define NL_SW_LTE_TNAG // AT&T/T-Mobile 4G LTE Modem //#define NL_SW_LTE_TEUG // GSM 4G LTE Modem, EU //#define NL_SW_LTE_GELS3 // VZW LTE Cat 1 Modem
- Next, to Line 73 in main.cpp, and change the DeviceID to the THING NAME you entered into your Freeboard:
main.cpp
/* --CHANGE THIS FOR YOUR SETUP" -- */ #define DeviceID "DweetIODeviceName" //Freeboard DweetIO unique ID
- If applicable, go to Line 77 in main.cpp and change the APN to your specific APN:
main.cpp
/* --CHANGE THIS FOR YORU SETUP (IF APPLICABLE)-- */ #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 std::string APN = "yourAPNhere"; #endif
- Compile and upload to the Nucleo, cycle power to the shield and the sensor data should start to upload to your new Freeboard.
Diff: main.cpp
- Revision:
- 10:5974a7b2cf38
- Parent:
- 9:555eb4259fc6
--- a/main.cpp Wed Jul 29 21:31:19 2015 +0000 +++ b/main.cpp Tue Mar 29 20:03:13 2016 +0000 @@ -1,6 +1,6 @@ /* main.cpp */ -/* v1.1 - * Copyright (C) 2015 nimbelink.com, MIT License +/* v3.0 + * Copyright (C) 2016 nimbelink.com, MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, @@ -18,45 +18,108 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* + * DESCRIPTION + * This code updated sensor data on the Nimbelink ST Development Kit (NL-AB-ST-NCL) and sends + * the information to www.dweet.io using the Thingname "DeviceID". That information can be + * viewed using a Freeboard at www.freeboard.io (account required). Depending on your + * ST Development Kit version, clone the following freeboard: + * Rev A (Legacy): https://freeboard.io/board/jqlneI + * Rev B (Current): https://freeboard.io/board/LhnbrX + * + * Please consult the wiki for more information + */ + +/* + * INSTRUCTIONS FOR USING THIS CODE + * 1. Under the "DEFINE THE SKYWIRE MODEM" section of the code, uncomment the modem that you + * are using to enable to proper setup and features of your Skywire modem. + * + * NOTE: Make sure the other Skywire modems listed are commented out. + * + * 2. Change the "DeviceID" to a unique identifier for your Nucleo board. One recommendation + * would be to use the MEID/IMEI of your Skywire Modem. + * + * 3. If applicable, change the APN for your Skywire Modem. + */ + #include "mbed.h" #include "LPS331.h" #include "LIS3DH.h" #include "LM75B.h" #include "hts221.h" - -/* --CHANGE THIS FOR YOUR SETUP" -- */ -#define DeviceID "DweetIODeviceName" //Freeboard DweetIO unique ID +#include <string> -DigitalOut myled(LED1); -DigitalOut skywire_en(PA_6); -DigitalOut skywire_rts(PA_7); +/* + * DEFINE THE SKYWIRE MODEM + * Uncomment only the modem that you are using. + * Make sure only one modem is uncommented! + */ +//#define NL_SW_1xRTT_V // Verizon 2G Modem - CE910-DUAL +//#define NL_SW_1xRTT_S // Sprint 2G Modem - CE910-DUAL +//#define NL_SW_1xRTT_A // Aeris 2G Modem - CE910-DUAL +//#define NL_SW_GPRS // AT&T/T-Mobile 2G Modem +//#define NL_SW_EVDO_V // Verizon 3G Modem +//#define NL_SW_EVDO_A // Aeris 3G Modem +//#define NL_SW_HSPAP // AT&T/T-Mobile 3G Modem +//#define NL_SW_HSPAPG // AT&T/T-Mobile 3G Modem w/ GPS +//#define NL_SW_HSPAPE // GSM 3G Modem, EU +//#define NL_SW_LTE_TSVG // Verizon 4G LTE Modem +//#define NL_SW_LTE_TNAG // AT&T/T-Mobile 4G LTE Modem +//#define NL_SW_LTE_TEUG // GSM 4G LTE Modem, EU +//#define NL_SW_LTE_GELS3 // VZW LTE Cat 1 Modem + +/* --CHANGE THIS FOR YOUR SETUP-- */ +#define DeviceID "yourDeviceIDhere" //Freeboard DweetIO unique ID -Serial skywire(PA_9,PA_10); -Serial debug_pc(USBTX, USBRX); +/* --CHANGE THIS FOR YORU SETUP (IF APPLICABLE)-- */ +#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 + std::string APN = "yourAPNhere"; +#endif -I2C i2c(PB_9,PB_8); -char msg[3]; +DigitalOut myled(LED1); // Main LED +DigitalOut skywire_en(PA_6); // Skywire Enable +DigitalOut skywire_rts(PA_7); // Skywire Send +DigitalOut green_LED(PA_1); // Green LED +DigitalOut red_LED(PA_4); // Red LED +DigitalOut blue_LED(PB_0); // Blue LED -LPS331 pressure(i2c); -LM75B LM75_temp(PB_9,PB_8); +AnalogIn photo_trans(PA_0); // Photo Transistor +AnalogIn pot(PC_0); // Potentiometer +DigitalIn button1(PB_3); // Button 1 +DigitalIn button2(PC_1); // Button 2 + +Serial skywire(PA_9,PA_10); // Serial comms to Skywire +Serial debug_pc(USBTX, USBRX); // USB connection to PC + +I2C i2c(PB_9,PB_8); // Setup I2C bus for sensors +bool sw1; // Boolean to check if button 1 is pressed +bool sw2; // Boolean to check if button 2 is pressed + +LPS331 pressure(i2c); // Pressure Sensor +LM75B LM75_temp(PB_9,PB_8); // Temp Sensor +// Accelerometer LIS3DH accel(i2c, LIS3DH_V_CHIP_ADDR, LIS3DH_DR_NR_LP_100HZ, LIS3DH_FS_2G); -HTS221 humidity(PB_9, PB_8); +HTS221 humidity(PB_9, PB_8); // Humidity Sensor - +// char array for reading from Skywire char str[255]; +// Variables for GPS float latitude; float longitude; int number; +// Variables for UART comms volatile int rx_in=0; volatile int rx_out=0; -const int buffer_size = 255; +const int buffer_size = 600; char rx_buffer[buffer_size+1]; - char rx_line[buffer_size]; -void Skywire_Rx_interrupt() { +// Interrupt for the Skywire +void Skywire_Rx_interrupt() +{ // Loop just in case more than one character is in UART's receive FIFO buffer // Stop if buffer full while ((skywire.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { @@ -66,7 +129,21 @@ return; } -void read_line() { +// Function to blink LEDs for debugging +// NOTE: Currently not used +void blink_leds(int num) +{ + for (int i = 0; i < num; i++) { + blue_LED = 0; + wait(0.5); + blue_LED = 1; + wait(0.5); + } +} + +// Read line from the UART +void read_line() +{ int i; i = 0; // Start Critical Section - don't interrupt while changing global buffer variables @@ -91,14 +168,18 @@ rx_line[i-1] = 0; return; } -int WaitForResponse(char* response, int num) { + +// Wait for specific response +int WaitForResponse(char* response, int num) +{ do { read_line(); debug_pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line); } while (strncmp(rx_line, response, num)); return 0; } -int main() + +int main() { float axis[3]; float press; @@ -106,16 +187,22 @@ float humi; float dummy_temp; - + // Setup serial comms with Skywire and PC debug_pc.baud(115200); skywire.baud(115200); - debug_pc.printf("SystemCoreClock = %d Hz\n", SystemCoreClock); - + debug_pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock); skywire.attach(&Skywire_Rx_interrupt, Serial::RxIrq); + + // Turn on blue LED + green_LED = 0; + red_LED = 0; + blue_LED = 1; + skywire_rts=0; myled=0; debug_pc.printf("Starting Demo...\r\n"); debug_pc.printf("Waiting for Skywire to Boot...\r\n"); + //Enable Skywire skywire_en=0; wait(2); @@ -124,37 +211,104 @@ skywire_en=0; myled=1; - wait(5); + // Wait for modem to initialize + // Wait time is different for each modem + #if defined NL_SW_LTE_GELS3 + wait(60); + #elif defined NL_SW_LTE_TSVG || defined NL_SW_LTE_TNAG || defined NL_SW_LTE_TEUG + wait(15); + #else + wait(5); + #endif + + // Start temp reading LM75_temp.open(); - + //Turn off echo + // Helps with checking responses from Skywire + debug_pc.printf("Turning off echo...\r\n"); skywire.printf("ATE0\r\n"); WaitForResponse("OK", 2); - + + // Turn on DNS Response Caching + // Used on the Telit-based Skywires + #if !defined NL_SW_LTE_GELS3 + debug_pc.printf("Turning on DNS Cacheing to improve speed..."); + skywire.printf("AT#CACHEDNS=1\r\n"); + WaitForResponse("OK", 2); + #endif + debug_pc.printf("Connecting to Network...\r\n"); // get IP address - skywire.printf("AT#SGACT=1,1\r\n"); - WaitForResponse("#SGACT", 6); - WaitForResponse("OK", 2); - - // connect to dweet.io - skywire.printf("AT#HTTPCFG=1,\"dweet.io\",80,0\r\n"); + #if defined NL_SW_LTE_GELS3 + // The last parameter in AT+SQNSCFG sets the timeout if transmit buffer is not full + // Time is in hundreds of ms: so, a value of 5 = 500ms + debug_pc.printf("Configuring context part 1...\r\n"); + skywire.printf("AT+SQNSCFG=3,3,300,90,600,5\r\n"); + WaitForResponse("OK", 2); + wait(1); + debug_pc.printf("Configuring context part 2...\r\n"); + skywire.printf("AT+CGDCONT=3,\"IP\",\"vzwinternet\"\r\n"); + WaitForResponse("OK", 2); + wait(1); + debug_pc.printf("Activating context...\r\n"); + skywire.printf("AT+CGACT=1,3\r\n"); + #elif defined NL_SW_LTE_TSVG + // The last parameter in AT#SCFG sets the timeout if transmit buffer is not full + // Time is in hundreds of ms: so, a value of 5 = 500 ms + skywire.printf("AT#SCFG=3,3,300,90,600,5\r\n"); + WaitForResponse("OK", 2); + wait(1); + skywire.printf("AT+CGDCONT=3,\"IP\",\"%s\"\r\n", APN); + WaitForResponse("OK", 2); + wait(1); + skywire.printf("AT#SGACT=3,1\r\n"); + WaitForResponse("#SGACT", 6); + #else + // The last parameter in AT#SCFG sets the timeout if transmit buffer is not full + // Time is in hundreds of ms: so, a value of 5 = 500 ms + skywire.printf("AT#SCFG=1,1,300,90,600,5\r\n"); + WaitForResponse("OK", 2); + skywire.printf("AT#SGACT=1,1\r\n"); + WaitForResponse("#SGACT", 6); + #endif WaitForResponse("OK", 2); - - //get location approximation from cell tower information - skywire.printf("AT#AGPSSND\r\n"); - WaitForResponse("#AGPSRING:", 10); + // Get triangulation data + // NOTE: This only works on the below modems! + #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 + //get location approximation from cell tower information + skywire.printf("AT#AGPSSND\r\n"); + WaitForResponse("#AGPSRING:", 10); + sscanf(rx_line, "%s %d,%f,%f,", str, &number, &latitude, &longitude); + debug_pc.printf("Location: Latt:%f, Long:%f\r\n", latitude, longitude); + #endif + + red_LED = 0; + blue_LED = 0; + green_LED = 1; - //debug_pc.printf("Skywire says: %s\r\n", rx_line); - sscanf(rx_line, "%s %d,%f,%f,", str, &number, &latitude, &longitude); - debug_pc.printf("Location: Latt:%f, Long:%f\r\n", latitude, longitude); - - wait(3); - while(1) { + // Green on to indicate code position + // Start of loop. Either entered loop for the first time or just sent to dweet.io + red_LED = 0; + blue_LED = 0; + green_LED = 1; + // connect to dweet.io + #if defined NL_SW_LTE_GELS3 + skywire.printf("AT+SQNSD=3,0,80,\"dweet.io\"\r\n"); + #elif defined NL_SW_LTE_TSVG + skywire.printf("AT#SD=3,0,80,\"dweet.io\"\r\n"); + #else + skywire.printf("AT#SD=1,0,80,\"dweet.io\"\r\n"); + #endif + WaitForResponse("CONNECT", 7); + + + // Update the sensors temp = (float)LM75_temp; + //temp = (temp * 9)/5 + 32; // convert C to F debug_pc.printf("Temp = %.3f\r\n", temp); press=(float)pressure.value() / 4096; debug_pc.printf("Pressure = %.3f\r\n", press); @@ -162,14 +316,41 @@ debug_pc.printf("Humidity = %.3f\r\n", humi); accel.read_data(axis); debug_pc.printf("Accel = %.3f, %.3f, %.3f\r\n", axis[0], axis[1], axis[2]); - //wait(10); + + wait(1); + + // Check buttons for presses + if (button1 == 0) + sw1 = 0; + else + sw1 = 1; + if (button2 == 0) + sw2 = 0; + else + sw2 = 1; - //Report Sensor Data to dweet.io - skywire.printf("AT#HTTPQRY=1,0,\"/dweet/for/%s?temp=%.3f&press=%.3f&humi=%.3f&X=%.3f&Y=%.3f&Z=%.3f&Latitude=%f&Longitude=%f\"\r\n", DeviceID, temp, press, humi, axis[0], axis[1], axis[2], latitude, longitude); - WaitForResponse("#HTTPRING", 9); - skywire.printf("AT#HTTPRCV=1\r\n"); - WaitForResponse("OK", 2); - wait(5); + // Green on to indicate code position: + // Sensors updated, have not sent to dweet.io + red_LED = 1; + green_LED = 0; + blue_LED = 0; + + debug_pc.printf("Sending information...\r\n"); + // Report the sensor data to dweet.io + 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); + + // Blue on to indicate code position + // Data sent to dweet + red_LED = 0; + green_LED = 0; + blue_LED = 1; + + // Wait for response from dweet.io + #if defined NL_SW_LTE_GELS3 + WaitForResponse("OK", 2); + wait(1); + #else + WaitForResponse("NO CARRIER", 10); + #endif } - -} +} \ No newline at end of file