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 шт):
Питание на серве не хватает. Она перегружает линию питания uart контроллера и тот уходит в ресет.
Попробуйте подцепить внешнее питание на линию питания сервы, а ардуину питайте от USB - это надежней.
Или используй более толстый кабель при питании от USB. И добавьте конденсаторы (см. ниже).
Ардуины у Вас с разъемом питания,если к нему подключаете блок питания, то проверьте достаточно ли в нем мощности (тока). Попробуйте поменять блок питания. И для защиты от скачков поставьте конденсатор.
А ошибка это просто отвал USB-COM-порта.

