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);
}