User Tag List

Страница 3 из 4 ПерваяПервая 1234 ПоследняяПоследняя
Показано с 21 по 30 из 42

Тема: Вопросы начинающего Ардуинщика...

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    SoftWareGuy
    Гость

    По умолчанию

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Почему именно const int?
    Считается хорошим тоном в программировании на Си++ делать константным всё, что не должно меняться по ходу выполнения программы. В общем то это не обязательно, просто в силу привычки так написал. Можно вынести отдельным дефайном, если хочется.

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    bool ???
    Определяется переменная isSuccess логического типа - в ней будем хранить результат всей этой операции - успешный ли был прием или нет.

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Вот это вообще не понял. Тут цикл на 5? У нас же 3 байта
    Смысл в том, что эти 3 байта могут быть еще не доступны в момент опроса Serial.available(). Если мк на том конце тупит и отправляет с задержками, то Там может быть 1 байт или 2, а может быть и 3 - если повезет. Чтобы исключить фактор "везения-невезения" (то есть рандом) нужно сделать несколько попыток считать данные.
    Мы все равно не считаем больше заданного предельного количества байт - там есть проверка на это. То есть случилось чудо и при первой же попытке вычитали все три байта, то выходим из цикла (строка с if (numBytesReceived == NumBytesToReceive) ).

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    А почему char ?
    Считывается один байт. Char как раз имеет разрядность 8 бит, можно конечно сохранять и в int, но это не имеет смысла - на восьмибитных контроллерах int равен 2 байтам, это лишнее место на стеке.

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Можно словами описать алгоритм этого кода или более подробно в комментариях?
    Все просто. Читаем данные до тех пор пока не прочитаем все 3 байта, но чтобы не висеть вечность, ставим максимальное количество попыток, причем с небольшой задержкой, так чтобы в самом плохом сценарии, когда данные шлют медленно, все же их получить с большей вероятностью...

    Этот пользователь поблагодарил SoftWareGuy за это полезное сообщение:

    SoftFelix(12.02.2020)

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2

    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    3,002
    Спасибо Благодарностей отдано 
    205
    Спасибо Благодарностей получено 
    113
    Поблагодарили
    97 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    SoftWareGuy, спасибо! Мне пока вот так нужно объяснять. И это я понимаю. Кстати, твой код нормально откомпилился в Ардуино IDE. Завтра на работе его попробую. А можно туда сразу добавить второй цикл синхронизации, как ПЦшном исходнике? В идеале на основе моего последнего кода.

    - - - Добавлено - - -

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    Считывается один байт. Char как раз имеет разрядность 8 бит, можно конечно сохранять и в int, но это не имеет смысла - на восьмибитных контроллерах int равен 2 байтам, это лишнее место на стеке.
    Тогда тут можно и byte использовать?
    МГТФ - любимый провод!
    KAY-1024(4096)/SL-4/TURBO v2010 + Nemo-FDC + Nemo-IDE (CF 4GB) + SMUC2 Rev.B RTC (HDD 1.6GB + DVD-ROM) + PROF-ROM + ZXMC2 + GENERAL SOUND 2MB + ZX-BUS_TEE + FDD 3.5' + FDD 5.25' + VGA&PAL

  4. #3
    Terabiterr
    Гость

    По умолчанию

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    А почему char ?
    По ардуино есть документация хорошая ну к ней приступать нужно только после прочтения основ языка С что бы вы начали ее более менее понимать. Нужно изучить не большой ряд основ языка С и пройти не много практики на простых задачах. Инфы полно в гугл. Запросы Уроки по С, как программировать на С и т.п...
    А дальше на справочник ардуино.
    https://doc.arduino.ua/ru/prog/

  5. #4

    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    3,002
    Спасибо Благодарностей отдано 
    205
    Спасибо Благодарностей получено 
    113
    Поблагодарили
    97 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    Исправленный код:
    Проверил на реальном железе - код полностью рабочий! А вот почему у меня не работало. Выявлено отладкой.

    Функция Serial.available() даже при вычитывании в переменную ( int n = Serial.available(); ) выдаёт всякую фигню о количестве байт в буфере. Очень редко там появляются правильные значения. Т.е. её можно использовать только как логический флаг true-false, сообщающий, что буфер не пуст (или пуст). И вот если буфер не пуст, то его надо вычитывать, что бы определить, сколько же там байт было. Твой алгоритм именно это и делает.

    Хотя описание функции такое:

    Serial.available()

    Функция получает количество байт(символов) доступных для чтения из последовательного интерфейса связи. Это те байты которые уже поступили и записаны в буфер последовательного порта. Буфер может хранить до 64 байт.
    МГТФ - любимый провод!
    KAY-1024(4096)/SL-4/TURBO v2010 + Nemo-FDC + Nemo-IDE (CF 4GB) + SMUC2 Rev.B RTC (HDD 1.6GB + DVD-ROM) + PROF-ROM + ZXMC2 + GENERAL SOUND 2MB + ZX-BUS_TEE + FDD 3.5' + FDD 5.25' + VGA&PAL

  6. #5
    SoftWareGuy
    Гость

    По умолчанию

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Функция Serial.available() даже при вычитывании в переменную ( int n = Serial.available(); ) выдаёт всякую фигню о количестве байт в буфере
    Это очень странно.
    В самом начале перед отправкой есть очистка входного буфера:
    Код:
    while (Serial.available()) Serial.read();
    Если в момент чтения available выдает всякую фигню, значит кто-то засирает входной буфер.

  7. #6

    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    3,002
    Спасибо Благодарностей отдано 
    205
    Спасибо Благодарностей получено 
    113
    Поблагодарили
    97 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    Если в момент чтения available выдает всякую фигню, значит кто-то засирает входной буфер.
    И только не МК на той стороне. С той стороны МК всегда отдаёт 3 байта (0d,0a,3e). Я это проверил в терминалке на ПЦ (подключил МК к ПЦ). Задал отправку 512 нулей в цикле на скорости 9600 и в другом окне (показывает, что принято от МК) через какое-то время (даже при незаконченном цикле 512-ти нулей) появляются три байта от МК - удачная синхронизация. И только ТРИ байта.

    Потом я вставил отладку в твой код - вывод принятых байтов на дисплей.

    Код:
    int receivedByte = Serial.read(); // можно сохранить это где нибудь чтобы проверить значение
    lcd.print(receivedByte);
    Первые три принятых байта были правильными и в нужной последовательности - 0d,0a,3e.

    Потом я увеличил количество ожидаемых байтов до 7-ми (ограничение дисплея и ленью возиться с переносом строки - всё делалось за 10 мин до конца рабочего дня).

    Код:
    NumBytesToReceive = 7; // количество байт которые ждем в ответ
    И вот тут получилось занятно - после первых трёх правильных байтов, в буфере есть ещё данные, которые доступны для чтения! Там вместилось (до конца строки на дисплее) ещё две повторяющиеся последовательности байтов. К сожалению, я забыл их переписать, теперь только в понедельник. Но МК их 200% не передаёт! Это либо железо Ардуины (очень вряд ли, т.к. я писал тест loop-back'а и там всё принимается нормально.

    Код:
    void ECHO_RUN() { //тест UART'a на loop-back (коротим Rx-Tx)
    
      Serial.end(); //для смены скорости сперва нужно закрыть!
      Serial.begin(9600); //настроили скорость UART на 115200
    
      lcd.clear();
      while (Serial.available()) Serial.read(); //вот это работает - очищает буфер UART'перед работой!!!
    
      lcd.setCursor(0, 0);
      lcd.print("Transmit=");
      lcd.setCursor(0, 1);
      lcd.print("Receive =");
    
      for (int i = 0; i <= 255; i++) {
        Serial.write(i);
        lcd.setCursor(9, 0);
        lcd.print(i);
    
        if (Serial.available()) { // Если в буфере есть данные
          incomingByte = Serial.read();
          lcd.setCursor(9, 1);
          lcd.print(incomingByte);
        }
        delay(200);
      }
    
      ECHO_TEST();
    }
    Ещё в своей версии синхронизации, я тоже вставил отладку - печать переменной n, возвращаемой функцией int n = Serial.available();...


    Код:
    void SYNC_1986() { //функция синхронизации с 1986ВЕ91
    
      Serial.end(); //для смены скорости сперва нужно закрыть!
      Serial.begin(9600); //настроили скорость UART на 9600
    
      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print("Try to Sync...");
      lcd.setCursor(5, 1); //подготовим позицию для печати результата ("Failed!" / "Succes!")
    
      while (Serial.available()) Serial.read(); //вот это работает - очищает буфер UART'перед работой!!!
    
      for (int i = 0; i < 512; i++) {
        Serial.write(0); //выдали в порт 512 байт 0х00
      }
      Serial.flush(); //ждём окончания передачи из буфера
    
      int n = Serial.available();
    
        lcd.setCursor(0, 1);
        lcd.print(n); //вывод количества байт в буфере.
    
      if (n == 3) {
        lcd.setCursor(5, 1);
        lcd.print("Succes!");
      } else {
        lcd.setCursor(5, 1);
        lcd.print("Failed!");
        delay(1000);
        menu = 3; //опять вернулись к файлу прошивки
        root = SD.open(name_folder + "/");
        SD_card(root);
        root.close();
      }
      }
    Так вот в этом случае у меня почти рандомно выводились значения 3,5,7,9,11 (dec). Эти наиболее часто. Очень редко были 17 и ещё выше.

    Т.е. всегда нечётное количество байт. Повторюсь: МК на той стороне всегда гарантированно отдаёт только 3 байта.
    МГТФ - любимый провод!
    KAY-1024(4096)/SL-4/TURBO v2010 + Nemo-FDC + Nemo-IDE (CF 4GB) + SMUC2 Rev.B RTC (HDD 1.6GB + DVD-ROM) + PROF-ROM + ZXMC2 + GENERAL SOUND 2MB + ZX-BUS_TEE + FDD 3.5' + FDD 5.25' + VGA&PAL

  8. #7

    Регистрация
    20.04.2006
    Адрес
    Санкт-Петербург
    Сообщений
    2,882
    Спасибо Благодарностей отдано 
    523
    Спасибо Благодарностей получено 
    253
    Поблагодарили
    227 сообщений
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Сразу предлагал автору отображать в окне консоли Arduino, получаемые от его mcu символы. А чтобы проконтролировать как действует функция Serial.available(), достаточно сделать "заворотку"(проще чем нуль-модем) на UNO board по последовательному порту и написать простенький тест. В том числе в этом тесте можно послать 64 и более символа и посмотреть, как она себя ведет. Могли ведь и китайцы в софте к плате UNO накосячить?
    Последний раз редактировалось andrews; 14.02.2020 в 20:27.

  9. #8

    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    3,002
    Спасибо Благодарностей отдано 
    205
    Спасибо Благодарностей получено 
    113
    Поблагодарили
    97 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Добавил проверку на правильность соответствия приёма трёх байт. Вот так заработает?

    Код:
    bool SYNC_1986_handshake()
    {
      while (Serial.available()) Serial.read();
    
      for (int i = 0; i < 512; i++) {
        Serial.write(0);
      }
      Serial.flush();
    
      const int NumBytesToReceive = 3; // количество байт которые ждем в ответ
      int syncSuccess1986 [3] = {0x0D, 0x0A, 0x3E}; //для проверки ответа от 1986ВЕ91
      int numBytesReceived = 0; // здесь храним количество принятых байт
      for (int istep = 0; istep < 5; ++istep) // делаем несколько попыток считать ответ
      {
        while (Serial.available() && numBytesReceived < NumBytesToReceive) // читаем все что уже есть во входном буфере
        {
          byte receivedByte = Serial.read(); // можно сохранить это где нибудь чтобы проверить значение
          if (receivedByte != syncSuccess1986[numBytesReceived]); //парсим принятый байт на правильное совпадение с ответом 1986
          {
            return false; //байт не совпал - выходим с ошибкой
          }
          ++numBytesReceived; // храним количество принятых байт
        }
    
        if (numBytesReceived == NumBytesToReceive) // получили все что нужно
        {
          return true; // возвращаем успех
        }
        delay(10);
      }
    
      return false; // возвращаем неудачу
    }
    МГТФ - любимый провод!
    KAY-1024(4096)/SL-4/TURBO v2010 + Nemo-FDC + Nemo-IDE (CF 4GB) + SMUC2 Rev.B RTC (HDD 1.6GB + DVD-ROM) + PROF-ROM + ZXMC2 + GENERAL SOUND 2MB + ZX-BUS_TEE + FDD 3.5' + FDD 5.25' + VGA&PAL

  10. #9
    SoftWareGuy
    Гость

    По умолчанию

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Вот так заработает?
    Есть одна небольшая ошибочка - лишняя точка с запятой в условии if (receivedByte != syncSuccess1986[numBytesReceived]). Это приведет к тому что в случае несовпадения байта выполнится пустая инструкция, а затем будет безусловный return false. Плюс кое-какие стилистические правки я добавил чтобы по возможности избавляться от "магических чисел" и дать возможность компилятору самому вычислять количество байт ответа основываясь на содержимом массива syncSuccess1986 - он обязательно должен быть типа byte иначе оператор sizeof вернет неправильное количество байт.

    Код:
    bool SYNC_1986_handshake()
    {
      while (Serial.available()) Serial.read();
    
      for (int i = 0; i < 512; i++) {
        Serial.write(0);
      }
      Serial.flush();
    
      byte syncSuccess1986 [] = {0x0D, 0x0A, 0x3E}; //для проверки ответа от 1986ВЕ91
      const int NumBytesToReceive = sizeof(syncSuccess1986); // количество байт которые ждем в ответ
    
      int numBytesReceived = 0; // здесь храним количество принятых байт
      for (int istep = 0; istep < 5; ++istep) // делаем несколько попыток считать ответ
      {
        while (Serial.available() && numBytesReceived < NumBytesToReceive) // читаем все что уже есть во входном буфере
        {
          byte receivedByte = Serial.read(); // можно сохранить это где нибудь чтобы проверить значение
          if (receivedByte != syncSuccess1986[numBytesReceived]) //парсим принятый байт на правильное совпадение с ответом 1986
          {
            return false; //байт не совпал - выходим с ошибкой
          }
          ++numBytesReceived; // храним количество принятых байт
        }
    
        if (numBytesReceived == NumBytesToReceive) // получили все что нужно
        {
          return true; // возвращаем успех
        }
        delay(10);
      }
    
      return false; // возвращаем неудачу
    }

    Этот пользователь поблагодарил SoftWareGuy за это полезное сообщение:

    SoftFelix(16.02.2020)

  11. #10

    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    3,002
    Спасибо Благодарностей отдано 
    205
    Спасибо Благодарностей получено 
    113
    Поблагодарили
    97 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    лишняя точка с запятой в условии
    Да, я с этим пока часто путаюсь... Получается, в конце if вообще не надо ставить точку с запятой?

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    он обязательно должен быть типа byte иначе оператор sizeof вернет неправильное количество байт.
    Точно - int же у нас 2х-байтовый? Из-за этого?

    Спасибо.
    МГТФ - любимый провод!
    KAY-1024(4096)/SL-4/TURBO v2010 + Nemo-FDC + Nemo-IDE (CF 4GB) + SMUC2 Rev.B RTC (HDD 1.6GB + DVD-ROM) + PROF-ROM + ZXMC2 + GENERAL SOUND 2MB + ZX-BUS_TEE + FDD 3.5' + FDD 5.25' + VGA&PAL

Страница 3 из 4 ПерваяПервая 1234 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Вопросы начинающего ATM'щика
    от Максагор в разделе Разный софт
    Ответов: 43
    Последнее: 19.09.2023, 13:52
  2. Вопросы начинающего спектрумопаятеля :)
    от The_Medved в разделе Несортированное железо
    Ответов: 44
    Последнее: 08.10.2011, 22:59
  3. Монитор начинающего Спектрумиста
    от Doktor в разделе Для начинающих
    Ответов: 5
    Последнее: 14.04.2011, 11:02
  4. Ответов: 5
    Последнее: 25.08.2008, 01:13

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •