Последовательная связь очень медленная через некоторое время
Я работаю над узлом для блендера, чтобы управлять Arduino. Я заметил, что через некоторое время он работает очень медленно, поэтому я изолировал проблему. Это хорошо для поддержания 60 кадров в секунду, а затем примерно через 40 секунд (довольно точно) оно по какой-то причине падает до довольно точного 1 кадра в секунду.
Что может происходить?
import serial
import time
ser = serial.Serial('COM3', 115200)
c = 0
while True:
c+=1
print("ok ", c)
numIn = "100n"
ser.write(numIn.encode('ascii'))
time.sleep(1./60)
код Arduino:
// особая благодарность Нику Гэммону
const unsigned int MAX_INPUT = 50;
unsigned long delay_time = 300;
unsigned long last_toggle_time = 0;
int current_state = LOW;
void setup () {
Serial.begin (115200);
pinMode(12, OUTPUT);
}
void process_data (const char * data) {
Serial.println (data);
delay_time = atoi(data);
}
void processIncomingByte (const byte inByte) {
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte) {
case 'n': // конец текста
input_line [input_pos] = 0; // завершающий нулевой байт
process_data (input_line);
input_pos = 0;
break;
case 'r':
break;
default:
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
}
}
void loop() {
while (Serial.available () > 0) {
processIncomingByte (Serial.read ());
}
unsigned long m = millis();
if (m > last_toggle_time + delay_time) {
current_state = current_state == HIGH ? LOW : HIGH;
digitalWrite(12, current_state);
last_toggle_time = m;
}
}
@clankill3r, 👍0
Обсуждение1 ответ
Лучший ответ:
Если вы печатаете с Arduino на последовательный порт и не читаете его, буфер заполняется. Заставляя его идти с секундной задержкой. Поэтому убедитесь, что вы тоже читаете, когда отправляете данные.
По какой-то причине требуется короткий сон между сном и чтением. В противном случае он зависнет.
import serial
from time import sleep
ser = serial.Serial('COM3', 115200)
sleep(1)
c = 0
while True:
c+=1
print("ok ", c)
numIn = "100"
ser.write((numIn + '\r\n').encode())
sleep(1./120)
inp = ser.readline()
print(inp.decode("utf-8"))
sleep(1./120)
Теория, лежащая в основе этого ответа, весьма сомнительна, и если у вас есть обычный Arduino типа Uno или что-то с отдельным USB-последовательным преобразователем, это невозможно., @Chris Stratton
- Программирование Arduino с использованием Python, а не C/C ++
- Не удается связаться с ардуино с помощью python (Windows)
- Последовательная связь Arduino с Python: отправка массива
- Построение графика на Python с использованием Tkinter Canvas
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Построение графика данных датчика Arduino в реальном времени на Processing, MatLab или Python
- Обработка времени чтения в Python с помощью pySerial
- Как отправить целое число через pyserial с Python на Arduino и получить тот же результат?
Подсказка: отметьте «if (m > last_toggle_time + delay_time)» и что произойдет, когда millis() переносится как int?, @Mikael Patel
Я изменил его на unsigned long, и это все еще так., @clankill3r
Кроме того, проблема не в моргании, с этим все в порядке. Это последовательная связь, которая замедляется., @clankill3r
Что произойдет, если вы удалите Serial.print() из process_data()? Что ваш скрипт Python делает с последовательным вводом?, @Mikael Patel
Круто, если я уберу отпечаток, то проблема исчезнет. Однако в конечном итоге я хочу, чтобы python читал ввод. Теперь python зависает на
ser.readLine()
. Может новая тема для зависания?, @clankill3rТеперь нам нужно объяснение, а не сразу переходить к следующему вопросу :) В чем была проблема, на самом деле? Arduino печатает. Сценарий хоста (Python) не читается, а внутренние буферы USB/USART заполнены. А что происходит на стороне Arduino при заполнении выходного буфера Serial? Проверьте код - он с открытым исходным кодом :), @Mikael Patel
BW: Будьте хорошим пользователем stackexchange, напишите ответ и отметьте этот вопрос как отвеченный., @Mikael Patel
Я думаю, это происходит с секундной задержкой :), @clankill3r
@MikaelPatel «Последовательные» выходные данные, невостребованные хостом, потенциально могут быть причиной замедления только в случае платы Leonardo или чего-то еще, где USB реализован непосредственно в процессоре приложения, и даже там это немного неопределенно. Это **определенно не** случай для Uno или чего-то еще, где прикладной процессор имеет соединение UART с преобразователем USB, так как в этом случае данные UART передаются вслепую, независимо от того, может ли приемник их обрабатывать или нет. ., @Chris Stratton
Пожалуйста, укажите, какой Arduino вы используете. Респонденты не понимают, будут ли исходящие сообщения блокироваться, если вы заполните буфер., @Nick Gammon
Я просто хочу отметить, что вы используете
n
в качестве разделителя довольно необычным образом. В моем коде это были\n
и\r
(новая строка и возврат каретки). Когда вы выполняете «Serial.println (data)», вы добавляете еще два байта (println добавляет возврат каретки и перевод строки), поэтому вы печатаете 6 байтов на каждые четыре полученных вами. Меня совсем не удивляет, что что-то заполняется через 40 секунд, однако при скорости 115200 бод это не должно быть проблемой для 60 x 6 байт., @Nick GammonБитовый удар с циклом задержки перед отправкой следующего бита. Переменная цикла задержки должна быть протестирована, чтобы не быть слишком быстрой. Синхронизируйте его со скоростью передачи данных. Я разработал продукт под торговой маркой «Bit Banger», который представлял собой последовательный контроллер ввода-вывода до того, как вы родились в 1997 году. С другой стороны, может помочь то, что Моей первой настоящей работой была технология периферийных контроллеров для 16-битной компьютерной компании в начале 70-х. Intel только что выпустила 4-битный слайсер 4004. К 74 году они вышли с tge 8080. Гарри, @Harry Regician