When turn on GPS, Data won't sync to the Notehub.io

if I took away the GPS function

it works fine

can pump up the data to Notehub.io continuously

once enable GPS function, the onboard LEDs flashing indicate “idle”

is there anything I do wrong? please help~~

thanks~~

// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// Version
// 2.0 - CANBus receive
// 2.1 - catch data and send to gagues
// 4.0 - use Notecard Library
// 4.1 - debuging J *req syntax
// 4.2 - updata location every 60 mints
// 4.3 - send date to cloud
// 4.4 - add GPS, send GPS data to cloud
// 5.0 - setting changing from Ver4.4
// 5.1 - optimized on blues notecard
// 5.2 - Configuartion SOC voltage 4.12 → 3.85V
// 5.3 - data to notehub
// 5.4 - low current transmit data to Notehub.io

#include <SAMDTimerInterrupt.h>
#include <SAMDTimerInterrupt.hpp>
#include <SAMD_ISR_Timer.h>
#include <SAMD_ISR_Timer.hpp>

#include <CAN.h>
#include <Wire.h>
#include <Notecard.h>
#include <NotecardPseudoSensor.h>

#define USING_TIMER_TC3 true // Only TC3 can be used for SAMD51
#define USING_TIMER_TC4 false // Not to use with Servo library
#define USING_TIMER_TC5 false
#define USING_TIMER_TCC false
#define USING_TIMER_TCC1 false
#define USING_TIMER_TCC2 false // Don’t use this, can crash on some boards

#define TIMER_INTERVAL_MS 250

#define serialDebug Serial
#define productUID “com.gmail.williamzoe2002:test”

Notecard notecard;

volatile uint32_t TimerCount = 0;

#if (TIMER_INTERRUPT_USING_SAMD21)

#if USING_TIMER_TC3
#define SELECTED_TIMER TIMER_TC3
#elif USING_TIMER_TC4
#define SELECTED_TIMER TIMER_TC4
#elif USING_TIMER_TC5
#define SELECTED_TIMER TIMER_TC5
#elif USING_TIMER_TCC
#define SELECTED_TIMER TIMER_TCC
#elif USING_TIMER_TCC1
#define SELECTED_TIMER TIMER_TCC1
#elif USING_TIMER_TCC2
#define SELECTED_TIMER TIMER_TCC
#else
#error You have to select 1 Timer
#endif

#else

#if !(USING_TIMER_TC3)
#error You must select TC3 for SAMD51
#endif

#define SELECTED_TIMER TIMER_TC3

#endif

#define usbSerial Serial
#define txRxPinsSerial Serial1

long int identity = 0; // CANBus ID

long wheel_D = 70; // unit: cm

long RPM_H = 0;
long RPM_L = 0;
long motor_T_H = 0;
long motor_T_L = 0;
long soc = 0;

long counter = 0;
long counter_sent = 0;
int delay_counter = 200;

int ENNOID_ID = 0;
int cell_min_H = 0;
int cell_min_L = 0;
int cell_max_H = 0;
int cell_max_L = 0;
float cell_100 = 3.85;
float cell_0 = 2.95;
float cell_min = 0;
float cell_max = 0;
float cell_SOC = 0;

int notecard_data_update_counter = 0; // up to 2 billion

byte x = 0;

char buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

// I2C M4 Feather to Blues
// char data_I2C[8] = {0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x01, 0x07};
using namespace blues;
NotecardPseudoSensor sensor(notecard);
size_t gps_time_s;
char data_I2C = {“hub.log”};
float temperature = sensor.temp();
float humidity = sensor.humidity();
bool notecardProductSet = false;

long previousMillis = 0;
long interval = 60000 * 10;

void resetNotecard();
bool productUIDMatch();
void setProductUID();
void configureHub();
void configureGPS();
void configureTracking();
void readFromSensors();

//=============================|----------------|L—rpm—H|-----------------|
unsigned char motor_speed[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

//=============================|----| SOC |-----------------------------------|
unsigned char fuel_level[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

//=============================|-----|-----------|----------------------------|
unsigned char wheel_speed[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

//=============================|----|-----------------------------------------|
unsigned char engine_temp[8] = {0x81, 0x92, 0xA3, 0xB4, 0xC5, 0xD6, 0xE7, 0xF8};

// Init selected SAMD timer
SAMDTimer ITimer(SELECTED_TIMER);

//////////////////////////////////////////////

void printResult(uint32_t currTime)
{
Serial.print(F("Time = “)); Serial.print(currTime);
Serial.print(F(”, TimerCount = ")); Serial.println(TimerCount);
}

void setup() {
// delay(3000); // delay 3s wait for notecard get it on
Serial.begin(115200);

// I2C
notecard.begin(); // I2C begin

// CANBus
Serial.println(“CAN Receiver”);
// start the CAN bus at 500 kbps

if (!CAN.begin(500E3)) {
Serial.println(“Starting CAN failed!”);
while (1);
}

// M4 Feather to Notecard
serialDebug.begin(115200);
notecard.begin();
notecard.setDebugOutputStream(usbSerial);

resetNotecard();
delay(16000); // wait 16s for notecard back on line
setProductUID();
//Make sure the ProductUID is now set before continuing
if (productUIDMatch()) {
serialDebug.println(“ProductUID matches, continuing configuration…”);
notecardProductSet = true;
} else {
serialDebug.println(“ProductUID does not match, please perform a manual configuration.”);
}

if (notecardProductSet) {
configureHub();
configureGPS();
configureTracking();
}

/*
req = NoteNewRequest(“card.location.mode”);
JAddStringToObject(req, “mode”, “periodic”);
JAddStringToObject(req, “vseconds”, “usb:1800;high:3600;normal:7200;low:43200;dead:0”);
notecard.sendRequest(req);

req = notecard.newRequest(“card.location.track”);
JAddBoolToObject(req, “sync”, true);
JAddBoolToObject(req, “heartbeat”, true);
JAddNumberToObject(req, “hours”, 1);
notecard.sendRequest(req);
*/
// Interval in millisecs
if (ITimer.attachInterruptInterval_MS(TIMER_INTERVAL_MS, TimerHandler))
{
Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
}
else
Serial.println(F(“Can’t set ITimer. Select another freq. or timer”));
} // setup

void TimerHandler()
{
CAN.beginExtendedPacket(0x00FEEE02);
for(int a=0;a<8;a++){ CAN.write(engine_temp[0]); }
CAN.endPacket();

CAN.beginExtendedPacket(0x00FEFC02);
for(int a=0;a<8;a++){ CAN.write(fuel_level[1]); }
CAN.endPacket();

CAN.beginExtendedPacket(0x00F00402);
for(int a=0;a<8;a++){ CAN.write(motor_speed[4]); }
CAN.endPacket();

CAN.beginExtendedPacket(0x00FEF102);
for(int a=0;a<8;a++){ CAN.write(wheel_speed[2]); }
CAN.endPacket();

notecard_data_update_counter++;

} // TimerHandler

void loop() {
// try to parse packet
int packetSize = CAN.parsePacket();

if (packetSize) {
// received a packet
Serial.print("Received ");

if (CAN.packetExtended()) {
  Serial.print("extended ");
}

if (CAN.packetRtr()) {
  // Remote transmission request, packet contains no data
  Serial.print("RTR ");
}

Serial.print("ID 0x");
Serial.print(CAN.packetId(), HEX);
Serial.println();
identity = CAN.packetId();


if (CAN.packetRtr()) {
  Serial.print(" and requested length ");
  Serial.println(CAN.packetDlc());
} else {
  Serial.print(" and length ");
  Serial.println(packetSize);
  // only print packet data for non-RTR packets
  int buf_counter = 0;
  while (CAN.available()) {
    buf[buf_counter] = (char)CAN.read();
    buf_counter++;
    //Serial.print((char)CAN.read(),HEX);
    
  }
  for(int a=0;a<8;a++){
    Serial.print("0x");
    Serial.print(buf[a],HEX);
    Serial.print(", ");
  }
  Serial.println();
}

// Serial.println();

if(identity == 0x0000097E)
{
  long buff = 0;
  RPM_H = buf[2];
  RPM_L = buf[3];
  RPM_H = RPM_H<<8;
  buff = (RPM_H + RPM_L);
  if(buff >= 65530 )
  {
    RPM_L = 0;
    RPM_H = 0;
  }
  motor_speed[4] = (float(RPM_H+RPM_L)/255);
  wheel_speed[2] = ( ( float(RPM_H+RPM_L) / 140 ) *  float(wheel_D*3.14)  * 60 ) / 1000*0.039;
}

if(identity == 0x0000107E)
{
  int buff = 0;
  motor_T_H = buf[2];
  motor_T_L = buf[3];
  if(motor_T_H >= 1)  {
    buff = motor_T_L+255;
  }
  if(motor_T_H <= 0)  {
    buff = motor_T_L;
  }
  engine_temp[0] = (buff/10)+40;
}

ENNOID_ID = (identity >> 8);
if(ENNOID_ID == 0x00002D)
{
  // CANBus Data from Battery
  cell_min_H = buf[0];
  cell_min_L = buf[1];
  cell_max_H = buf[2];
  cell_max_L = buf[3];
  cell_min = ((float)((cell_min_H*256) + cell_min_L)/1000);
  cell_max = ((float)((cell_max_H*256) + cell_max_L)/1000);
  Serial.println(cell_min_H,HEX);
  Serial.println(cell_min_L,HEX);
  Serial.println(cell_max_H,HEX);
  Serial.println(cell_max_L,HEX);

  cell_min = cell_min - cell_0;
  if(cell_min <= 0) cell_min = 0.01;
  cell_SOC = (cell_min/(cell_100-cell_0))*250;
  fuel_level[1] = cell_SOC;
  
  Serial.println(cell_SOC);
}

} // PacketSize

/*
cell_SOC++;
if(cell_SOC >= 100) { cell_SOC = 0; }
*/

//Serial.println(notecard_data_update_counter);
if(notecard_data_update_counter == 120){
// notecard_data_update_counter = 0;
J *req = notecard.newRequest(“note.add”);
JAddStringToObject(req, “mode”, “continuous”); // continuous // periodic
if( req != NULL ){
JAddStringToObject(req, “file”, “sensors.qo”);
J *body = JAddObjectToObject(req, “body”);
if (body){
JAddNumberToObject(body, “temp”, temperature);
JAddNumberToObject(body, “humidity”, humidity);
JAddNumberToObject(body, “cell_L”, (cell_min+cell_0));
JAddNumberToObject(body, “cell_H”, cell_max);
JAddNumberToObject(body, “SOC”, (cell_SOC/250));
JAddNumberToObject(body, “Motor_temp”, engine_temp[0]);
JAddNumberToObject(body, “Motor_rpm”, motor_speed[4]);
JAddNumberToObject(body, “Km/h”, wheel_speed[2]);
}
JAddBoolToObject(req, “sync”, true);
notecard.sendRequest(req);
Serial.println(“data_req”);
JAddStringToObject(req, “mode”, “periodic”); // continuous // periodic
}

/*
if( req != NULL ){
  J *req = NoteNewRequest("card.location.mode");
  JAddStringToObject(req, "mode", "continuous");

// JAddBoolToObject(req, “start”, true);
NoteRequest(req);
}
if( req != NULL ){
J *req = NoteNewRequest(“card.location”);
NoteRequest(req);

  J *rsp = notecard.requestAndResponse(notecard.newRequest("card.location"));
//  gps_time_s = JGetInt(rsp, "time");
  JAddBoolToObject(req, "sync", true);
  NoteDeleteResponse(rsp);
  
  Serial.println("GPS_req");
}
if( req != NULL ){
  J *req = NoteNewRequest("card.location.track");
  JAddBoolToObject(req, "sync", true);
  NoteRequest(req);
}
*/

} // if(notecard_data_update_counter >=1200)

if(notecard_data_update_counter >=243)
{
notecard_data_update_counter = 0;
J *req = NoteNewRequest(“card.location”);
notecard.sendRequest(req);
}
} // loop

void resetNotecard()
{
J *req = notecard.newRequest(“card.restore”);
JAddBoolToObject(req, “delete”, true);
notecard.sendRequest(req);
}

bool productUIDMatch()
{
bool isMatch = false;
J *req = notecard.newRequest(“hub.get”);
J *rsp = notecard.requestAndResponse(req);

if (rsp != NULL) {

if (notecard.responseError(rsp)) {
  notecard.deleteResponse(rsp);
  return isMatch;
}

// Get the note's body
char *setProductUID = JGetString(rsp, "product");
if (setProductUID != NULL) {
  NoteDebugf("Product UID: %s\n\n", setProductUID);

  if (strcmp(productUID, setProductUID) == 0) {
    isMatch = true;
  }
}

}
notecard.deleteResponse(rsp);

return isMatch;
}

void setProductUID()
{
Serial.println(“DONE_SET_UID”);
J *req = notecard.newRequest(“hub.set”);
JAddStringToObject(req, “product”, productUID);
notecard.sendRequest(req);
}

void configureHub()
{
J *req = NoteNewRequest(“hub.set”);
JAddStringToObject(req, “mode”, “continuous”); // continuous // periodic
JAddNumberToObject(req, “outbound”, 5);
JAddNumberToObject(req, “inbound”, 1440);
JAddNumberToObject(req, “duration”, 240);
// JAddBoolToObject(req, “sync”, true);
notecard.sendRequest(req);
}

void configureGPS()
{
J *req = notecard.newRequest(“card.location.mode”);
JAddStringToObject(req, “mode”, “periodic”); // track // continuous // periodic
JAddBoolToObject(req, “gps”, true);
// JAddBoolToObject(req, “sync”, true);
JAddNumberToObject(req, “seconds”, 51);
notecard.sendRequest(req);
}

void configureTracking()
{
J *req = notecard.newRequest(“card.location.track”);
JAddBoolToObject(req, “start”, true);
JAddBoolToObject(req, “heartbeat”, true);
JAddNumberToObject(req, “hours”, 1);
notecard.sendRequest(req);
}

Hi @williamzoe2002,

You should be aware that you cannot utilize the cellular radio and GPS module simultaneously - so even by maintaining a “continuous” cellular connection, that will be interrupted whenever the GPS module is enabled. Specifically look at the configureGPS method. It’s in periodic mode, but sampling every 51 seconds (that effectively keeps GPS in continuous mode, causing constant conflicts with the cellular radio).

So you have two choices:

  1. Increase seconds in configureGPS to a value > 300.
  2. If you NEED concurrent cellular and GPS, you’ll need to add an external GPS module like the Quectel L86.

Hope that helps!

Rob