Обмениваюсь между ПК и Ардуино УНО с помощью 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()) - такая же песня. Пожалуйста подскажите, кто может???
Попробуйте на ПК с терминала вручную данные отправлять, во всяком случае убедитесь, что причина не в передающей программе. И еще вот myservo1.write(servoAngle1); смущает, не она ли тормозит процесс?
Например вот так! Код (C++): int s = 2; gResult = WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL); и шлются данные не постоянно, а по команде - по нажатию кнопки!
В том что дело не в ПК, а в ардуино я убедился, когда ручную отправлял данные. Код myservo1.write(servoAngle1); убирал из скетча, та же песня! Похоже где-то недочет у меня с приемом передачи данных в скетче....
Я нашел, где именно подвисает. Это на стороне ПК при посылке данных Ардуино: Код (C++): gResult = WriteFile(hCom, &s, sizeof(s), &bytesWritten, NULL); Именно эта функция зависает от 0 до 10 секунд. Какие могут быть решения?
Функция именно подвисает или же отрабатывает, но данные отправляются не сразу. Могу ошибаться, но, если функция отрабатывает, а данные в Arduino приходят с задержкой, то проблема может быть связана с буферизацией вывода. Функция данные отправляет в буфер, а уже планировщик ввода/вывода принимает решение когда реально отправлять данные -- может сразу в порт отправить, а может чуть погодя. С какими параметрами создается файл? Здесь про буферизацию написано: https://msdn.microsoft.com/en-us/library/windows/desktop/cc644950(v=vs.85).aspx
Чтобы планировщик на несколько секунд затупил, нужно всю систему повесить задачей максимального приоритета. Не похоже на рассматриваемую ситуацию.
Дело не в загруженности системы, а немного в другом. В операционных системах (Windows начиная с NT, Linux и может ещё в каких) есть два режима работы -- пользовательский и режим суперпользователя. В пользовательском работают все приложения, а в режиме суперпользователя -- драйвера и системные службы. Что бы предать данные в драйвер, например, через вызов 'WriteFile', в пользовательском режиме производится системный вызов, который и осуществляет обмен данными между пользовательским приложением и драйвером. Всё было бы хорошо, если бы не одно "НО" -- переключение между пользовательским режимом и режимом суперпользователя удовольствие, скажем так, "дорогое". Поэтому разработчики ядра стараются эти переключения минимизировать -- либо перенести драйвер в режим пользователя, либо ввести буферизацию с планировщиком ввода/вывода, либо ещё как. Суть планировщика в том, что он не будет делать системный вызов (переключаться в режим суперпользователя и обратно) ради передачи каждого байта, а будет ждать пока объём данных достигнет определённого уровня или же пока не выйдет время ожидания следующих данных -- иначе малый объём данных может никогда не отправиться. Вот как-то так.... Надеюсь не очень наврал. PS: В Windows при создании файла буферизация включена по умолчанию.
Это я все знаю, дрова под винды писать приходилось. Планировщик отправит данные при первой же возможности. Буфера нужны для того, чтобы можно было сунуть драйверу сразу большую пачку данных. Если речь идет о паузе длительностью в несколько секунд, дело не в планировщике, нужно искать проблему где-то еще.
Может там антивирус какой перехватывает открытие файла и не отпускает пока не проверит процесс. И так каждый раз...
Вмешиваюсь в работу системы наверное я сам, я одновременно с writefile, использую другой поток с readfile. т..е. одновременно считываю данные из ком-порта и записываю туда же. Причем readfile работает в цикле while. Проблема была решена простым добавлением в цикл while функции Sleep(1). Не знаю даже решило ли это проблему навсегда или нет, но после добавления Sleep(1) отправка writefile данных в порт перестала зависать! Жду комментариев! )
Ну тогда все понятно. Ваша программа сама себя вешала вторым потоком. Копайте в сторону асинхронного чтения и обращайте внимание на загрузку процессора.