Новогодняя SMS-ёлка
- Платформы: Iskra Neo
- Языки программирования: Arduino (C++)
- Тэги: Merry Christmas, WS2811, GPRS, гирлянда, адресная светодиодная лента RGB, ёлка, IP-камера
Что это?
Ни один Новый Год не обходится без ёлки, гирлянды и подарков. Мы расскажем как прокачать вашу ёлку так, что она будет удивлять и ослеплять всех ваших гостей.
Сделаем гирлянду, цвет свечения которой может изменить каждый с помощью SMS. В сообщении достаточно отправить число от 0 до 360, которое определяет оттенок (Hue) по цветовому кругу, по модели HSV. Приняв сообщение, устройство переведёт цвет в нужное для ленты RGB-значение и с помощью незамысловатой анимации изменит цвет на новый.
Что нам понадобится?
- SIM-карта
- Блок питания (12 В, 12,5 А)
- Влагозащищенный корпус
- Евровилка сетевая с выключателем
- Герметичный разъём (розетка + вилка) 4pin
- Многожильный монтажный провод с сечением не менее 3×2,5 мм² (1 метр)
- Многожильный монтажный провод с сечением не менее 1 мм² (2 шт. разного цвета)
Как собрать?
- Вставьте сим-карту в GPRS Shield и установите его на платформу Iskra Neo.
- Установите в герметичный корпус блок питания (12 В, 12,5 А) и «бутерброд» из платы Iskra Neo и GPRS Shield’a, используя мегапластину от #структора.
- Сделайте два отверстия в корпусе и установите через них евровилку и герметичный разъём (розетка).
- Соедините клеммы входного напряжения блока питания
L
иN
с евровилкой, используя монтажные провода из кабеля 3×2,5. А клеммы выходного напряжения−V
и+V
— с герметичным разъёмом для питания светодиодной ленты. - Соедините цифровой пин
6
платформы Iskra Neo с герметичным разъёмом. По нему будут передаваться данные для контроллеров светодиодной ленты. - Подключите выходное напряжение
−V
и+V
от блока питания к плате Iskra Neo через внешний разъём, используя монтажные провода и штекер питания 2,1 мм. - Используя многожильный монтажный провод с сечением 3×2,5 мм² и герметичный разъём (вилка), сделайте шнур для подключения RGB-ленты к блоку управления, по которому будет подаваться питание и данные для адресной светодиодной ленты:
- питание
+V
— коричневый; - земля
−V
— синий; - сигнальный — зелёный.
- Далее соедините полученные проводники с адресной светодиодной лентой через клеммы.
- В заключении подключите сетевой шнур в евровилку, а герметичный разъём со шнуром (вилка) — в герметичный разъём в корпусе (розетка)
Внимание!
Если необходимо подключить несколько светодиодных лент, недостаточно подключить вторую ленту к первой последовательно. В таком случае первая лента может перегреваться, так как её токопроводящие дорожки рассчитаны на ток одной ленты.
Перегрев в свою очередь значительно сокращает срок службы светодиодов.
Правильный вариант – выходной сигнальный провод первой ленты оставить соединённым с входным сигналом второй ленты, а выводы питания и земли каждой ленты подключить непосредственно к выводам блока питания.
Алгоритм
- Сразу после подачи питания проверяем есть ли связь с GPRS устройством.
- Если связи нет, повторяем запрос снова и ждём подтверждения связи.
- Ожидаем приём новых сообщений.
- Если их нет, повторяем запрос снова и снова.
- Читаем сообщение и проверяем содержимое его текста:
- Если в тексте число 0–360, меняем по сегментам цвет гирлянды по шкале
HSV
и отчитываемся об изменении обратным смс. - Если текст не распознан, отправляем обратное смс об ошибке распознавания команды.
Исходный код
- christmastree.ino
// библиотека для эмуляции Serial-порта // она нужна для работы библиотеки GPRS_Shield_Arduino #include <SoftwareSerial.h> // библиотека для работы с GPRS устройством #include <GPRS_Shield_Arduino.h> // библиотека для работы с адресной RGB-лентой #include <Adafruit_NeoPixel.h> // номер пина, к которому подключен сигнальный провод ленты #define PIXEL_PIN 6 // количество сегментов в ленте #define PIXEL_COUNT 200 // текст сообщения, об удачном изменении цвета ленты #define MESSAGE_OK "Well done! "\ "You are hacked our Christmas Tree. Happy New Year 2016!" // текст сообщения, об ошибки ввода смс #define MESSAGE_ERROR "Whoops! Something wrong."\ "Your attempt is failed." // текст сообщения, о включении секретного режима #define MESSAGE_BONUS "You are hacked our Christmas Tree."\ "Secret mod has been activated. Happy New Year 2016!" // длина входящего сообщения сообщения #define MESSAGE_LENGTH 160 // массив текста сообщения char message[MESSAGE_LENGTH]; // номер, с которого пришло сообщение char phone[16]; // дата отправки сообщения char datetime[24]; // создаём объект класса GPRS и передаём в него объект Serial1 GPRS gprs(Serial1); // можно указать дополнительные параметры — пины PK и ST // по умолчанию: PK = 2, ST = 3 // GPRS gprs(Serial1, 2, 3); // если используете плату Arduino Uno или Arduino Mega2560 // прочтите внимательно статью о GPRS Shield, что бы сделать некоторые исправления // создаём объект класса Adafruit_NeoPixel Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_BRG + NEO_KHZ800); // переменные, содержащие насыщенность красного, синего и зелёного цветов int r, g, b; void setup() { // инициализация светодиодной ленты strip.begin(); strip.show(); // включаем GPRS шилд gprs.powerOn(); // проверяем, есть ли связь с GPRS-устройством while (!gprs.init()) { // если связи нет, ждём 1 секунду // процесс повторяется в цикле, // пока не появится ответ от GPRS устройства delay(1000); } // заполняем RGB-ленту по сегментам «бегущий огонь» colorWipe(strip.Color(190, 0, 255), 50); // гасим RGB-ленту по сегментам «бегущая тень» colorWipe(strip.Color(0, 0, 0), 50); } void loop() { // если пришло новое сообщение if (gprs.ifSMSNow()) { // сохраняем текст, номер с которого пришло и дату приёмки в переменные gprs.readSMS(message, phone, datetime); // проверяем подходит ли текст сообщения по нужный формат if (checkSMS() == 0) { // если нет, отправляем на номер с которого пришло сообщение // о неправильном формате смс gprs.sendSMS(phone, MESSAGE_ERROR); // возвращаемся в функцию loop и ожидаем нового сообщения return; } // переводим текст сообщения в целочисленную переменную int value = atoi(message); // проверка входит ли число в диапазон шкалы «HSV» if (value >= 0 && value <= 360) { // если да, отправляем на номер с которого пришло сообщение // об удачном смене цвета гирлянды gprs.sendSMS(phone, MESSAGE_OK); // переводим значение цвета из шкалы «HSV» в «RGB» f_HSV_to_RGB(value, 255, 255); // заполняем RGB-ленту по сегментам выбранным пользователем цветом colorWipe(strip.Color(r, g, b), 50); } else if (value == 2016) { // если число оказалось лотерейным // отправляем на номер с которого пришло сообщение // о включении секретного режима гирлянды gprs.sendSMS(phone, MESSAGE_BONUS); // включаем мигающий градиент цветов theaterChaseRainbow(50); // возвращаем предыдущий цвет RGB-ленты colorWipe(strip.Color(r, g, b), 50); } else { // если число не попало не в один диапазон чисел // отправляем на номер с которого пришло сообщение // о неправильном формате смс gprs.sendSMS(phone, MESSAGE_ERROR); } } } // функция проверки формата смс-сообщения bool checkSMS() { // создаём переменную и присваиваем ей длину текста сообщения int len = strlen(message); // если длина смс больше 4 символов или равна 0 if (len == 0 || len > 4) { // выходим из функции и возвращаем «ложь» return false; } // проверка всех символов текста смс for (int i = 0; i < len; i++) { // если в тексте есть хотя бы одна не цифра if (message[i] < '0' || message[i] > '9') { // выходим из функции и возвращаем «ложь» return false; } } // если все условия выполнеы возвращаем «истину» return true; } // функция перевода цвета из шкалы «HSV» в «RGB» void f_HSV_to_RGB(int hue, int sat, int val) { int base; if (sat == 0) { r = val; g = val; b = val; } else { base = ((255 - sat) * val) >> 8; switch (hue / 60) { case 0: { r = val; g = (((val - base) * hue) / 60) + base; b = base; break; } case 1: { r = (((val - base) * (60 - (hue % 60))) / 60) + base; g = val; b = base; break; } case 2: { r = base; g = val; b = (((val - base) * (hue % 60)) / 60) + base; break; } case 3: { r = base; g = (((val - base) * (60 - (hue % 60))) / 60) + base; b = val; break; } case 4: { r = (((val - base) * (hue % 60)) / 60) + base; g = base; b = val; break; } case 5: { r = val; g = base; b = (((val - base) * (60 - (hue % 60))) / 60) + base; break; } case 6: { r = val; g = 0; b = base; break; } } } } // функция заполнения каждого сегмента void colorWipe(uint32_t c, uint8_t wait) { for (uint16_t i = 0; i < strip.numPixels(); i++) { // заполняем текущий сегмент выбранным цветом strip.setPixelColor(i, c); strip.show(); // ждём delay(wait); } } // функция эффекта радуги void theaterChaseRainbow(uint8_t wait) { for (int j = 0; j < 256; j++) { for (int q = 0; q < 3; q++) { for (int i = 0; i < strip.numPixels(); i = i + 3) { // включаем каждый третий сегмент strip.setPixelColor(i + q, wheel((i+j) % 255)); } strip.show(); // ждём delay(wait); for (int i = 0; i < strip.numPixels(); i = i + 3) { // выключаем каждый третий сегмент strip.setPixelColor(i+q, 0); } } } } uint32_t wheel(byte wheelPos) { wheelPos = 255 - wheelPos; if (wheelPos < 85) { return strip.Color(255 - wheelPos * 3, 0, wheelPos * 3); } if (wheelPos < 170) { wheelPos -= 85; return strip.Color(0, wheelPos * 3, 255 - wheelPos * 3); } wheelPos -= 170; return strip.Color(wheelPos * 3, 255 - wheelPos * 3, 0); }
Для компиляции скетча вам понадобятся библиотеки GPRS-shield и Adafruit_NeoPixel.
Демонстрация работы устройства
Что дальше?
Заменив в своём проекте GPRS Shield на датчик шума вы дадите уши своему проекту. И получите из RGB-ленты — светомузыкальную установку.