Skip to content

Instantly share code, notes, and snippets.

@yuta-imai
Last active April 17, 2021 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuta-imai/7b1215eab7ff08837cbe4a570376ca51 to your computer and use it in GitHub Desktop.
Save yuta-imai/7b1215eab7ff08837cbe4a570376ca51 to your computer and use it in GitHub Desktop.
#include <SPI.h>
#define CAN_2515
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
#define CONSOLE Serial
#define INTERVAL_MS (1000)
#define ENDPOINT "uni.soracom.io"
#define SKETCH_NAME "send_uptime_with_soracom"
#define VERSION "1.0"
/* for LTE-M Shield for Arduino */
#define BAUDRATE 9600
#define BG96_RESET 15
#define TINY_GSM_MODEM_BG96
#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
SoftwareSerial LTE_M_shieldUART(3, 4);
SoftwareSerial gpsSerial(5, 6);
TinyGsm modem(LTE_M_shieldUART);
TinyGsmClient ctx(modem);
// #define RESET_DURATION 86400000UL // 1 day
void software_reset() {
asm volatile (" jmp 0");
}
void setupLTE() {
CONSOLE.print(F("resetting module "));
pinMode(BG96_RESET, OUTPUT);
digitalWrite(BG96_RESET, LOW);
delay(300);
digitalWrite(BG96_RESET, HIGH);
delay(300);
digitalWrite(BG96_RESET, LOW);
CONSOLE.println(F(" done."));
LTE_M_shieldUART.begin(BAUDRATE);
CONSOLE.print(F("modem.restart()"));
modem.restart();
CONSOLE.println(F(" done."));
CONSOLE.print(F("modem.getModemInfo(): "));
String modemInfo = modem.getModemInfo();
CONSOLE.println(modemInfo);
CONSOLE.print(F("waitForNetwork()"));
while (!modem.waitForNetwork()) CONSOLE.print(".");
CONSOLE.println(F(" Ok."));
CONSOLE.print(F("gprsConnect(soracom.io)"));
modem.gprsConnect("soracom.io", "sora", "sora");
CONSOLE.println(F(" done."));
CONSOLE.print(F("isNetworkConnected()"));
while (!modem.isNetworkConnected()) CONSOLE.print(".");
CONSOLE.println(F(" Ok."));
CONSOLE.print(F("My IP addr: "));
IPAddress ipaddr = modem.localIP();
CONSOLE.println(ipaddr);
}
void setupCAN() {
while (CAN_OK != CAN.begin(CAN_500KBPS)) {
CONSOLE.println("CAN init fail, retry...");
delay(100);
}
CONSOLE.println("CAN init ok!");
/* set mask, set both the mask to 0x3ff */
CAN.init_Mask(0, 0, 0x3ff);
CAN.init_Mask(1, 0, 0x3ff);
/* set filter, we can receive id from 0x04 ~ 0x09 */
CAN.init_Filt(0, 0, 0x202);
}
void setupGPS() {
gpsSerial.begin(BAUDRATE);
gpsSerial.listen();
/* Configuring GPS Module so it sends $GPGGA and $GPRMC everytime */
gpsSerial.print("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
while (gpsSerial.available() > 0) {
CONSOLE.print(gpsSerial.read());
}
}
void setup() {
CONSOLE.begin(115200);
CONSOLE.println();
CONSOLE.print(F("Welcome to ")); CONSOLE.print(SKETCH_NAME); CONSOLE.print(F(" ")); CONSOLE.println(VERSION);
setupCAN();
setupLTE();
setupGPS();
}
String NMEA2DD(float val) {
int d = val / 100;
int m = (((val / 100.0) - d) * 100.0) / 60;
float s = (((((val / 100.0) - d) * 100.0) - m) * 60) / (60 * 60);
return String(d + m + s, 6);
}
void loop() {
CONSOLE.println();
CONSOLE.println("=================================");
CONSOLE.println("==========New iteration==========");
CONSOLE.println("=================================");
unsigned char len = 0;
unsigned char canBuf[8];
if (CAN_MSGAVAIL == CAN.checkReceive()) {
CAN.readMsgBuf(&len, canBuf);
unsigned long canId = CAN.getCanId();
CONSOLE.println("===========CAN===========");
CONSOLE.print("CAN ID: 0x");
CONSOLE.println(canId, HEX);
for (int i = 0; i < len; i++) { // print the data
CONSOLE.print(canBuf[i], HEX);
CONSOLE.print("\t");
}
CONSOLE.println();
/*
* Retrieve location data.
*/
float latitude;
float longitude;
gpsSerial.listen();
delay(1000);
CONSOLE.println("===========Location===========");
while (gpsSerial.available() > 0) {
String line = gpsSerial.readStringUntil('\n');
if (line != "") {
int i, index = 0, len = line.length();
String str = "";
String list[30];
for (i = 0; i < 30; i++) {
list[i] = "";
}
/* Parse CSV */
for (i = 0; i < len; i++) {
if (line[i] == ',') {
list[index++] = str;
str = "";
continue;
}
str += line[i];
}
/* Read GPGGA sentense */
if (list[0] == "$GPGGA") {
if (list[6] != "0") {
latitude = NMEA2DD(list[2].toFloat()).toFloat();
longitude = NMEA2DD(list[4].toFloat()).toFloat();
CONSOLE.print("Latitude: "); CONSOLE.println(latitude);
CONSOLE.print("Longitude: "); CONSOLE.println(longitude);
} else {
CONSOLE.print("Could not retrieve location data.");
}
}
}
}
/*
* Combine data from CAN and GPS into single byte array.
*/
byte p[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
char canIdArray[4];
sprintf(canIdArray,"%04lx",canId);
unsigned int latitudeInt = (int)(latitude*100);
unsigned int longitudeInt = (int)(longitude*100);
byte loc[] = {highByte(latitudeInt),lowByte(latitudeInt),highByte(longitudeInt),lowByte(longitudeInt)};
memcpy(p,canIdArray,sizeof(canIdArray));
memcpy(p+sizeof(canId),canBuf,sizeof(canBuf));
memcpy(p+sizeof(canId)+sizeof(canBuf),loc,sizeof(loc));
/* Print data for debug */
CONSOLE.println("===========Combined data===========");
CONSOLE.print("Sending data in hex format: ");
for(int i =0; i < sizeof(p); i++){
CONSOLE.print(p[i],HEX);
}
CONSOLE.println();
/*
* Send data via LTE link
*/
CONSOLE.println("===========Sending data===========");
LTE_M_shieldUART.listen();
if (!ctx.connect(ENDPOINT, 23080)) {
CONSOLE.println(F("failed."));
delay(3000);
return;
}
/* send request */
ctx.write(p,sizeof(p));
/* receive response */
while (ctx.connected()) {
String line = ctx.readStringUntil('\n');
CONSOLE.print("Status Code: "); CONSOLE.println(line);
break;
}
}
ctx.stop();
#ifdef RESET_DURATION
if (millis() > RESET_DURATION )
{
CONSOLE.println("Execute software reset...");
delay(1000);
software_reset();
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment