Важная информация

User Tag List

Страница 4 из 5 ПерваяПервая 12345 ПоследняяПоследняя
Показано с 31 по 40 из 42

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

  1. #31
    Guru Аватар для SoftFelix
    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    2,741
    Спасибо Благодарностей отдано 
    49
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    25 сообщений
    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

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

  3. #32
    Member Аватар для SoftWareGuy
    Регистрация
    04.03.2018
    Адрес
    г. Киев, Украина
    Сообщений
    100
    Спасибо Благодарностей отдано 
    20
    Спасибо Благодарностей получено 
    48
    Поблагодарили
    43 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  4. #33
    Veteran Аватар для andrews
    Регистрация
    20.04.2006
    Адрес
    Санкт-Петербург
    Сообщений
    1,721
    Спасибо Благодарностей отдано 
    31
    Спасибо Благодарностей получено 
    18
    Поблагодарили
    15 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

  5. #34
    Guru Аватар для SoftFelix
    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    2,741
    Спасибо Благодарностей отдано 
    49
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    25 сообщений
    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

  6. #35
    Guru Аватар для SoftFelix
    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    2,741
    Спасибо Благодарностей отдано 
    49
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    25 сообщений
    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

  7. #36
    Member Аватар для SoftWareGuy
    Регистрация
    04.03.2018
    Адрес
    г. Киев, Украина
    Сообщений
    100
    Спасибо Благодарностей отдано 
    20
    Спасибо Благодарностей получено 
    48
    Поблагодарили
    43 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от 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; // возвращаем неудачу
    }

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

    SoftFelix (16.02.2020)

  9. #37
    Guru Аватар для SoftFelix
    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    2,741
    Спасибо Благодарностей отдано 
    49
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    25 сообщений
    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

  10. #38
    Member Аватар для SoftWareGuy
    Регистрация
    04.03.2018
    Адрес
    г. Киев, Украина
    Сообщений
    100
    Спасибо Благодарностей отдано 
    20
    Спасибо Благодарностей получено 
    48
    Поблагодарили
    43 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Точно - int же у нас 2х-байтовый? Из-за этого?
    Да, sizeof для массива дает не количество элементов в массиве, а весь размер - если тип будет int, то sizeof даст результат 3 (кол. элементов) * 2 (размер int) = 6 байт.

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

    SoftFelix (16.02.2020)

  12. #39
    Guru Аватар для SoftFelix
    Регистрация
    20.03.2007
    Адрес
    Санкт-Петербург
    Сообщений
    2,741
    Спасибо Благодарностей отдано 
    49
    Спасибо Благодарностей получено 
    30
    Поблагодарили
    25 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    byte syncSuccess1986 [] = {0x0D, 0x0A, 0x3E}; //для проверки ответа от 1986ВЕ91
    const int NumBytesToReceive = sizeof(syncSuccess1986); // количество байт которые ждем в ответ
    Для меня пока вот это сложней читается, чем более очевидное (конкретное указание размера массива). Словарный запас Си пока меленький.

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

    Цитата Сообщение от SoftWareGuy Посмотреть сообщение
    За if следует оператор либо блок операторов.
    А блок операторов (боле одного действия-команды?) мы выделяем фигурными скобками?
    Последний раз редактировалось SoftFelix; 16.02.2020 в 12:03.
    МГТФ - любимый провод!
    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

  13. #40
    Member Аватар для SoftWareGuy
    Регистрация
    04.03.2018
    Адрес
    г. Киев, Украина
    Сообщений
    100
    Спасибо Благодарностей отдано 
    20
    Спасибо Благодарностей получено 
    48
    Поблагодарили
    43 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    Для меня пока вот это сложней читается, чем более очевидное (конкретное указание размера массива).
    Можно делать так:

    Код:
      
    const int NumBytesToReceive = 3;
    byte syncSuccess1986 [NumBytesToReceive] = {0x0D, 0x0A, 0x3E};
    Если программист допишет в массив syncSuccess1986 еще пару элементов, то компилятор выдаст ошибку - т.к. размер задан NumBytesToReceive. Но проблема в том, что если программист уберет одно или более элементов из массива, например вот так:

    Код:
      
    const int NumBytesToReceive = 3;
    byte syncSuccess1986 [NumBytesToReceive] = {0x0D};
    то компилятор ничего не скажет и размер массива будет по прежнему 3, но два последних элемента будут пустыми - выходит что всегда нужно помнить менять значение NumBytesToReceive. Это ручная работа, правки нужно вносить не в одно а в два места (особенно если эти места разнесены по коду).

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

    Цитата Сообщение от SoftFelix Посмотреть сообщение
    А блок операторов (боле одного действия-команды?) мы выделяем фигурными скобками?
    Да. После них точка с запятой тоже не нужна.

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

    SoftFelix (16.02.2020)

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

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

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

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

Похожие темы

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

Ваши права

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