Circuitpython
Для работы с датчиком lis2dh12 используем библиотеку adafruit_lis3dh (для более новой версии), которая имеется в стандартном наборе библиотек от Adafruit (ссылка в конце урока). Всё, что нам нужно сделать для её установки — это скопировать файл adafruit_lis3dh.mpy в папку lib на накопителе CIRCUITPY.
Более подробно о работе с библиотеками CircuitPython мы писали в одном из ранних наших уроков: Библиотеки для CircuitPython
УСТАНОВКА ЗАВИСИМОСТЕЙ
Чтобы библиотека adafruit_lis3dh заработала, необходимо будет добавить еще две «зависимости»:
- adafruit_bus_device
- adafruit_register
Все эти библиотеки есть в сборнике от Adafruit. Точно также, копируем их на накопитель CIRCUITPY.
Программа
Для составления программы используем среду разработки Mu.
Пусть, самая первая наша программа будет выводить значения ускорения по трём осям в единицах измерения м/с за секунду. Начнём с подключения всех необходимых библиотек. Помним, что в python это делается с помощью команды import.
Кроме adafruit_lis3dh нам будут нужны еще три библиотеки:
- time — предоставляет функцию sleep для организации паузы;
- board — хранит названия всех контактов платы контроллера и их синонимы;
- busio — предоставляет интерфейс для работы с шиной I2C.
import time
import board
import busio
import adafruit_lis3dh
Затем инициализируем шину I2C. Следом — датчик, указывая в качестве параметров интерфейс i2c и его адрес 0x19.
i2c = busio.I2C()
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
Датчик позволяет настроить диапазон измерений: 2, 4, 8 или 16G. Пусть будет 2G. Так мы не сможем засечь, например, сильную вибрацию при запуске ракеты, но зато получится использовать датчик для достаточно точного определения наклона в пространстве.
lis3dh.range = adafruit_lis3dh.RANGE_2_G
Чтобы получить значения ускорения по осям X,Y и Z достаточно просто обратиться к свойству lis3dh.acceleration (фактически — это функция, которая не имеет аргументов и может вызываться без скобок). В момент обращения к этому свойству, библиотека запросит у lis2dh12 данные и автоматически преобразует их в единицы измерения ускорения — м/с за секунду.
Остаётся только вывести lis3dh.acceleration в консоль python, чтобы мы могли увидеть данные. Полный код программы:
import time
import board
import busio
import adafruit_lis3dh
# включение шины I2C
i2c = board.I2C()
# включение датчика с адресом 0x19
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
# установка диапазона 2G
lis3dh.range = adafruit_lis3dh.RANGE_2_G
while True:
# считывание показаний датчика и вывод их в консоль
print("x = %0.3f G, y = %0.3f G, z = %0.3f G" % tuple(lis3dh.acceleration))
time.sleep(0.1)
Сохраняем программу и открываем монитор последовательного порта (кнопка «Последовательный»). Датчик должен выдавать поток чисел каждые 100 мс.
В этом эксперименте плата LIS2DH12 лежала на столе так, что ось Z была направлена строго вверх. При этом логично, что значения по осям x и y почти равны нулю, ведь на датчик в этих направлениях не действуют никакие силы. А вот значение по оси Z практически равно ускорению свободного падения 9,8 м/с за секунду. При этом на датчик действует, конечно, не сила гравитации, а сила реакции опоры, которая направлена строго вверх.
Детектирование щелчка (tap, click)
Часто акселерометры применяются в качестве детекторов щелчка в тех случаях, когда в разрабатываемом приборе по каким-либо причинам невозможно сделать механическую или сенсорную кнопку. В датчике LIS2DH12 имеется встроенная функция определения одинарного и двойного щелчка.
Чтобы активировать детектирование щелчка используем функцию set_tap из библиотеки:
lis3dh.set_tap(2, 127)
где первый параметр — это режим работы, который может принимать два значения: 1 — одинарный щелчок, 2 — двойной;
второй параметр — чувствительность детектора: число от 0 до 127; чем больше число, тем грубее детектор. Этот параметр также зависит от текущего диапазона. То есть для диапазонов 4G, 8G и 16G его нужно скорректировать эмпирически.
Также, для экономии ресурсов контроллера используем прерывание. Подключим контакт модуля INT1 к контакту контроллера D10. Затем, в самом начале программы инициализируем этот контакт:
int1 = digitalio.DigitalInOut( board.D10 )
И затем укажем его в качестве третьего параметра в функции инициализации датчика:
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
Наконец, в суперцикле программы будем опрашивать свойство lis3dh.tapped на предмет появления там логический единиц и только после этого выводить на экран сообщение «Tapped!».
import time
import board
import busio
import digitalio
import adafruit_lis3dh
# включение шины I2C
i2c = board.I2C()
int1 = digitalio.DigitalInOut( board.D10 )
# включение датчика с адресом 0x19
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
# установка диапазона 2G
lis3dh.range = adafruit_lis3dh.RANGE_2_G
# настройка детектора щелчков
lis3dh.set_tap(2, 127)
# Loop forever printing if a double tap is detected.
while True:
if lis3dh.tapped:
print("Tapped!")
time.sleep(0.01)
Сохраняем программу и открываем монитор последовательного порта (кнопка «Последовательный»). Затем стучим по датчику и смотрим, появится ли в консоли слово Tapped!
Примечания
По поводу прерываний для функции детектирования щелчка. Прерывание можно и не использовать, но тогда нам придётся постоянно обращаться к датчику через I2C, нагружая его ненужной работой. С прерыванием же можно, например, погрузить датчик в режим низкого энергопотребления.
Об алгоритме детектирования щелчка. Если посмотреть внутрь библиотеки, то найдём там такой алгоритм:
- проверяем, не появился ли на контакте D10 высокий уровень, если нет — возвращаем ноль;
- если появился, то запрашиваем у датчика через I2C данные о его состоянии;
- проверяем состояние, имеется ли там упоминание о детектировании щелчка и если имеется — возвращаем из функции логическую единицу.
Ещё одна полезная функция в библиотеке — детектирование встряски. То есть можно определить, что мы потрясли прибор. Причём с помощью аргументов можно описать характер тряски 🙂
shake( 30, 10, 0.1)
первый параметр — чувствительность; второй — число биений; третий — общее время, которое мы будем трясти датчик.