Форум самогонщиков Сайт Барахолка Магазин За тех, кто оффлайн

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

Форум самогонщиков Автоматика
1 ... 3 4 5 6 7 8 9 ... 126 6
OldBean Доцент Красноярск 1K 1.4K
Отв.100  29 Янв. 17, 17:16
Не... Здесь очень далеко от захлеба. Чисто пленочный режим. Перепад давления на колонне всего порядка 50 мм водяного столба.

А иногда пики на "дальних хвостах" бывают очень хорошо локализованы. Вот пример одного из старых логов (зеленый датчик стоял выше и очень близко к змеевику охлаждения, поэтому на абсолютное значение "зеленой" температуры не обращайте внимание).
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

Кстати, я этот пик на хвосте тогда отобрал в виде отдельной пробы (анализ, правда, не делал). Воняет каким-то очень знакомым и мерзким растворителем для краски.

Колонна же не только этанол может разделять... :)))
OldBean Доцент Красноярск 1K 1.4K
Отв.101  30 Янв. 17, 05:18
2 C-Bell

Есть еще один аргумент в пользу того, что аномалии (неровности и даже пики) на температурных кривых на "дальних хвостах" - это выходящие из колонны примеси с температурами кипения между температурами кипения спирта и воды. Я тут немного порылся в архивах и нашел сохранившийся лог одной из двойных ректификаций. В куб заливался разбавленный спирт-ректификат (сортировка). Т.е. примесей там было мало. Фрагмент лога - на рисунке. Это уже конец второй ректификации.
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

"Зеленый" датчик тогда у меня был расположен еще неудачно, поэтому сигнал немного зашумлен. Но, если отвлечься от шума, то хорошо видно, что для смеси почти чистого этанола и воды никаких аномалий (пиков и полочек) ни на красном датчике, ни на зеленом не наблюдается.
OldBean Доцент Красноярск 1K 1.4K
Отв.102  30 Янв. 17, 16:34
13.3. Скрипт автоматизации - некоторые подробности

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

Код скрипта автоматизации

#coding:utf-8
import sys, os, time
import collections
"""Архив с модулями  sens, contr и kbh находятся в приложении к
  данному топику"""

import sens, contr, kbh

"""Сначала создаем объекты, соответствующие датчикам и контроллерам.
  Параллельно производится проверка их наличия и работоспособности.

  Начнем с датчиков температуры (DS18B20). Идентификаторы датчиков,
  установленных в системе известны. Определяем соответствующие
  переменные"""

hid = 0x180a353 # ID датчика температуры куба
cid = 0x18c5c68 # ID датчика температуры колонны
did = 0x18c4de1 # ID датчика температуры дефлегматора
wid = 0x180c746 # ID датчика температуры выходящей воды
"""Создаем вспомогательный список tids, для удобства коллективной
  работы со всеми датчиками"""

tids = (hid, cid, did, wid)
"""Статический метод Ts() класса DS18B20 возвращает словарь, содержащий
  пары {идентификатор датчика : его температура} для всех датчиков,
  подключенных к шине 1-Wire"""

Ts = sens.DS18B20.Ts()
"""Проверим, все ли датчики, с идентификаторами, перечисленными выше,
  есть в этом словаре (т.е. висят на шине и исправны)"""

flag = False
for id in tids: # Пробегаем по списку нужных нам датчиков
 if Ts.get(id) != None: # Соответствующий ключ (id) есть есть в словаре
   print "0x%012x :% 7.3f°C" % (id, Ts[id]) # Доложим об этом...
 else: # Увы...
   print "Датчик с ID = 0x%012x отсутствует или неисправен" % (id)
   flag = True # Выставляем флаг, что нужного датчика нет на шине
if flag:
 print "Один или более датчиков DS18B20 отсутствуют или неисправны. Завершение работы."
 sys.exit(1)

"""С датчиками температуры разобрались. Теперь займемся датчиком
  RMS (действующее напряжение сети)"""

vs = sens.RMS() # Создаем объект - датчик RMS
if vs != None: # Датчик в наличии и функционирует
 V = vs.V
 if V > 100: print "Действующее напряжение сети %d В" % (V)
 else:
   print "Слишком низкое напряжение сети. Завершение работы."
   sys.exit(2)
else: pass # Ну на нет и суда нет. Можно работать и без датчика RMS
"""Датчик атмосферного давления - полезная вещь. Проверим его наличие
  и работоспособность. Если его нет - не беда. Будем работать без него"""

ps = sens.BMP180() # Создаем объект - датчик атмосферного давления
if ps != None: # Датчик в наличии и функционирует
 print "Атмосферное давление: \t%5.1f мм.рт.ст." % (ps.P)
 print "Температура окружающей среды:\t%5.2f°C" % (ps.T)

"""Создаем объекты-контроллеры исполнительных устройств"""
teh = contr.TEH(vs) # Создадим объект "ТЭН"
if teh == None:
 print "Контроллер ТЭНа отсутствует или неисправен. Завершение работы."
 sys.exit(3)
sd = contr.SD() # Создадим объект "устройство отбора"
"""В принципе можно работать и без клапана отбора. Например, с ручной
  "пережимкой". Если ситуация именно такова, то закомментируйте следующие
  три строчки"""

if sd == None:
 print "Контроллер клапана отбора отсутствует или неисправен. Завершение работы."
 sys.exit(3)

"""Все. С датчиками и исполнительными устройствами мы разобрались.
  Теперь переведем консоль в неблокирующий режим работы. Это нужно
  для того, чтобы можно было бы в главном цикле приложения обрабатывать
  нажатие клавиш клавиатуры. Необходимый для этого сервис организован
  в виде класса TT, который находится в модуле kbh. При создании объекта
  (экземпляра этого класса) как раз и происходит переход консоли
  в неблокирующий режим. При уничтожении объекта (в деструкторе)
  консоль возвращается к обычному режиму работы.

  Параметр timeout задает время ожидания нажатия клавиши (он может быть
  равен 0). В данном случае мы используем этот параметр для регулирования
  длительности одного такта главного цикла приложения. При timeout = 3000
  длительность такта составляет около 4 сек"""

timeout = 3000 # В мс
tt = kbh.TT(timeout)

"""Теперь сформируем карту режимов, доступных в данном приложении. Режимы
  пронумерованы от 0 до 6. Карта режимов представляет собой список
  именованных кортежей (т.е. к элементам кортежа можно обращаться
  по имени). Это очень удобно. Имена элементов кортежа:
  W     - мощность нагрева ТЭНа, Вт (вещественное число)
  stab  - стабилизация мощности нагрева ТЭНа (True/False)
  Q     - скорость отбора, мл/час (вещественное число)
  ststp - режим старт-стопа (True/Flase)"""

#-------------------------------------------------------------------------------
mrec = collections.namedtuple('mrec', 'W stab Q ststp')
modes = [] # Собственно список режимов
modes.append(mrec(0, False, 0, False))        # 0 - Только мониторинг
modes.append(mrec(2000, False, 0, False))     # 1 - Разгон
modes.append(mrec(600, True, 0, False))       # 2 - Холостой ход
modes.append(mrec(600, True, 40, False))      # 3 - Отбора голов
modes.append(mrec(600, True, 400, True))      # 4 - Отбора тела
modes.append(mrec(600, True, 400, False))     # 5 - Отбор хвостов
modes.append(mrec(2000, False, 1000, False))  # 6 - Пропарка колонны

mode = old_mode = 0 # Начинаем работать всегда с нулевого режима

"""Это начало общего отсчета времени (относительное время программы)
  и момент начала текущего режима работы"""

tst = rst = time.time()

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

if os.path.exists("log") and os.path.getsize("log") > 127:
 log = open("log", "r") # Нужно прочитать последнюю строку
 log.seek(-127, 2) # Встанeм немного недоходя до конца файла
 for line in open("log", "r"): # и считаем последнюю строку
   last_line = line
 prevStopTime = float(last_line.split()[1])
 tst -= prevStopTime*60.0 # Локальное время будет продолжаться с конца
                          # предыдущей сессии
 log.close()
 log = open("log", "a") # А теперь откроем его уже для добавления
else: # В противном случае создаем новый файл журнала а нулевое
 log = open("log", "w") # локальное время уже установлено выше

"""Все. Все подготовительные операции закончены. Входим в главный
  цикл приложения"""

while True:

 """Сначала посмотрим на состояние клавиатуры"""
 if tt.kbhit(): # Какая-то клавиша уже была нажата
   ch = tt.getch() # Смотрим что было нажато....
   if ch == 'q': break # Выходим из цикла - конец работы
   elif ord(ch) >= 48 and ord(ch) <= 57: # Ввели номер режима
     old_mode = mode; mode = int(ch)

 """Теперь довольно громоздкий блок в котором мы измеряем все доступные
    текущие параметры процесса и формируем две строки. Одна (ss) краткая
    и раскрашенная для вывода информации на консоль. Вторая (s)
    "ненакрашенная" и (обычно) более подробная - для записи в журнал"""


 """Сначала общая длительность процесса на данный момент и длительность
    текущего режима"""

 now = time.time(); dtm = (now - tst)/60.0; dtrm = (now - rst)/60.0
 ss = "% 7.2f % 7.2f\x1b[33m %d\x1b[0m" % (dtm, dtrm, mode)
 """Для журнала добавляем еще и глобальное время"""
 s = time.strftime("%y.%m.%d.%H.%M.%S")
 s += "% 7.2f % 7.2f %d" % (dtm, dtrm, mode)

 """Добавим для выдачи текущие значения температур с датчиков"""
 Ts = sens.DS18B20.Ts() # Сначала их измерим
 for id in tids: # Теперь добавим в строки для выдачи
   if id == cid: # Подкрасим температуру в колонне для консоли
     ss += "\x1b[32m% 6.2f\x1b[0m" % (Ts[id])
   else: ss += "% 6.2f" % (Ts[id])
   s +=  "% 7.3f" % (Ts[id])

 """Измеряем и выводим текущую мощность нагрева"""
 cW = teh.W
 ss += "\x1b[31m %4d\x1b[0m" % (cW); s +=  " %4d" % (cW)

 """Если есть датчик RMS, то в журнал выведем напряжение в сети"""
 if vs != None:
   V = vs.V; s +=  " %3d" % (V)

 """Если есть датчик атмосферного давления - выводим давление"""
 if ps != None:
   P = ps.P; ss += "% 5.1f" % (P); s += "% 5.1f" % (P)

 """Если есть клапан отбора - выводим скорость отбора и общий расход"""
 if sd != None:
   Q = sd.Q; ss += " %4d" % (Q); s += " %4d" % (Q)
   F = sd.F; ss += " %5d" % (F); s += " %5d" % (F)

 log.write(s + "\n"); log.flush() # Пишем данные в журнал
 print ss # и выводим на экран

 """Далее собственно и следует вся ненавязчивая автоматизация :)))

    В данной задаче автоматическое переключение режимов нужно только
    для стадии разгона. Т.е. в режиме разгона (режим 1) после закипания,
    когда температура в 1/3 колонны превысит, скажем, 60°C, нужно
    перейти в режим 2 (сбросить мощность на "штатный" уровень).
    Ну так так и объясняем малинке."""

 if mode == 1: # Текущий режим - разгон
   if Ts[cid] >= 60: # Куб закипел - пора сбрасывать мощность  
     old__mode = mode; mode = 2

 """Теперь обработаем ситуацию, когда произошла смена режима работы
    установки (автоматически, или по нажатию клавиши). Для обработки
    используем карту режимов"""

 if old_mode != mode:
   """Для режимов без стабилизации мощности (разгон, пропарка колонны и т.п.)
      мощность устанвливается только один раз при смене режима"""

   if not modes[mode].stab and mode != 0: teh.W = modes[mode].W              
   sd.Q = modes[mode].Q # А вот для скорости отбора мы так делаем всегда
   old_mode = mode
   rst = now # Фиксируем момент начала нового режима
 """Для режимов со стабилизацией мощности (это написано в карте режимов),
    мощность обновляем на каждом такте главного цикла приложения
    (естественно, с учетом напряжения сети, если подключен датчик RMS)"""

 if modes[mode].stab:
   teh.W = modes[mode].W

Классы-обертки получились достаточно удобными и сильно упрощают разработку скриптов автоматизации.

======================================

Предыдущий топик  Вернуться к оглавлению  Следующий топик
Asus Доцент Москва 1.3K 665
Отв.103  30 Янв. 17, 19:25
Дорогой Сергей, а как же коррекция уставки Т.кип. спирта по атм. давлению и давлению в 1/3 трубе?
Я недавно наблюдал его рост на 15 ед.за три часа.
А вакуумная перегонка?
U-M Специалист MSK 196 35
Отв.104  31 Янв. 17, 00:01
А вопрос такой-на фото изделия просматривается клавиатура. В скрипте обрабатывается, а вот по ее подключению нет информации?
OldBean Доцент Красноярск 1K 1.4K
Отв.105  31 Янв. 17, 05:32
а как же коррекция уставки Т.кип. спирта по атм. давлению и давлению в 1/3 трубе?Asus, 30 Янв. 17, 19:25
"Всему свой час и время всякому делу под небесами...". Просто идем шагами. Это первый скрипт для первого теста нового софта (с классами-обертками). У меня в кубе ректификационной установки, с прошлого года, от незаконченной ректификации, оставалось немного спирта с хвостами. Вот на этой простой задаче (выгнать хвосты) я и решил протестировать классы-обертки "в боевых условиях".  Я так об этом и писал в самом начале этого раздела.

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

А вакуумная перегонка?Asus, 30 Янв. 17, 19:25
Ну как-то пока не планировал... В последнее время от дистилляции (в хорошем смысле слова "дистилляция":))) отошел. Использую только для быстрого получения сырца из сахарной бражки. Просто душа как-то постепенно успокоилась на схеме: "сахарная "турбо-бражка" -> сырец -> двойной ректификат -> сортировка -> настойки". Ну иногда еще немножко экстракции (сокслетом) из чего-нибудь растительного... Поэтому пока далек от вакуумной дистилляции...

клавиатура. В скрипте обрабатывается, а вот по ее подключению нет информации?U-M, 31 Янв. 17, 00:01
Да. Что-то совсем выскочило из головы, что с малинкой можно работать в совершенно разных конфигурациях компьютерного железа. Постараюсь (не откладывая) написать небольшой топик - как это все сделано (у меня). Ну просто - как пример конфигурации компьютерного железа и организации работы с установкой.
ys1797 Доцент Санкт-Петербург 1K 329
Отв.106  31 Янв. 17, 19:49
А вопрос такой-на фото изделия просматривается клавиатура. В скрипте обрабатывается, а вот по ее подключению нет информации?U-M, 31 Янв. 17, 00:01

Если USB - просто втыкаем и работает.
OldBean Доцент Красноярск 1K 1.4K
Отв.107  01 Февр. 17, 06:55
14.1. Вариант организации работы с малинкой

Малинка - полноценный компьютер, снабженный операционной системой Linux и возможностью непосредственного подключения к компьютерным сетям. Поэтому вариантов организации "общения" с малинком много.

Самый простой (но не самый дешевый) вариант - подключить к малинке дисплей (через специальный разъем или HDMI), USB-клавиатуру и USB-мышку. В этом случае работа с малинкой ничем не отличается от работы на обычном персональном компьютере под Linux.

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

Обе локальные сети связаны посредством VPN. Поэтому я могу общаться с малинкой с любой рабочей станции в любой сети. Можно и с любого мобильного устройства, имеющего Wi-Fi (планшет, смартфон), вблизи любого из роутеров. Либо вообще с любой точки интернета, если вдруг приспичило или просто соскучился. Итак, с физическим уровнем все ясно - малинка уже в сети и открыта для общения.

14.1. SSH

Теперь возникает вопрос о прикладном уровне: "А как общаться?" В принципе можно использовать web-технологии. Организовать на малинке web-сервер или развернуть WebIOPi. Пописать всякие скрипты на JS и т.п. Модно и красочно..., но очень хлопотно и, на самом деле, не очень удобно. Да и неуниверсально. Конечно здесь я говорю только о задаче управления ректификационной установкой. Для многих других задач, бывает, что и альтернативы-то Web-технологиям не скоро найдешь.

Но, слава Богу, в мире есть не только броузеры и Web. Существуют другие, ИМХО, более удобные и универсальные технологии работы с удаленным компьютером (с нашем случае - с малинкой). Одна из таких - SSH. Образно говоря, SSH - это протокол прикладного уровня, который позволяет поверх открытых сетей организовать защищенный канал (как бы "туннель"), позволяющий работать с удаленным компьютером точно так же, как с обычной рабочей станцией, за которой ты сидишь непосредственно. Т.е. как будто клавиатура, мышь и "кусок дисплея" подключены прямо к удаленному (в том числе и за тридевять земель) компьютеру. Причем, это касается не только работы с текстовой консолью (через командную оболочку). При достаточной пропускной способности канала связи можно работать и в графике. С рабочим столом удаленного компьютера, запускать графические приложения, слушать музыку (оттуда), смотреть кино (тоже оттуда) и т.д.

Для работы по SSH на самой малинке устанавливать ничего не нужно. "Все включено" в дистрибутив ОС и запущено после загрузки системы. Единственное, что, возможно, потребуется установить - это клиента SSH. Но не на малинке, а на рабочей станции, планшете или смартфоне, с которого мы будем общаться с малинкой по SSH. Для любых ОС такие клиенты есть. И, обычно, не в единственном числе. После установки клиента на клиентский компьютер и установления SSH-соединения с малинкой, работа с ней становится единообразной независимо от того на чем клиент стоит.

Примеры сессий работы с малинкой по SSH с рабочей станции под Linux я уже неоднократно приводил в предыдущих топиках. После набора команды:
ssh имя_пользователя@IP_адрес_малинки
вводим пароль пользователя и все! Мы уже как бы "в малинке". Как будто эту клавиатуру, мышь и дисплей мы подключили непосредственно к малинке!

14.2. SSHFS

На базе SSH (точнее, ее расширения SFTP) существует еще одна технология, делающая работу с удаленным компьютером еще более удобной. Это SSHFS, которая позволяет монтировать удаленную файловую систему на локальной рабочей станции так, что с файлами удаленного компьютера можно работать точно так же, как будто они находятся здесь, на локальном компьютере. Это очень удобно! Здесь я еще раз хочу подчеркнуть, что протокол SSH защищенный и все операции с файлами тоже защищены и шифруются. Кстати, SSHFS есть и для Windows, но сам я работать с SSHFS под Windows не пробовал.

Рассмотрим простой пример (для рабочей станции под Ubuntu). Для начала нужно инсталлировать sshfs из репозитория при помощи команды:
sudo apt-get install sshfs
Затем создадим в нашей рабочей директории папку, куда будем монтировать малинкину рабочую папку (пользователя pi). Назовем ее rpi. Теперь монтируем удаленную рабочую директорию пользователя pi малинки в папку rpi на нашей рабочей станции:
sshfs pi@192.168.0.22:/home/pi ~/rpi
Здесь pi - имя пользователя малинки, /home/pi - это домашняя папка пользователя pi, а "~" - сокращенное обозначение домашней папки пользователя на рабочей станции (т.е. мою - /home/ku), т.е. полное имя точки монтирования - /home/ku/rpi.

Теперь вводим пароль и все! В файловом менеджере на нашей рабочей станции в папке rpi мы увидим все "рабочее хозяйство" пользователя pi малинки. Зайдем в папку nna малинки, где мы складывали все наши скрипты и модули. Щелкнем по файлу nna_02.py (это скрипт автоматизации, который мы как раз недавно обсуждали). Он откроется в текстовом редакторе, мы можем его посмотреть, отредактировать и сохранить. В общем, можем сделать все, как будто бы этот файл находится здесь на рабочей станции. Для иллюстрации - рисунок ниже.
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

По окончанию работы можно "отмонтировать" малинку от рабочей станции командой:
fusermount -u ~/rpi
Все. Папка rpi опустела, малинка ушла...

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


14.3. Как посмотреть лог (температуры) в виде графика

Ну и в заключение топика про SSH, расскажу еще об одной простой, но удобной технике. Иногда, в процессе ректификации, хочется взглянуть не только на сами значения текущей температуры, но на их динамику и историю. В этом случае представление информации в виде графика гораздо информативнее для человеческого восприятия, чем колонка цифр. Опять же, для этого совсем не обязательно мудрить с WebIOPi и скриптами на JS. С помощью SSH и пары питоновских библиотек это делается элементарно.

Есть питоновская библиотека paramiko, которая позволяет работать с SSH непосредственно из питона. Кроме того, есть замечательная питоновская библиотека matplotlib, которая позволяет строить всевозможные графики. Ссылки на эти библиотеки и на популярные статьи как ими пользоваться я поместил в топике "Полезные ссылки".

matplotlib обычно уже присутствует в питоне (если нет - нужно ее инсталлировать), а paramiko нужно установить самому. Как и все в Linux (Ubuntu), это делается легко. Пишем в консоли:
sudo apt-get install python-paramiko
и билиотека paramiko установлена. Дальше пишем питоновский скрипт, который будет соединяться с малинкой по SSH, забирать файл журнала, вытаскивать из него значения температурных датчиков и строить график. Текст скрипта (ниже) я постарался прокомментировать максимально подробно. Так что разобраться в его работе будет несложно. Имя пользователя малинки (pi) и пароль по умолчанию (raspberry) вводить не нужно - они уже прописаны в самом скрипте.

Текст скрипта для показывания графиков температур с малинки#!/usr/bin/python
#coding:utf-8
import paramiko # Модуль для работы с SSH
import pylab as pl # Библиотека для построения графиков (matplotlib)

ssh = paramiko.SSHClient() # Содаем клиента
""""Упрощаем" политику работы с ключами :) """
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.0.22", 22, "pi", "raspberry") # Сединяемся с малинкой
stdin, stdout, stderr = ssh.exec_command("cat nna/log") # Выполняем команду (уже на малинке)

t = []; Tb = []; Tc = []; Td = [] # Подготавливаем данные для построения графиков
"""Файл журнала (log) уже здесь в stdout. Перебираем его построчно и выбираем нужные
данные для построения графика"""

for line in stdout.read().splitlines():
 w = line.split() # Разбиваем строку на слова по пробельным символам
 """Далее формируем массивы (списки) соответствующих переменных, которые желаем
 отобразить на графике. Индекс - это номер колонки в файле журнала"""

 t.append(float(w[1]))  # Здесь у нас локальное время
 Tb.append(float(w[4])) # Это температура в кубе
 Tc.append(float(w[5])) # Это температура в колонне
 Td.append(float(w[6])) # Это температура на входе дефлегматора
"""Все. Массивы (списки) сформированы. Теперь выводим их в виде простого графика"""
pl.plot(t, Tb, "b", t, Tc, "r", t, Td, "g") # В параметрах - пары t, T и цвет
pl.xlabel(u'Время, мин') # Устанавливаем подписи к осям
pl.ylabel(u'Температура, °C')
pl.grid(True) # Пусть на графике будет сетка
legend = pl.legend ((u"Tкуб", u"Tкол", u"Tдеф")) # Формируем легенду
legend.draggable(True) # Чтобы легенду можно было таскать мышкой
pl.show() # Теперь, наконец, показываем наш график
Архив скрипта - в приложении к данному топику (файл log_viewer.py). Размещаем файл скрипта в какой-нибудь папке на рабочей станции, например temp и пишем в консоли (текущая директория, естественно, temp):
python log_viewer.py
...
Библиотека matplotlib - это целый мир, о котором можно долго разговаривать. Я ограничусь только тем, что покажу картинку с графиками последнего лога, полученные на рабочей станции с помощью скрипта, приведенного выше. Естественно, этот скрипт запускается на рабочей станции, а не на малике :))) С малинкой он (скрипт) общается по SSH.
 Ненавязчивая автоматизация ректификационной установки
Ненавязчивая автоматизация ректификационной установки. Автоматика.

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


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

--------------------------

На этом мы заканчиваем первый этап ненавязчивой автоматизации ректификационной установки.
Впереди у нас много интересной работы - уже не тестовые, а полные циклы ректификаций с разнообразными алгоритмами управления процессами.

======================================

Предыдущий топик  Вернуться к оглавлению  Следующий топик
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.108  01 Февр. 17, 07:15, через 20 мин
Обе локальные сети связаны посредством VPNOldBean, 01 Февр. 17, 06:55
Можно чуть подробнее?
OldBean Доцент Красноярск 1K 1.4K
Отв.109  01 Февр. 17, 07:34, через 20 мин
Можно чуть подробнее?C-Bell, 01 Февр. 17, 07:15
Если по-простому, то VPN - это технология, позволяющая организовывать безопасное соединение (точнее, объединение) сетей (например, две локальные сети) в одну логическую сеть поверх каких-нибудь открытых сетей типа Интернет. Каждый компьютер этой объединенной сети чувствует себя как бы внутри одной объединенной "локальной" сети. Это широко используемая технология. Есть и бесплатные (открытые) варианты. Но "чуть подробнее" непросто сделать - технология не из простых. Это задача, скорее, для админов. Лучше о ней почитать в Сети, например, для начала здесь.
C-Bell Научный сотрудник Улан-Удэ 1.8K 1.3K
Отв.110  01 Февр. 17, 09:16
OldBean, дорогой коллега!
Это я с виду только на военного похож.
А так то я парень сообразительный. Улыбающийся

Какими средствами VPN формируешь?
U-M Специалист MSK 196 35
Отв.111  01 Февр. 17, 11:30
Если USB - просто втыкаем и работает.ys1797, 31 Янв. 17, 19:49

Чего-то недопонимаю.

Если воткнули клавиатуру в USB, то по идее малинка средствами ОС сама с клавиатурой работает. Но в скрипте автоматизации есть строки
....
timeout = 3000 # В мс
tt = kbh.TT(timeout)
....

и далее там еще есть касаемо клавиатуры. Но я так понимаю, то уже идет обработка кнопок, которые подключены к GPIO, а не USB ?
OldBean Доцент Красноярск 1K 1.4K
Отв.112  01 Февр. 17, 12:19, через 49 мин
Какими средствами VPN формируешь?C-Bell, 01 Февр. 17, 09:16
Sorry, коллега - OpenVPN Подмигивающий

Чего-то недопонимаю.

Если воткнули клавиатуру в USB, то по идее малинка средствами ОС сама с клавиатурой работает. Но в скрипте автоматизации есть строки
....
timeout = 3000 # В мс
tt = kbh.TT(timeout)
....

и далее там еще есть касаемо клавиатуры. Но я так понимаю, то уже идет обработка кнопок, которые подключены к GPIO, а не USB ?U-M, 01 Февр. 17, 11:30
Нет. GPIO здесь вообще не при чем. Речь идет о клавиатуре, которая обеспечивает стандартный ввод (stdin). Самая обычная компьютерная клавиатура, с которой работает ОС. А где эта клавиатура находится и как она реализована - неважно. Это может быть клавиатура, подключенная непосредственно к USB малинки. Либо клавиатура, на рабочей станции из которой мы работаем с малинкой по SSH. Некоторые сложности и нюансы реализации как бы "прерываний" от клавиатуры (функция kbhit) связана с тем, что мы имеем дело все-таки с терминалом (телетайпом в ранней юности). Поэтому я и сделал отдельный класс TT, где "инкапсулировал" все терминальные нюансы. Чтобы функция kbhit() выглядела простой. Такой же простой, как, например, в MS DOS.

Про timеout. Это время, в течение которого система будет тупо ждать каких-нибудь действий с клавиатурой (той самой, о которой шла речь в предыдущем абзаце). Можно timeout сделать вообще равным нулю и не заставлять систему простаивать в ожидании. В этом случае мы будем моментально (без дополнительных задержек) получать информацию о всех событиях, произошедших с клавиатурой. Я просто использую этот параметр как некий "бесплатный" Улыбающийся способ задания паузы в главном цикле приложения.
U-M Специалист MSK 196 35
Отв.113  01 Февр. 17, 13:35
Нет. GPIO здесь вообще не при чем.OldBean, 01 Февр. 17, 12:19

Опс. А за что тогда отвечают кнопки на фото установки, если не секрет?

bezimyannii.png
Bezimyannii. Ненавязчивая автоматизация ректификационной установки. Автоматика.
Безымянный.png
Безымянный.png Ненавязчивая автоматизация ректификационной установки. Автоматика.
OldBean Доцент Красноярск 1K 1.4K
Отв.114  01 Февр. 17, 17:03
Опс. А за что тогда отвечают кнопки на фото установки, если не секрет?U-M, 01 Февр. 17, 13:35
А... Теперь понятно, о чем речь. Sorry, я что-то сразу и не въехал...

Эти кнопки не подключены - старые задумки. Собирался (как вариант) сделать автономный режим работы малинки (без сети, без клавиатуры и без монитора). Четыре кнопки должны были выполнять запуск, переключение режимов работы и аварийную остановку. Но потом отказался от такого варианта работы. А кнопки так и остались - не стал убирать, т.к. через эту платку еще 5 вольт заводится для питания ардуинок.
U-M Специалист MSK 196 35
Отв.115  01 Февр. 17, 17:05, через 3 мин
Ага, теперь понятно.
OldBean Доцент Красноярск 1K 1.4K
Отв.116  15 Февр. 17, 07:05


Как-то один хороший знакомый попросил помочь автоматизировать процесс ректификации. Я предложил ему повторить мой вариант "ненавязчивой автоматизации". Поскольку мой знакомый - человек довольно далекий от электроники и программирования, договорились на том, что я ему спаяю электронику, прошью микроконтроллеры и научу минимальной работе с малинкой. А остальное он делает сам (остальное он умеет хорошо :))). Список всего необходимого (что нужно было подкупить) я ему отдал и через некоторое время он притащил мне все комплектующие. После этого я специально все сделал "тупо и строго по прописям", которые сам же и написал в этой ветке. Без фанатизма, с перерывами, на все (от изготовления печатных плат до прошивки, полной сборки и тестирования) ушло два дня. Вся электроника и софт заработали сразу. Калибровка датчика RMS тоже прошла безо всяких проблем. Так что "прописи" получились достаточно "вменяемыми" для повторения этих устройств без особых напряжений и размышлений. :)))

Тем не менее, при тестировании полной системы (все платы вместе с малинкой) возникла одна неожиданная проблема. При чтении значения напряжения (с датчика RMS) периодически в малинку приходили некорректные (существенно заниженные) значения напряжения. Раньше (в частности, на моей системе) такого никогда не наблюдалось. После локализации ошибки и небольшой "рефлексии" стало понятно, что причина находится где-то в реализации I2C в самой малинке - при чтении байта с относительно медленного "слэйва" (ведомого устройства) периодически просто "пропадал" старший бит!!! Причем, это происходило только на новых версиях малинки (Raspberry Pi 3 Model B v.1.2), которую как раз купил мой знакомый. Испытание еще двух "доступных" малинок этой же серии показало типичность этого сбоя для этих малинок. Интересно, что на моей старенькой малинке (одна из ранних версий "B", купленная еще в 2013 году - Raspberry Pi 2011.12) шина I2C работает абсолютно корректно (с этими же ведомыми устройствами и софтом). Причем, с baudrate по умолчанию - 100000!

Можно рассмотреть три подхода, лежащих на поверхности, для "фиксации" этой проблемы:

1. Самое простое решение - поставить "костыль". Для данной задачи это сделать очень просто. Поскольку "пропадает" только старший бит, а диапазон изменения напряжения сети невелик, то можно "отнормировать" значение так, чтобы оно не превышало 127 (т.е. старший бит всегда 0). Например, если напряжение в сети не превышает 250В и не ниже 123В, то можно просто вычитать из него 123. "Костыль" действительно очень простой, но не очень красивый. Решил отложить на самый конец (если не удастся решить проблему как-нибудь иначе, в разумные сроки :)))

2. Повозиться с I2C на стороне слейва (т.е. - ардуинки). Но, к сожалению, под рукой у меня не было никакого логического анализатора. А возиться с шиной без него - довольно хлопотное дело. Поэтому это решение тоже отпало (пока).

3. Ну и еще одно довольно простое решение - уменьшить скорость шины I2C. В данной системе автоматизации реальная средняя скорость обмена по I2C между малинкой, контроллерами и датчиками довольно мала (порядка байта в секунду и даже менее!). Поэтому запас по скорости шины очень большой. В частности, уменьшение скорости до baudrate=9600 полностью устраняет описанную выше проблему со старшим битом. При тестировании в течение суток (точнее - 100 тыс. обменов запись/чтение) при такой скорости не возникло ни одной ошибки записи/чтения между ардуинкой и малинкой по шине I2C.

Вот на этом варианте я и остановился.

Ну и теперь - как это (снижение скорости шины I2C) сделать. Делается это элементарно. Поскольку малинка является мастером (ведущим устройством), то все изменения производятся только на ней.

Шаг 1. Заходим в малинку по ssh (адрес поставьте свой):
ssh pi@192.168.0.62
Шаг 2. Создаем файл i2c.conf или редактируем, если он уже существует,  в редакторе nano командой:
sudo nano /etc/modprobe.d/i2c.conf
В файл нужно вставить вот такую строчку:
options i2c_bcm2708 baudrate=9600
Шаг 3. Сохраняем файл (cntr+O) и выходим из редактора (cntr+X).
Шаг 4. Далее перезагружаем малинку командой:
sudo reboot
После перезагрузки опять соединяемся с малинкой по ssh и проверим скорость командой:
sudo cat /sys/module/i2c_bcm2708/parameters/baudrate

Все. Таким способом, указанная выше проблема устраняется.
Может быть кто-нибудь сталкивался с такой проблемой и/или знает более "изящное" ее решение?
capsolo Новичок Зелик 5.3K 1.6K
Отв.117  15 Февр. 17, 08:52
3 вариант самый правильный. Поддерживаю. Однако предполагаю что причина - не версия платы, а наводки на линии
OldBean Доцент Красноярск 1K 1.4K
Отв.118  15 Февр. 17, 14:39
Однако предполагаю что причина - не версия платы, а наводки на линииcapsolo, 15 Февр. 17, 08:52
Все, конечно, возможно в этом мире... :))) Нужно как-нибудь (когда будет время) сесть хотя бы просто с осциллографом и посмотреть что там делается на шине. Может быть в предстоящие праздники удастся повозиться с этим вопросом. Если разберусь - расскажу в чем же дело.

Маловероятно, что это просто наводка по шине. Во-первых шина достаточно короткая (порядка 10 см) и никаких мощных "искрящих" устройств вблизи не работало. Во-вторых, на старой малинке таких сбоев нет (совсем нет). Причем платы и софт те же самые. И, в-третьих, при случайных наводках сбои были бы более случайными (не только старший бит). А так - строго старший бит, и строго - в ноль. Ну и еще - в сети есть сообщения о баге малинки, связанным с растягиванием синхроимпульсов по требованию ведомого устройства (см. Raspberry Pi I2C clock-stretching bug). Разработчик даже не рекомендует подключать непосредственно к шине I2C малинки медленные устройства, имеющие возможность затягивать синхроимпульсы для замедления скорости передачи. Все это наводит на мысли, что причина, скорее всего в малинке (точнее - в ее процессоре). Но я пока еще глубоко в это дело не въезжал. В общем - разбираться надо. А пока - просто снижать скорость. Благо - есть куда...
сообщение удалено
OldBean Доцент Красноярск 1K 1.4K
Отв.119  15 Февр. 17, 18:30
На новой (RPi 3 model B) платах резисторы впаяны. Померил тестером. Оба - 1.8k, как и должно быть по схеме. Старая малинка сейчас в другом месте - завтра буду рядом - гляну.
------------
Кстати, где-то я читал, что малинки вроде бы (принципиально!) делают только в Англии. На самой плате написано Made in the UK. Может и вправду не китайцы? :)))