Игры с акселерометром

Решил немно­го попро­бо­вать поиг­рать­ся с аксе­ле­ро­мет­ра­ми. Чисто по при­ко­лу. Ока­за­лась весь­ма занят­ная вещь.

Совре­мен­ные аксе­ле­ро­мет­ры рабо­та­ют по пье­зо­ди­на­ми­че­ско­му прин­ци­пу. Гру­бо гово­ря, есть полый куб, сде­лан­ный из пье­зо­элек­три­че­ских пла­стин, а внут­ри куба — шарик. В зави­си­мо­сти от поло­же­ния куба и уско­ре­ния, им испы­ты­ва­е­мо­го, шарик по-раз­но­му давит на пла­сти­ны, и полу­ча­ет­ся элек­три­че­ский сиг­нал. Самые про­стые аксе­ле­ро­мет­ры выда­ют ана­ло­го­вый сиг­нал, кото­рый мож­но счи­ты­вать в мик­ро­кон­трол­лер через АЦП.

Взял совсем недо­ро­гой и про­стень­кий аксе­ле­ро­метр ADXL335 (кар­тин­ка с Adafruit):

ADXL335

Даже тупо по над­пи­сям на пла­те сра­зу понят­но, как с ним рабо­тать.

В каче­стве интер­фей­са меж­ду ком­пью­те­ром и аксе­ле­ро­мет­ром взял свою ста­рень­кую Arduino UNO (чего ж ещё, для иссле­до­ва­тель­ских-то целей).

Теперь немно­го тех­ни­че­ско­го опи­са­ния и мате­ма­ти­ки. ADXL335 я питаю от 3.3 вольт. При уско­ре­нии в 0g, на соот­вет­ству­ю­щем выхо­де пла­ты име­ем VCC/2, т.е. 1.65V. АЦП на ATMEL ATmega328P — 10-бит­ные, соот­вет­ствен­но, полу­ча­ем раз­ре­ше­ние 5V/1024 = 4.9mv на одну еди­ни­цу. 1.65V/4.9mv = 336.

Так оно и полу­чи­лось: будучи поло­жен­ны­ми на абсо­лют­но плос­кую дос­ку, оси X и Y при счи­ты­ва­нии выда­ва­ли 336, а ось Z — 403 (пото­му что гра­ви­та­ция, и там у нас не 0g, а вовсе даже 1g).

Чув­стви­тель­ность аксе­ле­ро­мет­ра состав­ля­ет, при пита­нии от 3.3 вольт, 330 мил­ли­вольт на 1g. 330mv/4.9mv = 67, 336 + 67 = 403, всё пра­виль­но.

Но, блин, Арду­и­но, это, конеч­но, хоро­шо, но не очень. При запи­ты­ва­нии пла­ты напря­мую от USB, на вхо­де АЦП мик­ро­кон­трол­ле­ра есть очень силь­ный шум. У меня посто­ян­но пры­га­ли изме­ре­ния — от 0.98g до 1.02g. Свя­за­но это даже не сколь­ко с самим мик­ро­кон­трол­ле­ром, сколь­ко с тем, что напря­же­ние 5 вольт, выда­ва­е­мое обыч­ным ком­пью­те­ром — это что-то чудо­вищ­ное, с высо­ко­ча­стот­ны­ми навод­ка­ми, и про­чи­ми радо­стя­ми. Поэто­му если кому-то хочет­ся на обыч­ной Арду­и­но зани­мать­ся счи­ты­ва­ни­ем АЦП — сде­лай­те себе одол­же­ние, под­клю­чи­те сна­ча­ла нор­маль­ное ста­би­ли­зи­ро­ван­ное пита­ние. Запи­тал­ся от мое­го ста­ро­го лабо­ра­тор­но­го БП с линей­ным ста­би­ли­за­то­ром напря­же­ния — и нако­нец-то узрел нор­маль­ные непры­га­ю­щие зна­че­ния.

В прин­ци­пе, с шумом мож­но бороть­ся соф­то­вы­ми мето­да­ми, счи­ты­вая зна­че­ния мно­го раз, и усред­няя их. Но в зави­си­мо­сти от задач, это делать не все­гда прак­тич­но. Аксе­ле­ро­метр мож­но исполь­зо­вать, напри­мер, для рас­чё­та прой­ден­но­го рас­сто­я­ния. От пока­за­ний надо брать двой­ной инте­грал, так как пози­ция’ = ско­рость’ = уско­ре­ние. Но если пока­за­ния из-за усред­не­ния доступ­ны толь­ко раз в секун­ду, то полу­чит­ся фиг­ня, очень неточ­но.

Поэто­му в дан­ном виде аксе­ле­ро­метр для таких задач непри­го­ден. С ним мож­но толь­ко при­бли­зи­тель­но рас­счи­ты­вать, как накло­не­на пла­та. Ведь при накло­не­нии аксе­ле­ро­мет­ра, уско­ре­ние сво­бод­но­го паде­ния на оси Z пада­ет, и начи­на­ет дей­ство­вать на дру­гие оси. А даль­ше, в‑общем, про­стая три­го­но­мет­рия — про­ек­ции сил на оси, тре­уголь­ни­ки. Угол накло­на оси Z — арк­ко­си­нус от счи­ты­ва­е­мо­го уско­ре­ния, ника­кой магии. Накло­ни её на 90 гра­ду­сов — будешь счи­ты­вать 0g, arccos(0) = 90°, всё пра­виль­но.

Дабы не мудо­хать­ся со слож­ны­ми схе­ма­ми пита­ния, зака­зал дру­гой аксе­ле­ро­метр — MPU6050. У него внут­ри неон­ка свой АЦП, при­чём 16-бит­ный, что кру­че в 64 раза, а дан­ные он отда­ёт по I2C или SPI. Кро­ме того, у него есть трёх­ос­ный гиро­скоп! Я даже не знал, что быва­ют твёр­до­тель­ные гиро­ско­пы, кру­то! Буду про­дол­жать изыс­ка­ния.