Мы начинаем разработку классов-оберток, инкапсулирующих все низкоуровневые детали функционирования узлов установки. Все классы будут собраны в едином файле-модуле nna.py. По мере разработки классов, файл nna.py будет обновляться. Поэтому желательно работать с самой последней версией файла. Все детали реализации классов описаны в самом файле nna.py, а здесь (в топиках) мы будем рассматривать конкретные примеры, связанные с созданием объектов этих классов и работе с ними. Для того, чтобы не отвлекаться на всякие "фантики", создавать и тестировать объекты будем либо в консоли интерпретатора питона ("ручной" режим), либо путем запуска консольного варианта скрипта (автоматический режим).
Поскольку цифровой модуль и датчики еще свежи в памяти, начнем разработку классов-оберток именно с них.
17.5.1. Датчики и цифровые модули. Создание и работа с объектами классов Sensor, DM, BMP180
Предполагаем, что все необходимое железо у нас собрано, прошите и отлажено. В каналу 0 цифрового модуля подключим датчик DS18B20. Включаем питание (пока можно без высокого). Садимся за малинку или соединяемся с ней из рабочей станции по SSH.
Делаем папку, в которой находится файл nna.py, текущей. Запускаем интерпретатор питона. В консоли интерпретатора питона импортируем модуль nna командой
from nna import *
Первое, что нам нужно сделать, это создать объект-датчик температуры. Это делается путем создания объекта класса Sensor. Этот класс предназначен для описания любых датчиков, подключаемых к цифровому модулю. Конструктор класса содержит два параметра: coef и unit. Первый параметр coef задает некоторое число, на которое нужно умножить полученный код АЦП, для того, чтобы получить значение физической величины, которую этот датчик измеряет. Например, для датчика DS18B20 при полном цикле измерения этот коэффициент равен 0.0625. Т.е., если мы умножим код АЦП DS18B20 на 0.0625, то мы получим температуру в градусах Цельсия. Второй параметр конструктора класса Sensor - unit. Он представляет собой текстовую строку, обозначающую единицу измерения величин, измеряемых данным датчиком.
Для создания объекта-датчика пишем:
ts = Sensor(coef = 0.0625, unit = '°C')
ts = Sensor(0.0625, '°C')
Реальный датчик температуры у нас подключен к нулевому каналу цифрового модуля. В модуле nna есть класс DM, который описывает цифровые модули. Конструктор этого класса имеет один параметр addr. Это адрес на шине i2c, по которому малинка обращается к этому цифровому модулю. Для создания объекта-цифрового модуля пишем в консоли интерпретатора питона:
dm = DM(0x15)
Для подключения объектов-датчиков к объекту-цифровому модулю, у последнего есть метод addSensor(ch, sensor). У метода два параметра: ch - номер канала цифрового модуля, к которому мы подключен датчик, и sensor - ссылка на подключаемый объект-датчик. У нас реальный датчик температур подключен к нулевому каналу цифрового модуля. Поэтому пишем:
dm.addSensor(0, ts)
Теперь нам осталось актуализировать информацию об измерениях, проведенных цифровым модулем. Для этого, в классе DM есть метод update. Этот метод не имеет параметров. При его вызове, весь буфер данных цифрового модуля пересылается в объект-цифровой модуль. Итак, пишем в консоли интерпретатора питона:
dm.update()
print ts.v, ts.u
Избавленная от поясняющих комментариев последовательность выполненных выше действий выглядит следующим образом:
from nna import *
dm = DM(0x15) # Создаем объект - цифровой модуль
ts = Sensor(0.0625, '°C') # Создаем объект - датчик температуры
dm.addSensor(0, ts) # "Подключаем" виртуальный датчик к виртуальному цифровому модулю
dm.update() # Синхронизируем виртуальный мир с реальным миром ;)
print ts.v, ts.u # Смотрим температуру датчика
Конечно, рассмотренный пример очень прост. Следующий пример немного сложнее. Для демонстрации, я подключил к малинке (через цифровой модуль) четыре датчика DS18B20, "модель концевика" (на самом деле - просто проводок, при помощи которого можно замыкать сигнальную линию кнала цифрового модуля на землю ;), 30-градусный термоконтакт и датчик кубового давления. Датчик атмосферного давления BMP180 подключен непосредственно к шине i2c. Скрипт, работающий со всем этим "хозяйством" приведен ниже:
Скрытый текст
#coding:utf-8
import time
import sys
from nna import *
"""Демонстрация использования классов-оберток Sensor, DM и BMP180(), описанных
в модуле nna
:author: OldBean
16.10.2018"""
# Создаем объект - цифровой модуль
dm = DM(addr = 0x15)
if dm is None:
print('Не удалось создать объект класса DM')
sys.exit(1)
# Создаем датчики (объекты-сенсоры)
hts = Sensor(coef = 0.0625, unit = '°C') # Датчик температуры в кубе
cts = Sensor(coef = 0.0625, unit = '°C') # Датчик температуры в колонне
dts = Sensor(coef = 0.0625, unit = '°C') # Датчик температуры в дефлегматоре
wts = Sensor(coef = 0.0625, unit = '°C') # Датчик температуры в ТСА
con = Sensor(coef = 1) # Концевик
tcon = Sensor(coef = 1) # Термоконтакт
hps = Sensor(coef = 0.0733, unit = 'mm Hg') # Датчик кубового давления
# Добавляем датчики к цифровому модулю. Здесь:
# ch - номер канала цифрового модуля, к которому подключен датчик
# sensor - объект класса Sensor соответствующего датчика
dm.addSensor(ch = 0, sensor = hts)
dm.addSensor(ch = 1, sensor = cts)
dm.addSensor(ch = 2, sensor = dts)
dm.addSensor(ch = 3, sensor = wts)
dm.addSensor(ch = 4, sensor = con)
dm.addSensor(ch = 6, sensor = hps)
dm.addSensor(ch = 7, sensor = tcon)
# Создаем объект - датчик атмосферного давления и температуры
atm = BMP180()
if atm is None:
print('Не удалось создать объект класса BMP180')
sys.exit(1)
# Актуализируем данные с цифрового модуля
dm.update()
# Распечатаем актуализированные данные цифрового модуля
print(dm)
# Примеры печати конкретных данных
print('Температура в кубе: % 3.3f %s'%(hts.v, hts.u))
print('Давление в кубе: % 3.3f %s'%(hps.v, hps.u))
print('Атмосферное давление: %3.1f mm Hg'%(atm.p))
print('Температура окружающего воздуха: %2.3f °C'%(atm.t))
Конструктор класса BMP180 не имеет параметров. Питоновской командой
atm = BMP180()
Скриншот после выполнения этого скрипта показан на рисунке ниже:
Этот скрипт был выполнен уже непосредственно на малинке.
Текст скрипта (файл test_15.py) и модуль nna (файл nna.py) находится в архиве nna_18.10.17_and_test_15.zip в приложении к данному топику.
Добавление от 23.10.2018
Метод addSensor модифицирован так, чтобы объекты класса Sensor можно было создавать "на лету" прямо в этой функции. Подробности и модифицированный вариант модуля nna - в этом топике.
PS
Коллеги! При реализации классов, я исходил из своих потребностей и представлений об их функционале. Но, если у кого-то есть замечания или дополнительные пожелания к функциональности разрабатываемых классов - дайте знать. Постараюсь их учесть в следующих релизах модуля.
Предыдущий топик Вернуться к оглавлению Следующий топик