Пытаюсь считывать данные с эбу авто.
Вот такой код, но данные с буфера не читает, выходит по таймауту…
грешу на то, что в функции прерывания указано FALLING, то есть по спаду сигнала, а может при поступлении данных сигнал INT с кан модуля просто встает в 1 и не спадает пока буфер не прочитаешь?
Пин INT с модуля msp2115 подключен на D2.
Без прерываний другим скетчем-снифером данные читаются, то есть с модулем и шиной все в порядке.
#include <SPI.h> // подключение библиотеки протокола последоваетельного периферийного интерфейса
#include <mcp2515_can.h>
#define CAN_INT0 0 // прерывание 0 на D2
#define CAN_CS 10 // сигнал CS на D10
volatile bool canDataReceived= false; // флаг для обработки прерывания
mcp2515_can CAN1(CAN_CS);
unsigned long timeOut;
unsigned char len = 0; // длина CAN-сообщения
unsigned char rxbuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
long unsigned int rxId; // id CAN-сообщения
long int updPeriod[] = {5000, 2000, 500, 1000}; // период обновления данных
long int updTime[sizeof(updPeriod)]; // время последнего обновления
// датчики
int Temp; // Температура охлаждающей жидкости
int Vbat; // напряжение аккумулятора
unsigned char PID[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//==========================================================================
// SETUP
//--------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
while (CAN_OK != CAN1.begin(CAN_500KBPS, MCP_16MHz)); // init can bus : baudrate = 500k / 16MHz
Serial.println("CAN init ok.");
//RXB0 - первый приёмный буфер
CAN1.init_Mask(0, 0, 0xFFF); // маска
CAN1.init_Filt(0, 0, 0x7E8); // фильтры
CAN1.init_Filt(1, 0, 0x7E8);
//RXB1 - второй приёмный буфер
CAN1.init_Mask(1, 0, 0xFFF); // маска
CAN1.init_Filt(2, 0, 0x0); // фильтры
CAN1.init_Filt(3, 0, 0x0);
CAN1.init_Filt(4, 0, 0x0);
CAN1.init_Filt(5, 0, 0x0);
delay(100);
Serial.println("Masks and filters set.");
pinMode(CAN_INT0, INPUT_PULLUP);
detachInterrupt(digitalPinToInterrupt(CAN_INT0));
canDataReceived = false;
// подключить обработчик прерывания о поступлении данных по спадающему уровню сигнала
attachInterrupt(digitalPinToInterrupt(CAN_INT0), canInterrupt, FALLING);
}
void canInterrupt()
{
// установить флаг наличия данных в буфере
canDataReceived = true;
}
void loop() {
if (millis() > (updTime[0] + updPeriod[0])) {
updTime[0] = millis();
enginePIDs();
Serial.print("Temp:");
Serial.print(Temp , 1); //
Serial.print(" Vbat:");
Serial.print(Vbat , 1); //
}
}
//==========================================================================
// Функция общения с ЭБУ ДВС по протоколу Renault
//--------------------------------------------------------------------------
void enginePIDs() {
long unsigned int moduleIdRequest = 0x7E0; // id модуля в запросе данных
long unsigned int moduleIdAnswer = 0x7E8;
int i=0;
unsigned char Q;
PID[0] = 0x03; // количество байт в запросе
PID[1] = 0x22; // префикс PID для запроса
PID[2] = 0x00;
PID[3] = 0x02;
PID[4] = 0x00;
PID[5] = 0x00;
PID[6] = 0x00;
PID[7] = 0x00;
// посылаем запрос ЭБУ
CAN1.sendMsgBuf(moduleIdRequest, 0, 8, PID);
PID[1] = 0x62; // префикс PID для ответа
rxId = 0x000; // обнуляем идентификатор
timeOut = millis() + 1500; // крайнее время ожидания ответа
// ждём нужного ответа или выходим по тамауту
while(!canDataReceived ) {
if ( millis() > timeOut) {
Serial.println("");
Serial.println(" Timeout ");
return; }
}
canDataReceived = false;
if (CAN1.checkReceive()==CAN_MSGAVAIL) {
CAN1.readMsgBuf(&len, rxbuf); // чтение данных в rxbuf A = rxbuf[5], B = rxbuf[6], C = rxbuf[7]
rxId = CAN1.getCanId(); // получаем ID сообщения
}
if (rxId == moduleIdAnswer && rxbuf[2] == PID[1] ){
// напряжение бортовой сети
Vbat = 0.1 * rxbuf[6] ;
}
}