![](/media/cache/group/NimbeLink_Logo.png.50x50_q85.png)
M1DK Skywire Demo
Dependencies: SHT30-DIS-B mbed
Fork of M1DK_Skywire_Demo by
main.cpp
- Committer:
- GregNash
- Date:
- 2017-02-01
- Revision:
- 11:78a28ca6409f
- Parent:
- 10:5974a7b2cf38
- Child:
- 13:f827f384f0a1
File content as of revision 11:78a28ca6409f:
/* main.cpp */ /* v5.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, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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. This code will automatically detect the modem you are using. * * 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" // mbed Library #include "pinmap.h" // pinmap needed for hardware flow control #include "SHT30DISB.h" enum Skywire_Modem { NL_SW_1xRTT_V, // Verizon 2G Modem - CE910-DUAL NL_SW_1xRTT_S, // Sprint 2G Modem - CE910-DUAL NL_SW_1xRTT_A, // Aeris 2G Modem - CE910-DUAL NL_SW_GPRS, // AT&T/T-Mobile 2G Modem NL_SW_EVDO_V, // Verizon 3G Modem NL_SW_EVDO_A, // Aeris 3G Modem NL_SW_HSPAP, // AT&T/T-Mobile 3G Modem NL_SW_HSPAPG, // AT&T/T-Mobile 3G Modem w/ GPS NL_SW_HSPAPE, // GSM 3G Modem, EU NL_SW_LTE_TSVG, // Verizon 4G LTE Modem NL_SW_LTE_TNAG, // AT&T/T-Mobile 4G LTE Modem NL_SW_LTE_TEUG, // GSM 4G LTE Modem, EU NL_SW_LTE_GELS3, // VZW LTE CAT 1 Modem NL_SW_LTE_S7588 // VZW LTE CAT 4 Modem }; // Our modem Skywire_Modem MODEM; // --CHANGE THIS FOR YOUR SETUP-- #define DeviceID "M1DK-UNIT1" //DweetIO unique ID // --CHANGE THIS FOR YOUR SETUP (IF APPLICABLE)-- char const *APN = "NIMBLINK.GW12.VZWENTP"; //char const *APN = "mw01.VZWSTATIC"; //char const *APN = "VZWINTERNET"; DigitalOut myled(LED1); // Main LED DigitalOut skywire_en(A2); // Skywire Enable PinName skywire_rts(D5); // Skywire Send DigitalOut green_LED(D7); // Green LED DigitalOut red_LED(D10); // Red LED AnalogIn photo_trans(A3); // Photo Transistor DigitalOut photo_trans_nEN(D11); // Photo Transistor DigitalIn button1(D13); // Button 1 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 SHT30DISB SHT30(i2c); // char array for reading from Skywire char str[255]; char csq[3]="99"; int csq_val = 99; // 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 = 600; char rx_buffer[buffer_size+1]; char rx_line[buffer_size]; // Provisioning Flag for CE910 and DE910 only int prov_flag = 0; // 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)) { rx_buffer[rx_in] = skywire.getc(); rx_in = (rx_in + 1) % buffer_size; } return; } // Function to "pretty print" the delay time void wait_print(int time) { for (int i = time; i >= 0; i--) { if (i == 1) { debug_pc.printf("Delay Time Remaining: %d second \r", i); } else { debug_pc.printf("Delay Time Remaining: %d seconds \r", i); } green_LED = 0; wait(0.5); green_LED = 1; wait(0.5); } debug_pc.printf("Delay finished! \r\n"); return; } // Function to blink LEDs for debugging // NOTE: Currently not used void blink_leds(int num) { for (int i = 0; i < num; i++) { green_LED = 0; myled=0; wait(0.25); green_LED = 1; myled=1; wait(0.25); } } void blink_redled(int num) { for (int i = 0; i < num; i++) { red_LED = 0; wait(0.25); red_LED = 1; wait(0.25); } } // Read line from the UART void read_line() { int i; i = 0; // Start Critical Section - don't interrupt while changing global buffer variables __disable_irq(); // Loop reading rx buffer characters until end of line character while ((i==0) || (rx_line[i-1] != '\n')) { // Wait if buffer empty if (rx_in == rx_out) { // End Critical Section - need to allow rx interrupt to get new characters for buffer __enable_irq(); while (rx_in == rx_out) { } // Start Critical Section - don't interrupt while changing global buffer variables __disable_irq(); } rx_line[i] = rx_buffer[rx_out]; i++; rx_out = (rx_out + 1) % buffer_size; } // End Critical Section __enable_irq(); rx_line[i-1] = 0; return; } // Wait for specific response int WaitForResponse(const char *response) { debug_pc.printf("Command sent. Waiting for: %s\r\n", response); do { read_line(); debug_pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line); } while (strncmp(rx_line, response, strlen(response))); return 0; } // Get and parse the AT+GMM response // Depending on what it gets, parse and return int GetGMMResponse() { //int ret_val = 0; do { read_line(); debug_pc.printf("Waiting for: %s, Received: %s\r\n", "OK", rx_line); if (!strncmp(rx_line, "GE910-QUAD-V3", 13)) { MODEM = NL_SW_GPRS; debug_pc.printf("Modem detected: NL-SW-GPRS\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "CE910-DUAL", 10)) { MODEM = NL_SW_1xRTT_V; debug_pc.printf("Modem detected: NL-SW-1xRTT\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "DE910-DUAL", 10)) { MODEM = NL_SW_EVDO_V; debug_pc.printf("Modem detected: NL-SW-EVDO\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "HE910-NAD", 9)) { MODEM = NL_SW_HSPAP; debug_pc.printf("Modem detected: NL-SW-HSPAP\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "HE910-D", 7)) { MODEM = NL_SW_HSPAPG; debug_pc.printf("Modem detected: NL-SW-HSPAPG\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "LE910-SVG", 9)) { MODEM = NL_SW_LTE_TSVG; debug_pc.printf("Modem detected: NL-SW-LTE-TSVG\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "LE910-NAG", 9)) { MODEM = NL_SW_LTE_TNAG; debug_pc.printf("Modem detected: NL-SW-LTE-TNAG\r\n"); //ret_val = 1; return 1; } if (!strncmp(rx_line, "HL7588", 6)) { MODEM = NL_SW_LTE_S7588; debug_pc.printf("Modem detected: NL-SW-LTE-S7588\r\n"); //ret_val = 1; return 1; } } while (strncmp(rx_line, "OK", 2)); return 0; } // Get and parse the AT+GMM response // Depending on what it gets, parse and return int GetATIResponse() { int ret_val = 0; do { read_line(); debug_pc.printf("Waiting for: %s, Received: %s\r\n", "OK", rx_line); if (!strncmp(rx_line, "ELS31-V", 7)) { MODEM = NL_SW_LTE_GELS3; debug_pc.printf("Modem detected: NL-SW-LTE-GELS3\r\n"); ret_val = 1; } } while (strncmp(rx_line, "OK", 2)); return ret_val; } // Get the Skywire Model int getSkywireModel() { // Send ATI. Prints everything for CAT1, so we will check that first debug_pc.printf("Sending ATI...\r\n"); skywire.printf("ATI\r"); if (GetATIResponse()) { return 0; } // If you get here, then we have a non-CAT1 modem debug_pc.printf("Sending AT+GMM...\r\n"); skywire.printf("AT+GMM\r"); if (GetGMMResponse()) { return 0; } // Otherwise, we have an error (or no modem), so sit here and blink else { debug_pc.printf("Unable to detect modem: ERROR\r\n"); while(1) { blink_leds(10); } } } int bootSkywire() { int ret_val = 0; //Enable Skywire skywire.printf("AT\r"); read_line(); debug_pc.printf("Waiting for: %s, Received: %s\r\n", "OK", rx_line); if (strncmp(rx_line, "OK", 2)) { ret_val=1; debug_pc.printf("retval Value: %i\r\n", ret_val); } else { debug_pc.printf("Modem not detected; Attempt reboot.\r\n"); skywire_en=0; debug_pc.printf("Toggling enable pin low\r\n"); wait_print(4); skywire_en=1; debug_pc.printf("Toggling enable pin high\r\n"); wait_print(10); debug_pc.printf("retval Value2: %i\r\n", ret_val); skywire.printf("AT\r"); read_line(); debug_pc.printf("Waiting for: %s, Received: %s\r\n", "OK", rx_line); if (strncmp(rx_line, "OK", 2)) { ret_val=1; debug_pc.printf("retval Value: %i\r\n", ret_val); } } return ret_val; } int GetCSQResponse() { do { skywire.printf("AT+CSQ\r"); WaitForResponse("OK"); csq[0]=rx_line[6]; csq[1]=rx_line[7]; csq_val=atoi(csq); // debug_pc.printf("Waiting for CSQ: %s\r\n", csq); // debug_pc.printf("CSQ Value: %i\r\n", csq_val); } while (!strncmp(rx_line, "CSQ: 99,", 8)); return csq_val; } int Provision(void) { // 1x green means entered the provisioning process debug_pc.printf("\r\n\r\n"); blink_leds(1); debug_pc.printf("Provisioning request detected\r\n"); debug_pc.printf("Sending provisioning command...\r\n"); skywire.printf("ATD*22899;\r\n"); WaitForResponse("OK"); blink_leds(2); debug_pc.printf("Command sent, OK received!\r\n"); debug_pc.printf("Waiting for additional responses...\r\n"); WaitForResponse("#OTASP: 0"); WaitForResponse("#OTASP: 1"); WaitForResponse("#OTASP: 2"); blink_leds(3); debug_pc.printf("Waiting for NO CARRIER...\r\n"); WaitForResponse("NO CARRIER"); blink_leds(4); debug_pc.printf("\r\nReceived NO CARRIER! Rebooting...\r\n"); skywire.printf("AT#REBOOT\r\n"); //WaitForResponse("OK", 2); green_LED = 0; red_LED = 0; // wait 60 seconds for reboot, blink LEDs to indicate something is happening wait_print(60); return 0; } int main() { // First, check if the button is being held, set flag // and turn on green LED if (button1 == 0) { prov_flag = 1; green_LED = 1; red_LED = 0; } else { green_LED = 0; red_LED = 0; } debug_pc.printf("Prov Flag: %d\r\n", prov_flag); red_LED = 1; float temp; float humi; float photo; // Setup serial comms with Skywire and PC debug_pc.baud(115200); skywire.baud(115200); debug_pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock); skywire.attach(&Skywire_Rx_interrupt, Serial::RxIrq); //skywire_rts=0; // On the NL-SW-LTE-GELS3, flow control is required for consistent results //pin_function(skywire_rts, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)); pin_function(skywire_rts, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)); UART_HandleTypeDef handle; handle.Instance = (USART_TypeDef *)USART1_BASE; __HAL_USART_DISABLE(&handle); __HAL_UART_HWCONTROL_CTS_ENABLE(&handle); __HAL_UART_HWCONTROL_RTS_ENABLE(&handle); __HAL_USART_ENABLE(&handle); myled=0; blink_leds(30); debug_pc.printf("Starting Demo...\r\n"); debug_pc.printf("Waiting for Skywire to Boot...\r\n"); green_LED = !green_LED; // while(!bootSkywire()){ // debug_pc.printf("Waiting for Skywire to Boot...\r\n"); // // } // // skywire.printf("AT\r"); // WaitForResponse("OK"); myled=1; blink_leds(1); // Wait time is different for each modem, so wait up to one minute // wait_print(10); // Start temp reading/////////////////////////////////////////////////////////////// // Turn off echo // Helps with checking responses from Skywire debug_pc.printf("Turning off echo...\r\n"); skywire.printf("ATE0\r"); WaitForResponse("OK"); green_LED = !green_LED; // Get the modem from the Skywire, and set MODEM getSkywireModel(); // If you have a CDMA-based 2G or 3G Skywire, and you pressed the provision button, // provision the modem if ((MODEM == NL_SW_1xRTT_V || MODEM == NL_SW_EVDO_V) && prov_flag == 1) { Provision(); } // Debug stuff - get signal quality debug_pc.printf("Getting CSQ...\r\n"); GetCSQResponse(); green_LED = !green_LED; while(csq_val==99 || csq_val==0) { debug_pc.printf("CSQ Value: %i\r\n",csq_val); debug_pc.printf("No network sginal detected. \r\n"); debug_pc.printf("Waiting for device to connect to the network. \r\n"); debug_pc.printf("Please check antenna connections if network is not found after 30 seconds. \r\n"); wait(1); //add elapsed time debug_pc.printf("Checking network connectrion. \r\n"); GetCSQResponse(); red_LED = !red_LED; } debug_pc.printf("Network detected. Checking authorization...\r\n"); if (MODEM == NL_SW_LTE_TSVG || MODEM == NL_SW_LTE_TNAG) { green_LED = !green_LED; debug_pc.printf("Sending AT+CGREG...\r\n"); skywire.printf("AT+CGREG?\r"); } else if (MODEM == NL_SW_LTE_GELS3) { green_LED = !green_LED; debug_pc.printf("Sending AT+CEREG...\r\n"); skywire.printf("AT+CEREG?\r"); } else { green_LED = !green_LED; debug_pc.printf("Sending AT+CREG...\r\n"); skywire.printf("AT+CREG?\r"); } WaitForResponse("OK"); // Turn on DNS Response Caching // Used on the Telit-based Skywires if (MODEM != NL_SW_LTE_GELS3) { green_LED = !green_LED; debug_pc.printf("Turning on DNS Cacheing to improve speed...\r\n"); skywire.printf("AT#CACHEDNS=1\r"); WaitForResponse("OK"); } debug_pc.printf("Connecting to Network...\r\n"); // get IP address if (MODEM == NL_SW_LTE_GELS3) { green_LED = !green_LED; // set CFUN debug_pc.printf("Sending AT+CFUN=1\r\n"); skywire.printf("AT+CFUN=1\r"); WaitForResponse("OK"); // Setup AT+CGDCONT debug_pc.printf("Sending AT+CGDCONT...\r\n"); skywire.printf("AT+CGDCONT=3,\"IPV4V6\",\"%s\"\r", APN); WaitForResponse("OK"); // Turn on AT+CGATT debug_pc.printf("Sending AT+CGATT=1\r\n"); skywire.printf("AT+CGATT=1\r"); WaitForResponse("OK"); debug_pc.printf("AT^SISS=0, srvType...\r\n"); skywire.printf("AT^SISS=0,\"srvType\",\"Socket\"\r"); WaitForResponse("OK"); wait(1); debug_pc.printf("AT^SISS=0, conId...\r\n"); skywire.printf("AT^SISS=0,\"conId\",3\r"); WaitForResponse("OK"); wait(1); debug_pc.printf("AT^SISS=0,address...\r\n"); skywire.printf("AT^SISS=0,\"address\",\"socktcp://dweet.io:80\"\r"); //skywire.printf("AT^SISS=0,\"address\",\"socktcp://52.205.164.103:80\"\r"); WaitForResponse("OK"); wait(1); // AT^SICA activation debug_pc.printf("Activating context...\r\n"); skywire.printf("AT^SICA=1,3\r"); WaitForResponse("OK"); wait(1); // AT^SICA? query debug_pc.printf("AT^SICA?\r\n"); skywire.printf("AT^SICA?\r"); //WaitForResponse("OK"); //wait(1); } else if (MODEM == NL_SW_LTE_TSVG) { green_LED = !green_LED; // 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 debug_pc.printf("Configuring context part 1...\r\n"); skywire.printf("AT#SCFG=3,3,300,90,600,5\r"); WaitForResponse("OK"); green_LED = !green_LED; wait(1); debug_pc.printf("Configuring context part 2...\r\n"); skywire.printf("AT+CGDCONT=3,\"IP\",\"%s\"\r", APN); WaitForResponse("OK");// green_LED = !green_LED; // wait(1); // debug_pc.printf("Configuring context...\r\n"); // skywire.printf("AT#OTAUIDM=0\r", APN); // WaitForResponse("#DREL"); wait(1); debug_pc.printf("activating context ...\r\n"); skywire.printf("AT#SGACT=3,1\r"); WaitForResponse("#SGACT"); green_LED = !green_LED; } else if (MODEM == NL_SW_LTE_TNAG || MODEM == NL_SW_LTE_TEUG || MODEM == NL_SW_HSPAP || MODEM == NL_SW_HSPAPG || MODEM == NL_SW_HSPAPE || MODEM == NL_SW_GPRS) { debug_pc.printf("Configuring context part 1...\r\n"); skywire.printf("AT#SCFG=1,1,300,90,600,5\r"); WaitForResponse("OK"); green_LED = !green_LED; wait(1); debug_pc.printf("Configuring context part 2...\r\n"); skywire.printf("AT+CGDCONT=1,\"IP\",\"%s\"\r", APN); WaitForResponse("OK"); green_LED = !green_LED; wait(1); skywire.printf("AT#SGACT=1,1\r"); WaitForResponse("#SGACT"); green_LED = !green_LED; } 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"); green_LED = !green_LED; WaitForResponse("OK"); green_LED = !green_LED; skywire.printf("AT#SGACT=1,1\r"); WaitForResponse("#SGACT"); green_LED = !green_LED; } WaitForResponse("OK"); green_LED = !green_LED; // Get triangulation data // NOTE: This only works on the below modems! if (MODEM == NL_SW_1xRTT_V || MODEM == NL_SW_1xRTT_S || MODEM == NL_SW_1xRTT_A || MODEM == NL_SW_GPRS || MODEM == NL_SW_EVDO_V || MODEM == NL_SW_EVDO_A || MODEM == NL_SW_HSPAP || MODEM == NL_SW_HSPAPG || MODEM == NL_SW_HSPAPE) { //get location approximation from cell tower information skywire.printf("AT#AGPSSND\r"); WaitForResponse("#AGPSRING:"); sscanf(rx_line, "%s %d,%f,%f,", str, &number, &latitude, &longitude); debug_pc.printf("Location: Latt:%f, Long:%f\r\n", latitude, longitude); } red_LED = 1; green_LED = 0; char post[256]; 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; green_LED = 1; // connect to dweet.io if (MODEM == NL_SW_LTE_GELS3) { debug_pc.printf("Opening socket...\r\n"); skywire.printf("AT^SISO=0\r"); WaitForResponse("OK"); } else if (MODEM == NL_SW_LTE_TSVG) { skywire.printf("AT#SD=3,0,80,\"dweet.io\"\r"); WaitForResponse("CONNECT"); } else { skywire.printf("AT#SD=1,0,80,\"dweet.io\"\r"); WaitForResponse("CONNECT"); } // 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); // humidity.ReadTempHumi(&dummy_temp, &humi); //debug_pc.printf("Humidity = %.3f\r\n", humi); temp=SHT30.cTemp(); humi=SHT30.humidity(); photo_trans_nEN=0; photo=photo_trans*200; wait(1); // Check buttons for presses if (button1 == 0) sw1 = 0; else sw1 = 1; // Green on to indicate code position: // Sensors updated, have not sent to dweet.io red_LED = 1; green_LED = 0; if (MODEM == NL_SW_LTE_GELS3) { sprintf(post, "POST /dweet/for/%s?temp=%.3f&sw1=%d&photo=%.3f&humidity=%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, sw1, photo, humi); debug_pc.printf("Writing...\r\n"); skywire.printf("AT^SISW=0,%d\r", strlen(post)); WaitForResponse("^SISW:"); debug_pc.printf("Sending information...\r\n"); skywire.printf("%s", post); WaitForResponse("^SISR:"); debug_pc.printf("Reading...\r\n"); skywire.printf("AT^SISR=0,1000\r"); WaitForResponse("OK"); skywire.printf("AT^SISC=0\r"); WaitForResponse("OK"); } else { debug_pc.printf("Sending information...\r\n"); // Report the sensor data to dweet.io skywire.printf("POST /dweet/for/%s?temp=%.3f&sw1=%d&photo=%.3f&humidity=%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, sw1, photo, humi); WaitForResponse("NO CARRIER"); } // green on to indicate code position // Data sent to dweet red_LED = 0; green_LED = 1; } }