Хэллоуинская тыква

  • Платформы: Arduino M0
  • Языки программирования: Arduino (C++)
  • Тэги: хэллоуин, тыква, фонарь Джека, дым

Что это?

Хэллоуин — ночь перед Днём всех святых. По легенде именно в Хэллоуин духи выходят на землю, чтобы побезобразничать. В этот день принято выставлять в окно фонарь из тыквы со свечой внутри, чтобы отпугнуть злых духов. Мы расскажем как, используя новые технологии, сделать тыкву настолько страшной, что вся нечисть ещё долго будет обходить ваш район стороной.

Что нам понадобится?

  1. Многожильный монтажный провод с сечением не более 1 мм²
  2. Карта памяти microSD
  3. Аудио гнездо 3,5 мм
  4. Миниатюрный активный динамик
  5. Паяльник
  6. Глицерин
  7. Вата
  8. Крепёжные элементы: саморезы
  9. Тыква

Wireless SD Shield в данном проекте используется для подключения карты памяти microSD и считывания с неё wave-файлов, а не для подключения модулей беспроводной связи форм-фактора XBee.

Как собрать?

Для начала модернизируем Wireless SD Shield для подключения различных модулей.

Внимание!

В отличии от большинства плат Arduino, родным напряжением Arduino M0 является 3,3 В, а не 5 В. Соответственно, выходы для логической единицы выдают 3,3 В, а в режиме входа ожидают принимать не более 3,3 В. Подача большего напряжения может повредить микроконтроллер!

В связи с тем что в проекте используются 2 уровня напряжения, сделаем 3-пиновые разъёмы для подключения датчиков как с 3,3-вольтовой логикой, так и с 5-вольтовой логикой.

  1. Возьмите штырьковые соединители и контактную колодку по 3 пина и припаяйте к луженным отверстиям на Wirelees Shield.
  2. Соедините нижние 3-пиновые разъёмы с цифровыми сигналами 8, 9 и 11. Далее подключите к ним питание 5V и землю GND.

    Для эстетичности платы все провода и пайку проводите с обратной стороны Wireless SD Shield’a.

  3. Подключите к верхнему 3-пиновому разъёму цифровой сигнал пина 12, а также питание 3V3 и землю GND.
  4. Соедините два пина контактной колодки через электролитический конденсатор с пином A0, а 3 пин контактной колодки соедините с землёй GND. Конденсатор используется для отфильтровки постоянной составляющей сигнала.
  5. Вставьте microSD карту в Wireless SD Shield и установите его сверху на платформу Arduino M0.
  6. Подключите светодиоды «Пиранья» используя 3-проводные шлейфы через 3-пиновые разъёмы к 8 и 9 Wireless SD Shield.
  7. Инфракрасный датчик препятствий имеет на выходе бинарный цифровой сигнал. Если его питать напряжением 5 вольт, на выходе датчика при логической единице так же будет 5 вольт, которые спалят порт микроконтроллера. Чтобы такого не случилось подключите инфракрасный датчик препятствий через распаянный 3-пиновый разъём к пину12, рабочее напряжение которого 3,3 вольта.
  8. Теперь займёмся дымом. Возьмите паяльник, раскрутите его и достаньте металлическую трубку на которой намотана нихромовая нить.
  9. Извлеките от металлической трубки кусок нихромовой нити длинной 50–60 мм, намотайте на кусок ваты и припаяйте к обоим концам провода «папа-папа». Смочите вату глицерином, а оставшиеся по бокам части ваты поместите в ёмкость с глицерином. Таким способом при подключении на нихромовую нить напряжения питания 12 вольт, она будет греться и глицерин, которым пропитана вата, будет испаряться и создавать дым. А опущенные концы ваты в ёмкость с глицерином, будут создавать капиллярный эффект и не дадут испариться всему глицерину в области нагревания.
  10. Так как для получения дыма нам нужно подавать на нихромовую нить 12 вольт, подключим её к платформе Arduino M0 через силовой ключ:
    1. Подключите силовой ключ используя 3-проводной шлейф через 3-пиновый разъём к пину 11 Wireless SD Shield.
    2. Один провод нихромовой нити подключите к пину Vin
    3. Второй провод нихромовой нити подключите через клеммник к плюсу силового ключа.
    4. Минус силового ключа подключите к земле GND Wireless SD Shield’a.
  11. Соедините аудио разъём тремя проводами «папа-папа» через 3-пиновую контактную колодку с Wireless SD Shield:
    1. «правый канал» — через уже установленный конденсатор к пину A0 Wireless SD Shield;
    2. «левый канал» — соедините с «правым каналом», так как мы используем моно сигнал;
    3. «общий» — к пину GND.
      После чего подключите внешний динамик через аудио разъём.По итогу должна получиться следующая схема:
  12. Настало время гвоздя программы — страшной и ужасающей тыквы. С помощью ножа сделайте из тыквы адового монстра, чтоб ни одна душа не могла пройти спокойно мимо неё. Далее поместите всю электронику через верхнее заранее вырезанное отверстие в тыкву. Подключите импульсный источник питания через внешний разъём к Arduino M0.
  13. Инфракрасный датчик выведете через рот тыквы, чтоб он мог без препятствий сканировать окружающую местность в поиске жертвы.

Теперь можно поздней Хеллоуинской ночью взять тыкву на улицу, оставить её в тёмном месте и смотреть на реакцию вскрикивающих от ужаса мимо проходящих людей.

Алгоритм

  • Сразу после подачи питания проверяем есть ли связь с microSD картой.
    • Если связи нет, повторяем запрос снова и ждём подтверждения связи.
  • Проверяем в цикле состояния датчика препятствия
    • Если кто то прошёл мимо: зажигаем светодиоды, подаём высокий уровень на силовой ключ и включаем дважды заранее записанный трек с карты памяти.
    • После завершения трека гасим светодиоды и подаём низкий уровень на силовой ключ.
  • Ждём нового прохожего.

Исходный код

halloween.ino
// подключаем библиотеку для работы SPI
#include <SPI.h>
// подключаем библиотеку для работы c картой microSD
#include <SD.h>
// подключаем библиотеку для воспроизведения музыки с помощью Arduino M0
#include <AudioZero.h>
 
// даём разумное имя пинам к которым подключены светодиоды
#define LED1_PIN 8
#define LED2_PIN 9
 
// даём разумное имя пина к которому подключен силовой ключ
#define MOSFET_PIN 11
 
// даём разумное имя для пина к которому подключен
// инфракрасный датчик препятствий (infrared sensor barriers)
#define ISB_PIN 12
 
void setup()
{
  // начало работы с SD-картой памяти
  // передаём номер пина подключенного к линии CS SD-карты
  while (!SD.begin(4)) {
    // если связи нет, ждём 1 секунду
    // процесс повторяется в цикле
    // пока не появится положительный ответ от SD-карты
    delay(1000);
  }
 
  // настраиваем пины светодиодов в режим выхода
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  // гасим светодиоды
  digitalWrite(LED1_PIN, LOW);
  digitalWrite(LED2_PIN, LOW);
 
  // настраиваем пин силового ключа в режим выхода
  pinMode(MOSFET_PIN, OUTPUT);
  // подаём низкий уровень на силовой ключ
  digitalWrite(MOSFET_PIN, LOW);
}
 
void loop()
{
  // если на выходе датчика логический 0
  if (!digitalRead(ISB_PIN)) {
    // зажжём светодиоды
    digitalWrite(LED1_PIN, HIGH);
    digitalWrite(LED2_PIN, HIGH);
    // подаём высокий уровень на силовой ключ
    digitalWrite(MOSFET_PIN, HIGH);
 
    // вызываем дважды функцию воспроизведения трека
    playMusic();
    playMusic();
 
    // гасим светодиоды
    digitalWrite(LED1_PIN, LOW);
    digitalWrite(LED2_PIN, LOW);
    // подаём низкий уровень на силовой ключ
    digitalWrite(MOSFET_PIN, LOW);
  }
}
 
void playMusic()
{
  // начинаем работу с библиотекой AudioZero
  // выставляем частоту воспроизведения
  AudioZero.begin(2*44100);
  // открываем wave-файл с карточки microSD
  File myFile = SD.open("scream.wav");
  // если файл открывается, проигрываем его
  if (myFile) {
    AudioZero.play(myFile);
  }
  // прекращаем работу с библиотекой AudioZero
  AudioZero.end();
}

Работа программы во время воспроизведения музыки

В нашем проекте есть изъян, когда идёт воспроизведение музыки, программа стоит на месте и ожидает завершения трека. Если вы в этот момент хотите выполнять различные действия необходимо воспользоваться прерыванием по таймеру. Ниже представлен пример скетча, в котором во время воспроизведения музыки глаза у тыквы мигают. В скетче используются уже не только стандартные функции и методы языка Arduino (C++), а и общение с регистрами микроконтроллера на чистом «C».

halloweenInterruptBlink.ino
// подключаем библиотеку для работы SPI
#include <SPI.h>
// подключаем библиотеку для работы c картой microSD
#include <SD.h>
// подключаем библиотеку для воспроизведения музыки с помощью Arduino M0
#include <AudioZero.h>
 
// даём разумное имя пинам к которым подключены светодиоды
#define LED1_PIN 8
#define LED2_PIN 9
 
// даём разумное имя пина к которому подключен силовой ключ
#define MOSFET_PIN 11
 
// даём разумное имя для пина к которому подключен
// инфракрасный датчик препятствий (infrared sensor barriers)
#define ISB_PIN 12
 
void setup()
{
  // начало работы с SD-картой памяти
  // передаём номер пина подключенного к линии CS SD-карты
  while (!SD.begin(4)) {
    // если связи нет, ждём 1 секунду
    // процесс повторяется в цикле
    // пока не появится положительный ответ от SD-карты
    delay(1000);
  }
  // инициализация и настройка таймера
  timerInit();
  // настраиваем пины светодиодов в режим выхода
  // PORT_PA06 8 пин Arduino M0
  // PORT_PA07 9 пин Arduino M0
  PORT->Group[0].OUTTGL.reg = PORT_PA06;
  PORT->Group[0].DIRSET.reg = PORT_PA07;
  // гасим светодиоды
  PORT->Group[0].OUTCLR.reg = PORT_PA06;
  PORT->Group[0].OUTCLR.reg = PORT_PA07;
 
  // настраиваем пин силового ключа в режим выхода
  pinMode(MOSFET_PIN, OUTPUT);
  // подаём низкий уровень на силовой ключ
  digitalWrite(MOSFET_PIN, LOW);
}
 
void loop()
{
  // если на выходе датчика логический 0
  if (!digitalRead(ISB_PIN)) {
    // разрешаем прерывание по таймеру TC3
    NVIC_EnableIRQ(TC3_IRQn);
    // подаём высокий уровень на силовой ключ
    digitalWrite(MOSFET_PIN, HIGH);
    // вызываем дважды функцию воспроизведения трека
    playMusic();
    playMusic();
    // запрещаем прерывание по таймеру TC3
    NVIC_DisableIRQ(TC3_IRQn);
    // подаём низкий уровень на силовой ключ
    digitalWrite(MOSFET_PIN, LOW);
  }
}
 
void playMusic()
{
  // начинаем работу с библиотекой AudioZero
  // выставляем частоту воспроизведения
  AudioZero.begin(2*44100);
  // открываем wave-файл с карточки microSD
  File myFile = SD.open("scream.wav");
  // если файл открывается, проигрываем его
  if (myFile) {
    AudioZero.play(myFile);
  }
  // прекращаем работу с библиотекой AudioZero
  AudioZero.end();
}
 
void timerInit()
{
  // тактирование таймера TC3
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN|GCLK_CLKCTRL_GEN_GCLK0|GCM_TCC2_TC3;
  // 16 битный счётчик и предделитель 64
  TC3->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16|TC_CTRLA_PRESCALER_DIV64;
  // прерывание по переполнению
  TC3->COUNT16.INTENSET.reg |= TC_INTENSET_OVF;
  // запуск счётчика
  TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
 
  // настройка прерывания на таймер 3
  NVIC_DisableIRQ(TC3_IRQn);
  NVIC_ClearPendingIRQ(TC3_IRQn);
  NVIC_SetPriority(TC3_IRQn, 40);
  NVIC_EnableIRQ(TC3_IRQn);
}
 
// обработчик прерывания
void TC3_Handler(void)
{
  // инвертируем состояние светодиодов
  PORT->Group[0].OUTTGL.reg = PORT_PA06;
  PORT->Group[0].OUTTGL.reg = PORT_PA07;
  // сбрасываем флаг прерывания
  TC3->COUNT16.INTFLAG.reg |= TC_INTFLAG_OVF;
}

Демонстрация работы устройства

Что дальше?

Добавив в проект один из сервоприводов можно заставить тыкву вращаться и ещё сильнее пугать прохожих.

Если у вас вдруг не оказалось платформы Arduino M0, вы можете использовать, к примеру, Arduino Uno, добавить к ней Music Shield и, немного изменив скетч, воспроизводить музыку с плеера.