Как исправить задержку курсора мыши на голосовой и двигательной головной мыши в беспроводных настройках?
Для моего проекта head mouse, который основан на модуле распознавания голоса V3.1 для операций левого клика, двойного клика, правого клика, я столкнулся с проблемой. Я использую радиочастотный односторонний приемопередатчик 433 МГц для отправки данных. Когда я использую акселерометр MPU 6050 и гироскоп для перемещения курсора мыши и модуль распознавания голоса вместе только на одной плате Arduino, курсор мыши движется плавно, а голосовые команды работают плавно. Но когда я использую радиочастотный односторонний передатчик 433 МГц для одной платы Arduino, чтобы рассчитать движение мыши и выяснить голосовую команду, чтобы отправить ее беспроводным способом и получить значения и голосовые команды, используя модуль приемника rf433 МГц, курсор мыши начинает отставать. Он не движется гладко. Пожалуйста, помогите мне решить эту проблему. Код и принципиальная схема приведены ниже:
Передатчик.ино
/*433 MHz RF Module Transmitter Demonstration 1
RF-Xmit-Demo-1.ino
Demonstrates 433 MHz RF Transmitter Module
Use with Receiver Demonstration 1
DroneBot Workshop 2018
https://dronebotworkshop.com
*/
// Включить библиотеку амплитудной манипуляции RadioHead
#include <RH_ASK.h>
// Включить зависимую библиотеку SPI
#include <SPI.h>
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
VR myVR(8,9); // 9: RX 8: TX
uint8_t records[7]; // сохранить запись
uint8_t buf[64];
MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz, oax, oay, oaz, ogx, ogy, ogz;
int16_t vx, vy;
//
#define leftRecord (0)
#define rightRecord (1)
#define doubleRecord (2)
/**
@brief Print signature, if the character is invisible,
print hexible value instead.
@param buf --> command length
len --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
int i;
for(i=0; i<len; i++){
if(buf[i]>0x19 && buf[i]<0x7F){
Serial.write(buf[i]);
}
else{
Serial.print("[");
Serial.print(buf[i], HEX);
Serial.print("]aurav");
}
}
}
/**
@brief Print signature, if the character is invisible,
print hexible value instead.
@param buf --> VR module return value when voice is recognized.
buf[0] --> Group mode(FF: None Group, 0x8n: User, 0x0n:System
buf[1] --> number of record which is recognized.
buf[2] --> Recognizer index(position) value of the recognized record.
buf[3] --> Signature length
buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
Serial.println("VR Index\tGroup\tRecordNum\tSignature");
Serial.print(buf[2], DEC);
Serial.print("\t\t");
if(buf[0] == 0xFF){
Serial.print("NONE");
}
else if(buf[0]&0x80){
Serial.print("UG ");
Serial.print(buf[0]&(~0x80), DEC);
}
else{
Serial.print("SG ");
Serial.print(buf[0], DEC);
}
Serial.print("\t");
Serial.print(buf[1], DEC);
Serial.print("\t\t");
if(buf[3]>0){
printSignature(buf+4, buf[3]);
}
else{
Serial.print("NONE");
}
Serial.println("\r\n");
}
struct dataStruct{
int16_t moveX;
int16_t moveY;
int flag;
}myData;
byte tx_buf[sizeof(myData)] = {0};
// Создать объект амплитудной манипуляции сдвигом
RH_ASK rf_driver;
int flag = 15;
void setup()
{
/** initialize */
Wire.begin();
mpu.initialize();
if (!mpu.testConnection()) {
while (1);
}
myVR.begin(9600);
Serial.begin(115200);
Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
if(myVR.clear() == 0){
Serial.println("Recognizer cleared.");
}else{
Serial.println("Not find VoiceRecognitionModule.");
Serial.println("Please check connection and restart Arduino.");
while(1);
}
if(myVR.load((uint8_t)leftRecord) >= 0){
Serial.println("leftRecord loaded");
}
if(myVR.load((uint8_t)rightRecord) >= 0){
Serial.println("rightRecord loaded");
}
if(myVR.load((uint8_t)doubleRecord) >= 0){
Serial.println("doubleRecord loaded");
}
// Инициализация объекта ASK
rf_driver.init();
if(!rf_driver.init()) Serial.println("Init failed");
}
void loop()
{
int ret;
ret = myVR.recognize(buf, 50);
const char *msg = "Welcome to the Workshop!";
if(ret>0){
switch(buf[1]){
case leftRecord:
flag = 0;
break;
case rightRecord:
flag = 1;
break;
case doubleRecord:
flag = 2;
break;
default:
flag=3;
Serial.println("Record function undefined");
break;
}
/** voice recognized */
printVR(buf);
}
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
oax = ax+72;
oay = ay-382;
oaz = az-505;
ogx = gx+99;
ogy = gy-29;
ogz = gz-50;
vx = gx/200;
vy = -gz/200;
myData.moveX = vx;
myData.moveY = vy;
myData.flag = flag;
memcpy(tx_buf, &myData, sizeof(myData));
byte bufSize = sizeof(myData);
Serial.println("movX\tmovY\tmovZ\toax\toay\toaz\togx\togy\togz\tvx\tvy:");
Serial.print(myData.moveX, HEX);
Serial.print("\t");
Serial.print(myData.moveY, HEX);
Serial.print("\t");
Serial.print(myData.flag, HEX);
Serial.print("\t");
Serial.print(oax, DEC);
Serial.print("\t");
Serial.print(oay, DEC);
Serial.print("\t");
Serial.print(oaz, DEC);
Serial.print("\t");
Serial.print(ogx, DEC);
Serial.print("\t");
Serial.print(ogy, DEC);
Serial.print("\t");
Serial.print(ogz, DEC);
Serial.print("\t");
Serial.print(vx, HEX);
Serial.print("\t");
Serial.println(vy, HEX);
rf_driver.printBuffer("Buffer values [vx, vy, status flag respectively]: ", tx_buf, bufSize); // каждое значение равно 16 битам. и монитор serail будет отображаться в 8 + 8 = 16 битном формате
rf_driver.send((uint8_t *)tx_buf, bufSize);
//Serial.println();
rf_driver.waitPacketSent();
flag = 15;
delay(1);
}
Приемник.ино
// Включить библиотеку амплитудной манипуляции RadioHead
#include <RH_ASK.h>
// Включить зависимую библиотеку SPI
#include <SPI.h>
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#define leftRecord (0)
#define rightRecord (1)
#define doubleRecord (2)
// Создать объект амплитудной манипуляции сдвигом
RH_ASK rf_driver;
struct dataStruct{
int moveX, moveY, flag;
}myData;
void setup()
{
// Инициализация объекта ASK
Wire.begin();
rf_driver.init();
// Настройка последовательного монитора
Serial.begin(115200);
if(!rf_driver.init()) Serial.println("Init failed");
}
void loop()
{
// Установить размер буфера ожидаемого сообщения
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(buf);
// Проверьте, правильный ли размер полученного пакета
if (rf_driver.recv(buf, &buflen))
{
int i;
// Получено сообщение с хорошей контрольной суммой, сбросьте его.
rf_driver.printBuffer("Got:", buf, buflen);
memcpy(&myData, buf, sizeof(myData));
Serial.println("");
Serial.print("moveX: ");
Serial.print(myData.moveX);
Serial.print(" moveY: ");
Serial.print(myData.moveY);
Serial.print(" Command Status: ");
Serial.print(myData.flag);
// Сообщение, полученное с действительной контрольной суммой
Serial.print(" Message Received: ");
Serial.println((char*)buf);
Mouse.move(myData.moveX, myData.moveY);
if(myData.flag!=15){
switch(myData.flag){
case leftRecord:
Mouse.click(MOUSE_LEFT);
delay(10);
break;
case rightRecord:
Mouse.click(MOUSE_RIGHT);
delay(10);
break;
case doubleRecord:
Mouse.click(MOUSE_LEFT);
Mouse.click(MOUSE_LEFT);
delay(10);
break;
default:
break;
}
}
}
}
@Nahian Rifaat, 👍2
1 ответ
В общем, вы хотите передать некоторые данные в потоковом режиме. а отставание мыши - одно из главных препятствий в потоках данных; отставание. на ум приходит так много классических причин, таких как переполнение буфера и проблемы с синхронизацией.
Дешевые модули 433 МГц не являются хорошим выбором в случае потоков. им не хватает какого-либо надежного протокола, ACKing и безопасности.
Я бы сделал это, чтобы сделать его лучше:
- используйте передатчик получше. может быть, дешевые nRF24L01.
- используйте больший буфер
- используйте две нити на стороне передатчика. (например, используйте что-то вроде этого, но две нити). один поток для сбора данных и записи их в буфер, следующий - для отправки данных с помощью nrf. к сожалению, nRF24 может отправлять до 32 байт в одном буфере, а интерфейс SPI достаточно быстр, чтобы заполнить его как можно быстрее.
- если вам нужно, используйте другой поток для расчета перемещений из MPU6050. таким образом, вам не нужно постоянно читать его и отправлять все эти необработанные данные получателю. однако вы можете использовать некоторую интерполяцию на стороне приемника.
- Как использовать get_properties для получения RSSI в RF24?
- Декодировать радиочастотные удаленные сигналы с помощью ESP32 или node MCU?
- SD-карта и модуль Lora arduino uno
- Можно ли передавать радиосигнал дешевым передатчиком 433 МГц в виде строк и принимать его с помощью RTL-SDR?
- Зашифрованная радиосвязь Arduino
- Что это за модуль NRF24L01?
- Как исправить перегрузку питания при подключении nRF24L01 для голосовой+гироскопической головной мыши?
- RF Keyfob простой код кнопки
Но когда я использую nRF24L01, Arduino включается, а затем выключается. Я пробовал это как с Arduino Leonardo, так и с Micro. Как я могу это исправить? Это также иногда вызывает скачки напряжения и перегрев., @Nahian Rifaat
убедитесь, что контакты питания установлены правильно. эта проблема в основном связана с заменой контактов VCC / GND, @Tirdad Sadri Nejad