Извини, но просто повторяюсьDmi_D, 10 Февр. 18, 23:16
Пардон, не внимателен. Да, я видел. Полезно почитать отзывы, прежде чем покупать. к примеру нашел "прежде всего это не UPS! продавцом, используя это слово в описании .. я тестировал его, и если Я отрезать власти в филиал выход всегда есть задержки и например оранжевый PI перезагрузки сам .. The consumption of Orange PI ~ 0.32A так очень малый ток, но даже с этой небольшой ток это устройство не может вести себя, как UPS!" Т.е Orange PI на нем перегружается. Наша Малинка думаю тоже не вытерпит это... Да и по отзывам, греется как печка. На нетребовательную слаботочку может сгодится.
Dmi_D
Кандидат наук
Минск
393 138
Отв.1142 11 Февр. 18, 00:30 (через 24 мин)
Прости, не понял, о чем ты. В смысле, это отзыв на твою или на мою ссылку?
Я уже после поста перерыл отзывы.... Давай так - я получаю модуль, тестирую, отчитываюсь. А то делим шкуру, а медведя, может, и не было. Тайм-аут до получения посылки.
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1145 12 Февр. 18, 14:01
Всем, доброго дня. В связи с тем, что у меня часто выбивает термодатчики (подключены к raspberry Pi Zero), решил поизучать этот вопрос. Сделал программу на основе nna_02.py Скрытый текст#coding:utf-8 import sys, os, time import collections """Архив с модулями sens, contr и kbh находятся в приложении к данному топику""" import sens, contr, kbh
"""Сначала создаем объекты, соответствующие датчикам и контроллерам. Параллельно производится проверка их наличия и работоспособности.
Начнем с датчиков температуры (DS18B20). Идентификаторы датчиков, установленных в системе известны. Определяем соответствующие переменные""" hid = 0x8000001ee27b # ID датчика температуры куба cid = 0x8000001ef6e6 # ID датчика температуры колонны did = 0x000006273720 # ID датчика температуры дефлегматора wid = 0x8000000419af # 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) #----------------------------------------------------------------------- """Это начало общего отсчета времени (относительное время программы) и момент начала текущего режима работы""" tst = rst = time.time() #----------------------------------------------------------------------- i=0 #----------------------------------------------------------------------- """Все. Все подготовительные операции закончены. Входим в главный цикл приложения""" while True: #----------------------------------------------------------------------- i+=1; ss = "% 5d" % (i) # Счетчик циклов #----------------------------------------------------------------------- """Сначала общая длительность процесса на данный момент и длительность текущего режима""" now = time.time(); dtm = (now - tst)/60.0 ss += "% 7.2f" % (dtm) #----------------------------------------------------------------------- """Добавим для выдачи текущие значения температур с датчиков""" 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]) #----------------------------------------------------------------------- print ss # и выводим на экран time.sleep(5) В результате, если в процессе работы программы отключить датчики, на экране будут отображаться нули. Если подключить датчики, то показания восстанавливаются. В первой строке, после восстановления показаний, может отображаться 85.0. Если не подключать датчики, то через 21 шаг происходит сбой программы. Первый вопрос: почему в течение 21 шага отображаются нули? 2018-02-12-113449_635x822_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Изменил программу, добавив команду на завершение работы программы в случае если датчик отвалился. Скрытый текст#coding:utf-8 import sys, os, time import collections """Архив с модулями sens, contr и kbh находятся в приложении к данному топику""" import sens, contr, kbh #import contrSTPR, sensWEIGHT #-------------------------------------------------------------------------------- """Сначала создаем объекты, соответствующие датчикам и контроллерам. Параллельно производится проверка их наличия и работоспособности. #-------------------------------------------------------------------------------- Начнем с датчиков температуры (DS18B20). Идентификаторы датчиков, установленных в системе известны. Определяем соответствующие переменные""" hid = 0x8000001ee27b # ID датчика температуры куба cid = 0x8000001ef6e6 # ID датчика температуры колонны did = 0x000006273720 # ID датчика температуры дефлегматора wid = 0x8000000419af # 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)
#-------------------------------------------------------------------------------- """Это начало общего отсчета времени (относительное время программы) и момент начала текущего режима работы""" tst = rst = time.time() #-------------------------------------------------------------------------------- i=0 #-------------------------------------------------------------------------------- """Все. Все подготовительные операции закончены. Входим в главный цикл приложения""" while True: #-------------------------------------------------------------------------------- i+=1; ss = "% 5d" % (i) # Счетчик циклов #-------------------------------------------------------------------------------- """Сначала общая длительность процесса на данный момент и длительность текущего режима""" now = time.time(); dtm = (now - tst)/60.0 ss += "% 7.2f" % (dtm) #-------------------------------------------------------------------------------- """Добавим для выдачи текущие значения температур с датчиков""" Ts = sens.DS18B20.Ts() # Сначала их измерим flag = False for id in tids: # Теперь добавим в строки для выдачи if id in Ts: # Если датчик с таким ID есть в словаре, то выведем его температуру if id == hid: # Датчик в кубе Tcub Tcub = Ts[id] ss += "% 7.2f" % (Tcub) if id == cid: # Подкрасим температуру в колонне для консоли и определим переменную Tcol Tcol = Ts[id] ss += "\x1b[32m %7.2f\x1b[0m" % (Tcol) if id == did: # Подкрасим температуру в дефлегматоре для консоли и определим переменную Tdef Tdef = Ts[id] ss += "\x1b[33m %7.2f\x1b[0m" % (Tdef) if id == wid: # Датчик холодильника Thol Thol = Ts[id] ss += "% 7.2f" % (Thol) else: ss += "\x1b[31m %6.2f\x1b[0m" % (0.) # А если такого датчика нет - ставим нули. flag = True if flag: print "Завершение работы" sys.exit(1) #-------------------------------------------------------------------------------- print ss # и выводим на экран time.sleep(5) Результат такой же как и прежде, за исключением того, что программа завершается по команде, но через те же 21 шаг, отображая при этом нули. 2018-02-12-114043_635x822_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. В следующей модификации программы, вместо команды завершения программы, дал команду на отображение нулей красным цветом. Скрытый текст#coding:utf-8 import sys, os, time import collections """Архив с модулями sens, contr и kbh находятся в приложении к данному топику""" import sens, contr, kbh import contrSTPR, sensWEIGHT #-------------------------------------------------------------------------------- """Сначала создаем объекты, соответствующие датчикам и контроллерам. Параллельно производится проверка их наличия и работоспособности. #-------------------------------------------------------------------------------- Начнем с датчиков температуры (DS18B20). Идентификаторы датчиков, установленных в системе известны. Определяем соответствующие переменные""" hid = 0x8000001ee27b # ID датчика температуры куба cid = 0x8000001ef6e6 # ID датчика температуры колонны did = 0x000006273720 # ID датчика температуры дефлегматора wid = 0x8000000419af # 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)
#-------------------------------------------------------------------------------- """Параметр timeout задает время ожидания нажатия клавиши (он может быть равен 0). В данном случае мы используем этот параметр для регулирования длительности одного такта главного цикла приложения. При timeout = 3000 длительность такта составляет около 4 сек""" #timeout = 3910 # В мс. Должно быть 5 сек. #tt = kbh.TT(timeout)
"""Это начало общего отсчета времени (относительное время программы) и момент начала текущего режима работы""" tst = rst = New_time = time.time() #-------------------------------------------------------------------------------- i=0 #-------------------------------------------------------------------------------- """Все. Все подготовительные операции закончены. Входим в главный цикл приложения""" while True: #-------------------------------------------------------------------------------- i+=1; ss = "% 5d" % (i) # Счетчик циклов #-------------------------------------------------------------------------------- """Сначала общая длительность процесса на данный момент и длительность текущего режима""" now = time.time(); dtm = (now - tst)/60.0 ss += "% 7.2f" % (dtm) #-------------------------------------------------------------------------------- """Добавим для выдачи текущие значения температур с датчиков""" Ts = sens.DS18B20.Ts() # Сначала их измерим for id in tids: # Теперь добавим в строки для выдачи if id in Ts: # Если датчик с таким ID есть в словаре, то выведем его температуру if id == hid: # Датчик в кубе Tcub Tcub = Ts[id] ss += "% 7.2f" % (Tcub) if id == cid: # Подкрасим температуру в колонне для консоли и определим переменную Tcol Tcol = Ts[id] ss += "\x1b[32m %7.2f\x1b[0m" % (Tcol) if id == did: # Подкрасим температуру в дефлегматоре для консоли и определим переменную Tdef Tdef = Ts[id] ss += "\x1b[33m %7.2f\x1b[0m" % (Tdef) if id == wid: # Датчик холодильника Thol Thol = Ts[id] ss += "% 7.2f" % (Thol) else: ss += "\x1b[31m %6.2f\x1b[0m" % (0.) # А если такого датчика нет - ставим нули. #-------------------------------------------------------------------------------- time.sleep(5) print ss # и выводим на экран В результате после 21-го шага отображения нулей, начинают бесконечно отображаться нули красного цвета. Сама программа не завершается. То есть во всех этих трех вариантах, команда else:, непонятно почему выполняется только через 21 шаг после возникновения проблемы. 2018-02-12-115044_635x822_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Новая модификация программы: Скрытый текст#coding:utf-8 import sys, os, time import collections """Архив с модулями sens, contr и kbh находятся в приложении к данному топику""" import sens, contr, kbh import contrSTPR, sensWEIGHT import RPi.GPIO as GPIO ReadSensors = False #----------------------------------------------------------------------- GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) # Определяем пины по номерам GPIO.setup(12, GPIO.OUT) # Пин 12 - вывод GPIO.output(12,1) # Подаем высокое на пин 12 time.sleep(2) """Сначала создаем объекты, соответствующие датчикам и контроллерам. Параллельно производится проверка их наличия и работоспособности. #----------------------------------------------------------------------- Начнем с датчиков температуры (DS18B20). Идентификаторы датчиков, установленных в системе известны. Определяем соответствующие переменные""" hid = 0x8000001ee27b # ID датчика температуры куба cid = 0x8000001ef6e6 # ID датчика температуры колонны did = 0x000006273720 # ID датчика температуры дефлегматора wid = 0x8000000419af # 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)
#----------------------------------------------------------------------- """Это начало общего отсчета времени (относительное время программы) и момент начала текущего режима работы""" tst = rst = New_time = time.time() #----------------------------------------------------------------------- i=0 # Общий счетчик error_counter = 0 # Счетчик ошибок #----------------------------------------------------------------------- """Все. Все подготовительные операции закончены. Входим в главный цикл приложения""" while True: #----------------------------------------------------------------------- i+=1; ss = "% 5d" % (i) """Теперь довольно громоздкий блок в котором мы измеряем все доступные текущие параметры процесса и формируем две строки. Одна (ss) краткая и раскрашенная для вывода информации на консоль. Вторая (s) "ненакрашенная" и (обычно) более подробная - для записи в журнал""" #----------------------------------------------------------------------- """Сначала общая длительность процесса на данный момент и длительность текущего режима""" now = time.time(); dtm = (now - tst)/60.0 ss += "% 7.2f" % (dtm) #----------------------------------------------------------------------- while ReadSensors == False: print "Считываю датчики" Ts = sens.DS18B20.Ts() # Считаем датчики if Ts.get(id) != None and Ts[id] != 0: # Соответствующий ключ (id) есть есть в словаре ReadSensors = True if Ts[id] == 85.: ReadSensors = False time.sleep(2) print "Температура = %4.1f Возвращаюсь к считыванию датчиков." % (Ts[id]) continue print "Датчики считаны" else: # Увы... print "Датчики отсутствуют или неисправны" ReadSensors = False # GPIO.output(12,0) # Отключаем 3.3V от DS18B20 print "Отключаю питание" time.sleep(0.2) GPIO.output(12,1) # Включаем 3.3V на DS18B20 print "Включаю питание" error_counter += 1 time.sleep(2)
for id in tids: # Теперь добавим в строки для выдачи if id in Ts: # Если датчик с таким ID есть в словаре, то выведем его температуру if id == hid: # Датчик в кубе Tcub Tcub = Ts[id] ss += "% 7.2f" % (Tcub) if id == cid: # Подкрасим температуру в колонне для консоли и определим переменную Tcol Tcol = Ts[id] ss += "\x1b[32m %7.2f\x1b[0m" % (Tcol) if id == did: # Подкрасим температуру в дефлегматоре для консоли и определим переменную Tdef Tdef = Ts[id] ss += "\x1b[33m %7.2f\x1b[0m" % (Tdef) if id == wid: # Датчик холодильника Thol Thol = Ts[id] ss += "% 7.2f" % (Thol) #----------------------------------------------------------------------- ss += "% 5d" % (error_counter) print ss # и выводим на экран time.sleep(5) ReadSensors = False Так как после кратковременного отключения датчиков и последующего включения, показания восстанавливаются, пришла идея сделать так, чтобы при сбое датчика, автоматически отключалось и включалось питание. Для этого подключил питание датчиков к GPIO18 (pin 12). 2018-02-12-120200_635x822_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Казалось бы, проблема разрешилась. Но при использовании этого блока в основной программе происходит следующее - после восстановления питания, не понятно от куда появляются нули. Четыре группы нулей - по количеству датчиков. И если датчики не подключать в течение более длительного времени, то и количество групп нулей возрастает кратно количеству сообщений о неисправности датчиков. 2018-02-12-120937_995x966_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Скрытый текст#coding:utf-8 import sys, os, time import collections """Архив с модулями sens, contr и kbh находятся в приложении к данному топику""" import sens, contr, kbh import contrSTPR, sensWEIGHT import RPi.GPIO as GPIO ReadSensors = False Tcol_list=[] Tdef_list=[] dWeight = 0 dWeight1 = 0 Column_stabilized = False Tcol_max = False Max_ekstremum = False Temperature_grows = False wght_new = 0 wght_correct = 0 Old_Weight = 0 Start_time = 0 Finish_time = 0 Sel_Speed = 0 dTime = 0 #-------------------------------------------------------------------------------- """Сначала создаем объекты, соответствующие датчикам и контроллерам. Параллельно производится проверка их наличия и работоспособности. #-------------------------------------------------------------------------------- Начнем с датчиков температуры (DS18B20). Подключаем питание датчиков на пин 12 (GPIO 18), определяем его как пин вывода и подаем на него 1 (3.3V). """ GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) # Определяем пины по номерам GPIO.setup(12, GPIO.OUT) # Пин 12 - вывод GPIO.output(12,1) # Подаем высокое на пин 12 time.sleep(2) """Идентификаторы датчиков, установленных в системе известны. Определяем соответствующие переменные""" hid = 0x8000001ee27b # ID датчика температуры куба cid = 0x8000001ef6e6 # ID датчика температуры колонны did = 0x000006273720 # ID датчика температуры дефлегматора wid = 0x8000000419af # 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) #-------------------------------------------------------------------------------- """Датчик веса.""" weight = sensWEIGHT.BALANCE() if weight != None: #Датчик веса в наличии и функционирует print "Вес: %5.1f грамм." % (weight.B) else: None #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- """Создаем объекты-контроллеры исполнительных устройств""" #-------------------------------------------------------------------------------- teh = contr.TEH(vs) # Создадим объект "ТЭН" if teh == None: print "Контроллер ТЭНа отсутствует или неисправен. Завершение работы." sys.exit(3) #-------------------------------------------------------------------------------- #sd = contr.SD() # Создадим объект "устройство отбора" """В принципе можно работать и без клапана отбора. Например, с ручной "пережимкой". Если ситуация именно такова, то закомментируйте следующие три строчки""" #if sd == None: # print "Контроллер клапана отбора отсутствует или неисправен. Завершение работы." # sys.exit(3) #-------------------------------------------------------------------------------- Deflegmator=contrSTPR.STPR(addrSTPR=0x07) if Deflegmator == None: print "Контроллер Дефлегматора отсутствует или неисправен. Завершение работы." sys.exit(4) Holodilnik=contrSTPR.STPR(addrSTPR=0x08) if Holodilnik == None: print "Контроллер Холодильника отсутствует или неисправен. Завершение работы." sys.exit(5) #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- """Все. С датчиками и исполнительными устройствами мы разобрались. Теперь переведем консоль в неблокирующий режим работы. Это нужно для того, чтобы можно было бы в главном цикле приложения обрабатывать нажатие клавиш клавиатуры. Необходимый для этого сервис организован в виде класса TT, который находится в модуле kbh. При создании объекта (экземпляра этого класса) как раз и происходит переход консоли в неблокирующий режим. При уничтожении объекта (в деструкторе) консоль возвращается к обычному режиму работы.
Параметр timeout задает время ожидания нажатия клавиши (он может быть равен 0). В данном случае мы используем этот параметр для регулирования длительности одного такта главного цикла приложения. При timeout = 3000 длительность такта составляет около 4 сек""" timeout = 3910 # В мс. Должно быть 5 сек. 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(650, 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 = New_time = 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': #GPIO.output(12,0) # Отключаем 3.3V GPIO.cleanup() 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) """Проверим и выведим информацию о продолжительности цикла..""" Old_time = New_time New_time = time.time() Duration_of_cycle = New_time - Old_time """Выводим информацию о продолжительности цикла.""" ss += "% 2d" % (Duration_of_cycle) #----------------------------------------------------------------------- """Добавим для выдачи текущие значения температур с датчиков""" while ReadSensors == False: print "Считываю датчики" Ts = sens.DS18B20.Ts() # Считаем датчики if Ts.get(id) != None and Ts[id] != 0: # Соответствующий ключ (id) есть есть в словаре ReadSensors = True if Ts[id] == 85.: ReadSensors = False time.sleep(2) print "Температура = %4.1f Возвращаюсь к считыванию датчиков." % (Ts[id]) continue if Ts[id] == 0.: ReadSensors = False time.sleep(2) print "Температура = %4.1f Возвращаюсь к считыванию датчиков." % (Ts[id]) continue print "Датчики считаны" else: # Увы... print "Датчики отсутствуют или неисправны" ReadSensors = False # GPIO.output(12,0) # Отключаем 3.3V от DS18B20 print "Отключаю питание" time.sleep(0.2) GPIO.output(12,1) # Включаем 3.3V на DS18B20 print "Включаю питание" #error_counter += 1 time.sleep(2)
for id in tids: # Теперь добавим в строки для выдачи if id in Ts: # Если датчик с таким ID есть в словаре, то выведем его температуру if id == hid: # Датчик в кубе Tcub Tcub = Ts[id] ss += "% 7.2f" % (Tcub); s += "% 7.3f" % (Tcub) if id == cid: # Подкрасим температуру в колонне для консоли и определим переменную Tcol Tcol = Ts[id] ss += "\x1b[32m %7.2f\x1b[0m" % (Tcol); s += "% 7.3f" % (Tcol) if id == did: # Подкрасим температуру в дефлегматоре для консоли и определим переменную Tdef Tdef = Ts[id] ss += "\x1b[33m %7.2f\x1b[0m" % (Tdef); s += "% 7.3f" % (Tdef) if id == wid: # Датчик холодильника Thol Thol = Ts[id] ss += "% 7.2f" % (Thol); s += "% 7.3f" % (Thol) #----------------------------------------------------------------------- """Измеряем и выводим текущую мощность нагрева""" cW = teh.W ss += "\x1b[31m %4d\x1b[0m" % (cW); s += " %5d" % (cW) #----------------------------------------------------------------------- """Если есть датчик RMS, то в журнал выведем напряжение в сети""" if vs != None: V = vs.V; ss += " %3d" % (V); s += " %4d" % (V) #----------------------------------------------------------------------- """Если есть датчик атмосферного давления - выводим давление""" if ps != None: P = ps.P; ss += "% 6.1f" % (P); s += "% 5.1f" % (P) #----------------------------------------------------------------------- """Заполняем список и выводим информацию об изменении температуры в колонне""" if len(Tcol_list) <= 4: Tcol_list.append(Tcol) # ss += "\x1b[32m% 6.2f\x1b[0m" % (0.) else: del Tcol_list[0] Tcol_list.append(Tcol) dTcol = Tcol_list[4] - Tcol_list[0] # ss += "\x1b[32m% 6.2f\x1b[0m" % (dTcol) #----------------------------------------------------------------------- """Заполняем список и выводим информацию об изменении температуры в дефлегматоре""" if len(Tdef_list) <= 4: Tdef_list.append(Tdef) # ss += "\x1b[33m% 6.2f\x1b[0m" % (0.) else: del Tdef_list[0] Tdef_list.append(Tdef) dTdef = Tdef_list[4] - Tdef_list[3] # ss += "\x1b[33m% 6.2f\x1b[0m" % (dTdef) #----------------------------------------------------------------------- """Выводим информацию о положении кранов.""" ss += "% 4d" % (Deflegmator.N); s += "% 4d" % (Deflegmator.N) ss += "% 4d" % (Holodilnik.N); s += "% 4d" % (Holodilnik.N) #----------------------------------------------------------------------- """Выводим информацию с датчика веса.""" weight = sensWEIGHT.BALANCE() if weight != None: weight.B = 0 # Посылаем 0 чтобы считывать вес. Nou_weight = weight.B # Получаем значение реального веса. if Nou_weight == 0: wght_new = 0. #Nou_weight = 0. wght_correct = 0. else: wght_old = wght_new wght_new = weight.B if wght_new < wght_old: wght_correct += 200. Nou_weight = wght_correct + wght_new weight.B=1 Counter=weight.B/10. # Считывает значение счетчика капель else: None ss += "% 5d" % (Nou_weight); s += "% 5d" % (Nou_weight) # С Ардуинки принимаем целое число. ss += "\x1b[32m %5.1f\x1b[0m" % (Counter); s += "% 5.1f" % (Counter) #----------------------------------------------------------------------- """Выводим информацию о временном интервале, приросте веса и возможной скорости отбора.""" dWeight = Nou_weight - Old_Weight if Old_Weight == 0: dWeight = 0 if dWeight > 0: dWeight1 = dWeight Finish_time = New_time dTime = Finish_time - Start_time if dTime > 1000: dTime = 0 Start_time = Finish_time if dTime > 0: Sel_Speed = dWeight/dTime*3600 ss += "\x1b[33m% 5.1f\x1b[0m" % (dTime) ss += "% 5.1f" % (dWeight1) ss += "% 4d" % (Sel_Speed) Old_Weight = Nou_weight #-------------------------------------------------------------------------------- """Далее собственно и следует вся ненавязчивая автоматизация :)))
В данной задаче автоматическое переключение режимов нужно только для стадии разгона. Т.е. в режиме разгона (режим 1) после закипания, когда температура в 1/3 колонны превысит, скажем, 60°C, нужно перейти в режим 2 (сбросить мощность на "штатный" уровень). Ну так так и объясняем малинке.""" #-------------------------------------------------------------------------------- if mode == 1: # Текущий режим - разгон if Tcol != 0: # Если датчики температуры исправны, то... if Tcol >= 60: # Куб закипел - пора сбрасывать мощность old__mode = mode; Deflegmator.N=130; Holodilnik.N=10; mode = 2 else: # Если датчик заглючил, то Tcol = 0. Завершаем работу. print "Термодатчик неисправен. Завершение работы." sys.exit(6) #-------------------------------------------------------------------------------- if mode == 2: # Текущий режим - стабилизация с выходом на отбор голов if Tdef != 0: if Tdef_list[4] + 7 < Tcol_list[4]: # Регулируем кран дефлегматора только до заданной температуры. if Column_stabilized == False: # Если колонна не стабилизирована if Tcol_max == False and Tcol_list[2] > Tcol_list[4]: Tcol_max = True; print 'Максимум температуры колонны пройден.' if Tcol_max == True and Tcol_list[2]-Tcol_list[4] < 0.1: Column_stabilized = True; print 'Начало стабилизации колонны.' if Column_stabilized == True: # Началась стабилизация if Temperature_grows == False and Tdef_list[4]>Tdef_list[2]>Tdef_list[0]: Temperature_grows = True if Temperature_grows == True and Tdef_list[4] <= Tdef_list[2]: Max_ekstremum = True; Temperature_grows = False; if Tdef_list[4] < 50: oldDef = Deflegmator.N; Deflegmator.N = Deflegmator.N - 10 else: oldDef= Deflegmator.N; Deflegmator.N = Deflegmator.N - 7 if Deflegmator.N < 40: Deflegmator.N = oldDef else: None # Если датчик температуры заглючил, то ничего не делаем. #-------------------------------------------------------------------------------- """ if mode == 3: # Текущий режим - отбор голов. if Tdef != 0: # Написать инструкции анализа веса. else: None # Если датчик температуры заглючил, то ничего не делаем. """ #-------------------------------------------------------------------------------- """Теперь обработаем ситуацию, когда произошла смена режима работы установки (автоматически, или по нажатию клавиши). Для обработки используем карту режимов""" 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 # """Включаем счетчик циклов. И если step_number>steps_in_circle # сбрасываем счетчик""" # step_number=step_number+1 # if step_number>steps_in_circle: # step_number=1
log.write(s + "\n"); log.flush() # Пишем данные в журнал print ss # и выводим на экран #----------------------------------------------------------------------- ReadSensors = False Прошу помочь разобраться в этом вопросе.
OldBean
Доцент
Красноярск
1K 1.4K
Отв.1146 13 Февр. 18, 06:29
2ZagAl Александр, положите пожалуйста текст модуля sens.py, который Вы используете в своих тестах. Их было несколько версий (в том числе с различными вариантами работы с потоками при запуске Ds-ок). Ну чтобы у нас была однозначность.
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1147 13 Февр. 18, 11:15
OldBean, да, конечно нужно было сразу об этом подумать. Вот sens.py которым я пользуюсь. Скрытый текст#coding:utf-8 """Модуль sens содержит классы-обертки для датчиков, подключенных к шинам 1-Wire и I2C микрокомпьютера Raspberry Pi История изменений - в конце файла OldBean, 17.01.26""" import os, time, thread import smbus import Adafruit_BMP.BMP085 as bmp
#------------------------------------------------------------------------------- class DS18B20(object): # Класс датчика температуры DS18B20 """ Класс-обертка для датчиков DS18B20, подключенных к шине 1-Wire. Температура каждого объекта класса DS18B20 представляется свойством T. Цикл преобразования датчика запускается каждый раз, когда это свойство используется в правой части выражения. Класс DS18B20 также представляет средства для коллективной работы с датчиками: список всех датчиков, подключенных к шине 1-Wire (стаический метод IDs() и словарь, содержащий ключи - идентификаторы датчиков и значения - температуры соответствующих датчиков (статический метод Ts())""" path = "/sys/bus/w1/devices" # Директория с файлами датчиков tsd = {} # Словарь для коллективной работы с датчиками {id датчика : температура}
def __new__(cls, id): """ Перед созданием объекта В методе __new__ производится проверка наличия датчика DS18B20 с заданным id""" dn = cls.path + ("/28-%012x" % (id)) if os.path.isdir(dn): return super(DS18B20, cls).__new__(cls) else: print "Датчик c id = 0x%012x отсутствует или неисправен" % (id) return None
@staticmethod def temperature(fn, id = -1, lock = None): """ Запускается цикл преобразования одного датчика DS18B20. Если идентификатор датчика не установлен (по умолчанию), то просто возвращается значение температуры. Если же идентификатор датчика (параметр id) задан, то значение температуры записывается в словарь tsd. Ключом является id датчика. При таком режиме работы предполагается параллельная выполнение циклов преобразований датчиков. Поэтому по окончанию преобразования также освобождается и блокировка (параметр lock).""" lines = ["NoNoNo", ""] while not lines[0].strip().endswith("YES"): # Пока данные не будут готовы f = open(fn, "r") lines = f.readlines() f.close() pos = lines[1].find('t=') # Температура - после "t=" temp = -273.15 # :) if pos != -1: temp = float(lines[1][pos + 2:])/1000 # Температура в Цельсиях if id < 0: return temp DS18B20.tsd[id] = temp lock.release()
@property def T(self): """ Свойство - температура датчика. Цикл преобразования (около 750 мс) запускается при каждом использовании этого свойства в правой части выражения.""" return DS18B20.temperature(self._fn)
@staticmethod def IDs(): """ Возвращает список идентификаторов всех датчиков DS18B20, подключенных к шине 1-Wire.""" fnl = os.listdir(DS18B20.path) idl = [] for fn in fnl: if fn.startswith("28-"): # Директория соответствует датчику DS18B20 idl.append(int(fn[-12:], 16)) return idl
@staticmethod def Ts(): """ Возвращает словарь, содержащий идентификаторы всех датчиков DS18B20, подключенных к шине 1-Wire (в качестве ключей словаря), и температуры датчиков (соответствующие значения словаря). Обработка каждого датчика производится параллельно в отдельном потоке, поэтому суммарное время преобразования всех датчиков существенно меньше, чем при последовательном опросе. Например для 4-х датчиков - 0.991 сек вместо 3.349 сек.""" DS18B20.tsd.clear() ids = []; fns = []; locks = [] dnl = os.listdir(DS18B20.path) for dn in dnl: if dn.startswith("28-"): # Директория соответствует датчику DS18B20 ids.append(int(dn[-12:], 16)) # Выделяем ID датчика и - в список # Формируем полное имя файла с данными от датчика fns.append(DS18B20.path + "/" + dn + "/w1_slave") # Захватываем блокировки и заносим их в список блокировок lock = thread.allocate_lock() lock.acquire() locks.append(lock) nts = len(ids) # Количество датчиков DS18B20, подключенных к шине # Запускаем параллельные потоки циклов преобразований датчиков for i in range(nts): thread.start_new_thread(DS18B20.temperature, (fns, ids, locks)) for i in range(nts): # Ждем завершения всех циклов преобразований датчиков while locks.locked(): pass return DS18B20.tsd #------------------------------------------------------------------------------- class BMP180(object): """ Класс-обертка для датчика атмосферного давления и температуры BMP180. Давления и температура представлены соответствущими свойствами (P и T) экземпляра класса. Чтение датчиков происходит при каждом использовании свойств в правой части выражения.""" sensor = None def __new__(cls): """ Перед созданием объекта В методе __new__ производится проверка наличия и работоспособности датчика BMP180""" try: cls.sensor = bmp.BMP085() cls.sensor.read_pressure() cls.sensor.read_temperature() return super(BMP180, cls).__new__(cls) except: print "Датчик BMP180 отсутствует или неисправен" return None
def __init__(self): self._sensor = BMP180.sensor
@property def P(self): """Свойство - значение атмосферного давления в мм.рт.ст.""" return self._sensor.read_pressure()/133.322 # Паскали -> в мм.рт.ст.
@property def T(self): """Свойство - значение температуры датчика в градусах Цельсия.""" return self._sensor.read_temperature() #------------------------------------------------------------------------------- class RMS(object): """ Класс-обертка для датчика среднеквадратичного напряжения сети. По умолчанию предполагается, что датчик подключен к 1-ой шине I2C по адресу 5 (можно изменить при создании объекта).""" def __new__(cls, addr = 0x05, bus = smbus.SMBus(1)): """Перед созданием объекта в методе __new__ производится тестирование датчика (наличие и работоспособность). addr - адрес датчика на шине I2C. По умолчанию - 5 bus - шина (объект SMBus). По умолчанию - SMBus(1)""" try: # Проверим наличие и работоспособность датчика bus.read_byte(addr) # Все в порядке - создаем объект - датчик RMS return super(RMS, cls).__new__(cls) except: print "Датчик RMS отсутствует или неисправен" return None
def __init__(self, addr = 0x05, bus = smbus.SMBus(1)): """addr - адрес датчика на шине I2C. По умолчанию - 5 bus - шина (объект SMBus). По умолчанию - SMBus(1)""" self._addr = addr self._bus = bus
@property def V(self): """Свойство - значение среднеквадратичного напряжения сети""" return self._bus.read_byte(self._addr) + 100 #------------------------------------------------------------------------------- if __name__ == "__main__": # Тестирование классов модуля sens print "\nДатчики DS18B20" tsIDs = DS18B20.IDs() # Список ID всех датчиков DS18B20 на шине 1 Wire nts = len(tsIDs) # Количество датчиков DS18B20, обнаруженных на шине if nts == 0: print "Датчики DS18B20 не обнаружены" else: print "\nПоследовательный опрос %d датчиков" % (nts) st = time.time() for id in tsIDs: ts = DS18B20(id) # Создаем объект (датчик DS18B20) temperature = ts.T # Измеряем температуру этим датчиком print "%5.3f сек" % (time.time() - st)
print "\nПараллельный запуск %d датчиков" % (nts) st = time.time() d = DS18B20.Ts() # Метод Ts() возвращает словарь с id датчиков (ключи) и # температурой (значения) for id in d.keys(): print "0x%012x :% 7.3f°C" % (id, d[id]) print "%5.3f сек" % (time.time() - st)
print "\nДатчик BMP180" bmp = BMP180() if bmp != None: # Датчик в наличии и функционирует print "Давление: \t%5.1f мм.рт.ст." % (bmp.P) print "Температура:\t%5.2f°C" % (bmp.T)
print "\nДатчик RMS" vs = RMS() if vs != None: # Датчик в наличии и функционируе V = vs.V # Измеряем напряжение if V > 100: print "Среднеквадратичное напряжение: %d V" % (V) else: print "Слишком низкое напряжение в сети ( < 100B)"
print "\nТест на наличие датчика DS18B20 с id = 0x1888888 :)" ts = DS18B20(0x1888888) if ts != None: print "Есть такой датчик!!!"
#------------------------------------------------------------------------------- """История изменений
25.01.2017 ---------- 1. Написана документация модуля 2. Практически полностью переписан класс-обертка DS18B20 и расширен его функционал - добавлена возможность выполнения цикла преобразования каждого датчика в параллельных потоках 3. Перед созданием объектов-датчиков (RMS и BMP180) добавлено их тестирование (наличие датчика и работоспособность интерфейса).
26.01.2017 ---------- 4. Перед созданием объект-датчика DS18B20 производится проверка его наличия на шине 1-Wire
""" Этот и остальные файлы из комплекта nna_02.
OldBean
Доцент
Красноярск
1K 1.4K
Отв.1148 13 Февр. 18, 17:37
Спасибо, я понял какая у Вас версия. Но, похоже, у Вас проблемы с самими датчиками, а не со скриптами. Сами-то датчики система видит, но 3 из 4-х возвращают значение 85°C, которое присваивается при инициализации DS-ок. Это говорит о некорректной работе с датчиками. Наиболее вероятная причина - ошибки коммуникации малинки с этими тремя датчиками. Может быть помехи, а может - неисправности самих датчиков. Корректные значения иногда "прорываются".
Для фиксации проблемы проще воспользоваться средствами самой операционной системы для работы с датчиками, а не возиться со скриптами. В малинкиной директории /sys/bus/w1/devices/ должны быть четыре папки, названия которых совпадает с ID датчиков температуры (для DS-ок названия начинаются с "28-..."). Заходите в эти директории и ищите причину в файлах w1_slave. Это - тектовые файлы, в которых есть и диагностическая информация, и значения самих температур. Пока не добьетесь корректной работы датчиков (а именно - корректного содержимого файлов w1_slave) смысла возиться со скриптами нет. Так как методы класса-обертки DS18B20 (который описан в модуле sens) берут информацию как раз из этих файлов.
Смотрели? Что в этих файлах?
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1149 13 Февр. 18, 22:38
OldBean, вот: 2018-02-13-213303_815x516_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Или нужно запускать sens.py и если отображаются температуры 85.0 то тогда смотреть что в w1_slave? На некоторое время отключил датчики и вновь подключил. Вот лог: 2018-02-13-221258_815x498_scrot. Ненавязчивая автоматизация ректификационной установки. Автоматика. Что делать? Менять датчики?
OldBean
Доцент
Красноярск
1K 1.4K
Отв.1150 14 Февр. 18, 03:05
Что делать? Менять датчики?ZagAl, 13 Февр. 18, 22:38
Возможно, но я бы еще проверил. На всякий случай. Связь вроде нормальная, но, похоже, не запускается сам цикл преобразования. Если датчики без гильз, вытащите их и поставьте на питание (VCC-GND, подпаяйте прямо на ножки датчиков) керамические конденсаторы 0.1 мкФ. И потестируйте. Может быть им просто не хватает питания. Только запрашивайте не 1-2 раза, а много-много раз. Датчики должны работать безсбойно часами и сутками. Иначе никакая автоматизация толком работать не будет. PS Не покупайте дешевые датчики. "Левых" сейчас очень много. Не так давно взял (исключительно для пробы!) 4 недорогих датчика. Один всегда показывает 0, другой 127. Два других еще живы, но врут безбожно. Один показывает примерно градусов на 5 выше, второй - на 3. Вот так!
U-M
Магистр
MSK
212 40
Отв.1151 14 Февр. 18, 10:44
Не покупайте дешевые датчики. "Левых" сейчас очень много.OldBean, 14 Февр. 18, 03:05
На этом фоне - нет мысли применить PT100 в связке с МАХ31865. Главный минус - каждому датчику свой шлейф и своя МАХ...
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1152 14 Февр. 18, 11:09 (через 26 мин)
Только запрашивайте не 1-2 раза, а много-много раз.OldBean, 14 Февр. 18, 03:05
OldBean, Сергей, имеется ввиду цикл: включить, считать, выключить? P.S. Всегда покупаю у продавцов с хорошим рейтингом, пусть даже подороже. В наличии имеются запасные. Поэтому для начала попробую сравнить их работоспособность. Но и ваш вариант тестирования тоже опробую.
m16Модератор
Тамбов
1.9K 1K
Отв.1153 14 Февр. 18, 11:34 (через 26 мин)
На этом фоне - нет мысли применить PT100U-M, 14 Февр. 18, 10:44
U-M, шестой год пользую менее сложную 8-ми канальную конфигурацию
OldBean
Доцент
Красноярск
1K 1.4K
Отв.1154 14 Февр. 18, 14:57
имеется ввиду цикл: включить, считать, выключить?ZagAl, 14 Февр. 18, 11:09
Не обязательно. Любой из скриптов, которые Вы приводили чуть выше, где нет "костылей" (т.е. пересброса датчиков датчиков). Задача - добиться чтобы датчики работали без сбоев сколь угодно долго. Шина 1-Wire как у Вас устроена? Я имею в виду длину и топологию. Для начала сделайте все покороче и без ветвлений.
На этом фоне - нет мысли применить PT100 в связке с МАХ31865.U-M, 14 Февр. 18, 10:44
У DS-ок хорошее соотношение цена/качество. Если использовать Брезенхема для регулировки мощности и нет серьезных помех тут же рядом (типа электросварки ;), то с ними вообще никаких проблем нет. И быть не должно. Надо просто разобраться в источнике проблем у коллеги ZagAl. А те дешевенькие я взял специально из любопытства. Посмотреть как они работают. Ну посмотрел... ;)
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1155 14 Февр. 18, 16:04
Любой из скриптов, которые Вы приводили чуть выше, где нет "костылей"OldBean, 14 Февр. 18, 14:57
Сергей, так там и не было "костылей". Сбои я моделировал, отключая датчики вручную. На неработающей колонне, датчики работают без сбоев. Проверял. Почти сутки. Длина проводов 3 метра. Ну сейчас еще запущу четвертый вариант, тот, что сбои считает. А вот на работающей колонне когда как. То выбивает датчики и довольно часто, то нет. В настоящее время экспериментирую на малых загрузках. Только для того чтобы посмотреть как колонна выходит на покапельный режим отбора голов и отбор голов с контролем веса и счетчика капель. Поэтому колонна в работе всего 2-3 часа. 202105. Ненавязчивая автоматизация ректификационной установки. Автоматика.Log_250118. Ненавязчивая автоматизация ректификационной установки. Автоматика. P.S. Может какие электромагнитные наводки возникают от ТЭНа? Хотя куб заземлен. Может заземление плохое?
makh
Профессор
Sаmara
2.1K 1K
Отв.1156 14 Февр. 18, 16:29 (через 26 мин)
ZagAl, если где-то в схеме устройства, или рядом, фигурирует один или несколько неизвестного происхождения импульсных блоков питания, попробуй менять по одному, и смотреть на реакцию железа. У мну такое было -- собираешь установку, все как обычно вроде, но откисает вся гирлянда градусников каждые пару минут. Методом исключения нашол китайский БП, который это делал. Пара одинаковых была, один на электронику и насосы, второй на воздушный деф, так вот когда глючный кормил вентиляторы проблемы не было, а когда электронику -- непонятной природы горе..
ZagAl
Доцент
Прибалтика
1.9K 915
Отв.1157 14 Февр. 18, 17:30
makh, я пользуюсь блоком питания от настольного компьютера. С него беру и 5 вольт и 12 (для шаговых двигателей).
PavelSaratov
Доктор наук
Саратов
623 80
Отв.1158 14 Февр. 18, 17:59 (через 30 мин)
А те дешевенькие я взял специально из любопытства. Посмотреть как они работают. Ну посмотрел...
Возникает вопрос - а где недешевенькие берете?
сообщение удалено
OldBean
Доцент
Красноярск
1K 1.4K
Отв.1159 14 Февр. 18, 19:21
так там и не было "костылей". Сбои я моделировал, отключая датчики вручную.ZagAl, 14 Февр. 18, 16:04
А... А я-то думал, что Вы автоматизировали перезагрузку датчиков (тексты смотрел только у первых скриптов, но по скриншотам стало ясно, что проблема в датчиках, а не в скриптах).
На неработающей колонне, датчики работают без сбоев. Проверял. Почти сутки. ... А вот на работающей колонне когда как. То выбивает датчики и довольно часто, то нет.ZagAl, 14 Февр. 18, 16:04
Тогда, с большой вероятностью, что наводки, а источник помех явно связан с установкой. Нужно искать. Про метод исключения коллега makh уже рассказал ;) Это действенный метод.
Кстати, отличная у Вас ложечка получилась! А я для аналогичной задачи (измерение расхода) хотел 100-грамовые тензовесы приспособить и сосуд с сифоном для периодического слива.
Возникает вопрос - а где недешевенькие берете?PavelSaratov, 14 Февр. 18, 17:59
В том же магазине, что и дешевые. Только цена в два (с небольшим гаком) раза поболее. Они работают нормально и, кстати, очень хорошо коррелируют с датчиками из совсем старой партии, которую я брал еще лет 10 назад