Для танцевальной новогодней вечеринки решил сделать простую лазерную установку, которая бы в такт музыке что-нибудь демонстрировала. Под рукой была лазерная указка с набором сменных вращающихся колпачков, которые позволяли получать симпатичные эффекты на потолке. Добавив пару сервоприводов и arduino mini pro — получил искомое.
Схема очень простая (один ключ, управляющий лазерной указкой; пара кремниевых диодов, для понижения напряжения для указки; резистор для электретного микрофона и готовый модуль DC-DC преобразователя напряжения от аккумулятора в пять вольт), выполнил на отрезке макетной платы.
Микрофон при таком простейшем включении — имеет довольно низкую чувствительность, так что устройство нужно ставить достаточно близко к колонкам.
Надо заметить, что несмотря на наличие ключа для управления лазерной указкой — он у меня фактически не используется (всегда включен), так что можно просто выкинуть. Ну или добавить какое-нибудь моргание, если хочется.
Теоретически, гораздо лучше было бы использовать двигатель с редуктором для вращения колпачка (чтобы избежать заметного дрожания), но с сервоприводом получилось проще (напечатал пару шестеренок на принтере и все).
Сервоприводы — Turnigy TGY-R5180MG (180 градусов, для вращения колпачка) и какая-то старая 9 граммовая серва (для вращения самого устройства). Подставка — треножник от вентилятора, которые hobbyking продавала как-то за копейки.
Видео работы:
Скетч:
Спасибо за внимание!
Схема очень простая (один ключ, управляющий лазерной указкой; пара кремниевых диодов, для понижения напряжения для указки; резистор для электретного микрофона и готовый модуль DC-DC преобразователя напряжения от аккумулятора в пять вольт), выполнил на отрезке макетной платы.
Микрофон при таком простейшем включении — имеет довольно низкую чувствительность, так что устройство нужно ставить достаточно близко к колонкам.
Надо заметить, что несмотря на наличие ключа для управления лазерной указкой — он у меня фактически не используется (всегда включен), так что можно просто выкинуть. Ну или добавить какое-нибудь моргание, если хочется.
Теоретически, гораздо лучше было бы использовать двигатель с редуктором для вращения колпачка (чтобы избежать заметного дрожания), но с сервоприводом получилось проще (напечатал пару шестеренок на принтере и все).
Сервоприводы — Turnigy TGY-R5180MG (180 градусов, для вращения колпачка) и какая-то старая 9 граммовая серва (для вращения самого устройства). Подставка — треножник от вентилятора, которые hobbyking продавала как-то за копейки.
Видео работы:
Скетч:
#include <Servo.h>
// 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()
Спасибо за внимание!
Поделиться с друзьями
Комментарии (23)
madf
28.12.2016 12:09+1Ничего непонятно, расскажите нормально про механику (схемы и скейчи — вторичны).
vasimv
28.12.2016 13:25Да, наверное стоило бы более подробно разобрать. Там один сервопривод вращает шестеренку, которая вращает другую шестеренку на колпачке указки. На валу второго сервопривода прикреплена платформа, на которой закреплены упомянутые элементы.
Rumlin
резковато движется. Думаю два лазера давали бы интереснее эффекты
Mistx
А если три, да еще и разных цветов, то вообще дисплей получится
vasimv
Скорость движения можно уменьшать (повышая задержки YAW_PERIOD/ROLL_PERIOD), хотя там есть выраженная ступенчатость из-за ограничений ардуиновской библиотеки Servo (шаг в один градус только).