demo1

Dependencies:   SHT30-DIS-B WakeUp mbed

Fork of M1DK_Skywire_Demo by NimbeLink

main.cpp

Committer:
charlesxu918
Date:
2018-06-22
Revision:
14:44eb72d9995e
Parent:
13:f827f384f0a1

File content as of revision 14:44eb72d9995e:

/* main.cpp */
/* Copyright (C) 2017 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"

#include "WakeUp.h"

#include "LowPowerTimeout.h"
#include "sleep_api.h"
#include "cmsis.h"

// --CHANGE THIS FOR YOUR SETUP--
#define DeviceID "CP Prototype001"  //DweetIO unique IDA

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




//LowPowerTimeout timeout;







int main() 
{
   
  
  debug_pc.baud(115200);
   /*  sleep mode testing.
   
    red_LED = 1;
    float temp;
    float humi;
    float photo;
    char *CSQValue;

    // Setup serial comms with Skywire and PC
    debug_pc.baud(115200);
    skywire.baud(115200);
    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...\r\n");
    nRESET = 1;
    wait_ms(100);
    nRESET = 0;
    wait(6);
    debug_pc.printf("Resetting baud...\r\n");
    skywire.printf("\rAT+IPR=115200\r");
    wait_ms(100);
    skywire.baud(115200);
    wait_ms(100);
    debug_pc.printf("Baud reset!\r\n");
    myled=0;
    debug_pc.printf("Starting Demo...\r\n");
    debug_pc.printf("Waiting for Skywire to Boot...\r\n");
    green_LED = !green_LED;
    myled=1;
    //wait(120);

    
   // Make them comments for debugging:
    debug_pc.printf("Sending AT\r\n");
    skywire.printf("\rAT\r");
    WaitForResponse("OK");
    //WaitForResponse("+CEREG: 1");
    debug_pc.printf("Sending AT+CFUN=1\r\n");
    skywire.printf("AT+CFUN=1\r");
    WaitForResponse("OK");
    //wait_ms(2000);
   
    // 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("Network detected. Checking authorization...\r\n");
    skywire.printf("AT+CEREG?\r");
    WaitForResponse("OK");

    //debug_pc.printf("Connecting to Network...\r\n");
    debug_pc.printf("Setting up socket...\r\n");
    skywire.printf("AT+SQNSCFG=3,3,300,90,600,50\r");
    WaitForResponse("OK");

    red_LED = 1;
    green_LED = 0;


    debug_pc.printf("Check Version...\r\n");
    skywire.printf("ATI1\r");
    WaitForResponse("OK");


    
    ////////////////Added on April 18, 2018
    
    SPI spi(PB_15, PB_14,PB_13); // mosi, miso, sclk
    DigitalOut cs(PB_12);
    
    // Select the device by setting chip select low
    cs = 0;
 
    // Send 0x8f, the command to read the WHOAMI register
   //spi.write(0x80);
 
    // Send a dummy byte to receive the contents of the WHOAMI register
    long whoami = spi.write(0x80);
    
    debug_pc.printf("Read SPI information...\r\n");
    debug_pc.printf("SPI Value: %i\r\n",whoami );
    long whoami1 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami1 );
     long whoami2 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami2 );
     long whoami3 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami3 );
     long whoami4 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami4 );
    
    // Deselect the device
    cs = 1;
    //// Added on April 18, 2018

    wait_ms(100);



    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;
        //*  Comments for debugging
        int retries = 0;
        while (retries < 5) {
            //skywire.printf("AT+SQNSD=3,0,80,\"dweet.io\"\r");
             skywire.printf("AT+SQNSD=3,0,59001,\"12.193.202.234\"\r");
            //skywire.printf("AT+SQNSD=3,0,60001,\"<12.25.92.72>\"\r");
            if (WaitForResponse("CONNECT") == 1) {
                retries += 1;
                wait(1);
            } else
                break;
        }

  //*/   
  
  
  
  /*  sleep mode testing.
  
  
        //get temp and humi
        temp=SHT30.cTemp();
        humi=SHT30.humidity();
        photo_trans_nEN=0;
        photo=photo_trans*200;
        
    
                        
        //humi=csq_val;
        wait(1);
        
        
// SPI Reading Procedure Added on April 18 2018
         wait(2);  
        // Select the device by setting chip select low
    cs = 0;
 
    // Send a dummy byte to receive the contents of the WHOAMI register
    char whoami = spi.write(0x00);
    
    debug_pc.printf("Read SPI information...\r\n");
    debug_pc.printf("SPI Value: %i\r\n",whoami );
    
    //long whoami1 = spi.write(0x00);
    char whoami1 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami1 );
      char whoami2 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami2 );
     char whoami3 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami3 );
     char whoami4 = spi.write(0x00);
    debug_pc.printf("SPI Value: %i\r\n",whoami4 );
            
    photo=whoami1/14.5;
    
    unsigned char mask=1<<5;
    int sign=mask&whoami;
    
    long tempLong1=0;
    long tempLong2=0;
    long tempLong3=0;
    long tempLong4=0;
    
    char tempChar;
    long convertedResults=0;// converted results
    
     float output;
    
    if (sign==0) // negative readings:
    {
    
        tempChar=whoami;
       tempChar=tempChar<<3;
       tempChar=tempChar>>3;
       debug_pc.printf("test1 Value is: %i\r\n", tempChar );
       
       tempLong1=tempLong1|tempChar;
       debug_pc.printf("test2 Value is: %i\r\n", tempLong1 );
     
       tempLong1=tempLong1<<24;
       debug_pc.printf("test3 Value is: %i\r\n", tempLong1 );
       
       
       tempChar=whoami1;
       tempLong2=tempLong2|tempChar;
       tempLong2=tempLong2<<16;
       
       tempChar=whoami2;
       tempLong3=tempLong3|tempChar;
       tempLong3=tempLong3<<8;
       
       tempChar=whoami3;
       tempChar=tempChar>>5;
       tempChar=tempChar<<5;
       tempLong4=tempLong4&tempChar;
       
       convertedResults=tempLong1|tempLong2|tempLong3|tempLong4;
       convertedResults=~ convertedResults;
       convertedResults=convertedResults<<3;
       convertedResults=convertedResults>>3;
       convertedResults= convertedResults>>5;
        
       
       
   debug_pc.printf("Long1 Value is: %i\r\n", tempLong1 );
   debug_pc.printf("Long2 Value is: %i\r\n", tempLong2 );
   debug_pc.printf("Long3 Value is: %i\r\n", tempLong3 );
   debug_pc.printf("Long4 Value is: %i\r\n", tempLong4 );
        
     output = -convertedResults*0.0000120;
     
    
    
    }
    else // positive readings:
    {
       tempChar=whoami;
       tempChar=tempChar<<3;
       tempChar=tempChar>>3;
       debug_pc.printf("test1 Value is: %i\r\n", tempChar );
       
       tempLong1=tempLong1|tempChar;
       debug_pc.printf("test2 Value is: %i\r\n", tempLong1 );
     
       tempLong1=tempLong1<<24;
       debug_pc.printf("test3 Value is: %i\r\n", tempLong1 );
       
       
       tempChar=whoami1;
       tempLong2=tempLong2|tempChar;
       tempLong2=tempLong2<<16;
       
       tempChar=whoami2;
       tempLong3=tempLong3|tempChar;
       tempLong3=tempLong3<<8;
       
       tempChar=whoami3;
       tempChar=tempChar>>5;
       tempChar=tempChar<<5;
       tempLong4=tempLong4&tempChar;
       
       convertedResults=tempLong1|tempLong2|tempLong3|tempLong4;
        convertedResults= convertedResults>>5;
        
       
       
   debug_pc.printf("Long1 Value is: %i\r\n", tempLong1 );
   debug_pc.printf("Long2 Value is: %i\r\n", tempLong2 );
   debug_pc.printf("Long3 Value is: %i\r\n", tempLong3 );
   debug_pc.printf("Long4 Value is: %i\r\n", tempLong4 );
         output = convertedResults*0.0000120;
    } 
    
    
    debug_pc.printf("Measured Value Sign is: %i\r\n",sign );
   
    
    debug_pc.printf("Converted Value is: %i\r\n", convertedResults );
    debug_pc.printf("Converted True Value is: %f\r\n", output );
    

    // Deselect the device   
    
    
    cs = 1;
//// End of SPI Reading Procedure  Added on April 18, 2018




                   
         wait(2);  
        
        

        // 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;
        
     // /*
        photo=output;
        float para1;
        float para2;
        float para3;
        float para4;
        float para5;
        float para6;
        float para7;
        float para8;
        float para9;
        float para10;
        float para11;
        para1=csq_val;
        para2=temp/1.4;
        para3=output;
        para4=humi;
        para5=0;
        para6=0;
        para7=0;
        para8=0;
        para9=0;
        para10=0;
        para11=0;
        if (retries != 5) {
            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&CSQ=%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, sw1, photo, humi);
            //skywire.printf("POST %s,%.3f,%.3f,%.3f,%.3f HTTP/1.0\r\n\r\n", DeviceID, temp, sw1, photo, humi);
            skywire.printf("%s,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f \r\n\r\n", DeviceID, para1, para2, para3, para4,para5,para6,para7,para8,para9,para10,para11);
            WaitForResponse("NO CARRIER");
        }
//        }        
        debug_pc.printf("Closing socket...\r\n");
        skywire.printf("AT+SQNSH=3\r");
        WaitForResponse("OK");
        wait(2);  
        skywire.printf("AT+CGATT=0\r");
        WaitForResponse("OK");
        wait(2);  
        skywire.printf("AT+CGATT=1\r");
        WaitForResponse("+CEREG: 1");
        wait(2);  
        red_LED = 0;
        green_LED = 1;
              
        wait(3);    
        skywire.printf("AT+CSQ\r");
        WaitForResponse("OK");
        csq[0]=rx_line[6];
        csq[1]=rx_line[7];
        csq_val=atoi(csq);  
        wait(6);    
   
   // sleeping testing
   
   
   // after data sending: 
    
   */ //Sleep mode testing
   
   
   
      
        
        
        wait(5);
 
      //The low-power oscillator can be quite inaccurate on some targets
      //this function calibrates it against the main clock
      WakeUp::calibrate();
     
     
      while(1) {
          //Set LED to zero
          red_LED = 0;
        green_LED = 1;
          //Set wakeup time for 2 seconds
          WakeUp::set_ms(2000);
          
          //Enter deepsleep, the program won't go beyond this point until it is woken up
          deepsleep();
          
          //Set LED for 1 second to one
         red_LED = 1;
        green_LED = 0;
          wait(1);
      }
        
         
        
        
        
        
   
   // End of sleeping, get back to work
        
    
   
  
   
     
   
   
}