Улучшение цикла перемещения мыши для оптимизации скорости.
Код:
#include <Mouse.h>
#include <hiduniversal.h>
#include "hidmouserptparser.h"
#include <USBController.h>
USBController controller;
USB Usb;
HIDUniversal Hid(&Usb);
HIDMouseReportParser Mou(nullptr);
String x;
String y;
boolean isX;
int recv;
void setup() {
Mouse.begin();
Usb.Init();
delay(200);
if (!Hid.SetReportParser(0, &Mou))
ErrorMessage<uint8_t > (PSTR("SetReportParser"), 1);
}
void loop() {
Usb.Task();
recv = controller.read();
if ((recv-48)==29){ // получение = M
// , : -4
///н: -38
x="";
y="";
isX = true;
while (true){
recv = controller.read();
if (recv!=0 && recv!=2){ // отфильтровываем 0 и 2
if ((recv-48)==-38){ // -38 — разрыв строки
break;
}
else if ((recv-48)==-4){ // переключаемся на значение y после запятой
isX = false;
continue;
}
if (isX){
x+=String(recv-48);
}
else{
y+=String(recv-48);
}
}
}
Mouse.move(x.toInt(),y.toInt());
}
}
void onButtonDown(uint16_t buttonId) {
Mouse.press(buttonId);
}
void onButtonUp(uint16_t buttonId) {
Mouse.release(buttonId);
}
void onMouseMove(int8_t xMovement, int8_t yMovement, int8_t scrollValue) {
Mouse.move(xMovement, yMovement, scrollValue);
}
Я использую Arduino Leonardo с USB-хостом. Моя цель состоит в том, чтобы переместить курсор в определенное место на основе считанных данных. Формат считанных данных: «MX,Y». и разрыв строки.
В основном цикле
- Я прочитал данные и вычел 48, потому что это настоящее число.
- Затем я проверяю, является ли первый символ М, потому что именно здесь начинается начало моих данных.
- Затем я отфильтровываю 0 и 2, потому что эти значения для меня бесполезны и появляются случайным образом.
- Я добавляю целочисленные значения в виде строк к x, а затем переключаюсь на y после появления запятой.
- Затем я преобразую значения
string
вint
иmouse.move
.
Проблема в том, что движение мыши медленное и нервное, и я думаю, это потому, что методы toInt
и String()
замедляют его. Как я могу улучшить свой алгоритм?
@Jake Jin, 👍2
1 ответ
Лучший ответ:
Это:
while (true){ recv = controller.read(); // ... }
является циклом блокировки. Это означает, что при выполнении этой части
код, Arduino зависает на неопределенное время и может
больше ничего не делай. В частности, он не может запускать Usb.Task()
, что может
мы будем причиной вашего нервного поведения.
Я бы рекомендовал читать входящие данные неблокирующим способом: каждый раз, когда нужно прочитать байт, прочитайте его и двигайтесь дальше. Не жди для последующих байтов. Только когда вы найдете конец очереди, вы обрабатывать полученные данные. Например:
// Разбираем и выполняем команду, полученную через USB.
executeCommand(String &command) {
// Реализация оставлена читателю в качестве упражнения.
}
// Получаем ли мы в данный момент символы из команды.
bool receivingCommand = false;
// Получена команда, может быть неполной.
String command;
void loop() {
Usb.Task();
if (controller.available()) {
char c = controller.read();
if (!receivingCommand && c == 'M') { // начало команды
receivingCommand = true;
} else if (receivingCommand && c == '\n') { // конец команды
executeCommand(command);
command = "";
receivingCommand = false;
} else if (receivingCommand) { // тело команды
command += c; // буферизуем полученный символ
}
}
}
Лучше было бы избегать класса String
, который не
дружелюбен к памяти вашего Arduino и используйте простую строку C, как
объяснено в разделе Чтение последовательного порта на Arduino. Это, однако,
скорее всего, это не связано с вашей проблемой дрожания.
- Тахометр на базе Леонардо?
- Несколько срочных задач
- Как использовать SPI на Arduino?
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
Спасибо! Как бы я использовал строку C для этой программы. Изначально мой ввод представляет собой число с плавающей запятой, и мне нужно добавить его в массив символов. Разве мне не нужно сначала преобразовать его в строку?, @Jake Jin
@JakeJin: Нет, вам не нужна строка. Вы можете преобразовать число с плавающей точкой в массив символов, используя [
dtostrf()
](https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42)., @Edgar Bonet