Последовательное соединение между arduino и процессором не работает: Порт занят
Я пытаюсь подключить arduino и обработку через serial. Всякий раз, когда я запускаю скетч обработки, я получаю следующую ошибку при обработке:
RuntimeException: Error opening serial port COM26: Port busy
Could not run the sketch (Target VM failed to initialize).
Ниже приведен скетч arduino и код обработки, который я "позаимствовал" отсюда, чтобы попытаться программно найти правильный последовательный порт для подключения.
Arduino:
int var;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available()) {
var = Serial.read();
}
Serial.println(var);
delay(100);
}
Обработка:
import processing.serial.*;
Serial ser_port; // для последовательного порта
PFont fnt; // для шрифта
int num_ports;
boolean device_detected = false;
String[] port_list;
String detected_port = "";
void setup() {
size(400, 200); // size of application window
background(0); // black background
fnt = createFont("Arial", 16, true); // шрифт, отображаемый в окне
println(Serial.list());
// получить количество обнаруженных последовательных портов
num_ports = Serial.list().length;
// сохранить текущий список последовательных портов
port_list = new String[num_ports];
for (int i = 0; i < num_ports; i++) {
port_list[i] = Serial.list()[i];
}
}
void draw()
{
background(0);
// показать инструкции пользователю
textFont(fnt, 14);
text("1. Arduino or serial device must be unplugged.", 20, 30);
text(" (unplug device and restart this application if not)", 20, 50);
text("2. Plug the Arduino or serial device into a USB port.", 20, 80);
// посмотрите, было ли подключено Arduino или последовательное устройство
if ((Serial.list().length > num_ports) && !device_detected) {
device_detected = true;
// определить, к какому порту было подключено устройство
boolean str_match = false;
if (num_ports == 0) {
detected_port = Serial.list()[0];
} else {
// пройдите по текущему списку портов
for (int i = 0; i < Serial.list().length; i++) {
// пройдите по сохраненному списку портов
for (int j = 0; j < num_ports; j++) {
if (Serial.list()[i].equals(port_list[j])) {
break;
}
if (j == (num_ports - 1)) {
str_match = true;
detected_port = Serial.list()[i];
}
}
}
}
}
// вычислить и отобразить имя последовательного порта
if (device_detected) {
text("Device detected:", 20, 110);
textFont(fnt, 18);
text(detected_port, 20, 150);
ser_port = new Serial(this, detected_port, 9600);
}
}
Я новичок в этом деле, поэтому не уверен, что делаю не так. Буду признателен за любую помощь :)
1 ответ
Лучший ответ:
Я попробовал ваш скетч обработки, и он действительно обнаруживает и пытается подключиться к последовательному порту, но по какой-то причине терпит неудачу.
Обработка "кода" может включать блок try catch, который поможет вам диагностировать проблему. Используя этот модифицированный скетч, вы можете распечатать ошибки в окне консоли.
import processing.serial.*;
Serial ser_port; // для последовательного порта
PFont fnt; // для шрифта
int num_ports;
boolean device_detected = false;
String[] port_list;
String detected_port = "";
void setup() {
size(400, 200); // size of application window
background(0); // black background
fnt = createFont("Arial", 16, true); // шрифт, отображаемый в окне
println(Serial.list());
// получить количество обнаруженных последовательных портов
num_ports = Serial.list().length;
// сохранить текущий список последовательных портов
port_list = new String[num_ports];
for (int i = 0; i < num_ports; i++) {
port_list[i] = Serial.list()[i];
}
}
void draw()
{
background(0);
// показать инструкции пользователю
textFont(fnt, 14);
text("1. Arduino or serial device must be unplugged.", 20, 30);
text(" (unplug device and restart this application if not)", 20, 50);
text("2. Plug the Arduino or serial device into a USB port.", 20, 80);
// посмотрите, было ли подключено Arduino или последовательное устройство
if ((Serial.list().length > num_ports) && !device_detected) {
device_detected = true;
// определить, к какому порту было подключено устройство
boolean str_match = false;
if (num_ports == 0) {
detected_port = Serial.list()[0];
} else {
// пройдите по текущему списку портов
for (int i = 0; i < Serial.list().length; i++) {
// пройдите по сохраненному списку портов
for (int j = 0; j < num_ports; j++) {
if (Serial.list()[i].equals(port_list[j])) {
break;
}
if (j == (num_ports - 1)) {
str_match = true;
detected_port = Serial.list()[i];
}
}
}
}
}
else{
text("else", 20, 110);
}
// вычислить и отобразить имя последовательного порта
if (device_detected) {
text("Device detected:", 20, 110);
textFont(fnt, 18);
text(detected_port, 20, 150);
try{
ser_port = new Serial(this, detected_port, 9600);
}
catch(Exception e){
// Выведите подробную информацию об ошибке на консоль.
System.err.println(e);
e.printStackTrace();
}
}
else{
text("Device NOT detected:", 20, 140);
}
}
Это ошибки, которые я получаю на своем компьютере, используя Arduino Uno.
at processing.serial.Serial.<init>(Unknown Source)
at processing.serial.Serial.<init>(Unknown Source)
at sketch_211210a.draw(sketch_211210a.java:85)
at processing.core.PApplet.handleDraw(PApplet.java:2475)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)
java.lang.RuntimeException: Error opening serial port /dev/tty.wchusbserial620: Port busy
java.lang.RuntimeException: Error opening serial port /dev/tty.wchusbserial620: Port busy
Другая проблема связана с этой частью кода: if (device_detected)
. Функция draw()
похожа на функцию Arduino loop()
в том смысле, что она продолжает зацикливаться на коде. Он неоднократно пытается установить новое последовательное соединение с тем же портом, что МОЖЕТ объяснить, почему сообщение об ошибке Port busy
повторяется в сообщениях об ошибках консоли.
При использовании Processing IDE 3.5.3 в нижней части окна консоли есть вкладка errors. Я получаю там 2 ошибки, которые, похоже, не связаны с проблемой подключения порта.
Если вы установите библиотеку controlP5 в среду IDE обработки, вы можете использовать этот скетч тестирования портов, чтобы увидеть изменение идентификатора порта каждый раз, когда вы создаете с ним новое соединение. Я подозреваю, что ваш скетч может подключиться к Arduino в первый раз через функцию
draw ()
, а затем он продолжает пытаться подключиться к тому же порту, который занят.
// Тестер подключения последовательных портов. Обработка версии 3.5.3.
// Для получения списка всех доступных методов контроллера
// use: "ControlP5.printPublicMethodsFor(ScrollableList.class);"
// вывести на консоль весь список из 165 функций.
import controlP5.*;
import java.util.*;
import processing.serial.*;
ControlP5 cp5;
Serial myPort;
Textlabel outputWindowLine1, outputWindowLine2;
String portName;
void setup(){
size(500, 431);
// Используйте шрифт больше, чем по умолчанию "6px".
ControlFont font = new ControlFont(createFont("Verdana", 14));
// ALL CAPS - это шрифт по умолчанию для элемента управления. Почему?
Label.setUpperCaseDefault(false);
// Настройка списка прокрутки controlP5.
cp5 = new ControlP5(this);
cp5.addScrollableList("dropdown")
.setPosition(0, 50)
.setSize(500, 400)
.setBarHeight(50)
.setItemHeight(30)
.setFont(font)
.addItems(GetSerialPortList())
.setType(ScrollableList.LIST)
.setLabel("--- Click on a port name to try and connect to it ---")
;
outputWindowLine1 = cp5.addTextlabel("outputWindowLine1Label")
.setText("The list of port names is \"scrollable\".")
.setPosition(0, 0)
.setColorValue(0)
.setFont(font)
;
outputWindowLine2 = cp5.addTextlabel("outputWindowLine2Label")
.setText("Press any character on the keyboard to reload the list.")
.setPosition(0, 25)
.setColorValue(0)
.setFont(font)
;
}
void draw(){
background(255);
}
// Пользователь выбирает выпадающий элемент. Работает как JavaScript onChange()
// событие, за исключением того, что вы можете нажать на один и тот же элемент несколько раз, это
// код будет выполняться снова при каждом "щелчке" мыши по одному и тому же элементу.
void dropdown(int n){
// Создайте последовательное соединение и отправьте несколько
// chars к "USB to Serial Converter".
try{
// Получить имя порта.
portName = Serial.list()[n];
// Если вы этого не сделаете, вы не сможете снова подключиться к тому же порту.
// Повторное подключение к тому же порту дает вам новый "myPort ID" и может
// потратьте несколько секунд.
if(myPort != null){
myPort.clear();
myPort.stop();
}
// Создайте соединение с последовательным портом.
myPort = new Serial(this, portName, 9600);
// Сообщение пользователя.
outputWindowLine1.setText("Connected to portName: " + portName);
outputWindowLine2.setText("myPort = " + myPort);
}
catch(Exception e){
// Сообщение пользователя.
outputWindowLine1.setText("Error connecting to portName: " + portName);
outputWindowLine2.setText("");
// Выведите подробную информацию об ошибке на консоль.
System.err.println(e);
e.printStackTrace();
}
}
// Обновите выпадающий список имен последовательных портов.
void keyPressed(){
cp5.get(ScrollableList.class, "dropdown").setItems(GetSerialPortList());
outputWindowLine1.setText("Serial port list refreshed!");
outputWindowLine2.setText("");
}
// Получить список имен последовательных портов.
List GetSerialPortList(){
List serialPortList = Arrays.asList(Serial.list());
return serialPortList;
}
большое вам спасибо за ваш подробный ответ. Завтра я найду время, чтобы просмотреть его и переварить. И я буду публиковать здесь еще раз. Хорошего вечера., @Zhelyazko Grudov
Я решил сделать новый пост, так как ошибка кажется более простой/чем-то еще, и мне кажется, что было бы больше вреда, чем пользы, чтобы попытаться отредактировать этот пост., @Zhelyazko Grudov
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- В чем разница между Serial.write и Serial.print? И когда они используются?
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Программы построения последовательных данных
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Очистить существующий массив при получении новой последовательной команды
Вы проверяли вручную, действительно ли COM26 является COM-портом вашего Arduino? Работает ли связь с последовательным монитором?, @chrisl
Вероятно, вам следует установить обнаруженный порт, когда он будет найден, а не делать это после цикла, если ничего другого, и я бы рекомендовал получать последовательный список только один раз перед циклом, а не три раза. Это может и не решить проблему, но она, безусловно, более детерминирована., @Dave Newton
Порт, который он находит, является правильным. Однако мне так и не удалось наладить связь. Он говорит, что порт занят. Я использую Arduino nano каждый раз. @DaveNewton Вы говорите, что я должен установить последовательный порт сразу после его обнаружения, а не ждать, чтобы сделать это в функции if device detected? Что касается 2-го пункта, я не уверен, что код будет работать, если я проверю только один раз, так как я не смогу программно найти com-порт, на котором находится Arduino, если я проверю только один раз., @Zhelyazko Grudov
И можете ли вы подключиться к этому порту с помощью последовательного монитора? Есть ли какая-то другая открытая программа, которая использует этот порт?, @chrisl
Я попробовал простое приложение, где вручную установил порт. Обработка не дает мне никаких ошибок и должна писать на Arduino. И если я попытаюсь открыть последовательный монитор, пока приложение работает, оно скажет, что порт занят. Однако переменная в скетче Arduino не обновляется., @Zhelyazko Grudov
Вопрос означал, можете ли вы подключиться к Arduino с помощью чего-либо еще *not* во время работы программы, например, работает ли она на *all*. Моя точка зрения на обнаружение заключается в том, что как только в цикле появляется не совпадающий последовательный порт,вы можете прекратить проверку—вы знаете индекс недавно подключенного последовательного порта устройства., @Dave Newton
IDE подключается к нему как обычно. Обработка работает не так, как ожидалось. Не знаете, с чем еще попробовать? Re: обнаружение - понятно, попробую упростить код., @Zhelyazko Grudov