Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Amir HaleemMark PhillipsCoco Tang
Published © Apache-2.0

GPS Tracking Using Helium, Azure IoT Hub, and Power BI

Building a wireless, battery-powered GPS tracker using a Helium Atom, Arduino Zero, Azure IoT Hub, and Power BI.

IntermediateFull instructions provided1 hour27,818
GPS Tracking Using Helium, Azure IoT Hub, and Power BI

Things used in this project

Story

Read more

Code

Atom + Arduino + Adafruit GPS

C/C++
/*
 * Copyright 2017, Helium Systems, Inc.
 * All Rights Reserved. See LICENCE.txt for license information
*/

#include "Arduino.h"
#include "avr/dtostrf.h"
#include "Helium.h"
#include <math.h>
#include <Adafruit_GPS.h>
#include "wiring_private.h" // pinPeripheral() function

#define atom_serial Serial1
//for GPS
#define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12
#define PIN_SERIAL2_TX (36ul) // Pin description number for PIO_SERCOM on D10
#define PAD_SERIAL2_TX (UART_TX_PAD_2) // SERCOM pad 2
#define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) // SERCOM pad 3

Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);

void SERCOM1_Handler()
{
  Serial2.IrqHandler();
}

Helium helium(&atom_serial);
Channel channel(&helium);

//GPS stuff
#define gps_serial Serial2
Adafruit_GPS GPS(&gps_serial);

void setup() {  
    pinPeripheral(10, PIO_SERCOM);
    pinPeripheral(12, PIO_SERCOM);
    
    Serial.begin(115200);
    Serial.println("Starting");

    // Begin communication with the Helium Atom
    // The baud rate differs per supported board
    // and is configured in Board.h
    helium.begin(helium_baud_b115200);    

    // Connect the Atom to the Helium Network
    Serial.print("Connecting - ");
    int status = helium.connect();    
    while (status != helium_status_OK)
    {
        status = helium.connect();
    }
    Serial.println("Succeeded");
    
    // Begin communicating with the channel. This should only need to
    // be done once.
    //
    // NOTE: Please ensure you've created a matching channel in the Helium Dashbaord
    int8_t result;
    Serial.print("Creating Channel - ");
    status = channel.begin("Hackster Guide", &result);
    if (helium_status_OK == status && result == 0)
    {
        Serial.println("Succeeded");
    }
    else
    {
        Serial.println("Failed");
    }
    
    delay(1000);

    //Init GPS
    GPS.begin(9600);

    GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
    GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
    GPS.sendCommand(PGCMD_NOANTENNA);

    delay(2000);
}

uint32_t timer = millis();
void loop()
{
  char c = GPS.read();
  
  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA()))
      return;
  }
  
  if (timer > millis())  timer = millis();

  if (millis() - timer > 2000) {
    timer = millis(); // reset the timer
    if (GPS.fix) {         
      char lat[10];
      char lon[10];      
      char data[100];      
      dtostrf(GPS.latitudeDegrees, 4, 4, lat);
      dtostrf(GPS.longitudeDegrees, 4, 4, lon);
      //format a JSON object of lat/lon to send to Azure
      sprintf(data, "{\"lat\": \"%s\", \"lon\": \"%s\"}", lat, lon);

      // Send the location data to the configured channel
      int8_t result; //the response from the Helium Router
      Serial.print("Sending - ");
      int status = channel.send(data, strlen(data), &result); //status is the response from the Atom serial connection
      if (helium_status_OK == status && result == 0)
      {
          Serial.print("Successfully sent ");
          Serial.println(data);
      }
      else
      {
          Serial.println("Failed");
      }
    } else {
      Serial.println("No GPS fix!");
    }
  }
}

Credits

Amir Haleem

Amir Haleem

0 projects • 4 followers
CEO & Founder @ Helium
Mark Phillips

Mark Phillips

2 projects • 15 followers
Director of Customer Success at Helium
Coco Tang

Coco Tang

0 projects • 3 followers

Comments