Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя
Показано с 11 по 20 из 21

Тема: ModBus rtu Linux ПВТ100

  1. #11

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    Вот она наверное и хромает.
    не в обвязке дело, а в драйвере ядра. Под виндой все ок. Под линуксом я его тоже заводил, но работал крайне нестабильно. Ничего делать с ним не будут, тк микросхема снята с производства. Истину говорю, тк сам столкнулся с проблемой. На малинафоруме есть тоже пара веток с 2102 и 485.

  2. #12

    По умолчанию

    Добрый день. как то обучаясь Сям писал консольную программу обмена с МВ110-8А для опроса датчика под убунту. прикладываю исходник, возможно помогут.
    в scaner.c посмотрите как работает программа
    в my_header_for_modbus.h смените путь ведения лога
    то что чип определяется to UART - всё нормально. в большинстве случаев за ним стоит микруха преобразования в RS485. просто комп видит только "лицо" чипа со стороны USB а не дальнейший каскад преобразования
    p.s. код работает но не идеально. в то время не учитывал задержки переключения Rx/Tx , поэтому могут быть пропуски пакета
    Вложения Вложения

  3. #13

    По умолчанию

    Код:
    # ---------------instrument settings--------------------------------
    try:
        COM = MySerial.ComPort(portName, baudRate, timeout=0.07)
    except:
        raise Exception('Error openning port!')
    
    try:
        MVA = Owen.OwenDevice(COM, 16)
        print MVA
    except Owen.OwenProtocolError:
        print 'Модуль ввода отсутствует'
        s_log(u'Модуль ввода отсутствует')
    
    try:
        MU = Owen.OwenDevice(COM, 8)
        print MU
    except Owen.OwenProtocolError:
        print 'Модуль вывода отсутствует'
        s_log(u'Модуль вывода отсутствует')
    
    MMU = minimalmodbus.Instrument(portName, slaveaddress=8, mode='rtu') # port name, slave address (in decimal)
    MMU.debug = False
    MMU.serial.baudrate = baudRate
    
    try:
        if MMU.read_register(pwmPeriodReg + SSRPwm0) <> Freq:
            MMU.write_register(pwmPeriodReg + SSRPwm0, Freq)
            print 'Корректный период ШИМ'
            mModInitStr += u'Корректный период ШИМ,'
        else:
            mModInitStr += u'Корректировка ШИМ не нужна,'
    except IOError, ValueError:
        try:
            if MMU.read_register(pwmPeriodReg + SSRPwm0) <> Freq:
                MMU.write_register(pwmPeriodReg + SSRPwm0, Freq)
                print 'Корректный период ШИМ'
                mModInitStr += u'Корректный период ШИМ,'
            else:
                mModInitStr += u'Корректировка ШИМ не нужна,'
        except IOError, ValueError:
            print 'Ошибка установки периода ШИМ'
            mModInitStr += u'Ошибка установки периода ШИМ,'
    
    try:
        MMU.write_register(SSRPwm0, 0)
        MMU.write_register(Fan1, 0)
        MMU.write_register(Cont1, 0)
        MMU.write_register(Bell1, 0)
        print 'Порты в нуле'
        mModInitStr += u' Порты в нуле'
    except IOError, ValueError:
        try:
            MMU.write_register(SSRPwm0, 0)
            MMU.write_register(Fan1, 0)
            MMU.write_register(Cont1, 0)
            MMU.write_register(Bell1, 0)
            print 'Порты в нуле'
            mModInitStr += u' Порты в нуле'
        except IOError, ValueError:
            print 'Ошибка установки портов'
            mModInitStr += u' Ошибка установки портов'
    Код:
    class TempThread(QtCore.QThread):  # работа с АЦП в потоке
        def __init__(self, temp_signal, parent=None):
            super(TempThread, self).__init__(parent)
            self.temp_signal = temp_signal
            self.isRun = False
            self.counter=0 # ошибки
            self.counter2=0 # операции чтения
            self.temp_array = np.array([[0.0, 0],
                                       [0.0, 0],
                                       [0.0, 0],
                                       [0.0, 0],
                                       [0.0, 0],
                                       [0.0, 0],
                                       [0.0, 0]])
    
        def run(self):
            global portIsBusy
            while self.isRun:
                a = datetime.datetime.now()
                s = time.localtime()
                Ch = 1
                while portIsBusy:
                    print 'temp busy', portIsBusy
                    time.sleep(0.05)
                while Ch <= 3:
                    try:
                        portIsBusy = True
                        terr = self.temp_array[Ch][0]
                        # читаем с адреса базовый-1
                        result = MVA.GetIEEE32('rEAd', Ch-1, withTime=True)
                        print 'Ch', Ch, 'res:', result
                        self.temp_array[Ch][0] = round(result['value'],1)
                        self.temp_array[Ch][1] = int(0)
                    except Owen.OwenUnpackError as e:
                        self.error_unpack(e, terr, Ch, s) # обрабатываем ошибку раскодировки данных
                    except Owen.OwenProtocolError:
                        try: # пробуем еще раз
                            terr = self.temp_array[Ch][0]
                            # читаем с адреса базовый-1
                            result = MVA.GetIEEE32('rEAd', Ch - 1, withTime=True)
                            print 'Ch', Ch, 'res:', result
                            self.temp_array[Ch][0] = round(result['value'], 1)
                            self.temp_array[Ch][1] = int(0)
                        except Owen.OwenUnpackError as e:
                            self.error_unpack(e, terr, Ch, s)  # обрабатываем ошибку раскодировки данных
                        except Owen.OwenProtocolError:
                            print 'Модуль ввода не ответил, канал: ' + str(Ch)
                            s_log(u'Модуль ввода не ответил, канал: ' + str(Ch) + ' ' + str(
                                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                            self.counter += 1
                            if COM.isOpen():
                                COM.close()
                                COM.open()
    
                    print self.temp_array[Ch]
                    Ch+=1
                portIsBusy = False
                print '-------------------',str(s.tm_hour), ':', str(s.tm_min), ':', str(s.tm_sec), '-------------------'
                self.temp_signal.emit(self.temp_array)
                self.counter2 +=1
                error_buffer[0] = u'Ошибки = ' + str(self.counter) + u', ' + u'Вызовы = ' + str(self.counter2)
                print error_buffer[0]
                sleepparam = float(str(datetime.datetime.now() - a)[-6:]) / 1000000
                print '-------------------', sleepparam, '-------------------'
                time.sleep(5 - sleepparam)
    
        def stop(self):
            self.isRun = False
    
        def error_unpack(self, e, terr, Ch, s):
            if len(e.data) == 1:
                self.temp_array[Ch][1] = int(1)
                self.temp_array[Ch][0] = terr
                # это код ошибки
                if ord(e.data[0]) == 0xfd:
                    print 'Обрыв датчика'
                    s_log(u'Обрыв датчика, канал: ' + str(Ch) + ' ' + str(s.tm_hour) + ':' + str(
                        s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xff:
                    print 'Некорректный калибровочный коэффициент'
                    s_log(u'Некорректный калибровочный коэффициент, канал: ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xfb:
                    print 'Измеренное значение слишком мало'
                    s_log(u'Измеренное значение слишком мало, канал: ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xfa:
                    print 'Измеренное значение слишком велико'
                    s_log(u'Измеренное значение слишком велико, канал: ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xf7:
                    print 'Датчик отключен'
                    s_log(u'Датчик отключен, канал: ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xf6:
                    print 'Данные температуры не готовы'
                    s_log(u'Данные температуры не готовы ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                elif ord(e.data[0]) == 0xf0:
                    print 'Значение заведомо неверно'
                    s_log(u'Значение заведомо неверно, канал: ' + str(Ch) + ' ' + str(
                        s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
            else:
                print 'wtf it needs?'
                s_log(u'Неизвестная ошибка ввода, канал: ' + str(Ch) + ' ' + str(
                    s.tm_hour) + ':' + str(s.tm_min) + ':' + str(s.tm_sec))
                if COM.isOpen():
                    COM.close()
                    COM.open()
    Изображения Изображения
    Последний раз редактировалось danilk; 22.06.2018 в 13:44.

  4. #14
    Пользователь
    Регистрация
    20.06.2018
    Адрес
    СПБ
    Сообщений
    6

    По умолчанию

    Да, действительно связи с портом не было. Ждал, пока кто-нибудь там появится и проверит. Проблема была в том, что провод на переходнике переломился. Данная программа работает исправно.

    Спасибо!
    Последний раз редактировалось art_air; 22.06.2018 в 18:40.

  5. #15
    Пользователь
    Регистрация
    20.06.2018
    Адрес
    СПБ
    Сообщений
    6

    По умолчанию

    Добрый день. как то обучаясь Сям писал консольную программу обмена с МВ110-8А для опроса датчика под убунту. прикладываю исходник, возможно помогут.
    в scaner.c посмотрите как работает программа
    в my_header_for_modbus.h смените путь ведения лога
    то что чип определяется to UART - всё нормально. в большинстве случаев за ним стоит микруха преобразования в RS485. просто комп видит только "лицо" чипа со стороны USB а не дальнейший каскад преобразования
    p.s. код работает но не идеально. в то время не учитывал задержки переключения Rx/Tx , поэтому могут быть пропуски пакета
    Спасибо большое!

  6. #16
    Пользователь
    Регистрация
    20.06.2018
    Адрес
    СПБ
    Сообщений
    6

    По умолчанию

    Всем спасибо большое за ответы!

  7. #17
    Пользователь
    Регистрация
    20.06.2018
    Адрес
    СПБ
    Сообщений
    6

    По умолчанию

    Всем добрый день! Работу одобрили, но задали два вопроса:
    1) Как несколько программ могут работать с одним последовательным устройством, представляющим шину?
    (Я же правильно понимаю, тут проблема в том, что если одновременно две программы отправят сообщение разным датчикам, например с адресом 16 и 1, и ответы приду в одно время, то я сниму полную кашу?)
    2) Если программа хочет начать работать с датчиком, а он уже работает с другим процессом, как реализовать корректное ожидание освобождение процесса? И как это отслеживать?
    (Я думал перед опросом датчика, слушать шину, если что-то проходит, то значит, что кто-то общается, тогда ждать, пока канал не замолчит, но это костыль какой-то. Например, если датчик шлёт раз в 30 секунд ответ, то я получу, что шина свободна)

    Я буду благодарен за какие-нибудь направления или советы, так как кроме идеи, которую я выдвинул выше, я ничего не могу придумать. Гуглил, но ничего не нашёл, скорее всего не так гуглил.

    Заранее спасибо!

  8. #18

    По умолчанию

    Вам нужны объекты синхронизации. используйте мьютексы . также в программах закрывайте порт после приёма пакет, тогда другая программа сможет открыть порт и пускай он висит пока не сможет открыть порт, как открыла сделала цикл обмена закрыла, уснула на нужный период. либо сделать основную программу диспетчер запросов, которая будет управлять другими программами обмена, будет обеспечивать последовательность их выполнения, но это уже скорей не программы отдельные будут, а потоки внутри одного приложения.

    p.s. впринципе когда две программы обращаются к одному последовательному порту - не есть хорошее решение, и лучше пересмотреть архитектуру приложения
    Последний раз редактировалось Трофимов Артем; 26.06.2018 в 12:46.

  9. #19
    Пользователь
    Регистрация
    20.06.2018
    Адрес
    СПБ
    Сообщений
    6

    По умолчанию

    Цитата Сообщение от Трофимов Артем Посмотреть сообщение
    Вам нужны объекты синхронизации. используйте мьютексы . также в программах закрывайте порт после приёма пакет, тогда другая программа сможет открыть порт и пускай он висит пока не сможет открыть порт, как открыла сделала цикл обмена закрыла, уснула на нужный период. либо сделать основную программу диспетчер запросов, которая будет управлять другими программами обмена, будет обеспечивать последовательность их выполнения, но это уже скорей не программы отдельные будут, а потоки внутри одного приложения.

    p.s. впринципе когда две программы обращаются к одному последовательному порту - не есть хорошее решение, и лучше пересмотреть архитектуру приложения
    Артём, спасибо большое!
    Да, я уже понял, что это плохая идея, пока искал информацию. Сейчас пойду прочту про "мьютексы" и воспользуюсь советом про открытие/закрытие порта.

  10. #20

    По умолчанию

    Цитата Сообщение от Трофимов Артем Посмотреть сообщение
    также в программах закрывайте порт после приёма пакет
    я свой класс порта делал, чтобы в нем автоматом закрывался порт в части передачи пакетом, зачем в основной программе эти операции?

Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя

Похожие темы

  1. Подключение ПВТ100 к ПК
    от Vlesoslav в разделе Подбор Оборудования
    Ответов: 2
    Последнее сообщение: 09.05.2017, 16:37
  2. ПВТ100 и modbus
    от BETAL в разделе Эксплуатация
    Ответов: 3
    Последнее сообщение: 13.04.2017, 11:08
  3. Подключение ПВТ100
    от korel в разделе Эксплуатация
    Ответов: 7
    Последнее сообщение: 18.02.2017, 18:36
  4. MB110 Linux ModBus как начать?
    от multimorf в разделе Помощь Разработчикам
    Ответов: 22
    Последнее сообщение: 26.05.2015, 14:29

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •