英文:
Arduino takes 1-2 seconds to process serial input, how can I speed this up?
问题
I am almost entirely new to arduino/C++ so forgive me if this seems stupid. I am using a python program that detects faces in the camera frame and sends the x and y coordinate of the face to the arduino via serial (I have not implemented any code to deal with y yet). This works so long as I limit how often it sends the coordinates, however if they are sent too fast, the arduino seems to simply stop responding. My hypothesis as to why is that it is not able to read the data fast enough and it is lost before it can be processed. I know ultimately 1-2 seconds is not that big of a deal but unfortunately for me I'm a bit of a perfectionist and a 1-2 second delay really gets on my nerves.
As for the python script:
while True:
# Facial recognition stuff here
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
print(x, y)
if i == 30:
coord = f'{x} {y}'
arduinoData.write(coord.encode())
i = 0
i += 1
and the code running on my arduino:
#include <Servo.h>
Servo myservo;
int gLED = 2;
int rLED = 3;
String words[2];
void setup() {
Serial.begin(115200);
pinMode(rLED, OUTPUT);
pinMode(gLED, OUTPUT);
myservo.attach(8);
myservo.writeMicroseconds(1450);
}
void loop() {
while (Serial.available() > 0) {
String input = Serial.readStringUntil('\r');
int spaceIndex = input.indexOf(' ');
if (spaceIndex != -1) {
words[0] = input.substring(0, spaceIndex);
words[1] = input.substring(spaceIndex + 1);
} else {
words[0] = input;
words[1] = "";
}
int pos1 = words[0].toInt();
if (pos1 > 300) {
digitalWrite(gLED, HIGH);
digitalWrite(rLED, LOW);
myservo.writeMicroseconds(1400);
}
if (pos1 < 240) {
digitalWrite(rLED, HIGH);
digitalWrite(gLED, LOW);
myservo.writeMicroseconds(1510);
}
if (pos1 >= 240 && pos1 <= 300) {
digitalWrite(gLED, LOW);
digitalWrite(rLED, LOW);
myservo.writeMicroseconds(1450);
}
}
}
Does anyone have any tips on how I can speed up the response? Is it slow because of something stupid that I'm doing or is there maybe a different protocol that is faster? I briefly looked into i2c but I'm not sure if it's a better option.
英文:
I am almost entirely new to arduino/C++ so forgive me if this seems stupid. I am using a python program that detects faces in the camera frame and sends the x and y coordinate of the face to the arduino via serial (I have not implemented any code to deal with y yet). This works so long as I limit how often it sends the coordinates, however if they are sent too fast, the arduino seems to simply stop responding. My hypothesis as to why is that it is not able to read the data fast enough and it is lost before it can be processed. I know ultimately 1-2 seconds is not that big of a deal but unfortunately for me I'm a bit of a perfectionist and a 1-2 second delay really gets on my nerves.
As for the python script:
while True:
# Facial recognition stuff here
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
print(x, y)
if i == 30:
coord = f'{x} {y}'
arduinoData.write(coord.encode())
i = 0
i += 1
and the code running on my arduino:
#include <Servo.h>
Servo myservo;
int gLED = 2;
int rLED = 3;
String words[2];
void setup() {
Serial.begin(115200);
pinMode(rLED, OUTPUT);
pinMode(gLED, OUTPUT);
myservo.attach(8);
myservo.writeMicroseconds(1450);
}
void loop() {
while (Serial.available() > 0) {
String input = Serial.readStringUntil('\r');
int spaceIndex = input.indexOf(' ');
if (spaceIndex != -1) {
words[0] = input.substring(0, spaceIndex);
words[1] = input.substring(spaceIndex + 1);
} else {
words[0] = input;
words[1] = "";
}
int pos1 = words[0].toInt();
if (pos1 > 300) {
digitalWrite(gLED, HIGH);
digitalWrite(rLED, LOW);
myservo.writeMicroseconds(1400);
}
if (pos1 < 240) {
digitalWrite(rLED, HIGH);
digitalWrite(gLED, LOW);
myservo.writeMicroseconds(1510);
}
if (pos1 >= 240 && pos1 <= 300) {
digitalWrite(gLED, LOW);
digitalWrite(rLED, LOW);
myservo.writeMicroseconds(1450);
}
}
}
Does anyone have any tips on how I can speed up the response? Is it slow because of something stupid that I'm doing or is there maybe a different protocol that is faster? I briefly looked into i2c but I'm not sure if it's a better option.
答案1
得分: 2
@Roman is true. May be better to monitor the serial at regular interval and get data as they arrive:
unsigned long timer;
void loop() {
if (millis() - timer > 200) { // 每200毫秒执行一次
timer = millis();
String input = serialListen();
// 等等.....
}
}
String serialListen() {
String SerMsg = "";
while (Serial.available()) {
// 获取新字节:
char inChar = (char)Serial.read();
if (inChar == '\n') { //结束字符
return SerMsg;
} else {
// 添加到输入字符串中:
SerMsg += inChar;
}
}
}
英文:
@Roman is true. May be better to monitor the serial at regular interval and get data as they arrive:
unsigned long timer;
void loop() {
if (millis() - timer > 200) { //tick every 200mS
timer=millis();
String input = serialListen();
// etc.....
}
}
String serialListen() {
String SerMsg = "";
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == '\n') { //end char
return SerMsg;
} else {
// add it to the inputString:
SerMsg += inChar;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论