Обмен данными по Uart между Arduino и Webasto

Тема в разделе "Проводная и беспроводная связь", создана пользователем Pavel8564, 2 сен 2019.

  1. Pavel8564

    Pavel8564 Нуб

    Всем привет, помогите разобраться пожалуйста...

    В ходе своих очередных своих экспериментов, решил изучить Uart, как происходит обмен данными, взаимосвязь между пакетами данных и т.д.., для этого подключил Arduino к Webasto через K-Lineадаптер (его собрал на интерфейсной микросхеме L9637D), адаптер подключил к Webasto, у Webasto есть диагностическая шина (W-bus), это однопроводная шина, которая полностью соответствуют стандартам K-Line шине.

    «K-Line - симплексный интерфейс, обмен по которому происходит, как правило, по принципу "ведущий-ведомый». Ведущее устройство посылает команды ведомому, а ведомое устройство на эти команды отвечает.»

    К сожалению, в программирование не силён, но очень интересно, помаленьку разбираюсь в этом. На просторах интернета нашел примерных скетч, немного удалил оттуда лишнее, разумеется основное оставил. Оставил минимальную часть для понимания простого алгоритма действия.

    Суть такова…
    Для инициализации начала обмена c ЭБУ Webasto необходимо подать следующую последовательность уровней на K-линию: LOW (300ms), HIGH (25ms), LOW (25 ms), HIGH (3025ms), за тем на скорости 10400 бод необходимо отправить 5 байт инициализации в HEX 81 51 F1 81 44 , в Arduino (Rx) приходит ответ 12 байт - 81 51 F1 81 44 83 F1 10 C1 E9 8F BD, из которых 5 байт это "эхо" запроса, а 7 байт ответ от самой Webasto, в ответе байт C1 означает положительный ответ (ОК).

    Ардуино и Вебасто.jpg
    Как я понял, судя по алгоритму кода в скетче, действия должны происходить следующим образом:

    запрос - 81 51 F1 81 44 (5 байт)
    ответ - 81 51 F1 81 44 83 F1 10 C1 E9 8F BD (12 байт из которых 5 байт 81 51 F1 81 44 Эхо)
    после этого, должно происходить считывание из буфера поступивших данных, а это, я так понимаю 12 байт, потом выполняется условие (если кол-во байт соответствует 12, и байт 8 соответствует C1),
    далее очистка буфера, и новый запрос 83 51 F1 2A 01 01 F1

    Но! нечего не работает, вернее происходит так:
    выполняется запрос - 81 51 F1 81 44
    выполняется ответ - 81 51 F1 81 44 83 F1 10 C1 E9 8F BD
    после выполнения ответа, дальше никаких действий не происходит, весь хронометраж событий просматриваю с помощью логического анализатора DsLogic

    Подскажите где ошибка, или как быть? очень интересно понять.

    Сам скетч:
    byte Init1[] = {0x81, 0x51, 0xF1, 0x81, 0x44}; // иницилизациии связи
    byte Request1[] = {0x83, 0x51, 0xF1, 0x2A, 0x01, 0x01, 0xF1}; //*1 запрос на динамические даннные (темп, напряжение и т.д..)
    byte Request2[] = {0x83, 0x51, 0xF1, 0x2A, 0x01, 0x02, 0xF2}; //*2 запрос на статические данные ( текущее сост, ошибки, и т.д..)
    byte Request3[] = {0x83, 0x51, 0xF1, 0x2A, 0x01, 0x05, 0xF5}; //*3 запрос на статические данные (версия прошивки, тип топлива, и т.д..)
    int n;
    String s;
    int pac =0;
    #define K_line_RX 0
    #define K_line_TX 1


    void setup()
    {
    pinMode(K_line_RX, INPUT);
    pinMode(K_line_TX, OUTPUT);
    digitalWrite(K_line_TX, LOW), delay(300);
    digitalWrite(K_line_TX, HIGH), delay(50);
    digitalWrite(K_line_TX, LOW), delay(25);
    digitalWrite(K_line_TX, HIGH), delay(3025);
    Serial.begin(10400); // ISO 14230-4 KWP 10.4 Kbaud
    Serial.flush();
    Serial.write(Init1, 5); // 81 51 F1 81 44 иницилизациия связи (K-line шины)
    delay(100);
    }

    void loop()
    {
    char byfer[30];
    n = Serial.available(); //Функция получает количество байт(символов)
    if (n > 0)
    {
    pac++; //int pac =0;
    for (int i=0;i<n;i++) byfer=Serial.read();
    String byte8 = String(byfer[8],HEX); // С1 (HEX) = 193 (DEC) // С1 успешный ответ
    if (n == 12 && byte8 == "C1") // ждем инициализхации шины
    {
    Serial.flush();
    Serial.write(Request1,7); //83 51 F1 2A 01 01 F1 запрос на динам данные
    delay(100);
    }

    }
    }
     
  2. b707

    b707 Гуру

    ошибка в строке, где Serial.read()
    Попробуйте задуматься, куда вы читаете принятые символы.
     
  3. Pavel8564

    Pavel8564 Нуб

    А как должно быть в строке где Serial.read()?
    Я не очень понимаю в программировании, был бы благодарен за подсказку...
     
  4. b707

    b707 Гуру

    Код (C++):
    for (int i=0;i<n;i++) byfer[i]=Serial.read();
    это не единственная проблема в коде - но самая грубая ошибка.
    Остальные ошибки - логические. Например - вы принимаете из Сериала неизвестное количество байт. а потом проверяете восьмой из них на совпадение. А если из сериал пришло менее восьми байт, что получится? - ерунда
     
  5. Pavel8564

    Pavel8564 Нуб

    Я мягко говоря, слабо понимаю в программировании, но есть желание и по немного учусь, пока понял всё что написано до char byfer[30]; с этим всё нормально, но вот далее пока не понимаю, был бы признателен, если бы кто объяснил...
     
  6. b707

    b707 Гуру

    Что именно обьяснить? -если вы не знаете синтаксиса Си - то лучше начать с чтения учебника.
    если речь о логике программы - то в принципе вы ее сами изложили в первом сообщении. Разве что код довольно корявый. часть строк из него можно выкинуть без ущерба для результата.
    После правки строки с Сериал-рид не заработало?
     
  7. issaom

    issaom Гик

    В программировании нельзя ничего ни кому объяснить, нужно доходить до всего самому. Работа с UART начинается примера зажигания светодиодика через терминал COM порта, потом зажигания и управления яркостью трехцветного светодиодика через терминал COM порта. Потом с отправок простых сообщений на компьютер. Понять до конца как работает тот или иной оператор можно только пойгравшись с ним индивидуально - особенно если вы вообще никогда не писали программы. Любой программист Вам скажет что анализ чужого кода занимает гораздо больше времени и усилий чем написание своего собственного. Но именно то, за что возьмется не каждый проффи в прогаммировании, почему-то всегда начинают делать новички - берут чужой код и начинают пытаться вносить в него изменения.
    Вам нужно прочитать:
    Раз https://doc.arduino.ua/ru/prog/Serial
    Два https://doc.arduino.ua/ru/prog/Array
    Три https://doc.arduino.ua/ru/prog/For
    Больше в Вашем коде ничего вроде и не используется - потратите на это 10-30 минут и разберетесь самостоятельно.
     
    Daniil и DetSimen нравится это.
  8. Pavel8564

    Pavel8564 Нуб

    20190914_104122.jpg
    Подскажите пожалуйста, как перевести считанный байт (ХХ) в физическую величину,
    считываю два байта Hex, один из которых информирует температуру - B2, а второй напряжение - C7

    Формула расчёта:

    #11 Температура охлаждающей жидкости XX N=E-40 [C]
    #21 Напряжение бортсети XX N=5.2 +E*0.05 [В]

    Примечание: в таблице применяются следующие условные обозначения:
    E - передаваемое значение
    N - физическая величина.
    Перед расчетом, двухбайтные значения должны быть приведены к целочисленному типу.
     
  9. b707

    b707 Гуру

    Павел, байт - это целое число от 0 до 255. От того записано ли оно в десятичном виде - например 64, или тоже самое в HEX - 0x40 -смысл совершенно не меняется. И ту и другую запись вы можете непосредственно подставлять в ваши формулы

    Или я не поянл вопроса
     
  10. Pavel8564

    Pavel8564 Нуб

    Исходя из формулы я понял необходимо выполнить - B2(HEX) = 178(DEC), значит из 178-40 = 138, а по факту этот байт означает 26 градусов. Вот я и не понял как считать...
     
  11. b707

    b707 Гуру

    да, по этой формуле все так. А почему получается неверно - это уже следующий вопрос. Либо формула не та, либо еркнда в данных.
     
  12. Pavel8564

    Pavel8564 Нуб

    Данные точные однозначно, датчик нагреваю данные меняются только этого байта, проверял несколько раз
     
  13. b707

    b707 Гуру

    Павел, эта фраза - полная ерунда :) Из того, что меняется только один байт, совершенно не следует, что другие не нужны.
    Если хотите обсуждать дальше - нужен полный код - как меряете температуры и как передаете...
     
    Последнее редактирование: 14 сен 2019 в 11:33
  14. Pavel8564

    Pavel8564 Нуб

    3.png

    Динамично ведут себя только байт 5 и байт 7 ну и байт контр. суммы соответственно,
    байт 5 реагирует только на изменение температуры
    байт 7 реагирует только на изменение напряжения питания
    Остальные байты неизменны

    К шине данных Webasto (W-bus тот же K-Line) подключен логический анализатор, подключен осциллограф, питание осуществляется с помощью лабораторного источника питания, дополнительно подключил мультиметр (хотя есть на лаб источнике, но пусть будет), так-же подключен диагностический комплекс Webasto с помощью которого все текущие данные видны на компе, температура и напряжение, также просматривается протокол связи, пишется Log, где все указывает на выше перечисленные байты, параллельно работает лог анализатор, поэтому инструмента хватает чтобы понять что только эти байты отвечают за температуру и напряжение.