Ошибки при работе с терминалом на C#

Как спросить то, что не знаешь? В тупике, от не знания даже как оформить вопрос. Есть плата Ардуино, в неё залит чужой скетч. Сам Скетч arduino-psa-diag/arduino-psa-diag/arduino-psa-diag.ino at master · ludwig-v/arduino-psa-diag · GitHub
Есть написанная мной программа на C# для работы с этим скетчем, кототая работает как часы. Есть примерно 30% людей, которые жалуются что софт не работает. Я проверял на 3 ноутбуках и двух разных платах ардуино, ошибку воспроизвести не смог. Грешил на ктайские чипы CH. Но на оригинальной плате также глюк воспроизвёлся.
Сам скетч на управляющие команды должен вернуть либо "OK’ либо ‘7F0000’.
пример лога на не рабочем устройстве

>764:664
000000
1003
5003
222100
6221002200220122022203220422052206220722082209220A
222101
622101FF470150004C14FF0101800200
222103
622103000C9600004204641702
238D238F
222105
7F3E03

764:664 - это первая посланая команда мной.
000000 - это не верный ответ(скетч не умеет такое возвращать)
следующий ответы правдоподобны.
Порт я открываю так:

private void PortOpen()
{
    if (serialPort1.IsOpen)
    {
        serialPort1.Close();
        System.Threading.Thread.Sleep(2000);
    }
    serialPort1.Open();
    System.Threading.Thread.Sleep(2000);
    serialPort1.DiscardOutBuffer();
    serialPort1.DiscardInBuffer();
    System.Threading.Thread.Sleep(500);
}
 private void buttonIdent_Click(object sender, EventArgs e)
 {
     try
     {
         PortOpen();
         EcuIdent();
     }
     catch (TimeoutException ex)
     {
         MessageBox.Show(ex.Message, "Адаптер или ECU не ответил");
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message, "Проблемма обмена с портом");
     }
     serialPort1.Close();
     LogClose();
     LoadGridMain();
 }

У некоторых мусор в ответе, у других вылетает исключение Exception ex.
У всех при наборе команд в терминале проблем нет, соответственно где-то у меня не доделка в софте. Буферы как видно в коде я очишаю. Тайминги выставлены большие, так что адаптер может распологатся на другом конце света и порт пробрасоваться удалённо. Что я не знаю\забыл?

у тебя много чего не так может быть, но сишарп код на этом форуме (вставленный по правилам!!!) мне лично доставляет. Ардуино форум, который мы заслужили.

Посмотрел “чужой код” на гитхабе и буквально сразу наткнулся на ляп -

 if (millis() - lastCharMillis >= 1000 || rc == '\n' || pos >= MAX_DATA_LENGTH) {
      receiveDiagFrameData[pos] = '\0';

при таком условии переполнения буфера нуль-терминатор уже будет записан за пределами массива.
Так что я бы не удивлялся ничему с этим кодом

2 лайка

На самом деле там много ляпов, и очень сильное отклонение от ISO. но в определённых кругах хомячков, скетч пользуется спросом. Тут другой вопрос - где мой косяк. Накидайте пожалуйста говна на вентилятор, хоть что проверять.

Если вы подозреваете свой код (этим, кстати, вы очень отличаетесь от большинства “просителей” здесь, которые ищут ошибки где угодно, только не у себя… правильная привычка - жму руку)… так вот, если вы подозреваете свой код, я бы начал с того, что добавил бы в “тот скетч” печать полученной из порта строки - тогда вы сможете видеть, что именно послал ваш код С#

Вот тут загвозка, у меня работает, а те кто жалуются, - не хотят, не умеют, и т.д. Говорю - дай то что залил, или удалёнку, и т.д. - одни отмазки. Однако у вех есть один довод - они открывают терминал в arduinoIDE и ответ на туже команду - ‘OK’.

Подключают в комп все одинаковым способом?

неправильная кодировка ?

Не понимаю о чём вы. Можно как то “другим” способом подключить? Большинство пользователей - обычные автовладельцы и могут только собезьянничать.

В этом что то есть. Но все символы передаются в базе латиницы и равнозначны для всех кодировок.

Ну, например, штатное подключение через юсб ресетит порт.

Так а как по другому. Я же терминал открываю после того как винда уже провернёт все свои внутренние механизмы и приземлит порт в свои списки. Или штатный терминал c# работает на каком-то своём уровне?

Бес понятия как там у сишарп. На WebSerial я заколебался с этим ресетом.

char i[] = "\320\237\321\200\320\270\320\262\320\265\321\202"; // текст "Привет" в кодировке UTF-8.
char j[] = "\317\360\350\342\345\362"; // текст "Привет" в кодировке Windows-1251.
char k[] = "\217\340\250\242\245\342"; // текст "Привет" в кодировке CP-866.
char l[] = "\360\322\311\327\305\324"; // текст "Привет" в кодировке KOI-8R.
char m[] = "\277\340\330\322\325\342"; // текст "Привет" в кодировке ISO-8859-5.
char n[] = "Привет";                   // текст "Привет" в кодировке файла скетча.
void setup() {
Serial.begin(9600);         // Инициируем работу шины UART на скорости 9600 бит/сек.
Serial.println(i);          // Отправляем символ в монитор последовательного порта.
delay(1000);
Serial.println(j);          // Отправляем символ в монитор последовательного порта.
delay(1000);
Serial.println(k);          // Отправляем символ в монитор последовательного порта.
delay(1000);
Serial.println(l);          // Отправляем символ в монитор последовательного порта.
delay(1000);
Serial.println(m);          // Отправляем символ в монитор последовательного порта.
delay(1000);
Serial.println(n);          // Отправляем символ в монитор последовательного порта.
delay(1000);
}

void loop() {}

наверное это просто тычек пальцем в небо, но если совсем вариантов не будет, то пусть пользователь загрузит код, и если увидит то что не видите вы, то проблема в кодировке… фиг знает что там на стороне пользователя…

в виндовом драйвере serial есть ошибка с обработкой сигнала DTR которую микрософт так и не исправил, так что с высокой долей вероятности садман прав

так я и не понял о чём идёт речь? Это:

Попробовать другую терминальную программу.

Ещё , как варианты защиты от “непонятных” процессов - задержки после включения,
а так же установка подтягивающих резисторов (~ 20кОм) на
линии RX TX . Смысл резисторов в том, чтобы исключить незапланированный низкий уровень на шине(напр. при reset-e), который может быть принят за стартовый бит, и , начало приёма данных.