Форум самогонщиков Сайт Барахолка Магазин Помощь солдатам

Ненавязчивая автоматизация ректификационной установки

Форум самогонщиков Автоматика
1 ... 71 72 73 74 75 76 77 ... 132 74
OldBean Доцент Красноярск 1K 1.4K
Отв.1460  17 Окт. 18, 18:17
17.5. Классы-обертки

Мы начинаем разработку классов-оберток, инкапсулирующих все низкоуровневые детали функционирования узлов установки. Все классы будут собраны в едином файле-модуле 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')
Если интерпретатор питона не ругнулся, значит все нормально. Мы создали датчик температуры с именем ts. У этого объекта есть несколько свойств, доступных для чтения: с - код АЦП, v - значение измеренной физической величины (в данном случае это будет температура) и u - единица измерения, которую мы задали в конструкторе при создании объекта (параметр конструктора unit). Обратиться к этим свойствам можно следующим образом: имя_объекта.свойство. Т.е. после имени объекта ставится точка, затем пишем имя свойства.

Реальный датчик температуры у нас подключен к нулевому каналу цифрового модуля. В модуле nna есть класс DM, который описывает цифровые модули. Конструктор этого класса имеет один параметр addr. Это адрес на шине i2c, по которому малинка обращается к этому цифровому модулю. Для создания объекта-цифрового модуля пишем в консоли интерпретатора питона:
dm = DM(0x15)
Здесь dm - это имя нашего виртуального цифрового модуля, а 0x15 - это его адрес на шине i2c.

Для подключения объектов-датчиков к объекту-цифровому модулю, у последнего есть метод addSensor(ch, sensor). У метода два параметра: ch - номер канала цифрового модуля, к которому мы подключен датчик, и sensor - ссылка на подключаемый объект-датчик. У нас реальный датчик температур подключен к нулевому каналу цифрового модуля. Поэтому пишем:
dm.addSensor(0, ts)
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 # Смотрим температуру датчика
ИМХО, компактно, просто и понятно. Скриншот выполнения этих команд из консоли рабочей станции, соединенной с малинкой по SSH, показан ниже:
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

Конечно, рассмотренный пример очень прост. Следующий пример немного сложнее. Для демонстрации, я подключил к малинке (через цифровой модуль) четыре датчика 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. Это класс-обертка для работы с датчиками BMP180, при помощи которых мы измеряем атмосферное давление и температуру воздуха. Эти датчики подключаются непосредственно к шине i2c, поэтому они немного "выпадают" из нашего концепта варианта LITE, в котором все датчики могут иметь достаточно длинные провода и подключаются к малинке через цифровые модули. Но атмосфера - она и около малинки атмосфера. Поэтому можно смириться с этим... ;)

Конструктор класса BMP180 не имеет параметров. Питоновской командой
atm = BMP180()
создается объект - датчик атмосферного давления. У объекта есть два свойства, доступные для чтения: p - атмосферное давление в мм.рт.ст. и t - температура воздуха в градусах Цельсия. Таким образом, atm.p - даст нам атмосферное давление, а atm.t - температуру (см. в качестве пример последние две строчки приведенного выше скрипта). И это - все. Инкапсуляция, таки, весьма удобная штука ;)

Скриншот после выполнения этого скрипта показан на рисунке ниже:
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

Этот скрипт был выполнен уже непосредственно на малинке.

Текст скрипта (файл test_15.py) и модуль nna (файл nna.py) находится в архиве nna_18.10.17_and_test_15.zip в приложении к данному топику.

Добавление от 23.10.2018

Метод addSensor модифицирован так, чтобы объекты класса Sensor можно было создавать "на лету" прямо в этой функции. Подробности и модифицированный вариант модуля nna - в этом топике.

PS
Коллеги! При реализации классов, я исходил из своих потребностей и представлений об их  функционале. Но, если у кого-то есть замечания или дополнительные пожелания к функциональности разрабатываемых классов - дайте знать. Постараюсь их учесть в следующих релизах модуля.

Предыдущий топик  Вернуться к оглавлению  Следующий топик
09_sch.png
09_sch.png Ненавязчивая автоматизация ректификационной установки. Автоматика.
10_2018-10-16-093406_1920x1080_scrot.png
10_2018-10-16-093406_1920x1080_scrot.png Ненавязчивая автоматизация ректификационной установки. Автоматика.

nna_18.10.17_and_test_15.zip 3.9 Кб
gol_avto Доцент Москва - Серпухов - Анапа 1.3K 458
Отв.1461  18 Окт. 18, 15:29
Попробовал модуль, работает! Вопрос. У меня 2 датчика MPX5010DP, подключал оба, на изменение давления реагируют до 75 мм рт.ст., но один показывает 9,676, второй 11,288 мм, когда оба штуцера свободны.
А как калибровать и чтобы при отсутствии на них воздействия давлением показывали 0 мм рт. ст.?
Этим коэффициентом? Но он ведь на 0 не повлияет, не так ли?
hps = Sensor(coef = 0.0733, unit = 'mm Hg') # Датчик кубового даления
12.jpg
12.jpg Ненавязчивая автоматизация ректификационной установки. Автоматика.
OldBean Доцент Красноярск 1K 1.4K
Отв.1462  18 Окт. 18, 17:22
один показывает 9,676, второй 11,288 мм, когда оба штуцера свободныgol_avto, 18 Окт. 18, 15:29
Мда... Сильный дисбаланс. Хорошо. В следующем релизе nna добавим в конструктор класса Sensor третий параметр offset. Для смещения ненулевого нуля.
Esc Профессор Москва 2K 2K
Отв.1463  19 Окт. 18, 15:23
в кубе иногда бывает довольно шумноOldBean, 13 Окт. 18, 11:19
"Фото" шумов кубового давления. Взял из трех погонов НДРФ на тарельчатых колонах. Для пущей наглядности свел данные в единную диаграмму.
shym_kybovogo_davleniya.png
Shym_kybovogo_davleniya. Ненавязчивая автоматизация ректификационной установки. Автоматика.

Легенды на диаграмме.
tКуб-1, 2, 3 - температура кубовой жидкости для трех погонов (отсчет значений левый игрек).
Дав-1, 2, 3 - аналогично кубовое давление в мм.рт.ст. (отсчет по правому игреку).

Для упрощения восприятия кривых давления, попросил Exel сдвинуть их вверх и вниз относительно зеленой кривой (обычно среднее значение около 10мм.рт.ст.):
• Погон №1 (красная кривая) - работа только программного усреднителя;
• Погон №2 (зеленая кривая) - добавил в пневмотрассу от куба до MPX5010DP дросселирующую иголку;
• Погон №3 (голубая кривая) - результат работы "пневматического интегратора";

2 датчика MPX5010DP...
... но один показывает 9,676, второй 11,288 мм, когда оба штуцера свободны.gol_avto, 18 Окт. 18, 15:29
В этих девайсиках допускается наличие некого напряжение на выходе, при нулевом дифференциальном давлении на датчик. Его значение примерно 0,2в. Для каждого датчика это напряжение индивидуальное. Моя автоматика вычитает "нулевую напружку датчика" из результата измерений.
gol_avto Доцент Москва - Серпухов - Анапа 1.3K 458
Отв.1464  19 Окт. 18, 16:29
автоматика вычитает "нулевую напружку датчика" из результата измерений.
Видимо это напряжение незначительно, но плавающее (а возможно просто шумы), поскольку сегодня еще раз запускал тест, давление датчики показали 10,115 - 10,482 мм и 11,581 - 11,142. Хотя разбросом в +-0,5 мм можно пренебречь
Esc Профессор Москва 2K 2K
Отв.1465  19 Окт. 18, 17:03, через 34 мин
Хотя разбросом в +-0,5 мм можно пренебречьgol_avto, 19 Окт. 18, 16:29
Ну не скажи.
Например при погоне браги, 0,5мм.рт.ст в моем кубике эт нормальное давление. А когда оно перевалит за 1мм.рт.ст. (вырастет на те же 0,5мм) - это уже предвестник беды. Контроллер понимает, что еще чуть, чуть и будет полная опа. "Бражные бульки" выползут из куба и полезут гадить вышестоящее оборудование. На отлавливании этих пренебрежительных чуть и работает функция "Авто Боботик" (электронный аналог популярного пеногасителя).
gol_avto Доцент Москва - Серпухов - Анапа 1.3K 458
Отв.1466  19 Окт. 18, 17:43, через 41 мин
10,115 - 10,482 мм и 11,581 - 11,142gol_avto, 19 Окт. 18, 16:29
Это разброс между двумя последовательными измерениями просто на воздухе, а поскольку результаты плавают, возможно придется значения обрабатывать программным интегратором или поставить RC цепочку между датчиком и АЦП.

Ну не скажи.Esc, 19 Окт. 18, 17:03
Допускаю. У меня не было опыта погонов с анализом давления в кубе.
OldBean Доцент Красноярск 1K 1.4K
Отв.1467  20 Окт. 18, 02:16
"Фото" шумов кубового давления. Взял из трех погонов НДРФ на тарельчатых колонах.Esc, 19 Окт. 18, 15:23
ИМХО, источником такого сильного шума является, скорее всего, тарельчатая колонна, а не куб. Косвенно на это намекает и резкое снижение шумов при переходе от голов к телу.

На насадочной колонне в пленочном режиме, скорее всего, шум будет гораздо меньше. Я в реальных процессах электронные датчики давления пока не использовал. Поэтому логов давления нет. Но у меня к кубу подключена U-образная трубка с водой. В процессе ректификации, вода в трубке лишь слегка подрагивает. Т.е. "визульно" шум давления в кубе - на уровне нескольких мм. водяного столба.

Видимо это напряжение незначительно, но плавающее (а возможно просто шумы), поскольку сегодня еще раз запускал тест, давление датчики показали 10,115 - 10,482 мм и 11,581 - 11,142.gol_avto, 19 Окт. 18, 16:29
Странно. У меня, вроде, ноль не гуляет. Когда обе пипки датчика открыты на атмосферу, код АЦП всегда 0x0029. И позавчера смотрел, и вчера, и вот сейчас посмотрел. По счастью, я оставил малинку включенной, когда уезжал с работы. Поэтому можно будет посмотреть долговременную стабильность нуля датчика давления. Сейчас запущу скрипт в цикле, с записью лога. Посмотрим, будет ли "гулять" ноль... ;)

Кстати, коррекцию нуля (параметр offset) я уже добавил в класс Sensor.

PS
Еще, кстати. Можете запустить этот тест у себя. Скрипт - в архиве в приложении к топику. Малинка будет каждые 10 секунд измерять дифференциальные давление датчиком MPX5010DP, атмосферное давление и выводить их на терминал и в файл с именем "log". Первая колонка - время в секундах с момента запуска скрипта, вторая - код АЦП сигнала с MPX5010DP в шестнадцатеричном формате, следующая - диф. давление в мм.рт.ст и последняя - атмосферное давление с датчика BMP180. Если датчик MPX5010DP у Вас подключен к другому каналу цифрового модуля (у меня подключен к 6-му) - поправьте строчку dm.addSensor(6, ps)
Esc Профессор Москва 2K 2K
Отв.1468  20 Окт. 18, 04:31
Странно. У меня, вроде, ноль не гуляет. Когда обе пипки датчика открыты на атмосферу, код АЦП всегда 0x0029. И позавчера смотрел, и вчера, и вот сейчас посмотрел.OldBean, 20 Окт. 18, 02:16
В свое время предпринял попытку постичь алгоритм функционирования топаса (локальное очистное сооружение). Для мониторинга динамики изменения уровней жидкости в отсеках установки (один из важнейших параметров), применял эту же модельку датчика давления. Отметил, что некоторым экземплярам МРХ был присущ "плавающий ноль".

ИМХО, источником такого сильного шума является, скорее всего, тарельчатая колонна, а не куб. Косвенно на это намекает и резкое снижение шумов при переходе от голов к телу.OldBean, 20 Окт. 18, 02:16
Тоже обратил на это внимание. Так же существует вероятность, что на шум влияет и крепость кубовой навалки (о кубовой спиртуозности можно судить по температурным кривым).
Для себя "головной шум" объясняю следующим образом. Порция высоко спиртуозной флегмы, попадая на низко спиртуозную поверхность кубовой жидкости, мгновенно испаряясь превращается в пар. Пар и даёт скачек давления. И чем менее спиртуозная кубовая жидкость, тем более заметен головастый шум. При отборе же тела, только часть флегмы возвращается в куб. Что и даёт меньший уровень шума.

Добавлено через 17мин.:

у меня к кубу подключена U-образная трубка с водой. В процессе ректификации, вода в трубке лишь слегка подрагивает.OldBean, 20 Окт. 18, 02:16
Не исключено, что U-образник массой своей воды, демпфирует кубовый шум в большей степени, чем "лёгкая" мембрана МРХ.
Думаю, что лог реального процесса, таки расставит большинство точек над и.
OldBean Доцент Красноярск 1K 1.4K
Отв.1469  20 Окт. 18, 06:11
Думаю, что лог реального процесса, таки расставит большинство точек над и.Esc, 20 Окт. 18, 04:31
Да. Конечно ;)

Добавлено через 1дн. 59мин.:

2gol_avto
Сегодня утром посмотрел как проходит тест стабильности нуля датчика MPX5010DP. Результат: за почти 28 часов непрерывного опроса датчика с интервалом в 10 сек, значение кода АЦП стоит четко на значение 0x0029 плюс-минус один квант АЦП (минимальное значение кода по всему логу - 0x0028, максимальное - 0x002a). Естественно, питание датчика и опорное напряжение АЦП 1-Wire адаптера берутся от одного и того же источника. Это важно.

Итог тестирования: либо мне очень повезло с этим датчиком (что маловероятно), либо слухи о нестабильности их нуля сильно преувеличены ;)
BogAD Кандидат наук Красногорск - Белово 403 184
Отв.1470  21 Окт. 18, 10:08
...тест стабильности нуля датчика MPX5010DP. Результат: за почти 28 часов непрерывного опроса датчика...OldBean, 20 Окт. 18, 06:11
В статическом режиме, без возмущения мембраны датчика? А если её по возмущать, показания вернуться к нулю?
OldBean Доцент Красноярск 1K 1.4K
Отв.1471  21 Окт. 18, 13:51
В статическом режиме, без возмущения мембраны датчика? А если её по возмущать, показания вернуться к нулю?BogAD, 21 Окт. 18, 10:08
Конечно в статике. Совсем непросто возмутить мембрану на расстоянии в десяток километров. Без жертв и разрушений ;) Но, завтра буду рядом с датчиком - попробую.

Добавлено 22.10.2018
"Повозмущал" немного мембрану. Методика: датчик давления опрашивается раз в секунду, результат пишется в лог. В какой-то момент времени я подцепляю кембрик со шприцом к пипке датчика (см.момент на графике в приложении). Шток шприца аккуратно, насколько это возможно, двигаю туда-сюда. Затем отдираю кембрик от пипки датчика. С точностью до кванта ноль возвращается на место. Так что, вроде бы, вполне приличный датчик...

Ну а более долговременные и "горячие" возмущения попробуем уже в реальной работе. Шприц - не самый удобный инструмент для таких тестов ;)
test_pressure_zero.png
test_pressure_zero.png Ненавязчивая автоматизация ректификационной установки. Автоматика.
OldBean Доцент Красноярск 1K 1.4K
Отв.1472  21 Окт. 18, 18:18
17.5.2. Класс RMS

Продолжаем разработку классов-оберток.

Из диагностических средств нам осталось рассмотреть еще один датчик - датчик RMS. Так же как и датчик атмосферного давления, датчик RMS подключен не к цифровому модулю, а непосредственно к шине i2c. Измерения среднеквадратичного напряжения производятся непрерывно. Время усреднения - 1 секунда. За это время суммируется 5000 квадратов мгновенных значений напряжения сети. Эта сумма передается малинке в качестве исходной информации для вычисления RMS. Она же используется и для вычисления кода, передаваемого контроллеру ТЭНа, в случае стабилизации мощности нагрева.

Конструктор класса RMS имеет два параметра, которые нужно задавать при создании объекта. Первый addr - адрес устройства на шине i2c, второй coef- калибровочный коэффициент для расчета напряжения по измеренным данным. Процедура калибровки будет рассмотрена ниже. Пример создания объекта датчика RMS:
rmss = RMS(0x11, 0.3838)
(0.3838 это калибровочный коэффициент для моего датчика RMS). После создания объекта, мы можем получить текущее значение среднеквадратичного напряжения сети в вольтах (свойство rms):
rms = rmss.rms,
сумму 5000 квадратов мгновенных значений напряжения сети (свойство crms):
crms = rmss.crms
и код (свойство code), необходимый для калибровки датчика RMS:
code = rmss.code
Процедура калибровки выглядит следующим образом. Образцовым вольтметром (желательно True RMS) измеряется среднеквадратичное напряжение сети. Пусть это будет Uобр. В это же время производится измерение напряжения датчиком RMS и значение свойства code при помощи приведенной выше команды. После этого вычисляется значение параметра coef по формуле:
coef = Uобр/code
В последствии, именно этот параметр и должен задаваться в конструкторе класса RMS.

Обновленный релиз модуля nna от 21.10.2018 и пара простых тестовых скриптов находятся в архиве в приложении к данному топику.

Предыдущий топик  Вернуться к оглавлению  Следующий топик
OldBean Доцент Красноярск 1K 1.4K
Отв.1473  22 Окт. 18, 06:51
Изменение метода addSensor класса цифрового модуля DM

При "виртуальном" подключении датчика (объект класса Sensor) к цифровому модулю (объект класса DM), необходимо сначала создать объект-датчик, а затем добавить его при помощи метода addSensor() класса DM. Но, поскольку все датчики (кроме RMS и атмосферного давления) подключаются к малинке только посредством цифовых модулей, можно объединить процесс создания датчика с подключением его к цифровому модулю. Это сделает рабочие скрипты более компактными и логичными. Поэтому я модифицировал метод addSensor() класса DM так, чтобы можно было создавать объекты-датчики "на лету" прямо в этом методе. Метод возвращает ссылку на созданный объект-датчик, по которой этот объект можно использовать в скрипте далее.

Новый прототип метода выглядит так:
addSensor(ch = 0, coef = 0, unit = None, offset = 0)
Параметры:
ch - номер канала,цифрового модуля к которому подключен датчик
coef - коэффициент для перевода кода АЦП в значение физической
      величины, измеряемой этим датчиком
unit - единица измерения этой физической величины (текстовая строка)
offset - смещение кода АЦП для коррекции нуля
Значения параметров по умолчанию указаны в прототипе выше. Пример использования - в скрипте ниже:

Скрытый текст
#coding:utf-8
import time
import sys
from nna import *

"""Демонстрация использования класса DM по-новому...
:author: OldBean
22.10.2018"""

# Создаем объект - цифровой модуль
dm = DM(addr = 0x15)
if dm is None:
  print('Не удалось создать объект класса DM')
  sys.exit(1)
# Добавляем датчики к цифровому модулю. Здесь ch - номер канала цифрового
# модуля, к которому подключен датчик
hts = dm.addSensor(ch = 0, coef = 0.0625, unit = '°C') # Датчик т-ры в кубе
cts = dm.addSensor(ch = 1, coef = 0.0625, unit = '°C') # Датчик т-ры в колонне
dts = dm.addSensor(ch = 2, coef = 0.0625, unit = '°C') # Датчик т-ры в дефлегматоре
wts = dm.addSensor(ch = 3, coef = 0.0625, unit = '°C') # Датчик т-ры в ТСА
con = dm.addSensor(ch = 4, coef = 1) # Концевик
hps = dm.addSensor(6, 0.0733, 'mm Hg', 0x0029) # Датчик кубового даления
tcon = dm.addSensor(ch = 7, coef = 1) # Термоконтакт

atm = BMP180() # Создаем объект - датчик атмосферного давления и температуры
if atm is None:
  print('Не удалось создать объект класса BMP180')
  sys.exit(1)

rmss = RMS(0x11) # Создаем объект - датчик RMS напряжения сети
if rmss is None:
  print('Не удалось создать объект класса RMS')
  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))
print('Напряжение сети: %3.1f В'%(rmss.rms))

Свежая версия модуля nna и файл приведенного выше теста - в архиве в приложении к топику

Перейти в топик про цифровой модуль и датчики
Перейти к оглавлению темы[url]
nic2015 Магистр Феодосия 219 56
Отв.1474  22 Окт. 18, 07:38, через 47 мин
Сергей подскажите, калибровочный коэффициент для перевода кода в вольты в nna.py нужно вставлять свой, полученный при калибровке RMS?
OldBean Доцент Красноярск 1K 1.4K
Отв.1475  22 Окт. 18, 09:44
калибровочный коэффициент для перевода кода в вольты в nna.py нужно вставлять свой, полученный при калибровке RMS?nic2015, 22 Окт. 18, 07:38
Если Вы имеете в виду значение, заданное по умолчанию, в объявлении конструктора класса RMS, то - не обязательно. Но в этом случае, свой калибровочный коэффициент Вы должны использовать при создании объекта-датчика RMS:
имя_датчика_RMS = RMS(адрес_датчика_RMS, Ваш_коэффициент_coef)
Или наоборот, Вы можете поставить свое значение калибровочного коэффициента непосредственно в файл nna.py в описание конструктора класса RMS, как значение по умолчанию. В этом случае, значением по умолчанию будет уже Ваш коэффициент, а не мой. Тогда, при создании объекта, параметр coef можете не писать. Т.е. инструкция будет выглядеть так:
имя_датчика_RMS = RMS(адрес_датчика_RMS)
gol_avto Доцент Москва - Серпухов - Анапа 1.3K 458
Отв.1476  22 Окт. 18, 10:50
Можете запустить этот тест у себя.OldBean, 20 Окт. 18, 02:16
Сергей, добрый день!
Запустил длинный тест. Ничего не понятно, всё пляшет
=====================================
"перешил" тиньку с помощью Geany. Стало стабильно, но всё-таки один сбой был. Помучаю ещё.
20181022_104614.jpg
20181022_104614.jpg Ненавязчивая автоматизация ректификационной установки. Автоматика.
2.jpg
2.jpg Ненавязчивая автоматизация ректификационной установки. Автоматика.
OldBean Доцент Красноярск 1K 1.4K
Отв.1477  22 Окт. 18, 13:29
Стало стабильно, но всё-таки один сбой был. Помучаю ещё.gol_avto, 22 Окт. 18, 10:50
Есть ощущение, что где-то "сопли". Например, код 0xffff будет периодически выскакивать, если болтается сигнальная линия 1-Wire. У Вас же датчик на макетке собран? Во время прошивки наверняка "пошевелили" макетку. Неплохо было бы внимательно проверить монтаж. Подергать проводки. Проверить "залипы". На всякий случай.
gol_avto Доцент Москва - Серпухов - Анапа 1.3K 458
Отв.1478  22 Окт. 18, 14:29
Добился стабильности. Теперь тарирую датчик, он немного занижал, поправил коэффициентом. В качестве эталона использовал стрелочный манометр.  Теперь смещение нуля. Правлю в файле nna.py (версия 18.10.22) параметр offset в этой строке
def __init__(self, coef = 0, unit = None, offset = -0.413):
у меня датчик показывает -0,413 мм рт. ст при свободных штуцерах, однако ничего не меняется. Я здесь правлю?
3.jpg
3.jpg Ненавязчивая автоматизация ректификационной установки. Автоматика.
OldBean Доцент Красноярск 1K 1.4K
Отв.1479  22 Окт. 18, 17:40
Теперь смещение нуля. Правлю в файле nna.py (версия 18.10.22) параметр offset в этой строкеgol_avto, 22 Окт. 18, 14:29
Здесь два ошибки.
Во-первых, файл nna.py - это отлаженная библиотека классов. Ее лучше вообще не трогать! По крайней мере на первых порах... А если у Вас два датчика с разными смещениями. Что будете туда писать?! Устанавливайте все коэффициенты и смещения в параметрах конструкторов при создании объектов. Для двух датчиков - два объекта и в каждом укажите свое смещение.
Во-вторых, параметр offset - это целое число (код АЦП) при нулевом дифференциальном давлении. Т.е. когда оба штуцера датчика давления открыты. Из Вашего предыдущего поста я вижу код 0x0023. Это код АЦП в шестнадцатеричном представлении, который получается когда датчик полностью открыт. Именно это число Вы должны указать в параметре offset, когда создаете объект-датчик давления.

Рассмотрим конкретный пример. Один датчик давления подключен, например, к 6 каналу цифрового модуля, а второй - к 7-му. Пишем скрипт:
#coding:utf-8

# Импортируем все из библиотеки nna
from nna import *

# Создаем объект - цифровой модуль, dm - имя объекта-цифрового модуля
dm = DM(addr = 0x15)

# Создаем и подцепляем к шестому каналу цифрового модуля первый датчик давления, 0x0023 - это Ваше смещение нуля. Его и задаем в конструкторе
ps1 = dm.addSensor(ch = 6, coef = 0.0733, unit = 'mm Hg', offset = 0x0023)

# Создаем и подцепляем к седьмому каналу цифрового модуля второй датчик давления. Его смещение я не знаю. Путь, к примеру, это будет 0x0031. Его и зададим в конструкторе
ps2 = dm.addSensor(ch = 7, coef = 0.0733, unit = 'mm Hg', offset = 0x0031)

# Обновляем данные цифрового модуля (данные пересылаются из цифрового модуля в малинку)
dm.update()

# Выводим на терминал значение давления и единицу измерения первого датчика давления, затем второго
print ps1.v, ps1.u
print ps2.v, ps2.u

Желательно проделать эти команды вручную в интерпретаторе питона. Почувствуйте как малинка Вас слушается и исполняет команды! Кстати, не забудьте сделать текущей ту папку, где лежит nna.py и оттуда же и запускайте интерпретатор питона: cd туда_где_nna.py затем python.