Подскажите пожалуйста по такому вопросу. Нашел код из этой темы Данные из K-line Эбу | Аппаратная платформа Arduino и переделал немного под свои нужды.
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <utf8rus2.h>
SoftwareSerial K_LINE(2, 3); // RX, TX
#define TIMER_DELAY \
Delay = 0; \
timerdelay = curmillis // включение этого таймера
#define TFT_CS 10
#define TFT_RST 8
#define TFT_DC 9
#define SERIAL_BAUDRATE 10400
const byte PCMaddress = 0x7A; // адрес эбу
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Инициализация объекта для работы с дисплеем
byte header = 0; // состояние заголовка
byte message_size = 0; // размер тела принимаемого сообщения, кол-во байт
byte j = 2; // инкремент
byte n = 2;
const byte bufsize = 60; // размер буфера принятого сообщения
byte buf[bufsize] = { 0 }; // буфер принятого сообщения
byte checksum = 0; // контрольная сумма входящего сообщения
uint32_t curmillis = 0; // снимок системного времени
byte delaybyte_TX = 0; // задержка между байтами отправляемого сообщения
byte waitbyte_RX = 1; // задержка, мс для успевания заполнения буфера RX (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
uint32_t timerdelay = 0; // таймер ожидания байт (для успевания заполнения буфера УАРТ)
bool Delay = 0; // таймер ожидания байт (для успевания заполнения буфера УАРТ)
#define TIMER_DELAY \
Delay = 0; \
timerdelay = curmillis // включение этого таймера
uint32_t prevRESETheader = 0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались
bool RESETheader_timer = 0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались
uint32_t prevtimeRequest = 0;
uint16_t periodRequest = 1000; // периодичность запроса параметров ЭБУ, мс
bool Init = 0;
uint32_t prevInit = 0;
int Temperature;
//**************************** команды, посылаемые на ЭБУ
byte StartSession[] = { 0x81 }; // команда на старт диагностики (может также быть 82)
byte StopSession[] = { 0x82 }; // команда на стоп диагностики
//byte DataRequest[] = { 0x21, 0x80 }; // команда на запрос параметров
byte DataRequest[] = { 0x21, 0xAA }; // команда на запрос параметров
//byte DataRequest[] = { 0x21, 0x01 }; // команда на запрос параметров
//****************************
void lcdPrint(int x, int y, int c1, int c2, String s, int width = 0, int f = 0){
String ss;
tft.setCursor(x,y);
if (width == 0) {
width = s.length();
}
while (ss.length() < width-s.length()) ss += " ";
ss += s;
if (c2 == 0){
tft.setTextColor(c1);
}
else{
tft.setTextColor(c1, c2);
}
tft.print(ss);
}
void setup() {
Serial.begin(SERIAL_BAUDRATE); // настойки монитора порта отладки
K_LINE.begin(SERIAL_BAUDRATE); // настройки шины к-лайн
delay(2000);
tft.initR(INITR_BLACKTAB); // Инициализация дисплея
tft.fillScreen(ST7735_BLACK); // Очистка экрана перед выводом новых данных
tft.setTextColor(ST7735_WHITE); // Установка цвета текста
tft.setRotation(3);
tft.setTextSize(2);
lcdPrint(0, 0, ST7735_WHITE, ST77XX_RED, utf8rus2("Связь с ЭБУ"));
lcdPrint(50, 20, ST7735_BLACK, ST77XX_GREEN, utf8rus2("НЕТ"));
lcdPrint(0, 50, ST7735_WHITE, ST77XX_RED, utf8rus2("Обороты"));
lcdPrint(0, 70, ST7735_BLACK, ST77XX_GREEN, String(0), 6);
lcdPrint(85, 70, ST7735_BLACK, ST77XX_GREEN, utf8rus2("об/мин"));
lcdPrint(0, 90, ST7735_WHITE, ST77XX_RED, utf8rus2("Скорость"));
lcdPrint(0, 110, ST7735_BLACK, ST77XX_GREEN, String(0), 6);
lcdPrint(85, 110, ST7735_BLACK, ST77XX_GREEN, utf8rus2("км/ч"));
Serial.println(sizeof(buf));
}
void loop() {
curmillis = millis(); // снимок системного времени
K_LINEread(); // читаем шину к-лайн
if (curmillis - prevtimeRequest > periodRequest) { // периодически делаем запрос параметров
if (Init) {
lcdPrint(50, 20, ST7735_BLACK, ST77XX_GREEN, utf8rus2("ДА"), 3);
SendMessage(DataRequest, sizeof(DataRequest));
}else SendMessage(StartSession, sizeof(StartSession));
prevtimeRequest = curmillis;
}
if (curmillis - prevInit > 10000) {
lcdPrint(50, 20, ST7735_BLACK, ST77XX_GREEN, utf8rus2("НЕТ"));
Init = 0;
prevInit = curmillis;
} // периодически делаем сброс инита, если ЭБУ не отвечает
}
void SendMessage(const byte *command, const size_t size) {
const byte siZe = size + 4;
byte Mes[siZe];
byte Checksum = 0;
for (byte i = 0; i < siZe; i++) {
if (i == 0) {
Mes[i] = size;
bitWrite(Mes[i], 7, 1);
}
if (i == 1) Mes[i] = PCMaddress;
if (i == 2) Mes[i] = 0xF1;
if (i == 3) {
for (byte t = 0; t < size; t++) {
Mes[i] = command[t];
Checksum += Mes[i];
K_LINE.write(Mes[i]);
i++;
}
}
if (i != siZe - 1) Checksum += Mes[i];
else Mes[i] = Checksum;
K_LINE.write(Mes[i]);
}
}
void K_LINEread() {
if (K_LINE.available()) {
// первый старт байт
if (header == 0 && Delay) {
TIMER_DELAY;
buf[0] = K_LINE.read();
if (!bitRead(buf[0], 6) && bitRead(buf[0], 7)) {
header = 1;
RESETheader_timer = 1;
prevRESETheader = curmillis;
}
}
// второй старт байт
if (header == 1 && Delay) {
TIMER_DELAY;
buf[1] = K_LINE.read();
if (buf[1] == 0xF1) {
header = 2;
} else {
header = 0;
RESETheader_timer = 0;
}
}
// третий старт байт
if (header == 2 && Delay) {
TIMER_DELAY;
buf[2] = K_LINE.read();
if (buf[2] == PCMaddress) {
message_size = buf[0];
if (buf[0] != 0x80) {
header = 4;
message_size &= ~0x80;
j = 3;
n = 3;
} else {
header = 3;
j = 4;
n = 4;
}
if (message_size > bufsize) message_size = bufsize;
checksum = 0;
} else {
header = 0;
RESETheader_timer = 0;
}
}
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay) {
TIMER_DELAY;
buf[3] = K_LINE.read();
message_size = buf[3];
Serial.print("message_size:");
Serial.println(message_size);
if (message_size > bufsize) message_size = bufsize;
checksum = 0;
header = 4;
}
// пишем тело сообщения
if (header == 4 && Delay && j < message_size + n + 1) {
buf[j] = K_LINE.read();
if (j < message_size + n) checksum += buf[j]; // подсчёт КС
if (j == message_size + n) {
Serial.println("header 5");
header = 5;
}
TIMER_DELAY;
j++;
}
} // end of K_LINE.available()
// сообщение приняли, действуем
if (header == 5) {
TIMER_DELAY;
for (byte i = 0; i < n; i++) checksum += buf[i]; // прибавляем к контрольной сумме старт байты
Serial.print(F("Receive from PCM: "));
for (byte i = 0; i < message_size + n + 1; i++) {
if (buf[i] <= 0x0F) Serial.print(F("0"));
Serial.print(buf[i], HEX);
Serial.print(" ");
} // Отладка в монитор порта
Serial.println();
// если контрольная сумма верна:
if (buf[message_size + n] == checksum) {
prevInit = curmillis; // сбрасываем таймер сброса инита, если получили хоть какое-то сообщение от ЭБУ
if (buf[n] == 0xC1) Init = 1; // если пришёл ответ на запрос инита, делаем инит прошёл успешно
// ниже если получили длинный ответ от ЭБУ с параметрами парсим его, я взял только температуру ДВС
else if (buf[n] == 0x61 && buf[n + 1] == DataRequest[1]) {
Temperature = buf[n + 10] - 40;
Serial.print(F("TempEngine: "));
Serial.println(Temperature);
}
// ТУТ ЧТО НИБУДЬ ДЕЛАЕМ КОГДА ПОЛУЧИЛИ СООБЩЕНИЕ ОТ ЭБУ
}
// если контрольная сумма не совпала:
//else Serial.println("CRC fail!!!" );
message_size = 0;
header = 0;
RESETheader_timer = 0;
j = 3;
checksum = 0;
}
// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1;
// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {
RESETheader_timer = 0;
header = 0;
}
}
если отправлять 81 7a f1 81 6d 83 f1 7a c1 d0 8f 0e на ответ 81 7a f1 81 6d все нормально
а вот на 82 7a f1 21 aa b8 если отправить 82 7a f1 21 aa b8 9a f1 7a 61 AA 00 94 00 00 00 4A 00 00 00 00 03 20 03 22 01 00 00 04 00 00 03 FF 00 00 , то в ответ ничего не приходит. И при просмотре через Serial Port Monitor наблюдается обрыв чтения ответа вроде как