Arduino перезагружается при попытке управлять сервоприводом через последовательный порт

К плате Arduino подключен 1 сервопривод MG995R. Плата подключена к компьютеру с Ubuntu 20.04 через Serial port. Задача состоит в том, что бы в монитор порта можно было послать число от 0 до 180, после чего сервопривод должен повернуться на угол заданный этим числом и в качестве проверки плата должна вернуть посланное в порт значение при помощи Serial.println(value). Алгоритм работает от одного до 3 раз, далее если я правильно смог понять ситуацию плата перезагружается и Ubuntu видит ее уже по другому пути. Путь к порту по умолчанию в моем случае /dev/ttyUSB0, но после возникновения ошибки он меняется на /dev/ttyUSB1 и далее можно поменять порт в мониторе порта и снова послать 1 - 3 значение в порт. Раздельно управление сервоприводом и работа с портом работают как обычно, проблема возникает при совмещении их в одном скетче. Ниже приведен пример скетча, он универсален для платы Arduino Uno и Arduino Mega 2560. Прошивал им обе платы и возникала аналогичная ошибка. Ниже прикреплю пример кода с комментариями и саму ошибку.

#include <Servo.h>

Servo servo1;

void setup (){
  Serial.begin(9600);
  /*
  Данной строкой я задал timeout для порта. 
  Пробовал разные значения.
  На ошибку это не как не по влияло.
  */
  Serial.setTimeout(5);
  
  
  // Пробовал подключать разным портам поддерживающим pwm, на результат это не повлияло.
  servo1.attach(9);
}

void loop (){
  if(Serial.available() > 0){
    // Получаем значение из порта.
    // Валидация в данном примере не предусмотрена, правильность мы отслеживаем вручную.
    int a = Serial.parseInt();
    // Поворачиваем сервопривод на нужное значение.
    servo1.write(a);
    delay(500);
    // Возвращаем принятое значение в порт, для проверки правильности ввода.
    Serial.println(a);
  }
}

Ошибка возникающая после нескольких циклов работы алгоритма:

java.io.IOException: Ошибка ввода/вывода in writeArray
    at gnu.io.RXTXPort.writeArray(Native Method)
    at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1173)
    at processing.app.Serial.write(Serial.java:517)
    at processing.app.Serial.write(Serial.java:540)
    at processing.app.SerialMonitor.send(SerialMonitor.java:200)
    at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
    at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
    at java.desktop/javax.swing.JTextField.fireActionPerformed(JTextField.java:508)
    at java.desktop/javax.swing.JTextField.postActionEvent(JTextField.java:723)
    at java.desktop/javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:839)
    at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1810)
    at java.desktop/javax.swing.JComponent.processKeyBinding(JComponent.java:2900)
    at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:2948)
    at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2862)
    at java.desktop/java.awt.Component.processEvent(Component.java:6412)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
    at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1950)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:870)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1139)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1009)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:835)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4892)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2772)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

В каком направлении стоит искать пути решения и какие ошибки я допустил в скетче?


Ответы (1 шт):

Автор решения: eri

Питание на серве не хватает. Она перегружает линию питания uart контроллера и тот уходит в ресет.

Попробуйте подцепить внешнее питание на линию питания сервы, а ардуину питайте от USB - это надежней.

введите сюда описание изображения

Или используй более толстый кабель при питании от USB. И добавьте конденсаторы (см. ниже).

Ардуины у Вас с разъемом питания,если к нему подключаете блок питания, то проверьте достаточно ли в нем мощности (тока). Попробуйте поменять блок питания. И для защиты от скачков поставьте конденсатор.

введите сюда описание изображения

А ошибка это просто отвал USB-COM-порта.

→ Ссылка