// библиотека для эмуляции Serial-порта // она нужна для работы библиотеки GPRS_Shield_Arduino #include // библиотека для работы с GPRS устройством #include // библиотека для работы с адресной RGB-лентой #include // номер пина, к которому подключен сигнальный провод ленты #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); }