[recovery mode] DIY дискотечная лазерная установка из указки и ардуинки

Для танцевальной новогодней вечеринки решил сделать простую лазерную установку, которая бы в такт музыке что-нибудь демонстрировала. Под рукой была лазерная указка с набором сменных вращающихся колпачков, которые позволяли получать симпатичные эффекты на потолке. Добавив пару сервоприводов и arduino mini pro — получил искомое.

Схема очень простая (один ключ, управляющий лазерной указкой; пара кремниевых диодов, для понижения напряжения для указки; резистор для электретного микрофона и готовый модуль DC-DC преобразователя напряжения от аккумулятора в пять вольт), выполнил на отрезке макетной платы.

Микрофон при таком простейшем включении — имеет довольно низкую чувствительность, так что устройство нужно ставить достаточно близко к колонкам.


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

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

Сервоприводы — Turnigy TGY-R5180MG (180 градусов, для вращения колпачка) и какая-то старая 9 граммовая серва (для вращения самого устройства). Подставка — треножник от вентилятора, которые hobbyking продавала как-то за копейки.

Видео работы:

Скетч:

#include  // yaw servo - PWM #define SERVO_YAW 5 // roll servo - PWM #define SERVO_ROLL 6 // Laser pin - PWM or DO #define LASER 9  // Microphone input - A0 #define MIC A0  // Yaw servo period (in ms) #define YAW_PERIOD 40  // Roll servo period (in ms) #define ROLL_PERIOD 100  // MIN value for yaw servo #define MIN_YAW 40 // MAX value for yaw servo #define MAX_YAW 130 // MIN value for roll servo #define MIN_ROLL 10 // MAX value for roll servo #define MAX_ROLL 150  Servo yaw_servo; Servo roll_servo;  // Current position and direction for servos int16_t roll_pos = MIN_ROLL; int8_t roll_dir = 1; int16_t yaw_pos = MIN_YAW; int8_t yaw_dir = 1;  // Sound peak detected boolean flag_sound = false;  // Internal sound volume average stuff int16_t arr_vol[32]; int8_t arr_pos = 0;  unsigned long last_sound = 0;  // Detect sound volume peaks void check_sound() {   int16_t volume = analogRead(MIC);   int i;   int32_t sum;   int16_t average;    // Calculate average from last reads   arr_vol[arr_pos] = volume;   arr_pos++;   if (arr_pos > (sizeof(arr_vol) / sizeof(arr_vol[0])))     arr_pos = 0;   sum = 0;   for (i = 0; i < (sizeof(arr_vol) / sizeof(arr_vol[0])); i++)     sum += arr_vol[i];   average = sum / (sizeof(arr_vol) / sizeof(arr_vol[0]));    if (flag_sound && ((millis() - last_sound) > 200))     flag_sound = false;   if ((millis() - last_sound) < 300)     return;   if (volume > (average + 4)) {     flag_sound = true;     last_sound = millis();   } } // void check_sound()  unsigned long last_yaw = 0;  // Rotate yaw servo void rotate_yaw() {   if ((millis() - last_yaw) < YAW_PERIOD)     return;   last_yaw = millis();   yaw_pos += yaw_dir;   // Change rotate direction when reached limit   if ((yaw_pos >= MAX_YAW) || (yaw_pos <= MIN_YAW))     yaw_dir = -yaw_dir;   yaw_servo.write(yaw_pos); } // void rotate_yaw()   unsigned long last_roll = 0;  // Rotate roll servo void rotate_roll() {   if ((millis() - last_roll) < ROLL_PERIOD)     return;   last_roll = millis();   roll_pos += roll_dir;    // Rotate faster when we detect sound peaks   if (flag_sound) {     roll_pos += (8 * roll_dir);     if (roll_pos < MIN_ROLL)       roll_pos = MIN_ROLL;     if (roll_pos > MAX_ROLL)       roll_pos = MAX_ROLL;   }      // Change rotate direction when reached limit   if ((roll_pos >= MAX_ROLL) || (roll_pos <= MIN_ROLL))     roll_dir = -roll_dir;   roll_servo.write(roll_pos); } // void rotate_roll()  void setup() {   // put your setup code here, to run once:   pinMode(LASER, OUTPUT);   digitalWrite(LASER, HIGH);    yaw_servo.attach(SERVO_YAW);   yaw_servo.write(yaw_pos);   roll_servo.attach(SERVO_ROLL);   roll_servo.write(roll_pos);      Serial.begin(115200);   delay(300); } // void setup()  void loop() {   // put your main code here, to run repeatedly:    check_sound();   rotate_yaw();   rotate_roll();    delay(10); } // void loop()

Спасибо за внимание!


Источник

DIY, лазерное шоу, Музыка, новый год

Читайте также