Evan Rust
Published © GPL3+

Bike Tracker with Avnet IoTConnect

Build a small device that can track a bike's movements and then display that data on an Avnet IoTConnect dashboard.

IntermediateFull instructions provided6 hours2,910
Bike Tracker with Avnet IoTConnect

Things used in this project

Hardware components

SparkFun ESP32 Thing
SparkFun ESP32 Thing
×1
SparkFun 9DoF Sensor Stick
SparkFun 9DoF Sensor Stick
×1
GPS Module with Enclosure
DFRobot GPS Module with Enclosure
×1
Adafruit ADT7410 Breakout Board
×1

Software apps and online services

Arduino IDE
Arduino IDE
VS Code
Microsoft VS Code
Avnet IoTConnect

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Tray

Schematics

Schematic

Code

bikeTracker.ino

C/C++
// Connection with IoTConnect 
#include "IoTConnect.h"
// for getting real time from NTP server
#include "time.h"
#include <Wire.h>
#include "Adafruit_ADT7410.h"
#include <SparkFunLSM9DS1.h>
#include "TinyGPS.h"

#define UPDATE_RATE 2000    // send data every 2 seconds to the cloud

// making IOTConnectClient client for use IOTConnectClient functions  
IOTConnectClient client;      
// other objects
TinyGPS gps;
LSM9DS1 imu;

#define LSM9DS1_M	0x1E // Would be 0x1C if SDO_M is LOW
#define LSM9DS1_AG	0x6B // Would be 0x6A if SDO_AG is LOW

Adafruit_ADT7410 tempsensor = Adafruit_ADT7410();
  
// Prerequisite input data
//"Get your ENV and CPID from the portal key vaults module or visit https://help.iotconnect.io SDK section."

   String ENV     	= "environment (Avnet most likely)";
   String cpId    	= "Company ID";						// your CPID (Company ID)								
   String uniqueId	= "device ID";					// your UniqueID (Device name )
   char *ssid        = "SSID";               // your network SSID (name)
   char *pass        = "PSK";            // your network password (use for WPA, or use as key for WEP)                                         
   

unsigned long lastMillis = 0, fix_age;
int count = 0;
float lat, lon;

String Months(String in){                                     
       if(in == "Jan")  return "01";  else if(in == "Feb")  return "02";
  else if(in == "Mar")  return "03";  else if(in == "Apr")  return "04";
  else if(in == "May")  return "05";  else if(in == "Jun")  return "06";
  else if(in == "Jul")  return "07";  else if(in == "Aug")  return "08";
  else if(in == "Sep")  return "09";  else if(in == "Oct")  return "10";
  else if(in == "Nov")  return "11";  else if(in == "Dec")  return "12";
}

    // Get time From NTP and setup in SDK format
String GetTime(){                                             // Setup UCT time from NTP server 
    String Y,M,D1,D2,Ti;
    time_t now = time(nullptr);       
    String T= (ctime(&now));
    //Serial.println(T);
    if (T.substring(20,22) == "20") {
        D1 = T.substring(8,9);          if (D1 == " ")D1 = "0";
        D2 = T.substring(9,10);
        M = Months(T.substring(4,7));   Y = T.substring(20,24);
        Ti = T.substring(11,19);
        return (Y+"-"+M+"-"+D1+D2+"T"+Ti+".000Z");
    }
      return (Y+"-"+M+"-"+D1+D2+"T"+Ti+".000Z");
}


void setup() {
    delay(500);
    Serial.begin(115200);                                      // setup Serial Monitor 
    Serial2.begin(9600);
    if(!tempsensor.begin()) {
        Serial.println(F("Failed to init temp sensor"));
        while(1);
    }
    imu.settings.device.commInterface = IMU_MODE_I2C;
    imu.settings.device.mAddress = LSM9DS1_M;
    imu.settings.device.agAddress = LSM9DS1_AG;
    if(!imu.begin()) {
        Serial.println(F("Failed to init IMU"));
        while(1);
    }
    WiFi.mode(WIFI_STA);    WiFi.begin(ssid, pass);
    Serial.println("\n\tConnecting WiFi ");
    while (WiFi.status() != WL_CONNECTED) {
        delay(50);
        Serial.print("-");
    }
    Serial.println("\n\t WiFi Connected");
    Serial.print("Device_IP: "); Serial.println(WiFi.localIP());
    configTime(0, 0, "pool.ntp.org");           // getting UCT time from NTP server
    // (timezone*3600,dst,"pool.ntp.org","time.nist.gov");      
	
	if(cpId || uniqueId){
        if(cpId == 0){
            Serial.println("cpId can not be blank");
			return ;
		}
        if(uniqueId == 0){
            Serial.println("uniqueId can not be blank");
			return ;
		}
    }
    client.InitializationSDK(cpId, uniqueId, CallBack, TwinCallBack, ENV);         // initialization SDK for IoTConnect
	
    delay(30);
    client.GetAllTwins();
}

void loop(){
    client.MQTT_loop();           // SDK connection in infinite loop
    delay(100);
    while(Serial2.available())
    {
        int c = Serial2.read();
        if(gps.encode(c));
    }
    gps.f_get_position(&lat, &lon, &fix_age);
    if(imu.accelAvailable())
    {
        imu.readAccel();
    }
    if(millis() - lastMillis >= UPDATE_RATE)
    {
        Serial.printf("Lat is: %f, Lon is: %f\n", lat, lon);
        sendSensorData();
        lastMillis = millis();
    }
}

void sendSensorData()
{
    DynamicJsonDocument  Attribute_json(2048);                                      
    JsonArray Device_data = Attribute_json.to<JsonArray>();                     
    JsonObject Device_01 = Device_data.createNestedObject();                    
    Device_01["uniqueId"] = uniqueId;                                 
    Device_01["time"] = GetTime();                                              
    JsonObject D01_Sensors=Device_01.createNestedObject("data");                
        D01_Sensors["temperature"] = tempsensor.readTempC() * 9.0 / 5.0 + 32;

    JsonObject D01_SensorsV = D01_Sensors.createNestedObject("accelerometer");      
        D01_SensorsV["x"] = imu.calcAccel(imu.ax);
        D01_SensorsV["y"] = imu.calcAccel(imu.ay);
        D01_SensorsV["z"] = imu.calcAccel(imu.az);

    JsonObject D01_SensorsG = D01_Sensors.createNestedObject("location");
        D01_SensorsG["lat"] = lat;
        D01_SensorsG["lon"] = lon;

    String Attribute_json_Data;                                                     
    serializeJson(Attribute_json, Attribute_json_Data); 

    client.SendData(Attribute_json_Data); 
    Attribute_json.clear();
}

void getAccel(float * x, float * y, float * z)
{
    
}

    // this function will Give you TwinCallBack payload
void TwinCallBack(String &topic, String &payload) {          
    Serial.println("Twin_msg >>  " +topic + " " + payload);       
    //TO update the twinproperty use UpdateTwin function                             
    //client.UpdateTwin(key,value);
}


    // this function will Give you Device CallBack payload
    // You can send command ACK by SendAck(DataBuffer, GetTime(), mt) function 
void CallBack(String &topic, String &payload) {        
    String cmd_ackID="";   String Cmd_value="";
    int Status = 0,mt=0;
    Serial.println("Cmd_msg >>  " + payload);    
    StaticJsonDocument<512> in_cmd;   
    deserializeJson(in_cmd, payload);
    cmd_ackID = in_cmd["ackId"].as<String>();  
    Cmd_value = in_cmd["cmdType"].as<String>();
    if(Cmd_value == "0x01" ){Status = 6; mt = 5;}
    else {Status = 7; mt = 11;}     
    StaticJsonDocument<400> Ack_Json; 
        Ack_Json["ackId"] = cmd_ackID;                                 
        Ack_Json["st"] = Status;
        Ack_Json["msg"] = "";
        Ack_Json["childId"] = "";
    String Ack_Json_Data;
    serializeJson(Ack_Json, Ack_Json_Data);
    
    // Sending ACk of command with Json(String), msg Type(int) and Current Time(String)  
    client.SendAck(Ack_Json_Data, GetTime(), mt);
    in_cmd.clear();    Ack_Json.clear();  
 }

Credits

Evan Rust

Evan Rust

120 projects • 1053 followers
IoT, web, and embedded systems enthusiast. Contact me for product reviews or custom project requests.

Comments