M1DK Skywire Demo

Dependencies:   SHT30-DIS-B mbed

Fork of M1DK_Skywire_Demo by Greg Nash

main.cpp

Committer:
kylerodgers
Date:
2018-06-08
Revision:
14:6a94410202bb
Parent:
13:f827f384f0a1

File content as of revision 14:6a94410202bb:

/* main.cpp */
/* V2 */
/* Copyright (C) 2018 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 sends sensor data to Dweet.io on the NL-M1DK.
 */

/*
 * INSTRUCTIONS FOR USING THIS CODE
 * 1. Change the "DeviceID" to a unique identifier for your Nucleo board. One recommendation
 * would be to use the MEID/IMEI of your Skywire Modem.
 */

#include "mbed.h"           // mbed Library
#include "pinmap.h"         // pinmap needed for hardware flow control

#include "SHT30DISB.h"

// --CHANGE THIS FOR YOUR SETUP--
#define DeviceID "thingname"  //DweetIO unique ID

// --CHANGE THIS FOR YOUR SETUP (IF APPLICABLE)--
const char *APN = "NIMBLINK.GW12.VZWENTP";

DigitalOut myled(LED1);                             // Main LED
DigitalOut skywire_rts(PB_5);                       // Skywire Send
DigitalOut green_LED(D7);                           // Green LED
DigitalOut red_LED(D10);                            // Red LED

DigitalOut nRESET(PB_4);                            // Skywire Reset line

AnalogIn photo_trans(A3);                           // Photo Transistor
DigitalOut photo_trans_nEN(D11);                    // Photo Transistor Enable
DigitalIn button1(PA_5);                            // 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

// SHT30 Sensor Setup
SHT30DISB SHT30(i2c);

// variable to switch state
bool sw1;

// char array for reading from Skywire
char str[255];

// Variables for checking CSQ
char csq[3]="99";
int csq_val = 99;

// 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];

// 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;
}

// 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();
        // If we get ERROR, return with 1
        if (strncmp(rx_line, "ERROR", strlen("ERROR")) == 0) {
            debug_pc.printf("ERROR\r\n");
            return 1;
        }
        debug_pc.printf("Waiting for: %s, Recieved: %s\r\n", response, rx_line);
    } while (strncmp(rx_line, response, strlen(response)));
    return 0;
}

// Send AT+CSQ until we get a good signal
int GetCSQResponse()
{   
    do {
        skywire.printf("AT+CSQ\r");
        WaitForResponse("OK");
        csq[0]=rx_line[6];
        csq[1]=rx_line[7];
        csq_val=atoi(csq);  
    } while (!strncmp(rx_line, "CSQ: 99,", 8));
    return csq_val;
}

int main() 
{
    red_LED = 1;

    float temp;
    float humi;
    float photo;

    // Setup serial comms with Skywire and PC
    debug_pc.baud(115200);
    skywire.baud(921600);
    skywire_rts = 0;
    debug_pc.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
    debug_pc.printf("Attaching interrupt...\r\n");
    skywire.attach(&Skywire_Rx_interrupt, Serial::RxIrq);
    debug_pc.printf("Interrupt attached...\r\n");

    // Reset the Skywire to get AT commands, and recover from any previous state
    debug_pc.printf("Resetting Skywire. This gets the Skywire into a known state.\r\n");
    wait_ms(1000);
    nRESET = 1;
    wait_ms(100);
    nRESET = 0;
    wait(3);
    debug_pc.printf("\r\n");
    debug_pc.printf("Resetting baud. This reduced the baudrate on your Skywire for reliability\r\n");
    skywire.printf("\rAT+IPR=115200\r");
    wait_ms(100);
    skywire.baud(115200);
    wait_ms(100);
    debug_pc.printf("\r\n");
    debug_pc.printf("Baud reset!\r\n");
    myled=0;
    debug_pc.printf("\r\n");
    debug_pc.printf("Starting Demo...\r\n");
    green_LED = !green_LED;
    myled=1;
    wait_ms(100);
    
    debug_pc.printf("\r\n");
    debug_pc.printf("Generally, you send a command and wait for a response.\r\n");
    debug_pc.printf("Depending on the response, you may need to take action.\r\n");
    debug_pc.printf("You'll need to wait for the response to the previous command\r\n");
    debug_pc.printf("to finish before continuing on to the next command.\r\n");
    debug_pc.printf("Sending AT to clear out previous commands.\r\n");
    debug_pc.printf("\r\n");
    wait_ms(1000);
    skywire.printf("\r\r");
    skywire.printf("AT\r");
    WaitForResponse("OK");
    debug_pc.printf("\r\n");
    debug_pc.printf("Enabling echo to make it easier to see commands\r\n");
    skywire.printf("ATE1\r");
    WaitForResponse("OK");
    debug_pc.printf("\r\n");
    debug_pc.printf("Setting up Skywire network settings\r\n");
    skywire.printf("AT+SQNAUTOINTERNET=1\r");
    WaitForResponse("OK");
    skywire.printf("AT^AUTOATT=1\r");
    WaitForResponse("OK");
    skywire.printf("AT+SQNAUTOCONNECT=1\r");
    WaitForResponse("OK");

    debug_pc.printf("\r\n");
    debug_pc.printf("Setting up socket...\r\n");
    skywire.printf("AT+SQNSCFG=3,3,300,90,600,5\r");
    WaitForResponse("OK");
    debug_pc.printf("\r\n");
    debug_pc.printf("Resetting Skywire to get into known state\r\n");
    skywire.printf("AT^RESET\r");
    WaitForResponse("OK");
    WaitForResponse("+SYSSTART");
    WaitForResponse("+CEREG: 1");

    // Check CSQ    
    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("\r\n");
    debug_pc.printf("Network detected. Checking authorization...\r\n");
    skywire.printf("AT+CEREG?\r");
    WaitForResponse("OK");

    red_LED = 1;
    green_LED = 0;

    debug_pc.printf("\r\n");
    debug_pc.printf("Everything is setup, and you're registered on the network.\r\n");
    debug_pc.printf("Entering the socket dial loop.\r\n");
    
    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;
        
        debug_pc.printf("Opening the socket\r\n");
        int retries = 0;
        while (retries < 5) {
            skywire.printf("AT+SQNSD=3,0,80,\"dweet.io\"\r");
            if (WaitForResponse("CONNECT") == 1) {
                retries += 1;
                wait(1);
            } else {
                
                break;
            }
        }
        debug_pc.printf("\r\n");
        debug_pc.printf("Socket open!\r\n");
        debug_pc.printf("\r\n");
        debug_pc.printf("Updating sensors\r\n");
        //get temp and 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 = 1;
        else
            sw1 = 0;
        
        // Green on to indicate code position:
        // Sensors updated, have not sent to dweet.io
        red_LED = 1;
        green_LED = 0;
        debug_pc.printf("\r\n");
        debug_pc.printf("Sensors updated!\r\n");
        debug_pc.printf("\r\n");
        debug_pc.printf("Sending information\r\n");
        if (retries != 5) {
            retries = 0;
            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");
        }
        
        debug_pc.printf("\r\n");
        debug_pc.printf("Information sent!\r\n");
 
        debug_pc.printf("\r\n");
        debug_pc.printf("Closing socket...\r\n");
        skywire.printf("AT+SQNSH=3\r");
        WaitForResponse("OK");
        red_LED = 0;
        green_LED = 1;
    }
}