Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Компоненты и материалы

Arduino 101 × 1 шт.
Стабилизатор напряжения Pololu ($4) × 1 шт.
Кейс для 3×AA батареек с выключателем × 1 шт.
AA батарейки (любые, 3 шт.) × 1 комплект
Адаптер «барел-джек» (мама, $1.95) × 1 шт.
Адаптер «барел-джек» (папа, $1.95) × 1 шт.
Адресуемая LED-лента (NeoPixel-совместимая, 60 пикселей) × 1 шт.
Спортивная лента (хлопковая, для фиксации и рукояти) × 1 рулон
Резиновые кольца (для временной фиксации) × 1 упаковка
Посох (метла, труба для полива, натуральная трость и т.д.) × 1 шт.

Программное обеспечение и онлайн-сервисы

О проекте

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Техническая часть

Код использует инерциальный модуль (IMU) Arduino 101 для измерения перегрузок, но не использует Pattern Matching Engine (пример с PME см. в проекте Kitty Yeung). Вместо этого код считает быстрые импульсы по осям X, Y, Z и запускает «заклинания» при определённых комбинациях в короткое время.

Как колдовать заклинания

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

Визуальная обратная связь

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

Детальная схема жестов

Держите посох с Arduino 101 лицом к себе. Сначала дважды ударьте посохом о землю (нежно!) или сделайте два быстрых вертикальных импульса в воздухе. При белой вспышке:

Когда цвет стал сплошным — финальный вертикальный удар запускает эффект: лента мерцает и вспыхивает выбранным цветом.

Жесты чувствительны ко времени! У вас 1 секунда между шагами, иначе заклинание сбрасывается. Если ошиблись — подождите секунду и начните заново. Случайные срабатывания при ходьбе исключены.

Сборка электроники

По сути: Arduino 101, батарея, лента NeoPixel.

Варианты питания: 9V-крона (быстро, но мало емкость), LiPo (профессионально, но нужен зарядник), 3×AA + $4 стабилизатор — баланс емкости и простоты (та же схема, что в проектах Shadow Theater и Kaleidoscope Infinity Mirror).

Шаг 1: Подготовка разъёма ленты

Отрежьте концевой разъём ленты с запасом ~1 см. Снимите изоляцию с проводов.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 2: Паяем пины к сигнальным проводам

Разберите гнутые пины из комплекта стабилизатора, припаяйте два к зелёному и жёлтому проводам ленты — для удобного подключения к пинам Arduino.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 3: Питание на стабилизаторе

Красный провод ленты → VIN стабилизатора. Два прямых пина в GND и VOUT.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 4: Бочковые разъёмы (barrel jack)

Провода батарейного отсека → мама-разъём: КРАСНЫЙ → (+), ЧЁРНЫЙ → (−).

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Свободные провода от начала ленты → папа-разъём: ЖЁЛТЫЙ → (−), КРАСНЫЙ → (+).

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 5: Подключение к Arduino 101

ЗЕЛЁНЫЙ → PIN 6, ЖЁЛТЫЙ → GND (рядом с #13). На стабилизаторе: GND → GND, VOUT → VIN Arduino. Не перепутайте полярность! Обратное подключение — запах гари и сгоревшие компоненты (проверено на личном опыте).

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Загрузка примера кода

  1. Батарейный отсек ВЫКЛ. Подключите Arduino 101 к ПК через USB, загрузите код через Arduino IDE. Инструкции для Arduino 101: arduino.cc.
  2. Отключите USB, включите батареи, тестируйте жесты (USB-порт вниз, пины к себе). Четыре вертикальных движения → Красное заклинание.

Разбор кода (можно пропустить, если используете как есть)

Код использует детектор ударов Arduino 101 для подсчёта импульсов с таймером сброса. Правильная комбинация до истечения таймера вызывает функцию «заклинания».

Жёсткий удар даёт основной импульс + шум от вибраций. Код выделяет доминирующий импульс из пакета и классифицирует: 1 = вертикаль, 2 = вперёд/назад, 3 = влево/вправо.

Машина состояний (switch) отслеживает последовательность: «если следующий импульс влево/вправо — переход к шагу 2, если таймер истёк — сброс».

Функции заклинаний (легко менять)

Сейчас — theater-chase в разных цветах. Первые три аргумента theaterChase — R, G, B, последний — скорость (больше = медленнее).

void tapspell() { // Красное
    theaterChase(strip.Color(127, 20, 0), 20);
    theaterChase(strip.Color(127, 20, 50), 55);
    strip.show();
}
void leftspell() { // Синее
    theaterChase(strip.Color(0, 0, 100), 20);
    theaterChase(strip.Color(0, 30, 120), 75);
    strip.show();
}
void forwardspell() { // Зелёное
    theaterChase(strip.Color(0, 127, 0), 30);
    theaterChase(strip.Color(0, 127, 90), 55);
    strip.show();
}

Сборка посоха

Много места для творчества! Базовая техника ниже, но делайте уникальный посох. Диффузоры (тьюль, тиссу, пластиковая бутылка над LED) создают классные эффекты.

Шаг 1: Находим палку

Метла, труба, натуральная трость. В Michael's (раздел с палками) тоже есть хорошие. Опционально: обмотайте участок спортивной лентой — чистая рабочая зона.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Накладьте несколько резинок для удобства крепления.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 2: Arduino 101 на палке (USB-порт вниз)

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 3: Намотка LED-ленты (резинки на обоих концах)

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 4: Спортивная лента — фиксация Arduino и батарейного отсека

Оставьте доступ к выключателю батарейного отсека. Батареи придётся менять.

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Шаг 5: Диффузия и декор

DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения
DIY-кит «Посох волшебника»: Arduino 101, LED-лента, стабилизатор напряжения

Программный код

Wizard Walking Staff Example Code (Arduino)

Подсчёт импульсов по осям X, Y, Z, определённые комбинации вызывают «заклинания» (световые эффекты) на NeoPixel-ленте.

/* Copyright (c) 2016 Intel Corporation. All rights reserved.
   Arduino 101 "Wizard's Walking Staff."
   Библиотека Adafruit Neopixel: https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation
   Требуется актуальный Intel Curie Core: https://www.arduino.cc/en/Guide/Arduino101
*/
#include "CurieIMU.h"
#include 
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

int tr = 0, tg = 0, tb = 0; // целевые цвета для сглаживания
int r = 0, g = 0, b = 0;    // текущие цвета
long globaltimer = 0;
long gesturetimer = 0;
long ledtimer = 0;
int fade = 10;              // скорость затухания/сглаживания
int tap = 0;   // счётчик вертикальных импульсов
int lr = 0;    // счётчик левых/правых
int fb = 0;    // счётчик вперёд/назад
int gesture = 0;
int state = 0; // состояние машины состояний

void setup() {
    globaltimer = millis();
    gesturetimer = millis();
    ledtimer = millis();

    CurieIMU.begin();
    CurieIMU.attachInterrupt(eventCallback);
    CurieIMU.setDetectionThreshold(CURIE_IMU_SHOCK, 1500); // 1.5g = 1500 mg
    CurieIMU.setDetectionDuration(CURIE_IMU_SHOCK, 50);    // мс пика для прерывания
    CurieIMU.interrupts(CURIE_IMU_SHOCK);

    strip.begin();
    strip.show(); // все пиксели выкл.
}

void loop() {
    // Базовый фильтр: IMU регистрирует множественные удары от отскока.
    // Пытаемся выделить доминирующий импульс в каждом жесте.
    if (millis() - globaltimer > 170) {
        if ((tap > lr) && (tap > fb)) {
            gesture = 1; tap = 0; lr = 0; fb = 0;
        } else if ((lr > fb) && (lr > tap)) {
            gesture = 2; tap = 0; lr = 0; fb = 0;
        } else if ((fb > lr) || (fb > tap)) {
            gesture = 3; tap = 0; lr = 0; fb = 0;
        }
    }

    // Таймауты сброса
    if (millis() - globaltimer > 1000) {
        globaltimer = millis() - 170;
        tr = tg = tb = 0;
        state = 0;
    }
    if (millis() - gesturetimer > 1000) {
        gesturetimer = millis() - 350;
        tr = tg = tb = 0;
        state = 0;
    }

    // Машина состояний жестов
    switch (state) {
        case 0: // ожидание первого вертикального удара
            if (millis() - gesturetimer > 350 && gesture == 1) {
                state = 1; gesture = 0; gesturetimer = millis();
            }
            break;
        case 1: // один удар записан, ждём второй
            if (millis() - gesturetimer > 350 && gesture == 1) {
                r = g = b = 10; // белая вспышка обратной связи
                state = 2; gesture = 0; gesturetimer = millis();
            }
            break;
        case 2: // два удара — точка ветвления для трёх заклинаний
            if (millis() - gesturetimer > 350) {
                if (gesture == 1) { state = 3; gesture = 0; gesturetimer = millis(); }
                if (gesture == 2) { state = 4; gesture = 0; gesturetimer = millis(); }
                if (gesture == 3) { state = 5; gesture = 0; gesturetimer = millis(); }
            }
            break;
        case 3: // три вертикальных удара — режим tapspell (красное)
            tr = 20; tg = 0; tb = 0; globaltimer = millis() - 250;
            if (millis() - gesturetimer > 350 && gesture == 1) {
                state = 0; tapspell();
            }
            break;
        case 4: // два удара + влево/вправо — leftspell (синее)
            tr = 0; tg = 0; tb = 20; globaltimer = millis() - 250;
            if (millis() - gesturetimer > 350 && gesture == 1) {
                state = 0; leftspell();
            }
            break;
        case 5: // два удара + вперёд/назад — forwardspell (зелёное)
            tr = 0; tg = 20; tb = 0; globaltimer = millis() - 250;
            if (millis() - gesturetimer > 350 && gesture == 1) {
                state = 0; forwardspell();
            }
            break;
    }

    // Сглаживание цветов и вывод на ленту (неблокирующее)
    if (millis() - ledtimer > fade) {
        if (tr > r + 1) r++; if (tg > g + 1) g++; if (tb > b + 1) b++;
        if (tr < r) r--; if (tg < g) g--; if (tb < b) b--;
        for (int i = 0; i < strip.numPixels(); i++) {
            strip.setPixelColor(i, r, g, b);
        }
        strip.show();
        ledtimer = millis();
    }
}

// Прерывание от IMU при обнаружении удара
static void eventCallback(void) {
    if (CurieIMU.getInterruptStatus(CURIE_IMU_SHOCK)) {
        if (CurieIMU.shockDetected(X_AXIS, POSITIVE)) { tap++; globaltimer = millis(); }
        if (CurieIMU.shockDetected(X_AXIS, NEGATIVE)) { tap++; globaltimer = millis(); }
        if (CurieIMU.shockDetected(Y_AXIS, POSITIVE)) { lr++; globaltimer = millis(); }
        if (CurieIMU.shockDetected(Y_AXIS, NEGATIVE)) { lr++; globaltimer = millis(); }
        if (CurieIMU.shockDetected(Z_AXIS, POSITIVE)) { fb++; globaltimer = millis(); }
        if (CurieIMU.shockDetected(Z_AXIS, NEGATIVE)) { fb++; globaltimer = millis(); }
    }
}

///////////////// Функции заклинаний /////////////////
void tapspell() {
    theaterChase(strip.Color(127, 20, 0), 20);
    theaterChase(strip.Color(127, 20, 50), 55);
    strip.show();
}
void leftspell() {
    theaterChase(strip.Color(0, 0, 100), 20);
    theaterChase(strip.Color(0, 30, 120), 75);
    strip.show();
}
void forwardspell() {
    theaterChase(strip.Color(0, 127, 0), 30);
    theaterChase(strip.Color(0, 127, 90), 55);
    strip.show();
}

// Theatre-style crawling lights (из примера Adafruit Strandtest)
void theaterChase(uint32_t c, uint8_t wait) {
    for (int j = 0; j < 10; j++) {
        for (int q = 0; q < 3; q++) {
            for (uint16_t i = 0; i < strip.numPixels(); i += 3) {
                strip.setPixelColor(i + q, c);
            }
            strip.show();
            delay(wait);
            for (uint16_t i = 0; i < strip.numPixels(); i += 3) {
                strip.setPixelColor(i + q, 0);
            }
        }
    }
}

Производственный процесс

  1. Обнаружение электрических полей переменного тока: Практическое руководство по емкостной связке и экраниров…
  2. Расчет рассеиваемой мощности в резистивных цепях
  3. Семь проверенных советов для защиты вашей пост-обработки в аддитивном производстве
  4. Пищевой цвет: как яркие оттенки усиливают аппетит и презентацию
  5. Как строить и валидировать работающие IoT бизнес-модели — практический гайд
  6. Сборка DIY Google Voice HAT для Raspberry Pi
  7. Создание робота на Arduino и Raspberry Pi: пошаговое руководство
  8. Полное руководство по производству стекловолокна
  9. Празднуйте производственное мастерство — выберите свой день для Дня производства
  10. Создание анимации прогрессивного среза в SolidWorks — Пошаговый урок