С момента появления знаменитого микрокомпьютера Raspberry Pi прошло уже более десяти лет. За это время вышло уже несколько поколений данного МК и также появилось множество аналогичных решений. Отличительными чертами МК является небольшой размер, скромные, по сравнению с компьютерами и ноутбуками, требования к питанию, а также отсутствие шума при работе. Взамен мы получаем некоторые неудобства, связанные с необходимостью подключения периферии к этой маленькой плате, по сути являющейся полноценным, хоть и не очень мощным компьютером.
Некоторое время назад российские разработчики представили микрокомпьютер Repka Pi. На просторах Хабра уже был ряд публикаций, посвященных этому МК. В этой статье мы не будем подробно разбирать процесс развертывания ОС на карте памяти и выполнение базовых настроек микрокомпьютера. Вместо этого мы уделим больше внимания использованию данного МК для задач интернета вещей. Однако, мы не будем погружаться в решение какой-либо конкретной задачи, например создание метеостанции, так как про это тоже уже много чего написано.
Нашей основной задачей станет рассмотрение общих принципов выполнения аналогово-цифровых преобразований (АЦП) на микрокомпьютере Repka Pi.
Что такое АЦП/ЦАП
В простейшем случае появление тока на контакте устройства или ножке микросхемы мы можем идентифицировать с помощью 0 и 1. Отсутствие тока или не превышение определенной величины можно считать нулем, а любое превышение этой величины уже является единицей. Однако, такой подход удобен только в простейших случаях, когда необходимо обнаружить нажатие кнопки или другое замыкание контактов.
Но, если нам необходимо измерить уровень передаваемого сигнала, то здесь необходимо использовать аналогово цифровое преобразование, то есть систему, которая преобразует аналоговый сигнал, такой как звук, улавливаемый микрофоном, или свет, попадающий на сенсор, в цифровой сигнал. Смысл здесь заключается в том, что тот же световой сенсор реагирует на активность попадающего на него света в аналоговом режиме, например меняя сопротивление. Но для использования в наших прошивках нам нужно некоторое цифровое значение, которое можно будет сравнивать с некоторой константой, например, для того, чтобы наше устройство включало освещение при уровне освещения ниже определенной величины. Обычно цифровой выходной сигнал представляет собой число, которое пропорционально уровню сигнала на АЦП. Чем выше разрядность этого числа, тем выше точность значения, которое мы получаем в результате аналогово-цифрового преобразования.
На практике существует несколько архитектур АЦП. Из-за сложности и потребности в точности работы компонентов все АЦП, кроме наиболее специализированных, реализованы в виде интегральных схем (ICS). Далее в статье мы будем рассматривать один из таких модулей для преобразования АЦП/ЦАП на микросхеме PCF8591.
Соответственно Цифро-аналоговый преобразователь (ЦАП) выполняет обратную функцию - он преобразует цифровой сигнал в аналоговый.
Модуль АЦП/ЦАП
Выбранный нами модуль предоставляет 8-битное аналого-цифровое и 8-битное цифро-аналоговое преобразование, с помощью которого мы можем считывать аналоговые значения с 4 входов и при необходимости генерировать аналоговые значения на один выход. Для работы модуля требуется напряжение питания 2,5-6 В. Обмен данными с микросхемой осуществляется посредством I2C интерфейса. Об этом интерфейсе, и его реализации на Repka Pi мы поговорим чуть позже.
На модуле уже установлены дополнительные компоненты: потенциометр, фоторезистор, терморезистор, которые подключены к входам АЦП (0, 1 и 3) с помощью перемычек, а расположение входных контактов позволяет использовать его на макетной плате без дополнительной доработки.
Учимся правильно понимать результат АЦП
АЦП выдает нам некоторое цифровое значение и наша задача правильно понимать, что же мы получили. Представленные далее формулы взяты из документации по работе с Repka Pi.
При работе с модулями АЦП / ЦАП на входные линии Repka Pi 3 мы будем получать преобразованные микросхемой значения входного сигнала, т.е. целочисленные значения в интервале от 0 до 255.
Значения входного сигнала вычисляются по формуле:
V = (U_in / U_adc) * 255
где:
V - значение со входа АЦП;
U_in - напряжение полученное АЦП на входе;
U_adc - напряжение питания.
Для лучшего понимания рассмотрим небольшой пример:
В результате АЦП получено значение 93, известно, что контакт подключен к сети напряжением 3,3 В. Вычислим напряжение, поступившее на вход АЦП сигнала.
(93 / 255) * 3,3 = 1,2 В.
Интерфейс I2C и его реализация
Интерфейс I2C (Inter-Integrated Circuit) — это двунаправленная асинхронная шина с последовательной передачей данных. Использует две двунаправленные линии связи (SDA и SCL), применяется для соединения низкоскоростных периферийных компонентов с процессорами и микроконтроллерами. В нашем случае мы будем взаимодействовать с микрокомпьютером.
Устройство, подключенное к шине I2C может выполнять одну из двух ролей: master (ведущий) или slave (ведомый). I2C позволяет одновременно сосуществовать нескольким ведущим и ведомым устройствам на одной шине. Обмен данными происходит сеансами, которыми полностью управляет master.
В качестве протокола обмена данными с устройством мы будем использовать SMBus (System Management Bus) — последовательный протокол обмена данными для устройств. Поддержка данного протокола реализована на уровне драйверов ядра Linux.
Для разрешения доступа пользователей в RepkaOS к контроллерам I2C необходимо выполнить команду для создания группы
sudo groupadd i2c
Затем назначить группу i2c владельцем I2C-контроллера. В примере ниже назначаем владельцем первого контроллера:
sudo chown :i2c /dev/i2c-1
Разрешим чтение и запись данных в первый контроллер членам группы i2c:
sudo chmod g+rw /dev/i2c-1
И наконец, нам надо добавить пользователя в группу i2c командой
sudo usermod -aG i2c user_name
Выйти из системы и зайти заново, для применения настроек.
Далее установим нужные пакеты:
sudo apt update
sudo apt install python3-smbus
Далее давайте посмотрим, что у нас получилось.
Тестируем АЦП
Схема, рекомендованная вендором для работы Repka Pi с АЦП имеет следующий вид:
Для программной обработки полученного сигнала мы воспользуемся небольшой программой на Python.
import os # модуль для работы с ОС
import time # модуль работы со временем
from smbus import SMBus # модуль для работы с I2C контроллером
# адрес устройства (PCF8591) на шине I2C
DEV_ADDR = 0x48
# словарь адресов данных для входных каналов АЦП
adc_channels = {
'AIN0':0b_0100_0000, # 0x40 (фоторезистор)
'AIN1':0b_0100_0001, # 0x41 (терморезистор)
'AIN2':0b_0100_0010, # 0x42 (свободный)
'AIN3':0b_0100_0011, # 0x43 (потенциометр)
}
# адрес данных для ЦАП
dac_channel = 0b_0100_0000 # 0x40
# получаем доступ к контроллеру I2C
# (1 контроллер I2C для 2-5 вариантов распиновки - контакты 3-SDA и 5-SCL)
# (2 контроллер I2C для 4 варианта распиновки - контакты 27-SDA и 28-SCL)
bus = SMBus(1)
# устанавливаем значение для ЦАП
dac_value = 0
while(True):
os.system('clear') # очищаем терминал
print("Нажмите Ctrl + C для завершения работы...\n")
# запускаем "бесконечный" цикл для обмена информацией с АЦП/ЦАП
for channel in adc_channels:
# получаем значения из АЦП для всех аналоговых входов
bus.write_byte(DEV_ADDR, adc_channels[channel])
# выбрасываем старое значение АЦП дважды (особенность устройства)
# т.к. нам не нужно сравнивать новое значение с предыдущим
bus.read_byte(DEV_ADDR)
bus.read_byte(DEV_ADDR)
value = bus.read_byte(DEV_ADDR) # получаем новое значение
# если текущая лини 3, то получаем значение с потенциометра
if channel == 'AIN3':
dac_value = value
# выводим в консоль значение АЦП для каждого входа
print('Канал ' + channel + ' ---> ' + str(value))
# устанавливаем значение для ЦАП (изменяем яркость светодиода)
bus.write_byte_data(DEV_ADDR, dac_channel, dac_value)
# ждем 100 миллисекунд
time.sleep(0.1)
Протестировать работу АЦП на микрокомпьютере можно довольно простыми способами, например посветив фонариком на фоторезистор или подышав на терморезистор. В результате мы увидим изменения значений, поступающих с модуля АЦП.
Заключение
Аналогово-цифровое преобразование активно используется при решении различных задач интернета вещей. Так, в “умном” доме мы можем автоматически собирать информацию о температуре, влажности и освещенности комнат для последующей визуализации на карте квартиры. А микрокомпьютер Repka Pi Может использоваться в качестве бесшумного домашнего сервера.
В завершение спешу напомнить про открытые уроки, которые в ближайшее время пройдут в рамках курса "IoT Developer":
3 июля: Мониторинг транспорта в платформе ThingsBoard. Пройдёмся поэтапно: подключение устройств, создание сущностей, разработка цепочек правил, разработка дашборда. Запись по ссылке
17 июля: Учет энергоресурсов в платформе ThingsBoard. На этом занятии рассмотрим решение учета энергоресурсов (вода, газ, э/э, тепло). Запись по ссылке
Sergey78
Для этого АЦП есть драйвер в ядре. Зачем его на питоне то опрашивать из userspace? Проще же один раз настроить и просто читать из "файла".
BoogieMan75
Главное написать кучу кода на питоне. Курсы сами себя не продают:)