Hello Blynk experts,
In this project, I am using Arduino YUn with CAN Bus Shield v1.2 in order to get the vehicle data and display few of them in the iOS app. Also I would like to record the signals while I am driving the car on SuperChart widget and then I can export them to computer.
I have few issues currently with getting the CAN data and sending it to Blynk app. It seems that I have to optimize my code or Blynk cannot handle so many Virtual pins.
When I am connected to CAN bus, I can send 1-2 signals to virtual pins but it is so unstable that sometimes Arduino YUN board goes to Offline and then Online again. (If I want to send more signals to virtual pins, it stays mostly offline)
So I am not sure, where the root cause of the problem.
Please check my code below:
/*************************************************************************************************
OBD-II_PIDs TEST CODE
Query
send id: 0x7df
dta: 0x02, 0x01, PID_CODE, 0, 0, 0, 0, 0
Response
From id: 0x7E9 or 0x7EA or 0x7EB
dta: len, 0x41, PID_CODE, byte0, byte1(option), byte2(option), byte3(option), byte4(option)
[https://en.wikipedia.org/wiki/OBD-II_PIDs](https://en.wikipedia.org/wiki/OBD-II_PIDs)
Input a PID, then you will get reponse from vehicle, the input should be end with '\n'
Blynk.virtualWrite(V1, val);
***************************************************************************************************/
#include "mcp_can.h"
#include <Bridge.h>
#include <BlynkSimpleYun.h>
char auth[] = "*********************";
WidgetTerminal terminal(V1);
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
#define BLYNK_PRINT Serial
#define CAN_ID_PID 0x7DF
unsigned char PID_INPUT;
unsigned char getPid = 0;
float test= 3.0;
float nEng=100.0;
float T_W_O=6.0;
void set_mask_filt()
{
/*
* set mask, set both the mask to 0x3ff
*/
CAN.init_Mask(0, 0, 0x7FC);
CAN.init_Mask(1, 0, 0x7FC);
/*
* set filter, we can receive id from 0x04 ~ 0x09
*/
CAN.init_Filt(0, 0, 0x7E8);
CAN.init_Filt(1, 0, 0x7E8);
CAN.init_Filt(2, 0, 0x7E8);
CAN.init_Filt(3, 0, 0x7E8);
CAN.init_Filt(4, 0, 0x7E8);
CAN.init_Filt(5, 0, 0x7E8);
}
void sendPid(unsigned char __pid)
{
unsigned char tmp[8] = {0x02, 0x01, __pid, 0, 0, 0, 0, 0};
Serial.print("SEND PID: 0x");
terminal.print("SEND PID: 0x");
Serial.println(__pid, HEX);
terminal.print(__pid, HEX);
terminal.print("\n");
terminal.print(test);
terminal.print("\n");
terminal.flush();
CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);
}
void sendPidPeriodic()
{
unsigned char tmp1[8] = {0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}; // 0x0C is for engine speed
unsigned char tmp2[8] = {0x02, 0x01, 0x05, 0, 0, 0, 0, 0}; // 0x05 is for coolant temp
//CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp2);
//delay(500);
//CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp1);
//delay(500);
}
BLYNK_WRITE(V1)
{
terminal.print("\n");
terminal.print("Send PID from terminal: 0x");
terminal.write(param.getBuffer(), param.getLength());
terminal.println();
terminal.flush();
//char c =param.getBuffer();
//sendPid(param.getBuffer);
}
void setup()
{
Serial.begin(115200);
Blynk.begin(auth);
terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
terminal.println(F("-------------"));
terminal.flush();
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init fail");
terminal.print("CAN BUS Shield init fail");
Serial.println(" Init CAN BUS Shield again");
terminal.print("Init CAN BUS Shield again");
delay(100);
}
Serial.println("CAN BUS Shield init ok!");
terminal.print("CAN BUS Shield init ok!");
terminal.print("\n");
terminal.flush();
set_mask_filt();
}
void loop()
{
Blynk.run();
taskCanRecv();
taskDbg();
sendPidPeriodic();
if(getPid) // GET A PID
{
getPid = 0;
sendPid(PID_INPUT);
PID_INPUT = 0;
}
}
void taskCanRecv()
{
unsigned char len = 0;
unsigned char buf[8];
if(CAN_MSGAVAIL == CAN.checkReceive()) // check if get data
{
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
Serial.println("\r\n-----");
Serial.print("Get Data From id: ");
Serial.println(CAN.getCanId(), HEX);
//Serial.print("data len = ");
//Serial.println(len);
for(int i = 0; i<len; i++) // print the data
{
//Serial.print("0x");
Serial.print(buf[i], HEX);
Serial.print("\t");
if(buf[2]==0x0C&&buf[1]==0x41){
nEng = ((buf[3]*256) + buf[4])/4;
//Serial.println(nEng);
Blynk.virtualWrite(V3, nEng); // Send Engine Speed
}
else if (buf[2]==0x5&&buf[1]==0x41){
T_W_O= (buf[3])-40;
Blynk.virtualWrite(V4, T_W_O); // Send coolant temp
}
else if (buf[1]==0x41){
test= (buf[3]);
Blynk.virtualWrite(V5, test);
}
}
//Serial.println();
}
}
void taskDbg()
{
while(Serial.available())
{
char c = Serial.read();
if(c>='0' && c<='9')
{
PID_INPUT *= 0x10;
PID_INPUT += c-'0';
}
else if(c>='A' && c<='F')
{
PID_INPUT *= 0x10;
PID_INPUT += 10+c-'A';
}
else if(c>='a' && c<='f')
{
PID_INPUT *= 0x10;
PID_INPUT += 10+c-'a';
}
else if(c == '\n') // END
{
getPid = 1;
}
}
}
// END FILE
Probably I am not requesting the OBD PIDs in the best way. But my aim is to receive the data as fast as possible without crashing anything.
Can you please support me how to make the request periodically and how to send them to Blynk app in a more optimized way ?
Thanks…