Синхронизация ПК и Ардуино

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Mihay, 4 апр 2016.

  1. Mihay

    Mihay Гик

    Обмениваюсь между ПК и Ардуино УНО с помощью Com-порта. Возникла проблема с приходом данных от ПК к Ардуино. В 50% случаях команды (данные) с ПК приходят в Ардуино с задержкой 5-10 сек. Но в 50% случаях задержек с теми же данными нет. Подскажите, может я неправильно организовал прием данных на Ардуино. Вот кусок кода;
    Код (C++):
    void loop()
    {
      if(Serial.available()) // слушаю порт
      {
        int s = Serial.read();  // тут я понимаю иногда и происходят задержки
        if (s==3)
        {
          analogWrite(INDICATOR, 255);
        }
        if (s==4)
        {
          analogWrite(INDICATOR, 0);
        }
        if (s==1)
        {
          Pr = true;
          prev_val0 = 0;
        }
        if (s==2)
        {
          Pr = false;
          servoAngle1 = servoAngle1 - 10;
          servoAngle1 = constrain(servoAngle1, 0, limAngle1);
          myservo1.write(servoAngle1);
        }
      }
     
      if (Pr == true)  
      {
         val0 = analogRead(SENSOR_PIN0);  // возможно задержки из-за того что пока не завершиться все чтение аналогового сигнала
         if (abs(val0-prev_val0)>2)
         {
            Serial.println(val0);
            val0 = constrain(val0, 0, 1023);
            servoAngle1 = map(val0, 0, 1023, 0, limAngle1);
            servoAngle1 = constrain(servoAngle1, 0, limAngle1);
            myservo1.write(servoAngle1);
         }
         prev_val0 = val0;
      }

    }
    Менял if(Serial.available()) на while(Serial.available()) - такая же песня.

    Пожалуйста подскажите, кто может???
     
    Последнее редактирование: 4 апр 2016
  2. Megakoteyka

    Megakoteyka Оракул Модератор

    А с ПК каким образом данные отправляются?
     
  3. ostrov

    ostrov Гуру

    Попробуйте на ПК с терминала вручную данные отправлять, во всяком случае убедитесь, что причина не в передающей программе. И еще вот myservo1.write(servoAngle1); смущает, не она ли тормозит процесс?
     
  4. Mihay

    Mihay Гик

    Например вот так!
    Код (C++):
       int s = 2;
       gResult = WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL);
     
    и шлются данные не постоянно, а по команде - по нажатию кнопки!
     
  5. Mihay

    Mihay Гик

    В том что дело не в ПК, а в ардуино я убедился, когда ручную отправлял данные. Код myservo1.write(servoAngle1); убирал из скетча, та же песня! Похоже где-то недочет у меня с приемом передачи данных в скетче....
     
  6. ostrov

    ostrov Гуру

    Вы используете метод Serial, может он слегка громоздкий, но не должен тупить по нескольку секунд.
     
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Тупить тут ничего не должно.
    Покажите код полностью.
     
  8. Mihay

    Mihay Гик

    Я нашел, где именно подвисает. Это на стороне ПК при посылке данных Ардуино:
    Код (C++):
    gResult = WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL);
    Именно эта функция зависает от 0 до 10 секунд.

    Какие могут быть решения?
     
  9. ostrov

    ostrov Гуру

    Попробуйте флешку другую для начала.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    Чему равно bytesWritten после отправки?
    Покажите инициализацию порта на всякий случай.
     
  11. AlexU

    AlexU Гуру

    Функция именно подвисает или же отрабатывает, но данные отправляются не сразу. Могу ошибаться, но, если функция отрабатывает, а данные в Arduino приходят с задержкой, то проблема может быть связана с буферизацией вывода. Функция данные отправляет в буфер, а уже планировщик ввода/вывода принимает решение когда реально отправлять данные -- может сразу в порт отправить, а может чуть погодя. С какими параметрами создается файл?
    Здесь про буферизацию написано: https://msdn.microsoft.com/en-us/library/windows/desktop/cc644950(v=vs.85).aspx
     
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Чтобы планировщик на несколько секунд затупил, нужно всю систему повесить задачей максимального приоритета. Не похоже на рассматриваемую ситуацию.
     
  13. AlexU

    AlexU Гуру

    Дело не в загруженности системы, а немного в другом. В операционных системах (Windows начиная с NT, Linux и может ещё в каких) есть два режима работы -- пользовательский и режим суперпользователя. В пользовательском работают все приложения, а в режиме суперпользователя -- драйвера и системные службы. Что бы предать данные в драйвер, например, через вызов 'WriteFile', в пользовательском режиме производится системный вызов, который и осуществляет обмен данными между пользовательским приложением и драйвером. Всё было бы хорошо, если бы не одно "НО" -- переключение между пользовательским режимом и режимом суперпользователя удовольствие, скажем так, "дорогое". Поэтому разработчики ядра стараются эти переключения минимизировать -- либо перенести драйвер в режим пользователя, либо ввести буферизацию с планировщиком ввода/вывода, либо ещё как. Суть планировщика в том, что он не будет делать системный вызов (переключаться в режим суперпользователя и обратно) ради передачи каждого байта, а будет ждать пока объём данных достигнет определённого уровня или же пока не выйдет время ожидания следующих данных -- иначе малый объём данных может никогда не отправиться. Вот как-то так....
    Надеюсь не очень наврал.

    PS: В Windows при создании файла буферизация включена по умолчанию.
     
  14. Megakoteyka

    Megakoteyka Оракул Модератор

    Это я все знаю, дрова под винды писать приходилось.
    Планировщик отправит данные при первой же возможности. Буфера нужны для того, чтобы можно было сунуть драйверу сразу большую пачку данных.
    Если речь идет о паузе длительностью в несколько секунд, дело не в планировщике, нужно искать проблему где-то еще.
     
  15. Unixon

    Unixon Оракул Модератор

    Может там антивирус какой перехватывает открытие файла и не отпускает пока не проверит процесс. И так каждый раз...
     
  16. Megakoteyka

    Megakoteyka Оракул Модератор

    Тогда по идее должна тормозить только первая посылка.
     
  17. Unixon

    Unixon Оракул Модератор

    Наверное. По косвенным признакам что-то постоянно вмешивается в нормальную работу системы.
     
  18. Mihay

    Mihay Гик

    Вмешиваюсь в работу системы наверное я сам, я одновременно с writefile, использую другой поток с readfile. т..е. одновременно считываю данные из ком-порта и записываю туда же. Причем readfile работает в цикле while. Проблема была решена простым добавлением в цикл while функции Sleep(1). Не знаю даже решило ли это проблему навсегда или нет, но после добавления Sleep(1) отправка writefile данных в порт перестала зависать!
    Жду комментариев! :)) ;)
     
  19. Megakoteyka

    Megakoteyka Оракул Модератор

    Ну тогда все понятно. Ваша программа сама себя вешала вторым потоком.
    Копайте в сторону асинхронного чтения и обращайте внимание на загрузку процессора.