Точность джойстика
Jun. 23rd, 2021 12:18 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Точность определения джойстиком угла наклона - где-то градус, т.е. положение пляшет вокруг этого значения. В принципе, это ОК, т.к. джойстик задает ускорение вращения, положение - дважды интеграл, а интегрирование само по себе фильтр. Однако можно еще увеличить точность -
Время счета положения джойстиком 8 миллисекунд. Нужно опрашивать джойстик хотя бы 20 раз в секунду, значит, перерыв между измерениями - 50 миллисекунд. Это значит, что можно сделать 5-6 измерений в интервале между опросами, сгладить их скользящим окном и передать уже сглаженное значение.
Алгоритм работы с джостиком -
1) посылался байт запроса
2) по этому событию производится измерение, и отсылается результат
Надо сделать так -
1) результаты непрерывно пишутся в массив из пяти значений, самое новое измеренное записывается в самый старый элемент массива
2) посылается байт запроса
3) по этому событию считается среднее от массива, отсылается результат.
Прошивка для прикидки времени счета -
Время счета положения джойстиком 8 миллисекунд. Нужно опрашивать джойстик хотя бы 20 раз в секунду, значит, перерыв между измерениями - 50 миллисекунд. Это значит, что можно сделать 5-6 измерений в интервале между опросами, сгладить их скользящим окном и передать уже сглаженное значение.
Алгоритм работы с джостиком -
1) посылался байт запроса
2) по этому событию производится измерение, и отсылается результат
Надо сделать так -
1) результаты непрерывно пишутся в массив из пяти значений, самое новое измеренное записывается в самый старый элемент массива
2) посылается байт запроса
3) по этому событию считается среднее от массива, отсылается результат.
Прошивка для прикидки времени счета -
#include "Wire.h" //I2C Arduino Library #define HMC5883L_ADDR 0x1E //0011110b, I2C 7bit address of HMC5883 bool haveHMC5883L = false; void setup() { digitalWrite(4,LOW); digitalWrite(5,HIGH); Serial.begin(9600); Wire.begin(); TWBR = 78; // 25 kHz TWSR |= _BV (TWPS0); // change prescaler delay(500); } void loop() { int xm,ym,zm; int x1,y1,z1; bool detect = detectHMC5883L(); if(!haveHMC5883L) { if(detect) { haveHMC5883L = true; Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883 Wire.write(0x02); //select mode register Wire.write(0x00); //continuous measurement mode Wire.endTransmission(); } else { Serial.println("No HMC5883L detected!"); delay(2000); return; } } else { if(!detect) { haveHMC5883L = false; Serial.println("Lost connection to HMC5883L!"); delay(2000); return; } } if (Serial.available()) { byte bb=Serial.read(); unsigned long t=micros(); Wire.beginTransmission(HMC5883L_ADDR); //Tell the HMC5883 where to begin reading data Wire.write(0x03); //select register 3, X MSB register Wire.endTransmission(); Wire.requestFrom(HMC5883L_ADDR, 6); //Read data from each axis, 2 registers per axis if(6<=Wire.available()){ x1 = Wire.read()<<8; //X msb x1 |= Wire.read(); //X lsb y1 = Wire.read()<<8; //Y msb y1 |= Wire.read(); //Y lsb z1 = Wire.read()<<8; //Z msb z1 |= Wire.read(); //Z lsb } Wire.beginTransmission(HMC5883L_ADDR); //Tell the HMC5883 where to begin reading data Wire.write(0x03); //select register 3, X MSB register Wire.endTransmission(); Wire.requestFrom(HMC5883L_ADDR, 6); //Read data from each axis, 2 registers per axis if(6<=Wire.available()){ xm = Wire.read()<<8; //X msb xm |= Wire.read(); //X lsb ym = Wire.read()<<8; //Y msb ym |= Wire.read(); //Y lsb zm = Wire.read()<<8; //Z msb zm |= Wire.read(); //Z lsb } double a=atan2(ym,x1)+atan2(x1,ym)+atan2(zm,ym)+atan2(1+xm,1-z1); a=sqrt(a*a+1); a=sqrt(a*a+2); t=micros()-t; Serial.print(a); Serial.println("/x"); Serial.println(t); delay(1); } } bool detectHMC5883L() { Wire.beginTransmission(HMC5883L_ADDR); //open communication with HMC5883 Wire.write(10); //select Identification register A Wire.endTransmission(); Wire.requestFrom(HMC5883L_ADDR, 3); if(3 == Wire.available()) { char a = Wire.read(); char b = Wire.read(); char c = Wire.read(); if(a == 'H' && b == '4' && c == '3') return true; } return false; }