Каждый год 31-го декабря я в костюме Деда Мороза и жена в роли Снегурочки разъезжаем по городу по своим друзьям с поздравлениями. Поскольку уже скоро наступит Новый Год, я решил проверить, все ли у меня к нему готово и достал из подвала свой давно видавший виды посох. К моему удивлению, пролежав в подвале целый год он исправно работал даже сейчас! Его аккумулятор все еще как-то заряжен! Посох не очень ярко, но светится. Конечно придется подзарядить, да и смотрю один светодиод перестал работать, но это дело поправимое — починим.
Этот посох я изготовил еще в 2012-м году и с тех пор он служил мне верой и правдой. Штука достаточно простая, но очень эффектная, особенно ему радуются дети. Он почти как меч джедая — только посох, а для настоящего Деда Мороза — это вещь просто необходимая. Решил написать про него здесь на Хабре — вдруг кто-то проникнется идеей и сделает такой и себе к Новому Году, время еще есть.
Для изготовления посоха понадобятся:
- кусок пластиковой водопроводной трубы 1.3 метра;
- немного блестящей самоклейки для украшения;
- кусок сетевого кабеля UTP-5 или любого другого подходящего;
- синие светодиоды, хотя бы 24 штуки;
- аккумулятор;
- кнопка включения;
- любая маленька плата микроконтроллера или FPGA, у кого что есть, которую вы умеете программировать;
- большой шар-елочная игрушка, который можно разделить пополам и чтобы в него можно было спрятать и плату и аккумулятор.
Необходимые запчасти видны на этом фото:
Устройство посоха очень простое. Тут особенно и писать нечего. Берем белую водопроводную пластиковую трубу и сверлим несколько отверстий на одинаковом расстоянии 200 мм. У меня получилось 6 отверстий.
Распускаем кабель UTP-5 на несколько витых пар. Нужно шесть пар проводов. Запускаем их в отверстия и выводим через один конец трубы, туда, где будет волшебный шар посоха. Там где пары проводов заходят в отверстия трубы зачищаем их и плотно оборачиваем вокруг трубы на некотором расстоянии друг от друга. Спаиваем. К получившейся «шине» по кругу посоха припаиваем параллельно 4 синих светодиода:
Вверху трубы нужно просверлить отверстие побольше и туда вклеить кнопку включения управляющей платы:
У меня в качестве платы управления идет платка «Марсоход». Тут стоит ПЛИС Альтеры MAX II и поскольку плата изначально предназначалась для подлючения маломощных игрушечных двигателей, то на плате выводы чипа объединены по 10 штук, чтобы выдать ток побольше. Таких объединенных выводов на плате как раз 6 штук — это «сигналы» платы f0, f1, f2, f3, f4, f5. Значит я могу напрямую питать от этих выводов светодиоды не боясь спалить вывод ПЛИС. так же на самой плате есть 8 желтых светодиодов — их тоже можно зажигать. Если шар на вершине посоха полупрозрачный, то это тоже добавит визуального эффекта.
Если вы будете использовать в посохе к примеру Ардуино, то возможно придется спаять небольшую платку с транзисторными ключами для управления многими светодиодами, так как с одного пина микроконтроллера лучше не брать больше 10-15мА, а нам нужно для светодиодов гораздо больше.
Плату нужно прошить управляющей программой. Идея такая, что когда нажимаешь на посохе кнопку, то включается плата и она сразу же начинает зажигать на посохе огни. Тут у кого какая фантазия. Я сперва зажигаю по очереди все светодиоды от первого ряда до шестого, а потом гашу по очереди с шестого по первый.
Код на Verilog HDL наверное пояснит лучше, что я имею ввиду:
module effect(
input wire clk,
input wire mclk,
output wire [7:0]leds,
output wire f0,
output wire f1,
output wire f2,
output wire f3,
output wire f4,
output wire f5
);
reg [3:0]cnt;
reg [5:0]bits;
initial
begin
bits= 6'h00;
cnt = 4'h0;
end
always @(posedge clk)
if(cnt==11)
cnt<=0;
else
cnt <= cnt + 1'b1;
always @*
begin
case(cnt)
4'h0: bits = 6'b000001;
4'h1: bits = 6'b000011;
4'h2: bits = 6'b000111;
4'h3: bits = 6'b001111;
4'h4: bits = 6'b011111;
4'h5: bits = 6'b111111;
4'h6: bits = 6'b011111;
4'h7: bits = 6'b001111;
4'h8: bits = 6'b000111;
4'h9: bits = 6'b000011;
4'ha: bits = 6'b000001;
default:
bits = 6'b000000;
endcase
end
assign f0 = bits[0] & mclk;
assign f1 = bits[1] & mclk;
assign f2 = bits[2] & mclk;
assign f3 = bits[3] & mclk;
assign f4 = bits[4] & mclk;
assign f5 = bits[5] & mclk;
assign leds = {bits[5],bits[5],bits[4],bits[3],bits[2],bits[1],bits[0],bits[0]};
endmodule
Это не модуль верхнего уровня, это модуль effect.v Из топ модуля сюда подается две тактовых частоты clk~40Гц — эта частота определяет скорость эффекта и вторая частота mclk~320Гц, в восемь раз выше. Сигнал mclk дополнительно модулирует выводы опять же, чтоб они не всегда были включены, чтоб не так ярко светили светодиоды и не грелся чип.
Не знаю нужно ли занаучивать эту статью. Но на всякий случай напишу, что вышеприведенный код Verilog вполне можно отсимулировать с помощью вот такого тестбенча:
`timescale 1ms / 1us
module tb;
reg clock = 1'b0;
always #10
clock = ~clock;
reg [3:0]counter=0;
always @(posedge clock)
counter <= counter+1;
wire [7:0]wleds;
wire wf0,wf1,wf2,wf3,wf4,wf5;
effect inst(
.clk( counter[2] ),
.mclk( clock ),
.leds( wleds ),
.f0( wf0 ),
.f1( wf1 ),
.f2( wf2 ),
.f3( wf3 ),
.f4( wf4 ),
.f5( wf5 )
);
initial
begin
$dumpfile("out.vcd");
$dumpvars(0,tb);
#10000;
$finish();
end
endmodule
Как именно производится симуляция проектов можно почитать, например, вот здесь.
Ну и по результатам симуляции можно получить вот такие временные диаграммы сигналов:
Если вы задумаете делать этот проект на Ардуине — это тоже можно. Я правда не большой знаток Ардуины, но мне кажется, что код может выглядеть как-то так:
int start_pin = 2;
int end_pin = 8;
void setup()
{
for (int i = start_pin; i< end_pin; i++ )
pinMode(i, OUTPUT);
}
void loop()
{
for (int i = start_pin; i< end_pin; i++ )
{
digitalWrite(i, HIGH);
delay(250);
}
for (int i = start_pin; i< end_pin; i++ )
{
digitalWrite(i, LOW);
delay(250);
}
}
В итоге должно получиться что-то вот такое:
Несмотря на то, что проект в целом очень простой, у зрителей и у случайных прохожих 31-го декабря вызывает неизменный восторг. Особенно когда выходишь на заснеженной улице из автомобиля в костюме Деда Мороза, подходишь к случайному прохожему и освещая путь посохом даришь мандаринку.
Автор: Николай