Технокуб для гиков — программируем свет

image

В том году мне посчастливилось получить для экспериментов набор от Амперки Технокуб (бесплатно, то есть даром), время шло, но попробовать его собрать времени всё не находилось… Набор увидел коллега по работе — и заинтересовался. Я с радостью отдал ему для экспериментов. И вот, что получилось (совместная статья):

Некоторое время назад меня заинтересовала платформа Ардуино как способ попробовать реализовать свои идеи. Ранее до этого был опыт сборки сурового аналогового сигнализатора в качестве курсового проекта по электронике. И волею судеб — коллега из местного хакспейса MakeItLab одолжил набор от Амперки Технокуб.

Про сборку и программирование простейшей системы индикации освещения на базе Технокуба и будет данная статья.

Предварительно надо сказать, в чём собственно предназначение DIY набора Технокуб? По сути это система световой индикации какого-либо события. Само событие — может инициироваться от компьютера (через USB соединение), например:

  • получение почты (это приложение идёт по-умолчанию с Технокубом)

  • наступление события в календаре

  • уведомление от какого-либо устройства или датчика

  • уведомление о приходе запроса с каким-либо приоритетом

  • и т.п.

Конечно Технокуб может работать и автономно.

Программную составляющую, мы рассмотрим в конец статьи, а сейчас посмотрим, что внутри и соберём (в нашем примере) — систему, что будет получать информацию от датчика освещения, и визуализировать цветом эти данные (по сути простейший ночной светильник).

Мне досталась большая коробка из постомата, внутри которой лежала коробочка поменьше с, собственно, самим Технокубом и датчиком освещенности.

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

Разложив все вместе, получилась следующая картина.

Как мы видим, набор Технокуба состоит из световых индикаторов, конструктивных элементов (в том количестве, чтобы можно было собрать куб).

И конечно же «мозг» системы — Ардуино (Iskra от Амперки, аналог Arduino Leonardo)

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

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

После того, как я закрепил плату и светодиоды на элементах конструктора я начал подключать провода…

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

После достаточно долгой сборки куба настал черед подключения кабеля. И тут меня ждал приятный сюрприз. Я имею привычку рассматривать USB-штекер прежде чем вставить его в разъем. Но этот штекер оказался не такой как все остальные. Я сделал предположение и…

… оказался прав! Эмпирическим путем было выяснено, что штекер двухсторонний. То есть не нужно мучаться проблемой суперпозиции USB-штекера.

Настала долгожданная очередь включения куба и проверки его работы!

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

Сложно описать тот детский восторг, который я испытал после того, как куб заработал!

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

После долгих попыток примастырить датчик к кубу было принято решение изменить начальную конструкцию.

У меня получилась такая конструкция.

Дальше нужно было понять, что будет делать будущее устройство с датчиком освещенности? Я решил, что с помощью светодиодов оно будет сигнализировать о текущем уровне освещенности следующим образом:

0 (минимальное освещение) — мигает красный светодиод
1 — горит красный светодиод
2 — горит два красных светодиода
3 — горит два красных светодиода и один зеленый
4 (максимальное освещение) — горят все светодиоды

Также в устройстве должна быть возможность задать максимальный и минимальный уровень освещенности.

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

У меня получился такой GUI.

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

Программирование

Из чего состоит базовая конфигураци ПО для Технокуба:

  • Скетч Firmata — записанный на Ардуино (позволяющий полностью управлять и получать данные с Ардуино через последовательный порт — реализованный через USB подключение)

  • Десктопное GUI приложение Cube на базе wxPython (wxPython 3.0 для Python 2.7)

Cube приложение состоит из нескольких файлов:

  • main.py — графический пользовательский интерфейс;

  • device.py — управление светодиодами на низком уровне;

  • modes.py — файл, который отвечает за проверку почты

После установки необходимых библиотек, запускается с помощью python main.py.

Графический интерфейс позволяет управлять цветом Куба вручную, или включить на выполнение одну из предустановленных Программ, как например индикация поступления почты (предварительно указав параметры)

Алгоритм Базовой программы Cube

Сразу после запуска приложения, программа проверяет количество подключенных COM-портов.

  • Если больше одного, то программа предложит выбрать один из них.
  • Если один — сразу подключится к нему автоматически.
  • Если ни одного — сообщит об ошибке и предложит повторить попытку.

Выбор режима работы приложения (бесконечный цикл):

Ручное управление.

  • Кликнув на первую кнопку загораются красные светодиоды.
  • Кликнув на вторую кнопку загораются зеленные светодиоды.

Проверка почты на GMail / Mail

  • Вводим данные: Логин/пароль и подтверждаем.
  • Если писем нет, горит красный светодиод.
  • Если есть новое письмо, мигаем попеременно светодиодами в течении 3 секунд и оставляем гореть зеленый.

Проверка почты через сервер IMAP

  • Вводим данные: Логин, пароль, сервер IMAP и подтверждаем.
  • Если писем нет, горит красный светодиод.
  • Если есть новое письмо, мигаем попеременно светодиодами в течении 3 секунд и оставляем гореть зеленый.

Амерка предусмотрела возможность сборки автономной exe программы — в случае если вы захотите сделать дистрибутив вашей версии ПО — для какого-либо приложения Технокуба (это делается с помощью запуска setup.py py2exe, и в папке «dist» появится exe файл).

Для нашего примера

Было создано отдельное приложение (на базе оригинального), суть приложения — получать данные с датчика освещённости, и в зависимости от его значения — включать один из режимов индикации. Как это было сделано:

В класс отвечающий за панельку, что открывается при выборе выпадающего списка «Показания датчик»

class SensorPanel(wx.Panel):

в методе def loop(self): была реализована следующая логика:

 def loop(self):
   while not self._stopped:
     raw_value = self.device.get_analog()
     self.sensor_label.SetLabel(u"%.3f" % raw_value)
     sensor_value = round((1 - (self.max_level - self.device.get_analog()) / (self.max_level - self.min_level)) * 5)
     self.device.show_level(sensor_value)
     sleep(1)

Метод loop() запускается при выборе пункта из выпадающем списке (в нашем случае называется «Показания датчика»):

threading.Thread(target=self.loop).start()

Суть метода, в бесконечном цикле (до тех пор пока не выставлен флаг _stopped) — получить значение с датчика:

raw_value = self.device.get_analog()

вывести это значение в GUI интерфейсе:

self.sensor_label.SetLabel(u»%.3f» % raw_value)

рассчитать число (от 0 до 4) на базе силы освещения

sensor_value = round((1 — (self.max_level — self.device.get_analog()) / (self.max_level — self.min_level)) * 5)

И далее дать команду Технокубу включить один из режимов подсветки:

self.device.show_level(sensor_value)

и засыпаем на 1 секунду (не блокируя интерфейс).

sleep(1)

На стороне датчика, необходимо было реализовать show_level(), это выглядит так:

class CubeDevice(object):
 ...
   def show_level(self, num):
     if num < 1:
       self.blink_light_level()
     else:
       self._write_pins([6], 1 if num >= 1 else 0)
     self._write_pins([5], 1 if num >= 2 else 0)
     self._write_pins([10], 1 if num >= 3 else 0)
     self._write_pins([9], 1 if num >= 4 else 0)

Возможно, не лучший python код — это мой первый опыт программирования на Python.

Заключение

Данный набор доставил мне массу приятных впечатлений и дал ценный опыт. Что было сделано:

  • произведена сборка самодостаточного устройства с привлекательным внешним видом из составных частей

  • практическое применений знаний по языку программирования Python

  • изучение библиотеки wx и доработка графического интерфейса

  • первый реальный опыт работы с Git и GitHub

Что дальше?

А дальше можно дорабатывать устройство следующими путями:

  • сделать корпус для устройства и заменить светодиоды на светодиодную шкалу, добавить кнопки для установки уровней

  • переписать программу с Python на C и залить на Ардуино, чтобы получилось самодостаточное устройство, не требущее запуска отдельного приложения на компьютере

  • и так далее…

Ссылки

авторы Ilya Nemihin и Антон Волокитин