Hi,
I'm trying to use a Seeed CAN buss I2C module.
Trying to compile the "get RPM example" I get the following compiler errors:
In file included from \\some path...\Coding\libraries\Seeed I2C_CAN_Arduino-main\Longan_I2C_CAN_Arduino.h:5:0,
from \\some path...\libraries\Seeed I2C_CAN_Arduino-main\Longan_I2C_CAN_Arduino.cpp:1:
\\some path...\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\Wire\src/Wire.h: In member function 'bool I2C_CAN::IIC_CAN_GetReg(unsigned char, int, unsigned char*)':
\\some path...\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
uint8_t requestFrom(int, int);
^~~~~~~~~~~
\\some path...\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
uint8_t requestFrom(uint8_t, uint8_t);
^~~~~~~~~~~
Reading other post about similar issues, I'm pretty sure it's a problem with the data type in the library function not being correct. I've tried a couple modifications, but i'm obviously out of my depth.
The example sketch:
/*************************************************************************************************
OBD-II_PIDs TEST CODE
Loovee, Longan Labs 2022
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
***************************************************************************************************/
#include <Wire.h>
#include "Longan_I2C_CAN_Arduino.h"
I2C_CAN CAN(0x25); // Set I2C Address
#define PID_ENGIN_PRM 0x0C
#define PID_VEHICLE_SPEED 0x0D
#define PID_COOLANT_TEMP 0x05
#define CAN_ID_PID 0x7DF
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};
CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);
}
bool getRPM(int *r)
{
sendPid(PID_ENGIN_PRM);
unsigned long __timeout = millis();
while(millis()-__timeout < 1000) // 1s time out
{
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
if(buf[1] == 0x41)
{
*r = (256*buf[3]+buf[4])/4;
return 1;
}
}
}
return 0;
}
void setup()
{
Serial.begin(9600);
while(!Serial);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
Serial.println("CAN init fail, retry...");
delay(100);
}
Serial.println("CAN init ok!");
set_mask_filt();
}
void loop() {
int __rpm = 0;
int ret = getRPM(&__rpm);
if(ret)
{
Serial.print("Engin Speed: ");
Serial.print(__rpm);
Serial.println(" rpm");
}else Serial.println("get Engin Speed Fail...");
delay(500);
}
// END FILE
What I believe is the offending library file:
#include "Longan_I2C_CAN_Arduino.h"
I2C_CAN::I2C_CAN(unsigned char __addr)
{
IIC_ADDR = __addr;
}
void I2C_CAN::begin()
{
Wire.begin();
}
void I2C_CAN::IIC_CAN_SetReg(unsigned char __reg, unsigned char __len, unsigned char *__dta)
{
Wire.beginTransmission(IIC_ADDR);
Wire.write(__reg);
for(int i=0; i<__len; i++)
{
Wire.write(__dta[i]);
}
Wire.endTransmission();
}
void I2C_CAN::IIC_CAN_SetReg(unsigned char __reg, unsigned char __dta)
{
Wire.beginTransmission(IIC_ADDR);
Wire.write(__reg);
Wire.write(__dta);
Wire.endTransmission();
}
bool I2C_CAN::IIC_CAN_GetReg(unsigned char __reg, unsigned char *__dta)
{
uint8_t my_size = 1; // MDR added
Wire.beginTransmission(IIC_ADDR);
Wire.write(__reg);
Wire.endTransmission();
//Wire.requestFrom(IIC_ADDR, 1); //Original
Wire.requestFrom(IIC_ADDR, my_size); //MDR modify
while(Wire.available())
{
*__dta = Wire.read();
return 1;
}
return 0;
}
bool I2C_CAN::IIC_CAN_GetReg(unsigned char __reg, int len, unsigned char *__dta) //ORIGINAL
//bool I2C_CAN::IIC_CAN_GetReg(uint8_t __reg, uint8_t len, uint8_t *__dta) //MDR MODIFIED
{
Wire.beginTransmission(IIC_ADDR);
Wire.write(__reg);
Wire.endTransmission();
Wire.requestFrom(IIC_ADDR, len);
//Wire.requestFrom( (int) IIC_ADDR, (int) len); //MDR MODIFIED
int __len = 0;
while(Wire.available())
{
__dta[__len++] = Wire.read();
}
return (len == __len);
}
byte I2C_CAN::begin(byte speedset) // init can
{
Wire.begin();
IIC_CAN_SetReg(REG_BAUD, speedset);
delay(10);
unsigned char __speed = 0;
if(IIC_CAN_GetReg(REG_BAUD, &__speed))
{
if(speedset == __speed)return 1;
}
delay(100);
return 0;
}
byte I2C_CAN::init_Mask(byte num, byte ext, unsigned long ulData) // init Masks
{
unsigned char dta[5];
dta[0] = ext;
dta[1] = 0xff & (ulData >> 24);
dta[2] = 0xff & (ulData >> 16);
dta[3] = 0xff & (ulData >> 8);
dta[4] = 0xff & (ulData >> 0);
unsigned char mask = (num == 0) ? REG_MASK0 : REG_MASK1;
IIC_CAN_SetReg(mask, 5, dta);
delay(50);
}
byte I2C_CAN::init_Filt(byte num, byte ext, unsigned long ulData) // init filters
{
unsigned char dta[5];
dta[0] = ext;
dta[1] = 0xff & (ulData >> 24);
dta[2] = 0xff & (ulData >> 16);
dta[3] = 0xff & (ulData >> 8);
dta[4] = 0xff & (ulData >> 0);
unsigned char filt = (7+num)*0x10;
IIC_CAN_SetReg(filt, 5, dta);
delay(50);
}
byte I2C_CAN::sendMsgBuf(unsigned long id, byte ext, byte rtr, byte len, byte *buf) // send buf
{
unsigned char dta[16];
dta[0] = 0xff & (id >> 24);
dta[1] = 0xff & (id >> 16);
dta[2] = 0xff & (id >> 8);
dta[3] = 0xff & (id >> 0);
dta[4] = ext;
dta[5] = rtr;
dta[6] = len;
for(int i=0; i<len; i++)
{
dta[7+i] = buf[i];
}
dta[15] = makeCheckSum(dta, 15);
IIC_CAN_SetReg(REG_SEND, 16, dta);
}
byte I2C_CAN::sendMsgBuf(unsigned long id, byte ext, byte len, byte *buf) // send buf
{
sendMsgBuf(id, ext, 0, len, buf);
}
byte I2C_CAN::readMsgBuf(byte *len, byte *buf) // read buf
{
readMsgBufID(&m_ID, len, buf);
}
byte I2C_CAN::readMsgBufID(unsigned long *ID, byte *len, byte *buf) // read buf with object ID
{
//IIC_CAN_GetReg(unsigned char __reg, int len, unsigned char *__dta)
unsigned long id = 0;
unsigned char dta[16];
IIC_CAN_GetReg(REG_RECV, 16, dta);
unsigned char __checksum = makeCheckSum(dta, 15);
if(__checksum == dta[15]) // checksum ok
{
id = dta[0];
id <<= 8;
id += dta[1];
id <<= 8;
id += dta[2];
id <<= 8;
id += dta[3];
*ID = id;
m_ID = id;
m_EXT = dta[4];
m_RTR = dta[5];
*len = dta[6];
//Serial.print("readMsgBufID, len = ");
//Serial.println(*len);
if(*len > 8)return 0;
for(int i=0; i<*len; i++)
buf[i] = dta[7+i];
return 1;
}
else
{
//Serial.println("CHECKSUM ERROR");
return 0;
}
}
byte I2C_CAN::checkReceive(void) // if something received
{
unsigned char num = 0;
if(IIC_CAN_GetReg(REG_DNUM, &num))
{
if(num > 0)
{
return CAN_MSGAVAIL;
}
}
return 0;
}
byte I2C_CAN::checkError(void) // if something error
{
return 0;
}
unsigned long I2C_CAN::getCanId(void) // get can id when receive
{
return m_ID;
}
byte I2C_CAN::isRemoteRequest(void) // get RR flag when receive
{
return m_RTR;
}
byte I2C_CAN::isExtendedFrame(void) // did we recieve 29bit frame?
{
return m_EXT;
}
unsigned char I2C_CAN::makeCheckSum(unsigned char *dta, int len)
{
unsigned long sum = 0;
for(int i=0; i<len; i++)sum += dta[i];
if(sum > 0xff)
{
sum = ~sum;
sum += 1;
}
sum = sum & 0xff;
return sum;
}
// END FILE
You will see some of the changes I tried (comment "MDR"). But I don't have a full grasp of the problem.
Any ideas?
Thank you.