Решил немного попробовать поиграться с акселерометрами. Чисто по приколу. Оказалась весьма занятная вещь.
Современные акселерометры работают по пьезодинамическому принципу. Грубо говоря, есть полый куб, сделанный из пьезоэлектрических пластин, а внутри куба — шарик. В зависимости от положения куба и ускорения, им испытываемого, шарик по-разному давит на пластины, и получается электрический сигнал. Самые простые акселерометры выдают аналоговый сигнал, который можно считывать в микроконтроллер через АЦП.
Взял совсем недорогой и простенький акселерометр ADXL335 (картинка с Adafruit):
Даже тупо по надписям на плате сразу понятно, как с ним работать.
В качестве интерфейса между компьютером и акселерометром взял свою старенькую 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. Кроме того, у него есть трёхосный гироскоп! Я даже не знал, что бывают твёрдотельные гироскопы, круто! Буду продолжать изыскания.