пропажа слешей

Dependencies:   mbed mbed-STM32F103C8T6 MLX90614 Watchdog DS1820

main.cpp

Committer:
spin7ion
Date:
2020-09-30
Revision:
10:51960145754a
Parent:
9:e8a07983289f
Child:
11:57fa27cb533e

File content as of revision 10:51960145754a:

#include "stm32f103c8t6.h"
#include "mbed.h"
#include "DS1820.h"
#include "MLX90614.h"
#include "config.h"
#include "ATCmdParser.h"
#include "UARTSerial.h"
#include "Watchdog.h"

Watchdog wd;

DigitalOut  myled(PC_13);

//SIM7000
UARTSerial *_serial;
ATCmdParser *_parser;
int rssiDB,rxQual;


//Termometers
OneWire oneWire(PIN_ONEWIRE);
const int SENSORS_COUNT = 10;
DS1820* ds1820[SENSORS_COUNT];
int sensors_found = 0;
const char sensorsOrder[]={4,2,5,8,0,3,6,1,9,7};
float stickTemperatures[SENSORS_COUNT];

int i=0;

//IR termometer
I2C i2c(PIN_SDA, PIN_SCL);   //sda,scl
MLX90614 thermometer(&i2c);
float IRtemp;

#if DEBUG_PC
Serial pc(PIN_TX, PIN_RX); // TX, RX
#endif

int index;
char bufferString[2048];

int h_time, m_time, s_time;
int fq, nst, fix, date;                                     // fix quality, Number of satellites being tracked, 3D fix
float latitude, longitude, timefix, speed, altitude;

char state=STATE_INIT;
int sleepTimer=0;
int fixTries=0;

void parseTime (float timeval)
{
    //format utc time to beijing time,add 8 time zone
                float time = timeval + 80000.00f;
                h_time = int(time) / 10000;
                m_time = (int(time) % 10000) / 100;
                s_time = int(time) % 100;
}

/* 
 * NMEA sentences:  https://www.gpsinformation.org/dale/nmea.htm#nmea
 *                  http://navspark.mybigcommerce.com/content/NMEA_Format_v0.1.pdf
 */
void nmea_parse(char *cmd)
{   
    char ns, ew, tf, status;
    
    
    // Global Positioning System Fix Data
    if(strncmp(cmd,"$GPGGA", 6) == 0) 
    {
        sscanf(cmd, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%*f,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
        #if DEBUG_PC
        pc.printf("GPGGA Fix taken at: %f, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
        #endif
    }
    
    // Satellite status
     else if(strncmp(cmd,"$GPGSA", 6) == 0) 
    {
        sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst);
        #if DEBUG_PC
        pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
        #endif
    }
    
    // Geographic position, Latitude and Longitude
    else if(strncmp(cmd,"$GPGLL", 6) == 0) 
    {
        sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
        #if DEBUG_PC
        pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
        #endif
    }
    
    // Geographic position, Latitude and Longitude
    else if(strncmp(cmd,"$GPRMC", 6) == 0) 
    {
        sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date);
        #if DEBUG_PC
        pc.printf("GPRMC Fix taken at: %f, Status: %c, Latitude: %f %c, Longitude: %f %c, Speed: %f, Date: %d\n", timefix, status, latitude, ns, longitude, ew, speed, date);
        #endif
    }
    
    // 
    else if(strncmp(cmd,"$GNVTG", 6) == 0) 
    {
     //   pc.printf("its a Vector Track message.\n");
    }
    
    else if(strncmp(cmd,"$GNGGA", 6) == 0) 
    {
        sscanf(cmd, "$GNGGA,%f,%f,%c,%f,%c,%d,%d,%*f,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
        parseTime(timefix);
        #if DEBUG_PC
        pc.printf("GNGGA Fix taken at: %f, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
        pc.printf("Time: %d:%d:%d\n", h_time, m_time, s_time);
        #endif
    }
    
    else if(strncmp(cmd,"$GNGSA", 6) == 0) 
    {
        sscanf(cmd, "$GNGSA,%c,%d,%d", &tf, &fix, &nst);
        #if DEBUG_PC
        pc.printf("GNGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
        #endif
    }
    
    else if(strncmp(cmd,"$GPGSV", 6) == 0) 
    {
     //   pc.printf("its a Satellite details message.\n");
    }
    
    else if(strncmp(cmd,"$GNGLL", 6) == 0) 
    {
        sscanf(cmd, "$GNGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
        #if DEBUG_PC
        pc.printf("GNGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
        #endif
    }
    
    else
    {
   //     pc.printf("Unknown message type\n");
    }
}

bool checkIfOk() {
    if(_parser->recv("OK")) {
        #if DEBUG_PC
        pc.printf("Done\r\n");
        #endif
        
        return true;
    } else {
        #if DEBUG_PC
        pc.printf("Fail\r\n");
        #endif
        
        return false;
    }       
}

bool enableGPS(bool powerUp) {
    #if DEBUG_PC
    pc.printf("Powering GPS %s:",powerUp?"up":"down");
    #endif
    if(powerUp){
        _parser->send("AT+CGNSPWR=1"); //GPS power on
    } else {
        _parser->send("AT+CGNSPWR=0"); //GPS power off
    }
    
    return checkIfOk();
}

bool enableRF(bool powerUp){
    #if DEBUG_PC
    pc.printf("Powering RF %s:",powerUp?"up":"down");
    #endif
    if(powerUp){
        _parser->send("AT+CFUN=1,1"); 
    } else {
        _parser->send("AT+CFUN=0"); //GPS power off
    }
    
    return checkIfOk();    
}

bool setPowerSavingMode() {
    _parser->send("AT+CPSMS=1");//power save
    return checkIfOk(); 
}

bool setSatSystems(){
    #if DEBUG_PC
    pc.printf("Setting sats:");
    #endif
    _parser->send("AT+CGNSMOD=1,1,1,1");
    return checkIfOk();    
}

bool getSignalQuality() {
    _parser->send("AT+CSQ");
    
    if(_parser->recv("+CSQ: %d,%d", &rssiDB,&rxQual) && _parser->recv("OK")) {
        return true;
    }
    return false;
}

bool setAPN() {
     _parser->send("AT+CNACT=1,\"iot\"");
    return checkIfOk();
}

bool disconnectNetwork() {
     _parser->send("AT+CNACT=0");
    return checkIfOk();
}

void initSIM(){
    enableRF(1);
    enableGPS(0);
    setSatSystems();
    wd.Service();
    setPowerSavingMode();
    setAPN();
    wd.Service();    
}

bool getGPS() {
    wd.Service();
    _parser->send("AT+CGNSTST=1,1");
    //wait(PARSER_TIMEOUT_S);
    
    if(_parser->recv("OK")) {
        int nmeaStrLen=_parser->read(bufferString, 2048);
        
        char *curLine = bufferString;
        while(curLine)
        {
          char *nextLine = strchr(curLine, '\n');
          if (nextLine) *nextLine = '\0';  // temporarily terminate the current line
          if(curLine[0]=='$'){
           nmea_parse(curLine);
           #if DEBUG_PC
           pc.printf("curLine=[%s]\n", curLine);
           #endif
          }
          if (nextLine) *nextLine = '\n';  // then restore newline-char, just to be tidy    
          curLine = nextLine ? (nextLine+1) : NULL;
        }
        return fix>0;
    } else{
        int nmeaStrLen=_parser->read(bufferString, 2048);
        pc.printf("curLine=[%s]\n", bufferString);
        }
    return false;
}

void terminateCOAPSession() {
    _parser->send("AT+CCOAPTERM");
    checkIfOk();
    wait(0.5);
    _parser->send("AT+CNACT=0");
    checkIfOk();
}

bool sendTelemetry() {
    wd.Service();
    setAPN();
    wait(1);
    _parser->send("AT+CCOAPINIT");
    if(!checkIfOk()){
        terminateCOAPSession();
        return false;
    }
    wait(1);
    _parser->send("AT+CCOAPURL=\"" MTS_TELEMETRY_URL_STRING);
    if(!checkIfOk()){ terminateCOAPSession();return false;}
    wait(1);
    _parser->printf("AT+CCOAPPARA=code,2,token,0,\"%s\",payload,1,",xstr(MTS_COAP_TOKEN));
    
    for (size_t i = 0; i < strlen(bufferString); i++) {
    _parser->printf("%x",bufferString[i]);
    }
    
    _parser->printf("\r\n");
    if(!checkIfOk()){ terminateCOAPSession();return false;}
    wait(0.5);
    _parser->send("AT+CCOAPACTION");
    if(!checkIfOk()){ terminateCOAPSession();return false;}
    wait(0.5);
    terminateCOAPSession();
    
    return true;
}

int main() {
    confSysClock();     //Configure system clock (72MHz HSE clock, 48MHz USB clock)  
    for(i=0;i<10;i++){
    myled = 0;
    wait(0.5);
    myled = 1;
    wait(0.5);
    myled = 0;}
    //wait(WATCHDOG_INTERVAL_S-15);//Let SIM7000 wake up
    
    #if DEBUG_PC
    pc.baud(115200);
    pc.printf("Starting\r\n");
    if (wd.WatchdogCausedReset()) {
        pc.printf("Watchdog caused reset.\r\n");
    }
    #endif
    
    #if ENABLE_WATCHDOG
    wd.Configure(WATCHDOG_INTERVAL_S);       // sets the timeout interval
    #endif
    
    //Initiate SIM7000 SERIAL
    _serial = new UARTSerial(PIN_SIM_TX, PIN_SIM_RX, 115200);
    _parser = new ATCmdParser(_serial);
    _parser->debug_on( DEBUG_SIM );
    _parser->set_delimiter( "\r\n" );
    _parser->set_timeout (PARSER_TIMEOUT_S);
    wait(0.5);
    
    initSIM();
    
    #if DEBUG_SIM
    _parser->send("AT+CMEE=2"); //report debug info
    checkIfOk();
    #endif
    _parser->send("AT+CPIN?");
    if(_parser->recv("+CPIN:READY")) {
        #if DEBUG_PC
        pc.printf("SIM ready\r\n");
        #endif
    }
    
    /*_parser->send("AT+CPSI?");
    checkIfOk();
    _parser->send("AT+CGNAPN");
    checkIfOk();
    _parser->send("AT+CAPNMODE=1");
    checkIfOk();
    _parser->send("AT+CREG?");
    checkIfOk(); 
    */
    getSignalQuality();
    #if DEBUG_PC
    pc.printf("Signal quality: %d\r\n",rssiDB);
    #endif
    
    wd.Service();
    //Initiate termal stick
    for(i = 0; i < SENSORS_COUNT; i++) {
          ds1820[i] = new DS1820(&oneWire);
          if(!ds1820[i]->begin()) {
              delete ds1820[i];
              break;
          }
    }
    
    sensors_found = i;
    #if DEBUG_PC
    pc.printf("Found %d sensors\r\n",sensors_found);
    if (sensors_found==0)
          pc.printf("No devices found");
    #endif
    
    //Feed the watchdog
    wd.Service();
    state=STATE_STARTING_GPS;
    
    while(1) {
        wd.Service();
        if (state==STATE_STARTING_GPS){
            #if DEBUG_PC
            pc.printf("STATE=STARTING GPS\r\n");
            #endif
            setSatSystems();
            enableGPS(1);
            state=STATE_WAITING_FIX;
            fixTries=0;
            wd.Service();
            wait(FIX_CHECK_TIME_S);
        } else if(state==STATE_WAITING_FIX) {
            
            #if DEBUG_PC
            pc.printf("STATE=WAITNG FIX\r\n");
            #endif
            wd.Service();
            if(getGPS()){
                wd.Service();
                enableGPS(0);
                fixTries=0;
                state=STATE_COLLECTING_TELEMETRY; 
            } else {
                wd.Service();
                #if DEBUG_PC
                pc.printf("No fix(%d) at %d/%d try\r\n", fix, fixTries, FIX_MAX_TRIES);
                #endif
                fixTries++;
                if (fixTries>FIX_MAX_TRIES) {
                    //fix not achieved in given tries, send as is
                    #if DEBUG_PC
                    pc.printf("No fix but continue\r\n");
                    #endif
                    enableGPS(0);
                    wd.Service();
                    state=STATE_COLLECTING_TELEMETRY;
                    fixTries=0;
                } else {
                    #if DEBUG_PC
                    pc.printf("Waiting %d sec\r\n",FIX_CHECK_TIME_S);
                    #endif
                    wd.Service();
                    wait(FIX_CHECK_TIME_S);
                }
            }
        } else if(state==STATE_COLLECTING_TELEMETRY) {
            #if DEBUG_PC
            pc.printf("STATE=COLLECTING TELEMETRY\r\n");
            #endif
            for(i=0;i<SENSORS_COUNT;i++){
                if(sensorsOrder[i]<sensors_found){
                    ds1820[sensorsOrder[i]]->startConversion();
                }    
            }
            wait(1.0);
            for(i=0;i<SENSORS_COUNT;i++){
                if(sensorsOrder[i]<sensors_found){
                    if(ds1820[sensorsOrder[i]]->isPresent()){
                        stickTemperatures[i]=ds1820[i]->read();
                    } else {
                        stickTemperatures[i]=-273.f; // Sensor is offline
                    }
                }
            }
        
            IRtemp=thermometer.read_temp(1);
            
            
            //Form JSON as {"tempIR":1,"temps":[1,...,10],"latitude":37,"longitude":51,"altitude":21,"validGeo":true}
            snprintf(bufferString,2048,"{\"tempIR\":%f,\"latitude\":%f,\"longitude\":%f,\"altitude\":%f,\"validGeo\":%s,temps:[", IRtemp, latitude/10.f, longitude/10.f, altitude, fix ? "true" : "false");
            
            index = strlen(bufferString);
            
            for(i=0;i<SENSORS_COUNT;i++){
                index += snprintf(&bufferString[index], 2048-index, i==0?"%f":",%f", stickTemperatures[i]);
            }
            strcat (bufferString,"]}");
            
            wd.Service();
            state=STATE_SENDING_TELEMETRY;
        } else if(state==STATE_SENDING_TELEMETRY){
            #if DEBUG_PC
            pc.printf("STATE=SENDING TELEMETRY\r\n");
            pc.printf(bufferString);
            #endif
            fixTries=0;
            while(fixTries<FIX_MAX_TRIES && !sendTelemetry()){
                disconnectNetwork();
                initSIM();
                fixTries++;
                wd.Service();
                wait(SLEEP_CHECK_TIME);
                wd.Service();
            }
            fixTries=0;
            wd.Service();
            state=STATE_SLEEPING;
        } else if(state==STATE_SLEEPING){
            #if DEBUG_PC
            pc.printf("STATE=SLEEPING already for %d\r\n",sleepTimer);
            #endif
            wd.Service();
            sleepTimer+=SLEEP_CHECK_TIME;
            
            if(sleepTimer>SLEEP_TIME_S){
                state=STATE_STARTING_GPS;
                sleepTimer=0;
            } else {
               wait(SLEEP_CHECK_TIME);  
            }
            wd.Service();
            #if DEBUG_PC
            pc.printf("After sleep\r\n");
            #endif
        }

        //Feed the watchdog
        wd.Service();
        wait(0.5);
    }
}