Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
michael ma
Created November 27, 2023

Traveling Guide with GPS and Cloud

Using GPS to position and upload note, retrieve note to meet the guide requirement in travelling.

27
Traveling Guide with GPS and Cloud

Things used in this project

Story

Read more

Code

Notehub and GPS code

C/C++
Get GPS data and parse position, push to cloud with Notehub.
#define GpsSerial  Serial
#define DebugSerial Serial
#define serialNotecard Serial1
#define NOTE_PRODUCT_UID "<com.smartsoft.gpsnote>"
//LED
int L = 13;
struct
{
    char GPS_Buffer[80];
    bool isGetData;     //get GPS data or not
    bool isParseData;   //parse is done or not
    char UTCTime[11];       //UTC time
    char latitude[11];
    char N_S[2];        //N/S
    char longitude[12];
    char E_W[2];        //E/W
    bool isUsefull;     //position information valid
} Save_Data;

const unsigned int gpsRxBufferLength = 600;
char gpsRxBuffer[gpsRxBufferLength];
unsigned int ii = 0;
void init_gps() //init
{
    GpsSerial.begin(9600);          //define bode 9600
    DebugSerial.begin(9600);
    DebugSerial.println("Waiting...");
    Save_Data.isGetData = false;
    Save_Data.isParseData = false;
    Save_Data.isUsefull = false;
}

bool process_gps()      //process GPS data
{
    gpsRead();        //get GPS data
    parseGpsBuffer(); //Parse gps data
    printGpsBuffer(); //print gps data
    // DebugSerial.println("\r\n\r\nloop\r\n\r\n");
    return Save_Data.isParseData;
}

void errorLog(int num)
{
    DebugSerial.print("ERROR");
    DebugSerial.println(num);
    while (1)
    {
        digitalWrite(L, HIGH);
        delay(300);
        digitalWrite(L, LOW);
        delay(300);
    }
}

void printGpsBuffer()
{
    if (Save_Data.isParseData)
    {
        Save_Data.isParseData = false;
        DebugSerial.print("Save_Data.UTCTime = ");
        DebugSerial.println(Save_Data.UTCTime);
        if(Save_Data.isUsefull)
        {
            Save_Data.isUsefull = false;
            DebugSerial.print("Save_Data.latitude = ");
            DebugSerial.println(Save_Data.latitude);
            DebugSerial.print("Save_Data.N_S = ");
            DebugSerial.println(Save_Data.N_S);
            DebugSerial.print("Save_Data.longitude = ");
            DebugSerial.println(Save_Data.longitude);
            DebugSerial.print("Save_Data.E_W = ");
            DebugSerial.println(Save_Data.E_W);
        }
        else
        {
            DebugSerial.println("GPS DATA is not usefull!");
        }
    }
}

void parseGpsBuffer()
{
    char *subString;
    char *subStringNext;
    if (Save_Data.isGetData)
    {
        Save_Data.isGetData = false;
        DebugSerial.println("**************");
        DebugSerial.println(Save_Data.GPS_Buffer);
        for (int i = 0 ; i <= 6 ; i++)
        {
            if (i == 0)
            {
                if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
                errorLog(1);    //parse error
            }
            else
            {
                subString++;
                if ((subStringNext = strstr(subString, ",")) != NULL)
                {
                    char usefullBuffer[2];
                    switch(i)
                    {
                        case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - su            bString);break;   //get utc time
                        case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;   
                        case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;  //get latitude 
                        case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;   //get N/S
                        case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break; //get longitude
                        case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;   //get E/W
                        default:break;
                    }
                    subString = subStringNext;
                    Save_Data.isParseData = true;
                    if(usefullBuffer[0] == 'A')
                        Save_Data.isUsefull = true;
                    else if(usefullBuffer[0] == 'V')
                        Save_Data.isUsefull = false;
                }
                else
                {
                    errorLog(2);    //解析错误
                }
            }
        }
    }
}

void gpsRead() {
    while (GpsSerial.available())
    {
        gpsRxBuffer[ii++] = GpsSerial.read();
        if (ii == gpsRxBufferLength)clrGpsRxBuffer();
    }
    char* GPS_BufferHead;
    char* GPS_BufferTail;
    if ((GPS_BufferHead = strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_BufferHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL )
    {
        if (((GPS_BufferTail = strstr(GPS_BufferHead, "\r\n")) != NULL) && (GPS_BufferTail > GPS_BufferHead))
        {
            memcpy(Save_Data.GPS_Buffer, GPS_BufferHead, GPS_BufferTail - GPS_BufferHead);
            Save_Data.isGetData = true;
            clrGpsRxBuffer();
        }
    }
}

void clrGpsRxBuffer(void)
{
    memset(gpsRxBuffer, 0, gpsRxBufferLength);      //clear
    ii = 0;
}
void setup() {
    // Initialize Serial Debug
    DebugSerial.begin(115200);
    while (!DebugSerial) {
        ; // wait for serial port to connect. Needed for native USB
    }
    DebugSerial.println("Starting...");
    // Initialize Notecard Serial
    serialNotecard.begin(9600);
    serialNotecard.println("\n");
    // Configure the Notecard
    serialNotecard.println("{\"req\":\"hub.set\",\"product\":\"" NOTE_PRODUCT_UID "\",\"mode\":\"continuous\"}");
    // Await and log Notecard configuration response
    delay(50); // wait for the Notecard to respond
    while (serialNotecard.available() > 0) {
        char incomingByte = serialNotecard.read();
        if (incomingByte != '\r' && incomingByte != '\n') {
            DebugSerial.print(incomingByte);
        }
    }
    DebugSerial.println();
    // Initialize and configure gps module
    init_gps();
}

void loop() {
    // Sample the BME680 sensor
    if (!process_gps()) {
        DebugSerial.println("Failed to obtain a reading...");
        delay(3000);
        return;
    }
    // Print readings to the console
    DebugSerial.print("longitude = ");
    DebugSerial.print(Save_Data.longitude);
    DebugSerial.print("latitude = ");
    DebugSerial.print(Save_Data.latitude);
    DebugSerial.println(" ");
    // Create the JSON request string
    char json_request[150];
    snprintf(json_request, sizeof(json_request),
        "{"
        "\"req\":\"note.add\","
        "\"file\":\"sensors.qo\","
        "\"start\":true,"
        "\"body\":{"
        "\"longitude\":%s,"
        "\"latitude\":%s"
        "}"
        "}",
        Save_Data.longitude,
        Save_Data.latitude
        );
    // Send request to Notecard
    serialNotecard.println(json_request);
    delay(50); // wait for the Notecard to respond
    while (serialNotecard.available() > 0) {
        char incomingByte = serialNotecard.read();
        if (incomingByte != '\r' && incomingByte != '\n') {
            DebugSerial.print(incomingByte);
        }
    }
    DebugSerial.println();
    delay(15000);
}

Credits

michael ma
6 projects • 2 followers

Comments