не выводятся нули в мониторе порта

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Здравствуйте. Сильно не пинайте. Не могу понять, почему в мониторе порта не отображаются нули в приходящих сообщениях из CAN
То есть вместо 0х01 выводится 0х1. в моём проекте эти нули важны.
 

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

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
Потому что числах 1,2,3,4,5,6,7,8,9 не цифры ноль. Что бы вывести ноль нужны некоторые ухищрения. Подсмотреть их можно в примере к wire , сканер i2c, вывод адреса как раз использует такой трюк
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Получается,что из CAN нули приходят, а вывести я это не могу без доп. if-else?

void TaskRecive03() {
unsigned char len = 0;
unsigned char buf[8];
if (CAN_MSGAVAIL == CAN.checkReceive()) {
CAN.readMsgBuf(&len, buf);
if ( buf[0] == 0x02 &&
buf[1] == 0x43 &&
buf[2] == 0x00)
{
Serial.print("В автомобиле ошибок нет");
}
else if (buf[0] > 0x02 &&
buf[1] == 0x43 &&
buf[2] >= 0x01<= 0x02)
{
Serial.println("Количество ошибок:");
Serial.println(buf[2], DEC);
Serial.println("Коды ошибок:");

Serial.print (buf[3], HEX);
Serial.println(buf[4], HEX);
Serial.print (buf[5], HEX);
Serial.println(buf[6], HEX);
Serial.println(buf[7], HEX);

buf[3] приходит 01, а в мониторе 1.
 

Александр Симонов

★★★★✩✩✩
2 Авг 2018
727
208
Получается,что из CAN нули приходят, а вывести я это не могу без доп. if-else?
Да никакие нули из CAN не приходят. 01, 1, 0x01 и 0x1 это одно и то же число, и даже 0x0000001 это то же самое число. Ведущие нули значения не имеют.
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Да никакие нули из CAN не приходят. 01, 1, 0x01 и 0x1 это одно и то же число, и даже 0x0000001 это то же самое число. Ведущие нули значения не имеют.

Хорошо. Объясню. на запрос приходит ответ об ошибках. одна ошибка -2 байта. и если в пером байте 01-09 то подставляем букву P
А7-А6Первый символ DTC
00​
P-Силовая Установка
01​
C-Шасси
10​
B-Тело
11​
U-Сеть

Если я получаю допустим 0113. то это P0113. если получаю 113, то это уже С113.
 

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

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
у вас буфер 8 символов. просто при получении выведите все 8 символов по одному да посмотрите что приходит. Если приходит 2 байта ответа, то это по идее должны быть 2 первых элемента массива.
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Хорошо. Объясню. на запрос приходит ответ об ошибках. одна ошибка -2 байта. и если в пером байте 01-09 то подставляем букву P
А7-А6Первый символ DTC
@Semmen74, я вижу вы сами это мало понимаете и потому других путаете. У вас нет никаких 01-09 в первом байте. Смотрите на свою табличку в сообщении #8 внимательнее, первый столбец обозначен A7-A6. В курсе, что это значит? - Это первые два бита первого байта, а вовсе не целиком байт, как вы читаете.
Формат DTC кодов ошибок описан в куче мест в интернете, вы бы сначала разобрались как они устроены. а то вы читаете из Кана какую-то ерунду и не знаете как ей пользоваться.
Я бы посоветовал вам начать проект с изучения битовых операций, потому что для того чтоб правильно интервпретировать ошибки из КАН, надо уметь извлекать каждый отдельный бит из байта, а вы в трех соснах путаетесь, не можете 0х00 от 0х0 отличить
 
Изменено:

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
у вас буфер 8 символов. просто при получении выведите все 8 символов по одному да посмотрите что приходит. Если приходит 2 байта ответа, то это по идее должны быть 2 первых элемента массива.
Вот сделал вот так:
Serial.println("Количество ошибок:");
Serial.println(buf[2], DEC);
Serial.println("Коды ошибок:");
Serial.println("\r\n------------------------------------------------------------------");
Serial.print("Get Data from ID: 0x");
Serial.println(CAN.getCanId(), HEX);
for (int i = 0; i < len; i++) { // Вывод данных
Serial.print("0x");
Serial.print(buf, HEX);
Serial.print("\t");


И получил вот так:

Get Data from ID: 0x7E8
0x4 0x43 0x1 0x1 0x13 0x0 0x0 0x0 Количество ошибок:
1
Коды ошибок:


@Semmen74, я вижу вы сами это мало понимаете и потому других путаете. У вас нет никаких 01-09 в первом байте. Смотрите на свою табличку в сообщении #8 внимательнее, первый столбец обозначен A7-A6. В курсе, что это значит? - Это первые два бита первого байта, а вовсе не целиком байт, как вы читаете.
Формат DTC кодов ошибок описан в куче мест в интернете, вы бы сначала разобрались как они устроены. а то вы читаете из Кана какую-то ерунду и не знаете как ей пользоваться.
Я бы посоветовал вам начать проект с изучения битовых операций, потому что для того чтоб правильно интервпретировать ошибки из КАН, надо уметь извлекать каждый отдельный бит из байта, а вы в трех соснах путаетесь, не можете 0х00 от 0х0 отличить
Вы хотите сказать, что сообщения читать справа налево?
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Вот сделал вот так:
Serial.println("Количество ошибок:");
.....
выложите строго тот код, которым вы читаете данные, а то этот вы явно сейчас по памяти писали, тут у вас куча ошибок - незакрытые скобки. нет индексов в буфере... Да и порядок данных в коде и в выводе разный.
Вы хотите сказать, что сообщения читать справа налево?
я хочу сказать, что некоторые из байтов надо разбирать побитно. А вы их на печать выдаете как символы - так у вас ничего не получится.
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
@Semmen74[/USER], я вижу вы сами это мало понимаете и потому других путаете. У вас нет никаких 01-09 в первом байте. Смотрите на свою табличку в сообщении #8 внимательнее, первый столбец обозначен A7-A6. В курсе, что это значит? - Это первые два бита первого байта, а вовсе не целиком байт, как вы читаете.
Формат DTC кодов ошибок описан в куче мест в интернете, вы бы сначала разобрались как они устроены. а то вы читаете из Кана какую-то ерунду и не знаете как ей пользоваться.
Я бы посоветовал вам начать проект с изучения битовых операций, потому что для того чтоб правильно интервпретировать ошибки из КАН, надо уметь извлекать каждый отдельный бит из байта, а вы в трех соснах путаетесь, не можете 0х00 от 0х0 отличить
[/QUOTE]


во-первых, я ни кого не путаю. что получаю,вижу, то и описал.
во-вторых из CAN я читаю то, что мне необходимо.За пол-года работы с этим проектом я Формат DTC кодов ошибок с закрытыми глазами могу произнести.
в третьих, как в известном анекдоте:" Не умничай-пальцем покажи". Для этого я и зарегился на форуме. Я технарь, не программист. Пытаюсь освоить..Поэтому спасибо за совет про биты. Однако я не понимаю зачем они мне здесь нужны. приходит,допустим, 3 байт в сообщении, я вижу 01, мне нужно через if-else подставить нужную букву и отправить дальше. а я вижу не 01,а 1. И вот здесь и затык. Запрос в Яндексе результатов не даёт.Поэтому я здесь. Если не затруднит, объясните как получить желаемый результат. А учить и перенаправлять я и сам могу не плохо

выложите строго тот код, которым вы читаете данные, а то этот вы явно сейчас по памяти писали, тут у вас куча ошибок - незакрытые скобки. нет индексов в буфере... Да и порядок данных в коде и в выводе разный.

я хочу сказать, что некоторые из байтов надо разбирать побитно. А вы их на печать выдаете как символы - так у вас ничего не получится.

// Библиотеки
#include <SPI.h>
#include "mcp_can.h" // Подключаем библиотеку для работы с CAN
#include "UTFT.h" // Подключаем библиотеку для работы с дисплеем
#include "TouchScreen.h" // Подключаем библиотеку для работы с TouchScreen
// подключаем шрифты
extern uint8_t SmallFont[]; // Устанавливаем маленький шрифт
extern uint8_t BigFont[]; // Устанавливаем большой шрифт
extern uint8_t SevenSegNumFont[]; // Устанавливаем семисегментный шрифт

#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE // Проверка соответствия связи МК с портами
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif

// Определяем выводы используемые для управления дисплеем 2.8" TFT 320x240 UNO:
const uint8_t RS = 8; // MOSI
const uint8_t WR = 7; // SCK
const uint8_t CS = 6; // CS
const uint8_t RST = 5; // RST
const uint8_t SER = 4; // D/C
// Определяем выводы используемые для чтения данных с TouchScreen:
const uint8_t YP = A0; // Вывод Y+ должен быть подключен к аналоговому входу
const uint8_t XM = A1; // Вывод X- должен быть подключен к аналоговому входу
const uint8_t YM = A2; // Вывод Y- должен быть подключен к аналоговому входу
const uint8_t XP = A3; // Вывод X+ должен быть подключен к аналоговому входу
// Определяем экстремумы для значений считываемых с аналоговых входов при определении точек нажатия на TouchScreen:
const int tsMinX = 100; // соответствующий точке начала координат по оси X
const int tsMinY = 120; // соответствующий точке начала координат по оси Y
const int tsMaxX = 950; // соответствующий максимальной точке координат по оси X
const int tsMaxY = 915; // соответствующий максимальной точке координат по оси Y
const int mipPress = 10; // соответствующий минимальной степени нажатия на TouchScreen
const int maxPress = 1000; // соответствующий максимальной степени нажатия на TouchScreen
//const uint8_t pen_radius = 3; // указываем размер точки, которая будет появляться при рисовании

const int SPI_CS_PIN = 9; // Определяем выводы, используемые для управления CAN Shild

// Создаём объекты библиотек:
MCP_CAN CAN(SPI_CS_PIN); // Установка CS pin

UTFT myGLCD(TFT01_24SP, RS, WR, CS, RST, SER); // Создаём объект для работы с дисплеем
TouchScreen ts = TouchScreen(XP, YP, XM, YM); // Создаём объект для работы с TouchScreen

// Определяем PIDs

#define PID_ENGIN_PRM 0x0C //
#define PID_VEHICLE_SPEED 0x0D //
#define PID_COOLANT_TEMP 0x05 //

#define CAN_ID 0x7DF //
#define CAN_ID_2 0x7E0
unsigned char OTRej_3[] = {0x01, 0x03, 0x00, 0, 0, 0, 0, 0}; // Запрос текущих ошибок DTC
unsigned char OTRTR [] = {0x30, 0, 0, 0, 0, 0, 0, 0};

void set_mask_filt() {

// Установка маски (set mask, set both the mask to 0x7FC)

CAN.init_Mask(0, 0, 0x7FC); // Маска для стандартных сообщений
CAN.init_Mask(1, 0, 0x7FC); // Маска для расширенных сообщений

// Установка фильтров для чтения сообщений ID 0x04 ~ 0x09 байт

CAN.init_Filt(0, 0, 0x7E8);
CAN.init_Filt(0, 0, 0x7E9);

CAN.init_Filt(2, 0, 0x7E8);
CAN.init_Filt(3, 0, 0x7E9);
CAN.init_Filt(4, 0, 0x7E8);
CAN.init_Filt(5, 0, 0x7E8);
}
void setup() {
Serial.begin(115200); // Инициируем передачу данных в монитор последовательного порта на скорости 115200 бод
myGLCD.InitLCD(); // Инициируем работу с TFT дисплеем
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
Serial.println("CAN BUS Shield init fail");
Serial.println(" Init CAN BUS Shield again");
myGLCD.setFont (BigFont); // устанавливаем большой шрифт
myGLCD.print("CAN BUS Shield init fail", CENTER, 100); // выводим текст в указанных координатах
delay(100);
}
Serial.println("CAN BUS Shield init ok!");
set_mask_filt();
myGLCD.setFont (BigFont); // устанавливаем большой шрифт
myGLCD.print("CAN init ok!", CENTER, 100); // выводим текст в указанных координатах
delay(2000);
myGLCD.clrScr(); // Чистим экран
delay(100);

myGLCD.setColor(VGA_WHITE); // Указываем белый цвет
myGLCD.drawLine(0, 0, 40, 40); // Рисуем линию
myGLCD.drawLine(40, 0, 0, 40); // Рисуем линию
myGLCD.setColor(VGA_YELLOW); // Указываем жёлтый цвет
myGLCD.fillRect(0, 40, 40, 80); // Рисуем квадрат
myGLCD.setColor(VGA_GREEN); // Указываем зелёный цвет
myGLCD.fillRect(0, 80, 40, 120); // Рисуем квадрат
myGLCD.setColor(VGA_RED); // Указываем красный цвет
myGLCD.fillRect(0, 120, 40, 160); // Рисуем квадрат
myGLCD.setColor(VGA_PURPLE); // Указываем фиолетовый цвет
myGLCD.fillRect(0, 160, 40, 200); // Рисуем квадрат
myGLCD.setColor(VGA_BLUE); // Указываем синий цвет
myGLCD.fillRect(0, 200, 40, 240); // Рисуем квадрат
}

void loop() {
// Считываем показания с TouchScreen:
TSPoint p = ts.getPoint(); // Считываем координаты и интенсивность нажатия на TouchScreen в структуру p
// Возвращаем режим работы выводов:
pinMode(XM, OUTPUT); // Возвращаем режим работы вывода X- в значение «выход» для работы с дисплеем
pinMode(YP, OUTPUT); // Возвращаем режим работы вывода Y+ в значение «выход» для работы с дисплеем
// Если зафиксировано нажатие на TouchScreen, то ...
if (p.z > mipPress && p.z < maxPress) { // Если степень нажатия достаточна для фиксации координат TouchScreen
p.x = map(p.x, tsMinX, tsMaxX, 0, 320); // Преобразуем значение p.x от диапазона tsMinX...tsMaxX, к диапазону 0...320
p.y = map(p.y, tsMinY, tsMaxY, 0, 240); // Преобразуем значение p.y от диапазона tsMinY...tsMaxY, к диапазону 0...240
if (p.x <= 40) { // Если нажатие было в зоне выбора цветов, то
if (p.y < 40 ) { // Если нажатие было в зоне кнопки "очищение экрана", то
myGLCD.clrScr(); // Чистим экран дисплея
myGLCD.setColor(VGA_WHITE); // Указываем цвет
myGLCD.drawLine(0, 0, 40, 40); // Рисуем линию
myGLCD.drawLine(40, 0, 0, 40); // Рисуем линию
myGLCD.setColor(VGA_YELLOW); // Указываем цвет
myGLCD.fillRect(0, 40, 40, 80); // Рисуем квадрат
myGLCD.setColor(VGA_GREEN); // Указываем цвет
myGLCD.fillRect(0, 80, 40, 120); // Рисуем квадрат
myGLCD.setColor(VGA_RED); // Указываем цвет
myGLCD.fillRect(0, 120, 40, 160); // Рисуем квадрат
myGLCD.setColor(VGA_PURPLE); // Указываем цвет
myGLCD.fillRect(0, 160, 40, 200); // Рисуем квадрат
myGLCD.setColor(VGA_BLUE); // Указываем цвет
myGLCD.fillRect(0, 200, 40, 240); // Рисуем квадрат
}
else if (p.y > 80 && p.y <= 120 ) { // Если нажатие было в зоне зелёного квадрата, то
myGLCD.setColor(VGA_GREEN); // Устанавливаем цвет
myGLCD.setFont (BigFont); // устанавливаем большой шрифт
myGLCD.print("Request DTC 3", 45, 100); // выводим текст в указанных координатах
CAN.sendMsgBuf(CAN_ID, 0, 8, OTRej_3); // Запрос режима 03
}
}
}
TaskRecive03();
}
void TaskRecive03() {
unsigned char len = 0;
unsigned char buf[8];
if (CAN_MSGAVAIL == CAN.checkReceive()) {
CAN.readMsgBuf(&len, buf);
if ( buf[0] == 0x02 &&
buf[1] == 0x43 &&
buf[2] == 0x00)
{
Serial.print("В автомобиле ошибок нет");
}
else if (buf[0] > 0x02 &&
buf[1] == 0x43 &&
buf[2] >= 0x01 <= 0x02)
{

Serial.print (buf[3], HEX);
Serial.println(buf[4], HEX);
Serial.print (buf[5], HEX);
Serial.println(buf[6], HEX);
Serial.println(buf[7], HEX);
}
else if ( buf[0] == 0x10 &&
buf[2] == 0x43 &&
buf[3] >= 0x03)
{
Serial.println("Количество ошибок:");
Serial.println(buf[3], DEC);
Serial.println("Коды ошибок:");
Serial.print (buf[4], HEX);
Serial.println(buf[5], HEX);
Serial.print (buf[6], HEX);
Serial.println(buf[7], HEX);
CAN.sendMsgBuf(CAN_ID_2, 0, 8, OTRTR); // Запрос RTR
}
else if ( buf[0] == 0x21)
{
Serial.println(buf[1], buf[2]);
Serial.println(buf[3], buf[4]);
Serial.println(buf[5], buf[6]);
Serial.print(buf[7]);
}
else if ( buf[0] == 0x22)
{
Serial.println(buf[1]);
Serial.println(buf[2], buf[3]);
Serial.println(buf[4], buf[5]);
Serial.println(buf[6], buf[7]);
}
else if ( buf[0] == 0x23)
{
Serial.println(buf[1], buf[2]);
Serial.println(buf[3], buf[4]);
Serial.println(buf[5], buf[6]);
Serial.print(buf[7]);
}
else if ( buf[0] == 0x24)
{
Serial.println(buf[1]);
Serial.println(buf[2], buf[3]);
Serial.println(buf[4], buf[5]);
Serial.println(buf[6], buf[7]);

}
}
}

Это набросок. Не оптимизированный. Работа с библиотекой CAN BAS-Shild/

C Дисплеем Tachsckreen

VIN номер я получаю без проблем. Ошибки получаю. Мне их хотелось бы интерпретировать на уровне скетча
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Это набросок. Не оптимизированный. Работа с библиотекой CAN BAS-Shild/
я не это просил.
Вот вы по совету @Старик Похабыч, писали коротенький код для вывода всего сообщения как набора символов. Покажите этот код, только без ошибок.

И не надо обижаться. Я не пытаюсь вас учить жизни. Просто на мой взгляд - вы кардинально не понимаете, что означают эти "00" и "01" в вашей таблице.
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Вы имеете ввиду вот это:
/*void taskCanRecv() {

if (getPid) { // Получить PID
getPid = 0;
sendPid(PID_INPUT);
PID_INPUT = 0;
}
if (CAN_MSGAVAIL == CAN.checkReceive()) { // проверка получения данных
CAN.readMsgBuf(&len, buf); // чтение данных, len: длина данных, buf: данные
Serial.println("\r\n------------------------------------------------------------------");
Serial.print("Get Data from ID: 0x");
Serial.println(CAN.getCanId(), HEX);
for (int i = 0; i < len; i++) { // Вывод данных
Serial.print("0x");
Serial.print(buf, HEX);
Serial.print("\t");
}
Serial.println();
}
}
Это я брал из примера к библиотеке


Вы правы. Я не совсем:" вы кардинально не понимаете, что означают эти "00" и "01" в вашей таблице. " Если не трудно ткните где посмотреть

Почему то при копировании не правильно отобразилось Serial.print(buf, HEX); Правильно :Serial.print(buf, HEX);

Опять то же самое. в buf квадратные скобки и в них

i
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Вы имеете ввиду вот это:
да, это
Только на будущее вставляйте код - как код, а то читать неудобно и комментировать слоно
C++:
/*void taskCanRecv() {

if (getPid) { // Получить PID
getPid = 0;
sendPid(PID_INPUT);
PID_INPUT = 0;
}
if (CAN_MSGAVAIL == CAN.checkReceive()) { // проверка получения данных
CAN.readMsgBuf(&len, buf); // чтение данных, len: длина данных, buf: данные
Serial.println("\r\n------------------------------------------------------------------");
Serial.print("Get Data from ID: 0x");
Serial.println(CAN.getCanId(), HEX);
for (int i = 0; i < len; i++) { // Вывод данных
Serial.print("0x");
Serial.print(buf[i], HEX);
Serial.print("\t");
}
Serial.println();
}
}
Собственно, я с вами эти пропавшие квадратные скобки в строке 15 и хотел обсудить... а это оказывается потому что вы код неверно вставили.
Вставляйте код правильно, чтобы не тратить время на обсуждение ошибок, которых нет
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
на данный момент получаю это:
Get Data from ID: 0x7E8
0x4 0x43 0x1 0x1 0x13 0x0 0x0 0x0 Количество ошибок:
1
Коды ошибок:
?
в моём скетче отображается 113

да, это
Только на будущее вставляйте код - как код, а то читать неудобно и комментировать слоно
C++:
/*void taskCanRecv() {

if (getPid) { // Получить PID
getPid = 0;
sendPid(PID_INPUT);
PID_INPUT = 0;
}
if (CAN_MSGAVAIL == CAN.checkReceive()) { // проверка получения данных
CAN.readMsgBuf(&len, buf); // чтение данных, len: длина данных, buf: данные
Serial.println("\r\n------------------------------------------------------------------");
Serial.print("Get Data from ID: 0x");
Serial.println(CAN.getCanId(), HEX);
for (int i = 0; i < len; i++) { // Вывод данных
Serial.print("0x");
Serial.print(buf[i], HEX);
Serial.print("\t");
}
Serial.println();
}
}
Собственно, я с вами эти пропавшие квадратные скобки в строке 15 и хотел обсудить... а это оказывается потому что вы код неверно вставили.
Вставляйте код правильно, чтобы не тратить время на обсуждение ошибок, которых нет

Да я и вставлял как есть, но почему то сайт убирает квадратные скобки
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Да я и вставлял как есть, но почему то сайт убирает квадратные скобки
потому что вы вставляете код просто как текст.
Обратите внимание, как выглядит код в моем сообщении #26 - в отдельном блоке, с номерами строки и с прокруткой. И скобки квадратные на месте
Вставляйте код правильно, для этого есть специальная кнопка
 

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
C++:
#include <SPI.h>
#include "mcp_can.h"                                   // Подключаем библиотеку для работы с  CAN
#include "UTFT.h"                                      // Подключаем библиотеку для работы с дисплеем
#include "TouchScreen.h"                               // Подключаем библиотеку для работы с TouchScreen
// подключаем шрифты
extern uint8_t SmallFont[];                            // Устанавливаем маленький шрифт
extern uint8_t BigFont[];                              // Устанавливаем большой шрифт
extern uint8_t SevenSegNumFont[];                      // Устанавливаем семисегментный шрифт

#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE                 // Проверка соответствия связи МК с портами
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif

//  Определяем выводы используемые для управления дисплеем 2.8" TFT 320x240 UNO:
const uint8_t RS   = 8;                                // MOSI
const uint8_t WR   = 7;                                // SCK
const uint8_t CS   = 6;                                // CS
const uint8_t RST  = 5;                                // RST
const uint8_t SER  = 4;                                // D/C
//  Определяем выводы используемые для чтения данных с TouchScreen:
const uint8_t YP   = A0;                               // Вывод Y+ должен быть подключен к аналоговому входу
const uint8_t XM   = A1;                               // Вывод X- должен быть подключен к аналоговому входу
const uint8_t YM   = A2;                               // Вывод Y- должен быть подключен к аналоговому входу
const uint8_t XP   = A3;                               // Вывод X+ должен быть подключен к аналоговому входу
//  Определяем экстремумы для значений считываемых с аналоговых входов при определении точек нажатия на TouchScreen:
const int tsMinX   = 100;                              // соответствующий точке начала координат по оси X
const int tsMinY   = 120;                              // соответствующий точке начала координат по оси Y
const int tsMaxX   = 950;                              // соответствующий максимальной точке координат по оси X
const int tsMaxY   = 915;                              // соответствующий максимальной точке координат по оси Y
const int mipPress = 10;                               // соответствующий минимальной степени нажатия на TouchScreen
const int maxPress = 1000;                             // соответствующий максимальной степени нажатия на TouchScreen
//const uint8_t pen_radius = 3;                          // указываем размер точки, которая будет появляться при рисовании

const int SPI_CS_PIN = 9;                              // Определяем выводы, используемые для управления CAN Shild

//  Создаём объекты библиотек:
MCP_CAN CAN(SPI_CS_PIN);                               // Установка CS pin

UTFT    myGLCD(TFT01_24SP, RS, WR, CS, RST, SER);      // Создаём объект для работы с дисплеем
TouchScreen ts     = TouchScreen(XP, YP, XM, YM);      // Создаём объект для работы с TouchScreen

//  Определяем PIDs

#define PID_ENGIN_PRM       0x0C                       //
#define PID_VEHICLE_SPEED   0x0D                       //
#define PID_COOLANT_TEMP    0x05                       //

#define CAN_ID          0x7DF                      //
#define CAN_ID_2        0x7E0
unsigned char OTRej_3[] = {0x01, 0x03, 0x00, 0, 0, 0, 0, 0}; // Запрос текущих ошибок DTC
unsigned char OTRTR  [] = {0x30, 0, 0, 0, 0, 0, 0, 0};

void set_mask_filt() {

  // Установка маски (set mask, set both the mask to 0x7FC)

  CAN.init_Mask(0, 0, 0x7FC);  // Маска для стандартных сообщений
  CAN.init_Mask(1, 0, 0x7FC);  // Маска для расширенных сообщений

  // Установка фильтров для чтения сообщений ID 0x04 ~ 0x09 байт

  CAN.init_Filt(0, 0, 0x7E8);
  CAN.init_Filt(0, 0, 0x7E9);

  CAN.init_Filt(2, 0, 0x7E8);
  CAN.init_Filt(3, 0, 0x7E9);
  CAN.init_Filt(4, 0, 0x7E8);
  CAN.init_Filt(5, 0, 0x7E8);
}
void setup() {
  Serial.begin(115200); // Инициируем передачу данных в монитор последовательного порта на скорости 115200 бод
  myGLCD.InitLCD();     // Инициируем работу с TFT дисплеем
  while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
    Serial.println("CAN BUS Shield init fail");
    Serial.println(" Init CAN BUS Shield again");
    myGLCD.setFont  (BigFont);                // устанавливаем большой шрифт
    myGLCD.print("CAN BUS Shield init fail", CENTER, 100); // выводим текст в указанных координатах
    delay(100);
  }
  Serial.println("CAN BUS Shield init ok!");
  set_mask_filt();
  myGLCD.setFont  (BigFont);                 // устанавливаем большой шрифт
  myGLCD.print("CAN init ok!", CENTER, 100); // выводим текст в указанных координатах
  delay(2000);
  myGLCD.clrScr();                           // Чистим экран
  delay(100);

  myGLCD.setColor(VGA_WHITE);         // Указываем белый цвет
  myGLCD.drawLine(0,   0, 40,  40);   // Рисуем линию
  myGLCD.drawLine(40,   0, 0,  40);   // Рисуем линию
  myGLCD.setColor(VGA_YELLOW);        // Указываем жёлтый цвет
  myGLCD.fillRect(0,  40, 40,  80);   // Рисуем квадрат
  myGLCD.setColor(VGA_GREEN);         // Указываем зелёный цвет
  myGLCD.fillRect(0,  80, 40, 120);   // Рисуем квадрат
  myGLCD.setColor(VGA_RED);           // Указываем красный цвет
  myGLCD.fillRect(0, 120, 40, 160);   // Рисуем квадрат
  myGLCD.setColor(VGA_PURPLE);        // Указываем фиолетовый цвет
  myGLCD.fillRect(0, 160, 40, 200);   // Рисуем квадрат
  myGLCD.setColor(VGA_BLUE);          // Указываем синий цвет
  myGLCD.fillRect(0, 200, 40, 240);   // Рисуем квадрат
}

void loop() {
  //  Считываем показания с TouchScreen:
  TSPoint p = ts.getPoint();                           // Считываем координаты и интенсивность нажатия на TouchScreen в структуру p
  //  Возвращаем режим работы выводов:
  pinMode(XM, OUTPUT);                                 // Возвращаем режим работы вывода X- в значение «выход» для работы с дисплеем
  pinMode(YP, OUTPUT);                                 // Возвращаем режим работы вывода Y+ в значение «выход» для работы с дисплеем
  //  Если зафиксировано нажатие на TouchScreen, то ...
  if (p.z > mipPress && p.z < maxPress) {              // Если степень нажатия достаточна для фиксации координат TouchScreen
    p.x = map(p.x, tsMinX, tsMaxX, 0, 320);            // Преобразуем значение p.x от диапазона tsMinX...tsMaxX, к диапазону 0...320
    p.y = map(p.y, tsMinY, tsMaxY, 0, 240);            // Преобразуем значение p.y от диапазона tsMinY...tsMaxY, к диапазону 0...240
    if (p.x <= 40) {                                   // Если нажатие было в зоне выбора цветов, то
      if (p.y < 40 ) {                                 // Если нажатие было в зоне кнопки "очищение экрана", то
        myGLCD.clrScr();                               // Чистим экран дисплея
        myGLCD.setColor(VGA_WHITE);                    // Указываем цвет
        myGLCD.drawLine(0,   0, 40,  40);              // Рисуем линию
        myGLCD.drawLine(40,   0, 0,  40);              // Рисуем линию
        myGLCD.setColor(VGA_YELLOW);                   // Указываем цвет
        myGLCD.fillRect(0,  40, 40,  80);              // Рисуем квадрат
        myGLCD.setColor(VGA_GREEN);                    // Указываем цвет
        myGLCD.fillRect(0,  80, 40, 120);              // Рисуем квадрат
        myGLCD.setColor(VGA_RED);                      // Указываем цвет
        myGLCD.fillRect(0, 120, 40, 160);              // Рисуем квадрат
        myGLCD.setColor(VGA_PURPLE);                   // Указываем цвет
        myGLCD.fillRect(0, 160, 40, 200);              // Рисуем квадрат
        myGLCD.setColor(VGA_BLUE);                     // Указываем цвет
        myGLCD.fillRect(0, 200, 40, 240);              // Рисуем квадрат
      }
      else if (p.y > 80 && p.y <= 120 ) {               // Если нажатие было в зоне зелёного квадрата, то
        myGLCD.setColor(VGA_GREEN);                     // Устанавливаем цвет
        myGLCD.setFont  (BigFont);                      // устанавливаем большой шрифт
        myGLCD.print("Request DTC 3", 45, 100);         // выводим текст в указанных координатах
        CAN.sendMsgBuf(CAN_ID, 0, 8, OTRej_3);      // Запрос режима 03
      }
    }
  }
  TaskRecive03();
}
void TaskRecive03() {
  unsigned char len = 0;
  unsigned char buf[8];
  if (CAN_MSGAVAIL == CAN.checkReceive()) {
    CAN.readMsgBuf(&len, buf);
    if ( buf[0] == 0x02 &&
         buf[1] == 0x43 &&
         buf[2] == 0x00)
    {
      Serial.print("В автомобиле ошибок нет");
    }
    else if (buf[0] > 0x02 &&
             buf[1] == 0x43 &&
             buf[2] >= 0x01 <= 0x02)
    {

      Serial.print  (buf[3], HEX);
      Serial.println(buf[4], HEX);
      Serial.print  (buf[5], HEX);
      Serial.println(buf[6], HEX);
      Serial.println(buf[7], HEX);
    }
    else if ( buf[0] == 0x10 &&
              buf[2] == 0x43 &&
              buf[3] >= 0x03)
    {
      Serial.println("Количество ошибок:");
      Serial.println(buf[3], DEC);
      Serial.println("Коды ошибок:");
      Serial.print  (buf[4], HEX);
      Serial.println(buf[5], HEX);
      Serial.print  (buf[6], HEX);
      Serial.println(buf[7], HEX);
      CAN.sendMsgBuf(CAN_ID_2, 0, 8, OTRTR);  // Запрос RTR
    }
    else if ( buf[0] == 0x21)
    {
      Serial.println(buf[1], buf[2]);
      Serial.println(buf[3], buf[4]);
      Serial.println(buf[5], buf[6]);
      Serial.print(buf[7]);
    }
    else if ( buf[0] == 0x22)
    {
      Serial.println(buf[1]);
      Serial.println(buf[2], buf[3]);
      Serial.println(buf[4], buf[5]);
      Serial.println(buf[6], buf[7]);
    }
    else if ( buf[0] == 0x23)
    {
      Serial.println(buf[1], buf[2]);
      Serial.println(buf[3], buf[4]);
      Serial.println(buf[5], buf[6]);
      Serial.print(buf[7]);
    }
  }
}
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
0x4 0x43 0x1 0x1 0x13 0x0 0x0 0x0
Количество ошибок:1
Хороший пример. Давайте разберем
Во первых, отбросим первые три числа - они к ошибкам отношения не имеют.
Четвертое число - количество ошибок, там 0х1, что значит просто - 1 ошибка. И не важно, 0х1 там , 0х01 или просто 1.
Далее идут сами ошибки
0x13 0x0 0x0 0x0
Вот тут и надо искать ваши "00" "01" и так далее.И не в виде отдельных байт. а прямо в ошибках
Где? - да в коде 0х13 например.
Код 0х13 начинается битов "00"
Определить это просто - 0х13 в бинарном виде - это будет 00010011, первые два бита слева - "00"
Так что 0х13 - это ошибка типа P и с номером 19 (потому что 0х13 - 19 в десятичной системе)

Этот разбор - только пример. Как именно пакуются ошибки - надо смотреть в стандарте. Они могут занимать несколько байт. Но главное, что я хотел донести - что комбинации "00" "01" - не являются отдельными байтами, они запакованы в сами байты ошибок. Об этом однозначно говорит запись А7-А6 в заголовке вашей таблицы. "А7-А6" - означает "два старших бита первого байта ошибки"
 
Изменено:

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Вы чуток ошибаетесь. ошибки идут не 0х13, а 0х1+0х13

каждая ошибка это два байта

Хороший пример. Давайте разберем
Во первых, отбросим первые три числа - они к ошибкам отношения не имеют.
Четвертое число - количество ошибок, там 0х1, что значит просто - 1 ошибка. И не важно, 0х1 там , 0х01 или просто 1.
Далее идут сами ошибки
0x13 0x0 0x0 0x0
Вот тут и надо искать ваши "00" "01" и так далее.И не в виде отдельных байт. а прямо в ошибках
Где? - да в коде 0х13 например.
Код 0х13 начинается битов "00"
Определить это просто - 0х13 в бинарном виде - это будет 00010011, первые два бита слева - "00"
Так что 0х13 - это ошибка типа P и с номером 19 (потому что 0х13 - 19 в десятичной системе)

Этот разбор - только пример. Как именно пакуются ошибки - надо смотреть в стандарте. Они могут занимать несколько байт. Но главное, что я хотел донести - что комбинации "00" "01" - не являются отдельными байтами, они запакованы в сами байты ошибок. Об этом однозначно говорит запись А7-А6 в заголовке вашей таблицы. "А7-А6" - означает "два старших бита первого байта ошибки"

Не четвёртое число, а третье-количество ошибок

а далее как раз и начинаются коды

0х4 это количество полезных байт в сообщении, 0х43 -это положительный ответ на запрос режима 03, 0х1-количество ошибок и далее сами ошибки.
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Не четвёртое число, а третье-количество ошибок
Вы сами разберитесь, число ошибок у вас в третьем байте или в четвертом.
Я ориентировался на ваш код. Смотрите строка 168 и далее.
Вот у вас написано - байт с индексом 3 - число ошибок, а далее сами коды:
C++:
Serial.println("Количество ошибок:");
      Serial.println(buf[3], DEC);
      Serial.println("Коды ошибок:");
      Serial.print  (buf[4], HEX);
      Serial.println(buf[5], HEX);
      Serial.print  (buf[6], HEX);
      Serial.println(buf[7], HEX);
или вы не в курсе, что buf c индексом 3 - это четвертый байт? Счет идет с нуля

Но даже если вы ошиблись и число ошибок и правда в третьем байте, принцип остается тем же.
Разберем код ошибки 0х1 0х13,
Здесь опять надо смотреть не весь байт 0х1, а только на его первые два бита.
0х1 = 0b00000001, соответственно два старших бита "00". ошибка типа P

И не имеет никакого значения, печатаете ли вы 0х1 или 0х01 -результат будет одинаков
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,272
1,303
Москва
0x4 0x43 0x1 0x1 0x13 0x0 0x0 0x0
В двоичном виде:
0b0000 0100 0b0010 1011 0b0000 0001 0b0000 1101

А теперь смотрим табличку и 1-ый байт
0b0000 0100 - подчеркнуты два бита А7 и А6 , они 0 и 0
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
А теперь смотрим табличку и 1-ый байт
0b0000 0100 - подчеркнуты два бита А7 и А6 , они 0 и 0
ну да, вот и я о том же :) смотреть надо биты :)
Только теперь главный вопрос, в каком байте. Мне кажется ты не прав.
Ты смотришь самый первый байт сообщения, это не то, 0х4 - это число байт данных в пакете
Первые три или четыре байта - это заголовок, их смотреть не надо.

Но принцип именно такой.

Добавка - вот картинку нашел

Смотрим в сообщении ТС
0x4 0x43 0x1 0x1 0x13 0x0 0x0 0x0
4 - число байт
0х43 - Mode
0х1 - PID
И байты данных А и В = 0х1 0х13
В таблице написано А7-А6, то есть относится к этому байту А.
Поэтому правильно извлекать старшие биты из байта 0х1


И кстати тут никакого "числа ошибок". что ТС ищет толи в третьем то ли в четвертом байте - нет
 
Изменено:

Semmen74

✩✩✩✩✩✩✩
2 Ноя 2020
18
3
Извините конечно. Но в режиме 03 ни каких PID нет. И в режиме 07 и в режиме 02 тоже нет. 3 байт слева -количество ошибок. Проверено на практике
 

bort707

★★★★★★✩
21 Сен 2020
3,067
916
Но в режиме 03 ни каких PID нет. И в режиме 07 и в режиме 02 тоже нет.
Одно другому не противоречит. В разных режимах формат может быть разным.
3 байт слева -количество ошибок. Проверено на практике
Так все-таки третий? а в программе у вас - четвертый

Я как-то больше в теорию верю, чем вашей практике, уж извините.
Ваши вопросы и сообщения в этой ветке свидетельствуют о том, что вы формат сообщений КАН пока понимаете не полностью