написал скетч похоже не правильно

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
добрый день, я вот мучаю код , походу уже затупил, инициализацию прописал, а запросы после 69 строки не идут, ардуино уно ,лсд TFT, общение по rxtx, помогите найти ошибку пжлста.

C++:
#include <TFT.h>                 // Подключаем библиотеку TFT 
#include <SPI.h>                 // Подключаем библиотеку SPI
#define cs   9                  // Указываем пины cs
#define dc   8                  // Указываем пины dc (A0)
#define rst  7                   // Указываем пины reset
TFT TFTscreen = TFT(cs, dc, rst);
#define K_line_RX 0
#define K_line_TX 1
int n;
int Temp1 = 75;
int Temp2 = 25;
int PMM = "      ";
int SPEED = "      ";
String s;
int pac =0;
int tm = 10000;
byte    init_obd[] = {0x81,0x10,0xFC,0x81,0x0E};      // инициализация K-line шины  81 10 FC 81 0E
byte     pmm_obd[] = {0x04,0x21,0x81,0x04,0x01,0xAB}; // запрос оборотов двигателя  C2 33 F1 01 0C F3
byte   temp1_obd[] = {0x05,0xAC,0x81,0x02,0x11,0x0D,0x52}; // запрос температуры ож      05 AC 81 02 11 0D 52
byte   temp2_obd[] = {0x81,0x10,0xF1,0xFC,0x82,0x0F}; // запрос температуры воздуха                          81 10 FC 82 0F
byte   speed_obd[] = {0xC2,0x33,0xF1,0x01,0x0D,0xF4}; // запрос скорости автомобиля C2 33 F1 01 0D F4

void setup()  {
  pinMode(K_line_RX, INPUT);
  pinMode(K_line_TX, OUTPUT);
  //myOLED.begin();
  //myOLED.clrScr();
  TFTscreen.begin();   // Эта строка необходима в начале каждого скетча, где используется TFT-экран:
  TFTscreen.background(0, 0, 0); // Очищаем фон экрана, заливая его черным цветом:

              }

void loop(){ 
   read_CAN();
   tm--;
   if (tm <0){
    tm=10000;   
    Serial.flush();   
    //for(int i=0;i<6;i++) Serial.write(pmm_obd[i]), delay (10);
           }
}


void read_CAN(){
 
if (pac == 0) {
  digitalWrite(K_line_TX, HIGH), delay(300);
  digitalWrite(K_line_TX, LOW), delay(25);   
  digitalWrite(K_line_TX, HIGH), delay(25); //-----------_-
  Serial.begin(10400);  // ------------_- ISO 14230-4 KWP 10.4 Kbaud
  for(int i=0;i<5;i++) Serial.write(init_obd[i]), delay (10); // отправляем команду инициализации K-line шины
   //for(int i=0;i<5;i++) Serial.write(pmm_obd[i]), delay (10); 
    //delay(100);
    for(int i=0;i<5;i++) Serial.write(temp2_obd[i]), delay (10);
   // delay(100);
for(int i=0;i<5;i++) Serial.write(init_obd[i]), delay (10);
//delay(100);
for(int i=0;i<5;i++) Serial.write(temp2_obd[i]), delay (10);
//delay(100);
for(int i=0;i<5;i++) Serial.write(init_obd[i]), delay (10);
delay(250);

}
 
  char byfer[30];
  n = Serial.available();
  if (n > 0) {  pac++;
  for (int i=0;i<n;i++) byfer[i]=Serial.read();
  String byte8 = String(byfer[8],HEX);   // С1 (HEX) = 193 (DEC) // С1 успешный ответ
  String byte10 = String(byfer[10],DEC); // 05 HEX = 05 DEC, 0F HEX = 15 DEC, 0C HEX = 12 DEC, 0D HEX = 13 DEC
 

if  (n == 14 && byte8 ==  "C1")   {  // ждем инициализхации шины
  
                                        Serial.flush();   
                                        for(int i=0;i<6;i++) Serial.write(pmm_obd[i]), delay (10);
                                        delay(100);
                                         }
 
if (n == 14  && byte10 ==  "12" )     {  // читаем обороты двигателя из 12-го и 13-го байта пакета
                                        s = String(byfer[11],DEC);
                                        int h = s.toInt();
                                        s = String(byfer[12],DEC);
                                        int l = s.toInt();
                                        PMM = word(h, l)/4;
                                        

TFTscreen.background(0, 0, 0);
TFTscreen.stroke(255, 255, 255);
TFTscreen.setTextSize(2);
  TFTscreen.setCursor(20,20);
    TFTscreen.print(PMM);
    delay(200);
    
        }
                                          
        }
              
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
Обрывок кода:
C++:
if (n > 0) {  pac++;
  for (int i=0;i<n;i++) byfer[i]=Serial.read();
  String byte8 = String(byfer[8],HEX);   // С1 (HEX) = 193 (DEC) // С1 успешный ответ
  String byte10 = String(byfer[10],DEC); // 05 HEX = 05 DEC, 0F HEX = 15 DEC, 0C HEX = 12 DEC, 0D HEX = 13 DEC
А кто сказал, что byfer[8] или byfer[10] существует в нужном виде ? А если n меньше 9 ?
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
нет не ИИ , я брал примеры, прочитал ардуино сайт, по работе с UART, я начал с того о чем пишут на форумах, написал ини дисплея и вывод переменных
потом посмотрел как пишут инициализацию обд, скачал логи с моей машины , прописал запросы согласно логам, потом посмотрел как пишут запросы данных , скачал логи данных,
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
вот логи ниссана

0000037950: Модуль "KLine Nissan EFI Type0" ver 1.0.0.6
0000037990: Open COM9 Baud=10400 RTO=20 P4=0 DTR=ON
0000038719: TxD(Эхо):81 10 FC 81 0E
0000038720: Grafic
0000038721: ECU не отвечает
0000038752: TxD(Эхо):81 10 FC 82 0F
0000038752: Close COM9
0000039072: Open COM9 Baud=10400 RTO=20 P4=0 DTR=ON
0000039791: TxD(Эхо):81 10 FC 81 0E
0000039792: Grafic
0000039793: ECU не отвечает
0000039824: TxD(Эхо):81 10 FC 82 0F
0000039824: Close COM9
0000040144: Open COM9 Baud=10400 RTO=20 P4=0 DTR=ON
0000040910: TxD(Эхо):81 10 FC 81 0E
0000040911: RxD:83 FC 10 C1 5D 8F 3C
0000040912: Fast Init OK
0000040913: Grafic
0000040954: TxD(Эхо):05 AC 81 02 11 0D 52
0000040954: RxD:02 EC 81 6F
0000041004: TxD(Эхо):04 21 81 04 01 AB
0000041004: RxD:03 61 81 69 4E
0000041054: TxD(Эхо):04 21 81 04 01 AB
0000041054: RxD:03 61 81 69 4E
0000041104: TxD(Эхо):04 21 81 04 01 AB
0000041104: RxD:03 61 81 69 4E
0000041154: TxD(Эхо):04 21 81 04 01 AB
0000041154: RxD:03 61 81 69 4E
0000041194: TxD(Эхо):04 21 81 04 01 AB
0000041194: RxD:03 61 81 69 4E
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
При передачи пакета надо убедиться, что он принят полностью.
Тут возможны варианты.
Если величина пакета строго определенная, то можно попробовать дождаться, когда буфер заполнится нужным числом байт. Но тут надо быть уверенным, чо начало пакета совпадает с начальным элементом буфера.
Если длина пакета может быть разной, то тогда это длинна либо как то задана внутри пакета, либо есть какой то завершающий байт. И действия для каждого из вариантов будет разное.
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
судя по лог то длинна одинаковая, я попробую найти справочник по передачи строки по uart, почитаю может что и получится
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
Если смотреть лог, то полученные данные то 4, то 5, то 7 байт, тогда какие 8-10 байт на прием идут ? Или выводится не вся строка.
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
в логе две отправки запроса , а правильный запрос 81 10 FC 81 0E вот этот, а ответ вот такой 83 FC 10 C1 5D 8F 3C где С1 из этого пакета означает что блок готов к передаче данных, вот тогда и пойдет запрос уже оборотов 04 21 81 04 01 AB а ответ нулевых оборотов будет 03 61 81 69 4E где изменяется последние два байта, в таком виде должно показывать десятичное число 0
в итоге что получаем
0x81,0x10,0xFC,0x81,0x0E отправка инициализации в формате hex
83 FC 10 C1 5D 8F 3C ответ (C1) я готов к обмену данных
0x04,0x21,0x81,0x04,0x01,0xAB запрос данных по оборотам двигателя
03 61 81 69 4Е данные оборотов
я задался этим потому что на моей машине не предусмотрено тахометра и она праворульная для внутреннего рынка японии так что покупка бортового компьютера пустая трата денег ни один не подошел
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
Я может чего не понимаю.
Если смотреть ответ, то C1 идет 4-ой по счету, если брать в буфере, то индекс будет 0. Почему тогда byfer[8] ?
И второй момент, для чего переводить byfer[8] в троку ? Что бы сравнить byfer[8] с C1 достаточно написать byfer[8]==0xC1
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
byfer[8]==0xC1 я прочитал что если так прописать то если в буфере появится С1 то все остальные данные игнорируются, если правильно то я пропишу и попробую инициализировать блок, спасибо за подсказку , и думаю прописать через if написать включение светодиода сигнализирующем о том что инициализация пройдена, else if можно их применить , надо почитать ))
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
Вы меня не поняли.
Почему именно индекс буфера 8 ?
И еще важно чистить буфер перед приемом новых сообщений, там может оказаться мусор, я не уверен, что при динамическом выделении памяти под него там будут нули.
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
Serial.flush(); если этой функцией чистить буфер то я на правильном пути, можно индекс поставить 16 или 64
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,293
1,310
Москва
Я не про буйфер UART, а про буфер куда считывается информация из UART , вот про этот byfer
И индекс это не размер, а номер массива этого буфера. В данном случае он почему от 8, или 10 . Хотя номер нужного элемента , как я уже выше писал 3
Индекс в буфре: 0 1 2 3
0000040911: RxD:83 FC 10 C1 5D 8F 3C
 

viktor110668

✩✩✩✩✩✩✩
24 Дек 2023
10
0
тут нарисовалась новая проблема, перед запросом данных есть еще запрос на разрешение чтения этих данных
TxD(Эхо):05 AC 81 02 12 01 47
RxD:02 EC 81 6F
голову можно сломать, теперь буду думать и читать дальше букварь ардуино