Ad Widget

Collapse

Zabbix+Arduino=...

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • sadman
    Senior Member
    • Dec 2010
    • 1611

    #1

    Zabbix+Arduino=...

    Dear DIY'rs, please use actual version of Zabbuino. Many commands and sources is obsolete for now.

    На носу выходные, а вам нечем заняться?

    Сделайте себе Zabbix-светофор и он начнет помогать вам в работе. С ним вы можете узнать состояние ваших триггеров не запуская web-интерфейс. Например, наблюдая за светофором из окна дома напротив. Ну, или когда выпиваете на работе. Кефир, разумеется.

    Что для этого нужно:
    1. Arduino из дальнего угла нижнего ящика стола. Та самая, которую вы покупали, представляя себе... А затем просто помигали светодиодом и надолго отложили;
    2. Ethernet shield Wiznet WS5100. Без него ничего не выйдет. Можно еще попробовать с enc28J60. Только возни будет больше;
    3. Zabbix server 2.x (в нем есть API);
    4. Архив со скетчем и небольшим скриптом из аттача к посту;
    5. Все ваши таланты для изготовления визуализирующей части светофора. Она может состоять как из галогеновых прожекторов, стащенных с соседней стройки, так и из пяти обычных разноцветных светодиодов и резисторов к ним - уж их-то вы научились подключать сразу после покупки платформы.

    Как и что делать:

    Самое сложное и интересное - это изготовить сам светофор. Или снять его с перекрестка у дома вашего заклятого друга.
    Далее - подключайте к Arduino Ethernet shield, втыкайте все необходимые провода - питание, usb, ethernet и нагрузку к пинам A0-A5.

    Теперь открывайте в Arduino IDE скетч zbx_Alarm_Machine.ino. Вам необходимо заменить в ip/gateway/subnet/zbxHostname предустановленные параметры на свои. Хакеры могут поменять MAC.

    Компиляция и... Делайте zabbix_get -s <адрес_arduino> -k agent.ping. Работает? Отлично. Проверим сигнализацию командой zabbix_get -s <адрес_arduino> -k toc.N. Перебирайте N от 0 до 31. Светодиоды моргали? Половина дела сделана.

    Переходите к скрипту SendStateToAlerter.sh. В нем необходимо откорректировать zbxUser/zbxPass/zbxAPI/zbxAlarmMachine. Уже догадались зачем? Создайте в ситуацию, которая приведет к появлению разноцветных триггеров в "Last 20 issues".

    Запускайте скрипт! Если у вас были голубенькие "Information" - вспыхнет светодиод на pin0, "Warning" - pin1, "Average" - pin2 и так далее. Каждый пин соответствует приоритету триггеров.
    Конечно, мне кажется, что Disaster должен иметь приоритет 1, но в Zabbix ему выделен почему-то 5-й.

    Запихивайте скрипт в cron с расписанием запуска каждые 30-60-... секунд, вешайте светофор над монитором или ставьте посередине комнаты.

    Начиная с этого момента вы будете знать - в порядке ли ваш список триггеров или какие-либо из них находятся в состоянии проблемы и каков приоритет этих активных триггеров.

    ...конечно, актуализация состояния светофора не привязана только к cron'у, но об этом в следующей серии.

    Собирайте, компилируйте, запускайте и делитесь своими идеями по визуализации.
    Attached Files
    Last edited by sadman; 21-08-2016, 21:38.
  • sadman
    Senior Member
    • Dec 2010
    • 1611

    #2
    После уточнения концепции устройства в код Zabbix Alarm Machine внесены изменения, и теперь arduino по команде Zabbix-сервера умеет устанавливать:
    • Состояние регистров данных портов PORTB, PORTC, PORTD;
    • Уровень напряжения HIGH/LOW на заданном порте вывода (digitalWrite(..));
    • Величину Duty cycle 0...255 на заданном PWM порте вывода (analogWrite(..));
    • Сигнализировать об отсутствии входящих команд на протяжении заданного периода.


    Итого, на данный момент поддерживаются команды:
    agent.ping - см. документацию Zabbix
    agent.version - -"-"-
    agent.hostname - -"-"-
    agent.counter - возвращает количество принятых команд - успешных или же нет
    setport.<port>.<value> - записывает значение <value> в <port> (см. Arduino Port Manipulation)
    setd.<pin>.<value> - устанавливает порт <pin> в состояние <value> (digitalWrite(..))
    seta.<pin>.<value> - устанавливает порт <pin> в значение <value> (analogWrite(..))

    Некоторые пояснения и замечания.

    Код написан под протокол Zabbix2.

    setport - в этой команде <port> задает цифровое обозначение порта, регистр которого устанавливается - "b" (PORTB), "c" (PORTC), "d" (PORTD).
    Пример: zabbix_get -s 192.168.0.1 -k setport.d.63

    Устанавливаемое значение <value> принудительно приводится к безопасному виду для соблюдения следующих условий:
    • PORTB - устанавливаются только биты 0, 1 (pins 8, 9). Биты 2-5 (pins 10-13) используются Ethernet Shield, биты 6,7 не используются микропроцессором.
    • PORTС - устанавливаются все биты 0-5 (pins A0-A5)
    • PORTD - устанавливаются только биты 2-7 (pins 2-7). Биты 0, 1 (pins 0, 1) зарезервированны для TX/RX линий.

    В связи с этим наблюдаются некоторые артефакты:
    • ключ setport.d.<value> со значениями, использующими биты 0 и 1 - бессмысленны. Поэтому команды setport.d.1, setport.d.3 не сработают.
    • в ключе setport.b.<value> значения выше 3 - бессмысленны.


    seta - в этой команде значение <pin> совпадает с номером цифрового порта (Digital pin), аналоговые порты не поддерживаются.
    Она применима только к PWM-пинам. Например 3, 5, 6, 9.
    Пример: zabbix_get -s 192.168.0.1 -k seta.9.69

    setd - так же, как в случае с seta значение <pin> совпадает с номером цифрового порта, аналоговые порты не поддерживаются.
    Приемлемые значения - 1 и 0.
    Пример: zabbix_get -s 192.168.0.1 -k setd.2.1

    Внимание! Запись в порт ввода/вывода значения, полученного в командах seta/setd происходит без проверки безопасности.
    Поэтому, указание в качестве целевого, порта зарезервированного под системные нужды (1 и 2 для RX/TX, 10-13 для Ethernet shield) потенциально ведет к отказу в работе.

    Так же есть небольшая, но интересная особенность: после записи какого-либо отличного от нуля значения в PWM порт командой seta, последующее применение setport не изменяет состояние этого порта. Применение же setd - изменяет.

    Для контроля за приемом команд необходимо подключить устройство индикации к порту, заданному в ALARM_LED и установить необходимый таймаут в PING_TIMEOUT.
    При отсутствии входящих команд в обозначенный промежуток времени, на ALARM_LED будет подан высокий уровень. Любая команда, включая те, что вызывают ответ ZBX_UNSUPPORTED, сбрасывают состояние тревоги.
    Внимание! Не используйте для индикации Onboard LED (pin 13 используется для нужд Ethernet shield).

    А теперь варианты ответа на интересующий многих вопрос - как это можно использовать:
    1. Подключить к PWM выходу #9 огромный стрелочный индикатор и, получая значения использования процессора самого главного сервера, делать zabbix_get ... -k seta.9.$value, где $value=$cpuutil*2,25
    2. Подключить к другому PWM выходу #6 вентилятор и, пересчитав значения скорости получения коммитов на вашем git-сервере, выкинуть их в порт с помощью seta.6.$InetSpeed. Вентилятор следует направить на наиболее рьяного работника.
    3. Приладить к цифровому порту сирену. Включать при активации опаснейшего триггера - на исчерпания воды в кулере.
    4. Управлять через arduino дверцей в офисный холодильник. Блокировать ее, пока в наличии имеются активные триггеры.
    5. Новогодняя гирлянда, переливающаяся в такт с магистральным траффиком - что может быть прекрасней?


    Думаю, что это не последнее расширение возможностей Zabbix Alarm Machine. Правда, на моей Freeduino 2009 осталось только 28 bytes of program storage space...
    Attached Files

    Comment

    • sadman
      Senior Member
      • Dec 2010
      • 1611

      #3
      Обзавелся модулем на базе enc28j60 - бюджетный аналог Ethernet Shield-а.
      Скетч компилируется при использовании UIPEthernet вместо штатной Ethernet библиотеки.
      К сожалению в Atmega168 UIPEthernet не влезает даже необвешенный кодом. Поэтому следует смотреть на Arduino с Atmega328. Я проводил компиляцию и проверку работы на Arduino Pro mini.

      Серьёзные тесты с enc28j60 ещё не проводились, поэтому вероятны какие-то сбои в работе программно-аппаратного комплекса.

      Итак, необходимо внести небольшие коррективы в скетч:

      Code:
      #include <UIPEthernet.h>
      [I]//#include <Ethernet.h>
      //#include <SPI.h>[/I]
      ...
          if (!clntIsConnected) {
          [I]// ethClient.flush();[/I]
      ...
      .flush() зачем-то глотает заголовок пакета Zabbix-a, поэтому его стоит закомментировать. Буду разбираться, зачем он так делает.

      Comment

      • sadman
        Senior Member
        • Dec 2010
        • 1611

        #4
        Итак, продолжаем впихивать в ATMEGA Zabbix Agent. Рабочее название агента - Zabbuino.

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

        К сожалению, в очередной раз пришлось изменить имена ключей. Теперь они по возможности приведены в соответствие с именами вызываемых функций языка Arduino. Это позволит обращаться за справкой относительно параметров ключей к руководству по данному языку.

        Все имена ключей регистронезависимы. Из-за ограниченного объема доступного программе в микроконтроллере проверки корректности параметров ключей сведены к минимуму. Будьте внимательны - не взорвите чип излишне большими значениями.

        Zabbuino поддерживает протокол Zabbix2, Ethernet-модули WizNet (стандартная библиотека Ethernet) и ENC28J60.

        Компилировался на Freeduino 2009 (ATmega 168) с Ethernet-модулем W5100 и Deek-Robot Arduino Mini Pro clone (ATmega 328) с Ethernet-модулем ENC28J60.

        Комбинация ATmega 168 + ENC28J60 недоступна. Оптимальный вариант - ATmega 328 + W5100. В последнем случае Zabbuino можно дошпиговать обработкой разнообразных дополнительных датчиков, требующих взаимодействие с аппаратной частью.

        Код скетча содержит комментарии. Прочтите их перед модификацией комплекса. По умолчанию все доступные пины устанавливаются в режим OUTPUT. Ряд пинов защищена от модификации при выполнении команд агента. Установка иных режимов производится напрямую в коде. Это сделано с целью защиты вашей Arduino от бездумных или неосторожных тыканий проводком VCC в различные пины, а так же от подвешивания устройства с помощью записи неожиданных значений в служебные порты.

        Примеры доступа к аппаратной части через Zabbuino будут приведены позднее.

        Доступные на данный момент команды

        Команда: agent.ping
        Параметры: не требуются
        Результат: возвращается значение '1'

        Команда: agent.hostname
        Параметры: не требуются
        Результат: возвращается имя узла

        Команда: agent.version
        Параметры: не требуются
        Результат: возвращается версия агента

        Команда: agent.cmdcount
        Параметры: не требуются
        Результат: возвращается количество обработанных команд

        Команда: agent.cmdstr
        Параметры: не требуются
        Результат: возвращается принятая команда.
        Примечание: используется в целях отладки

        Команда: sys.freeram
        Параметры: не требуются
        Результат: возвращается объем свободной оперативной памяти контроллера

        Команда: portwrite[port, value]
        Параметры: port - символьное обозначение порта (B,C,D..), value - значение, которое требуется записать в заданный порт ввода/вывода
        Результат: изменяется состояние порта ввода/вывода (PORTB, PORTC, PORTD...) и происходит возврат значения '1'.
        Примечание: если ваш экземпляр Arduino имеет более, чем три порта, то на данный момент вам необходимо самостоятельно добавить в скетч информацию о них.

        Команда: analogwrite[pin, value]
        Параметры: pin - цифровое обозначение пина, value - значение скважности, которое требуется задать для данного пина.
        Результат: изменяется скважности PWM для пина. Удачное выполнение команды влечет за собой возврат значения '1', неудачное - значения '0'.
        Примечание: команда является оберткой функции analogWrite() www.arduino.cc/en/Reference/AnalogWrite
        Состояние OUTPUT для пина должно быть задано в коде скетча. Если пин защищен, изменения режима не происходит. Если пин не является PWM-совместимым, на нем выставляется значение HIGH.
        Внимание! Функция analogWrite() самостоятельно устанавливает пин в режим работы OUTPUT

        Команда: analogread[pin]
        Параметры: pin - цифровое обозначение пина
        Результат: возврат величины, "считанной" с пина. Диапазон значений 0...1023 (возможные варианты диапазона значений зависят от способа подключения сигнала к пину и внутренних настроек Arduino)
        Примечание: команда является оберткой функции analogRead() www.arduino.cc/en/Reference/AnalogRead
        Данная команда имеет смысл только для аналоговых пинов.
        Состояние INPUT для пина должно быть определено в коде скетча. В противном случае совпадения считываемых данных с ожидаемыми может не произойти.

        Команда: analogReference[source]
        Параметры: source - источник опорного напряжения (0..N). Значения можно найти в заголовочном файле Arduino.h
        Результат: устанавливается источник опорного напряжения относительно которого происходят аналоговые измерения и происходит возврат значения '1'
        Примечание: команда является оберткой функции analogReference() www.arduino.cc/en/Reference/AnalogReference

        Команда: digitalwrite[pin, value]
        Параметры: pin - цифровое обозначение пина, value - значение, которое требуется выставить на заданном пине.
        Результат: изменяется состояние пина. Удачное выполнение команды влечет за собой возврат значения '1', неудачное - значения '0'.
        Примечание: команда является оберткой функции digitalWrite() www.arduino.cc/en/Reference/DigitalWrite
        Состояние OUTPUT для пина должно быть задано в коде скетча. Если пин защищен, изменения режима не происходит.

        Команда: digitalread[pin]
        Параметры: pin - цифровое обозначение пина
        Результат: возвращается значение, "считанное" с пина. Диапазон значений - HIGH/LOW.
        Примечание: команда является оберткой функции DigitalRead() www.arduino.cc/en/Reference/DigitalRead
        Состояние INPUT для пина должно быть определено в коде скетча. В противном случае совпадения считываемых данных с ожидаемыми может не произойти.

        Команда: tone[pin, frequency, duration]
        Параметры: pin - цифровое обозначение пина, frequency - частота сигнала, duration - длительность сигнала
        Результат: начинается генерация на указанном пине сигнала "прямоугольная волна" заданной частоты.
        Примечание: команда является оберткой функции tone() www.arduino.cc/en/Reference/Tone
        Состояние OUTPUT для пина должно быть задано в коде скетча. Если пин защищен, изменения режима не происходит.

        Команда: notone[pin]
        Параметры: pin - цифровое обозначение пина
        Результат: завершается генерации на указанном пине пине сигнала "прямоугольная волна"
        Примечание: команда является оберткой функции noTone() www.arduino.cc/en/Reference/NoTone
        Состояние OUTPUT для пина должно быть задано в коде скетча. Если пин защищен, изменения режима не происходит.

        Команда: randomseed[value]
        Параметры: value - начальное число ряда псевдослучайных значений
        Результат: инициализируется генератор псевдослучайных чисел
        Примечание: команда является оберткой функции randomSeed() www.arduino.cc/en/Reference/randomSeed

        Команда: random[min, max]
        Параметры: min, max - нижняя и верхняя границы псевдослучайных значений
        Результат: возвращается псевдослучайное число
        Примечание: команда является оберткой функции random() www.arduino.cc/en/Reference/random

        Команда: shiftout[dataPin, clockPin, latchPin, bitOrder, value]
        Параметры: dataPin, clockPin, latchPin - цифровые обозначения пинов вывода данных, синхронизации, защелкивания.bitOrder - последовательность вывода бит, value значение для вывода.
        Результат: устанавливается соответствующее параметру value состояние выводов подключенного сдвигового регистра. Удачное выполнение команды влечет за собой возврат значения `1`, неудачное - значения '0'.
        Состояние OUTPUT для пинов должно быть задано в коде скетча. Если пины защищены, вызова соотвествующих функций не происходит.
        Примечание: команда является расширением функции shiftOut(). Параметр value может быть задан как в десятичной и шестнадцатеричной форме (с префиксом 0x). Длина числа в шестнадцатеричной форме ограничена размером внутреннего буфера.
        Attached Files

        Comment

        • sadman
          Senior Member
          • Dec 2010
          • 1611

          #5
          Обещанные примеры

          zabbix_get -s 192.168.0.1 -k agent.ping
          Проверить готовность Zabbuino

          zabbix_get -s 192.168.0.1 -k agent.cmdcount
          Получить количество команд, исполненных Zabbuino с момента старта.
          При использовании данного ключа в элементе данных, хранящим "Дельта (скорость в секунду)" можно получить значение "команд в секунду".

          zabbix_get -s 192.168.0.1 -k agent.cmdstr[12,34,56,78,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]
          Посмотреть в каком виде функции парсинга параметров обрабатывает полученную команду.
          Можно применять в целях отладки - для того, чтобы убедиться в том, что строка не подрезается в середине из-за слишком маленького буфера, например.

          zabbix_get -s 192.168.0.1 -k sys.freeram
          Получить текущее количество свободной памяти микроконтроллера.
          Теоретически, отслеживая этот параметр, можно следить за утечкой памяти микроконтроллера. Практически же - я всегда получал одно и то же число, не меняющееся до следующей перекомпиляции. Функция определения количества стащена с интернетов, так что за корректность результата работы поручиться не могу.

          zabbix_get -s 192.168.0.1 -k analogWrite[9,127]
          Зажечь на половину яркости светодиод, подключенный к PWM-выводу D9.
          PWM метод регулирования также может применяться, например, к вентилятору. Таковой, естественно, подключается с учетом потребляемой им мощности через управляющий ключ.

          zabbix_get -s 192.168.0.1 -k analogRead[14]
          Считать аналоговое значение с пина A0 (14).
          Считывание аналогового значения может быть полезно при подключении фоторезистора для измерение освещенности,
          датчика тока ("Current Sensor Module for Arduino" на Ebay) и напряжения ("Voltage Transformer Active Single Phase Voltage Sensor Module for Arduino") - для расчета потребляемой мощности.

          zabbix_get -s 192.168.0.1 -k analogReference[0]
          Установить в качестве источника опорного напряжения внешний источник, подключенный к выводу AREF.

          zabbix_get -s 192.168.0.1 -k analogReference[2]
          Для системы на базе микроконтроллера ATmega2560 установить в качестве источника опорного напряжения внутренний источник напряжения 1.1V

          zabbix_get -s 192.168.0.1 -k digitalRead[4]
          Считать логическое состояние цифрового датчика, подключенного к D4.
          С помощью этой команды можно, например, опрашивать кнопки, датчики движения (SparkFun PIR Motion Sensor) и пожарные извещатели (те, что сигнализируют повышением напряжения на выходе Alarm).
          Естественно, при этом необходимо учитывать тот факт, что момент опроса пина и, как следствие, снятие показаний с датчика может не совпасть с его реальным наступлением события. Поэтому, очевидно, в данном случае имеет смысл использовать датчики, переходящие в стабильное состояние при наступлении события. Таковым, например, является, концевой выключатель или датчик разбития стекла.
          Применение же высокореактивных датчиков, например - движения, видится мне для специфических случаев - обнаружения факта того, что нечто активное перестало двигаться. Конечно, не исключен вариант доработки датчика для его логического защелкивания при срабатывании.
          Так же проблему представляет необходимость определения обрыва цепи. Например, датчик, выдающий в нормальном состоянии лог. "0", при отсоединении от цифрового пина, будет продолжать видеться в Zabbuino, как подключенный, но несработавший. Выходом из таковой ситуации может быть логическая инверсия на стороне датчика. При этом в состоянии ожидания с него должен считываться лог. "1", а в случае отсоединения или при наступлении события - лог. "0".

          zabbix_get -s 192.168.0.1 -k digitalWrite[7,1]
          zabbix_get -s 192.168.0.1 -k digitalWrite[7,0]

          Включить/выключить релейный блок, подключенный к выводу D7.
          Выключить/включить релейный блок, подключенный к выводу D7.

          Двусмысленность формулировки "выключить/включить" связана с тем, что встречаются релейные блоки, как включающиеся по уровню HIGH, так и отключающиеся по нему. Дополнительную неопределенность вносит применение в таких модулях переключающего реле, так что в любом случае два из трех контактов будет замкнуты и два разомкнуты.
          Модуль ищется на eBay по фразе "N Channel Relay Module for Arduino", где N - количество управляемых каналов.

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

          zabbix_get -s 192.168.0.1 -k portWrite[c,85]
          Одновременно выставить на выводах A0-A5 состояние HIGH через один пин. Пины A0-A5 относятся к порту PORTC.
          Этот способ включения "лампочек" сработает на порядок быстрее, чем несколько команд digitalWrite[]

          zabbix_get -s 192.168.0.1 -k tone[9,11000]
          Начать генерацию звукового сигнала частотой 11кГц на устройстве, подключенном к пину D9

          zabbix_get -s 192.168.0.1 -k noTone[9]
          Завершить генерацию звукового сигнала на устройстве, подключенном к пину D9

          zabbix_get -s 192.168.0.1 -k tone[9,11000,5000]
          Заставить звучать устройство, подключенное к пину D9 в течении 5 сек

          В качестве устройства звукового сигнала можно использовать пьезодинамик (buzzer) со неисправной материнской платы, например. Для проверки я использовал то, что на eBay называется "Passive Buzzer Module for Arduino".
          Активный вариант этого модуля (Active Buzzer Module for Arduino) подключается по схеме релейного блока.

          zabbix_get -s 192.168.0.1 -k randomSeed[91]
          Инициализировать генератор ПСЧ числом 91

          zabbix_get -s 192.168.0.1 -k random[6,77]
          Получить значение генератора ПСЧ в ряду от 6 до 77

          zabbix_get -s 192.168.0.1 -k shiftOut[3,4,5,0,85]
          Вывести в сдвиговый регистр с защелкой, подключенный выводами dataPin, clockPin и latchPin к D3, D4, D5 соответственно, значение 85. При выводе использовать порядок LSBFIRST.

          Используя эту команду со сдвиговыми регистрами типа 74HC595 можно наэкономить выходных пинов, работающих по команде digitalWrite[]. Подробности - в любом уроке по подключению сдвигового регистра к Arduino.

          zabbix_get -s 192.168.0.1 -k shiftOut[3,4,,1,0x6426]
          Вывести в сдвиговый регистр без защелки, подключенный выводами dataPin и clockPin к D3 и D4 соответственно, значение 0x6426. При выводе использовать порядок MSBFIRST.

          При указании в команде shiftOut[] числа в десятичной форме практически невозможно использовать каскадируемые сдвиговые регистры, так как функция Arduino shiftOut() оперирует размерностью выводимого значения, равным byte. Т.е. управлять в этом случае более, чем восемью "лампочками" невозможно. Для обхода данного ограничения в команде Zabbuino может применяться шестнадцатеричная форма записи числа. Его размер примерно ограничен размером задаваемого в скетче буфера.

          Для проверки я применил изъятый из сгоревшего коммутатора D-Link 1024 модуль индикации PAL-B. Он представляет собой 3 группы светодиодов размерностью 4x4, управляемых каскадированными сдвиговыми регистрами HC164 - по два регистра на группу. Подключив вводы data и clock всех групп к цифровым выводами Arduino (хотя, в данном случае можно все data собрать на один пин), я послал в Zabbuino следующие команды:
          zabbix_get -s 192.168.0.1 -k shiftOut[2,3,,1,0xFFFF]
          zabbix_get -s 192.168.0.1 -k shiftOut[2,3,,1,0xFDDD]
          zabbix_get -s 192.168.0.1 -k shiftOut[4,5,,1,0xFFFF]
          zabbix_get -s 192.168.0.1 -k shiftOut[4,5,,1,0xF640]
          zabbix_get -s 192.168.0.1 -k shiftOut[6,7,,1,0xFFFF]
          zabbix_get -s 192.168.0.1 -k shiftOut[6,7,,1,0xF060]

          Так, как я не нашел у данного модуля возможность сбросить регистры одновременно, пришлось "вручную" выставлять на всех их выводах соотв. значение. С учетом инверсии (при '1' светодиод соотв. выводу регистра горит) это делается записью 0xFFFF на вход группы регистров. В результате все 16 светодиодов гаснут. Второй командой на светодиодном поле "рисуется" некий символ.
          Результат можно увидеть на демонстрационном фото с котиком.


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

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

          Заглянув в библиотечку для управления таким изделим, как "Led Addressable RGB Pixel Strip" или "гирлянда индивидуально адресуемых свеетодиодов / лента флеш-модулей" c чипами WS2801 и LDP6803, можно увидеть, что алгоритм управления ими схож с примененным выше. Таким образом - с помощью shiftOut[] получится рулить такими лентами светодиодов. Теоретически. Проверить не могу, по причине отсутствия в нашей деревне простого доступа к таким вещам.

          Comment

          • sadman
            Senior Member
            • Dec 2010
            • 1611

            #6
            Итак, времени даром не теряем, копаем вглубь и вширь.

            На сегодняшний день:
            • Введена возможность подключения/отключения блоков команд (это влияет на размер итоговой прошивки) через определение соответствующих макросов. На случай того, если в МК скетч не влезает, а некоторые возможности агента не нужны вовсе;
            • Размер прошивки постепенно вылезает за пределы возможностей ATmega168, так что пришлось заменить в моем подопытном МК на ATmega328 и теперь я тестируюсь только на нем;
            • Переписаны функции, связанные с командой shiftOut[]. Теперь вывод происходит путем прямого манипулирования портами. Дрыганье ногами должно работать в несколько раз быстрее прежнего. Теоретически;
            • Починена agent.cmdstr[];
            • Добавлена поддержка цифровых термометров Dallas DS18x20. Команда ds18x20read[pin, resolution, id]. Пока - с точностью в 0,5 градуса. Работу с несколькими DS-ками на одной OneWire шине проверить пока не удалось, но работать должно;
            • Реализована установка состояния пина при инициализации микроконтроллера. Т.е. для OUTPUT можно задать HIGH, для INPUT - INPUT_PULLUP прямо на старте;
            • Опытная эксплуатация показала невозможность использования ENC28J60 в долговременной перспективе без применения функций watchdog совместно с бутлоадером optiboot. Вешается через сутки. В связи с этим одна китайская ардуина окирпичена. W5100 выдерживает достаточно продолжительную бомбежку от заббикса с интервалом между запросами в 5 секунд. Естественно, что несколько параметров с такой частотой получать невозможно - агент поддерживает только один одновременный сеанс с Zabbix-сервером. Элементы данных при наложении запросов будут уходить в Unsupported.


            Добавленная команда
            Команда: ds18x20read[pin, resolution, id]
            Параметры: pin - цифровое обозначение пина, к которому подключен цифровой термометр DS18x20. Resolution - разрешение термометра - 9..12бит, id - идентификатор (адрес) термометра.
            Результат: с цифрового термометра считывается температура и значение в градусах Цельсия возвращается пользователю.
            Примечание: параметр resolution на данный момент не используется и зарезервирован для дальнейших улучшений. Текущая точность показаний - 0,5 градуса Цельсия. Идентификатор (адрес) термометра можно получить через Serial Monitor Arduino IDE при выполнении скетча DallasTemperature -> Single.
            Состояние INPUT для пина должно быть задано в коде скетча.
            Так, как только для получения значений от датчика нужно не менее 1000ms, стоит внимательно покрутить таймауты в Zabbix.

            Пример: zabbix_get -s 192.168.0.1 -k DS18x20Read[2,9,284bd6d4010000f5]
            Получить значение температуры от датчика с идентификатором 284bd6d4010000f5, подключенного к пину D2.

            Поправка к вышеописанному примеру с shiftOut[]: конечно же дополнительную очистку группы индикаторов, подключенных к сдвиговому регистру можно не производить. При условии посылки данных, в котором количество бит будет равно количеству "лампочек". В противном случае артефакты гарантированны.
            Attached Files

            Comment

            • sadman
              Senior Member
              • Dec 2010
              • 1611

              #7
              Обновки.
              • В команде получения температуры с датчика DS18x20 появилась возможность задавать точность замера через параметр resolution (9-12bit). Достигнуто паспортное значение точности - 1/16 С. Введена функция поиска датчика при при отсутствии заданного идентификатора.
              • Добавлена поддержка датчиков DHT11/DHT21/DHT22/AM2301/AM2302 и аналогичных. Точность замера паспортная - 0.1
              • Добавлена поддержка датчиков BMP085/180. Точность замера паспортная.


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

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

              Несколько DS18x20 на одной шине живут хорошо, опрашиваются - проверил. Можно развешивать термометры по серверной.

              Добавленные / исправленные команды

              Команда: DS18x20.Temperature[pin, resolution, id]
              Параметры: pin - цифровое обозначение пина, к которому подключен цифровой термометр DS18x20. resolution - разрешение термометра 9..12бит, id - идентификатор (адрес) термометра. При отсутствии в команде параметра id опрашивается первый найденный на шине термометр.
              Результат: с цифрового термометра считывается температура и значение в градусах Цельсия возвращается пользователю.
              Примечание: Точность показаний (1/2 ... 1/16 C) зависит от параметра resolution, от него, также зависит время выполнения команды. Максимальный временной промежуток - 825ms (resolution = 12bit). Идентификатор (адрес) термометра можно получить через Serial Monitor при выполнении скетча DallasTemperature -> Single. Значение -127 выдается при какой-либо ошибке в функции - невозможности считать данные с термометра вследствие ошибки подсоединения или ошибочно указанном ID. Так же это значение выдается при попытке обращения к термометру неподдерживаемой модели.

              Команда: DHT.Temperature[pin, model]
              Параметры: pin - цифровое обозначение пина, к которому подключен цифровой датчик DHT/AM/..., model - идентификатор модели датчика - 11 (DHT11), 21 (DHT21, AM2301), 22 (DHT22, AM2302).
              Результат: с цифрового датчика DHT11/21/22 считывается температура и значение в градусах Цельсия возвращается пользователю.
              Примечание: Значение -127 выдается при какой-либо ошибке - например несовпадении CRC.
              Если модель датчика не указана или указана неверно, то расчет температуры производится по формуле, применяемой для DHT22. Команда самостоятельно устанавливает состояние INPUT/OUTPUT пина. В целях безопасности стоит инициализировать пин как OUTPUT.

              Команда: DHT.Humidity[pin, model]
              Параметры: pin - цифровое обозначение пина, к которому подключен цифровой датчик DHT/AM/...,model - идентификатор модели датчика - 11 (DHT11), 21 (DHT21, AM2301), 22 (DHT22, AM2302).
              Результат: с цифрового датчика считывается величина относительной влажности и значение в процентах возвращается пользователю.
              Примечание: Значение -127 выдается при какой-либо ошибке - например, несовпадении CRC. Если модель датчика не указана или указана неверно, то расчет величины влажности производится по формуле, применяемой для DHT22. Команда самостоятельно устанавливает состояние INPUT/OUTPUT пина. В целях безопасности стоит инициализировать пин как OUTPUT.

              Команда: BMP.Temperature[sdaPin, sclPin]
              Параметры: sdaPin, sclPin - цифровые обозначение пинов, к которым подключена шина I2C.
              Результат: с цифрового датчика BMP085/BMP180 считывается температура и значение в градусах цельсия возвращается пользователю.
              Примечание: Точность датчика - 0,1C. Обозначения sdaPin, sclPin на данный момент не имеют значения (используются стандартные пины для I2C подключения) и зарезервированы для внедрения SoftTWI интерфейсов.

              Команда: BMP.Pressure[sdaPin, sclPin, overSampling]
              Параметры: sdaPin, sclPin - цифровые обозначение пинов, к которым подключена шина I2C. overSampling - значение, определяющее точность и длительность измерения. 0 - ultra low power, RMS noise = 6Pa, conversion time = 4,5ms ... 3 - ultra high resolution, RMS noise = 3Pa, conversion time = 25,5ms. Подробнее - в datasheet.
              Результат: с цифрового датчика считывается величина атмосферного давления и значение в Паскалях возвращается пользователю.
              Примечание: Обозначения sdaPin, sclPin на данный момент не имеют значения (используются стандартные пины для I2C подключения) и зарезервированы для внедрения SoftTWI интерфейсов. Популярные в России мм. ртутного столба возможно получить через Calculated Item по формуле last(BMP.Pressure[...])/133.3

              Примеры

              zabbix_get -s 192.168.0.1 -k DS18x20.Temperature[2,12,]
              Получить температуру с первого найденного на OneWire шине термометра DS18x20, применив 12-битное преобразование значения. Измерение с такой точностью имеет смысл в небольшом температурном диапазоне, затем ошибка измерения начинает нарастать.

              zabbix_get -s 192.168.0.1 -k DHT.Temperature[4,22]
              Получить температуру с датчика DHT22, подключенного к пину 4.

              zabbix_get -s 192.168.0.1 -k DHT.Humidity[4,22]
              Получить величину относительной влажности с датчика DHT22, подключенного к пину 4.

              zabbix_get -s 192.168.0.1 -k BMP.Temperature[18,19]
              Получить температуру с датчика BMP085/BMP180, подключенного к стандартной I2C шине.

              zabbix_get -s 192.168.0.1 -k BMP.Pressure[18,19,3]
              Получить с повышенной точностью величину атмосферного давления с датчика, подключенного к стандартной I2C шине. Имейте в виду, что давление, измеренное на первом этаже здания отличается от давления, измеренного на последнем этаже
              Attached Files

              Comment

              • brood
                Junior Member
                • Jul 2015
                • 5

                #8
                Добрый день, sadman!

                Собрал устройство на базе Arduino Uno R3 (atmega 328) + WizNET 5100. Установил на борт датчик DHT11. При запросе через zabbix_get выдает странные значения, например:
                Code:
                [root@zabbix ~]# zabbix_get -s 192.168.10.147 -k DHT.Temperature[3,11]
                614.4
                
                [root@zabbix ~]# zabbix_get -s 192.168.10.147 -k DHT.Humidity[3,11]
                972.8
                Не подскажите в чем может быть дело?

                Comment

                • sadman
                  Senior Member
                  • Dec 2010
                  • 1611

                  #9
                  Полагаю, что в отсутствии code revision. "break;" пропустил в switch-e функции DHTRead(). Вот и перевычисляется все, как для DHT22 (следующего по switch-у типу датчика), а не выскакивает после выполнения блока под условием.
                  Можете подправить самостоятельно в двух местах, а то мне с телефона много не пописать. Исходники лучше отсюда взять: https://github.com/zbx-sadman/zabbuino - они там посвежее. Вам нужен файл dht.ino.

                  Comment

                  • brood
                    Junior Member
                    • Jul 2015
                    • 5

                    #10
                    К сожалению, моих навыков не хватило, чтобы самому поправить код. Но нашёлся другой температурный датчик (DS18b20) на котором всё отлично заработало. Низкий поклон и благодарность за данный проект, все очень просто и работоспособно! С нетерпением жду поправки в коде

                    Comment

                    • sadman
                      Senior Member
                      • Dec 2010
                      • 1611

                      #11
                      Подправил полчаса тому назад. Не компилировал, но должно работать. Брать там же, на гитхабе.

                      Comment

                      • sadman
                        Senior Member
                        • Dec 2010
                        • 1611

                        #12
                        Не за горами зимние праздники, а значит самое время подумать о развлекательной программе. И конечно, Zabbuino спешит на помощь своим друзьям, которые не ищут легких путей.

                        Итак, берем Arduino, Ethernet Shield, заливаем в него Zabbuino, подключаем светодиодную ленту на базе WS2801, подаем отборные вольты и амперы, хорошенечко обматываем всё это изолентой и получаем удаленно управляемый по Ethernet автомат световых эффектов, которым радуем сервера, елку или поддавших коллег.

                        Переключение LED-пикселей ленты происходит по команде shiftout[dataPin, clockPin, latchPin, bitOrder, value], где dataPin подключен к DI ленты, clockPin к CI, а в value подаются шестнадцатеричные строки, задающие цвет пикселей. Так, как модуль WS2801 поддерживает 24-битный цвет, то на каждый LED-пиксель отводится по шесть символов.

                        Пример:
                        zabbix_get -s 192.168.0.2 -k shiftOut[2,3,,1,0xFF000000FF000000FF]
                        Задаем цвет первого led-пикселя FF0000 (красный), второго - 00FF00 (зеленый), третьего - 0000FF (синий).

                        Длина строки определяется размером буфера ARGS_SIZE. На ленту из 50-ти пикселей требуется размер в 50*6 => 300 символов. На ATMega 328p приходится, правда, отключать лишние функциональные блоки. Пока что достигнутая максимальная скорость не очень высокая и больше подходит для бегущих огней - где-то 0,5 сек задержки между переключениями на 50-пиксельной ленте.

                        Небольшой скрипт на perl, содержащий несколько примеров праздничной иллюминации, доступен по ссылке: ws2801.pl

                        Comment

                        • sadman
                          Senior Member
                          • Dec 2010
                          • 1611

                          #13
                          Пока все отдыхают и наслаждаются пляжем, шашлыком и арбузом, Zabbuino взрослеет на импортозамещенном сыре из пальмового масла, обрастает нужными и ненужными щупалами и мигалами.

                          К большому сожалению микроконтроллер ATMega168 выходит из игры, так как более не справляется с объемом прошивки. Хотя, энтузиасты, конечно могут покрошить код настолько, что он влезет и в эту устаревшую модель.

                          Давайте взглянем, что интересного добавлено в Zabbuino 1.0.0:
                          • Сетевые процедуры переработаны на 90%, убраны старые глупые ошибки и добавлены новые;
                          • Достигнута более-менее стабильная работа с ENC28J60;
                          • По прежнему поддерживаются:
                            • сетевые модули WS51xx and ENC25J60;
                            • статический IP-адрес;
                            • часть ключей, совместимых c агентом Zabbix;
                            • проксированные запросы к функциям языка программирования Arduino;
                            • цифровые термометры серии DS18X20;
                            • датчики DHT11/21/22/33/44, AM2301/2302 и иные, совместимые с ними;
                            • датчики BOSCH BMP180/085;
                            • иные сенсоры, доступные через функции Arduino `analogRead()` и `digitalRead()`;
                            • светодиодные ленты на чипе WS2801 (и совместимые с ним) в нединамическом режиме;
                            • исполнительные устройства, запускаемые через функции Arduino `analogWrite()` и `digitalWrite()`;

                          • Добавлена поддержка:
                            • протокола DHCP;
                            • удаленного конфигурирования системы и ее перезагрузки;
                            • сохранения сетевых и системных настроек в EEPROM;
                            • сторожевого таймера (Watchdog);
                            • получения системных метрик (последнего/минимального/максимального значения VCC, последнего/минимального свободного объема RAM, времени работы и пр.)
                            • сканирования шин 1-Wire и I2C для определения адресов подключенных устройств;
                            • датчиков температуры и относительной влажности Sensirion SHT2X (чип SI7021);
                            • датчиков температуры и атмосферного давления BOSCH BMP280/BME280. Для BME280 так же поддерживается получение значения относительной влажности;
                            • датчика освещенности ROHM BH1750;
                            • датчика расстояния HC-SR04;
                            • датчиков тока Allegro ACS7xx;
                            • датчиков угла поворота (инкрементальных трехтерминальных энкодеров), обслуживаемых по прерыванию;
                            • иных сенсоров, нуждающихся в счете событий по прерыванию - датчиков вибрации, сотрясения, сухих контактов, PIR, расходомеров воды, датчиков скорости ветра и пр.
                            • индикаторов, подключенных к МС MAX7219 (например светодиодной матрицы 8x8);
                            • одно-, двух- (а может быть и четырех-) строчных алфавитно-цифровых дисплеев, подключенных через I2C экспандер PC8574;
                            • простых I2C устройств (экспандеров, цифровых потенциометров и пр);
                            • симуляции инфракрасных передатчиков для устройств, управляемых по этому каналу.


                          Подробное описание команд, их примеры, а так же прочие полезные и не очень материалы можно найти на https://github.com/zbx-sadman/Zabbui...ino-in-Russian и https://github.com/zbx-sadman/Zabbui...ses-in-Russian

                          Сам Zabbuino живёт рядом: https://github.com/zbx-sadman/Zabbuino
                          Last edited by sadman; 16-08-2016, 11:31.

                          Comment

                          • brood
                            Junior Member
                            • Jul 2015
                            • 5

                            #14
                            Отзыв

                            @sadman, огромное спасибо за проделанную работу!
                            Вот уже около года использую Zabbuino в серверной для мониторинга температуры в Zabbix. Всё работает стабильно, ни одного зависания за это время. Разглядываю красивые графики температуры, когда народ забывает включить кондёр прилетают алерты, всё пучком!
                            P.S. Пользуюсь Zabbuino v.9999

                            Comment

                            • sadman
                              Senior Member
                              • Dec 2010
                              • 1611

                              #15
                              Originally posted by brood
                              @sadman, огромное спасибо за проделанную работу!
                              Вот уже около года использую Zabbuino в серверной для мониторинга температуры в Zabbix. Всё работает стабильно, ни одного зависания за это время. Разглядываю красивые графики температуры, когда народ забывает включить кондёр прилетают алерты, всё пучком!
                              P.S. Пользуюсь Zabbuino v.9999
                              Перебирайтесь на 1.0.0 - в нем всё должно быть лучше и веселее. Вот, к примеру, я у себя такой информер тестирую (высоты столбиков масштабируются, если событый > 8):




                              Мне удобно, не нужно постоянно пялится в веб-интерфейс или дергаться от смс-ок.

                              Comment

                              Working...