Introduction: Altera Board Metronome
Using Verilog and the Altera DE2-115 project board, we have created a metronome with the following features:
-User can select a tempo between 60 and 230 beats per minute using the board's 18 switches
-Tempo is displayed using the 8 green LEDs as well as using a speaker to give the tempo audibly
-Current tempo is displayed using the 7-segment display
-Finally, the user can accurately "tweak" the tempo using the board's keys to slightly increase or decrease the tempo
To make this metronome you will need the following:
-The Altera DE2-115 project board
-3.5mm aux to rca cable
-Speaker with rca input
-Solderless bread board
-40 pin GPIO to breadboard cable
-2 wires, ~3" long
-3.5mm female aux jack
-Quartus II web edition software
Step 1: Assemble Hardware
Start by plugging the female end of your 40 pin ribbon cable to the GPIO. Then plug the opposite male end into any section of the breadboard. Take your three inch wires and plug one end next to the sixth and seventh pins in the breadboard. Connect the wire next to the sixth pin to the ground of the female aux jack, and connect the other to either of the remaining two pins. Now connect the male aux cable into the female and either one of the RCA ends into the speaker(if one doesn't work the other will). Finally plug your Altera board into your computer through usb, and also to power.
Step 2: Verilog Code
Open your Quartus II software. create a new project and a new verilog file. copy in the following code:
module metronew(
input clock,//50MHz internal clock
input [17:0]in,//SW0-17
input tapup,//KEY3
input tapdown,//KEY2
input reset,//KEY0
output spk,//GPIO (speaker)
output [7:0]led,//LEDG0-7
output reg [0:6]hex0,hex10,hex100);//HEX0-2
/*integer*/
integer counter1;
integer counttap = 1;
integer bpm;
integer speed;
/* reg */
reg [7:0] state;
/* assign */
assign led = state;
assign spk = state[0]|state[7];
/* always */
always @(in, tapup, tapdown) begin
hex0 = 7'b0000001;
//Displays tempo on seven segment display from switches,
//sets bpm to given tempo
if (in[0]==1)begin
hex100 = 7'b0000001; //0
hex10 = 7'b0100000; //6
speed = 60;
bpm = 49999999/speed*120;
end
else if (in[1]==1)begin
hex100 = 7'b0000001; //0
hex10 = 7'b0001111; //7
speed = 70;
bpm = 49999999/speed*120;
end
else if (in[2]==1)begin
hex100 = 7'b0000001; //0
hex10 = 7'b0000000; //8
speed = 80;
bpm = 49999999/speed*120;
end
else if (in[3]==1)begin
hex100 = 7'b0000001; //0
hex10 = 7'b0001100; //9
speed = 90;
bpm = 49999999/speed*120;
end
else if (in[4]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0000001; //0
speed = 100;
bpm = 49999999/speed*120;
end
else if (in[5]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b1001111; //1
speed = 110;
bpm = 49999999/speed*120;
end
else if (in[6]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0010010; //2
speed = 120;
bpm = 49999999/speed*120;
end
else if (in[7]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0000110; //3
speed = 130;
bpm = 49999999/speed*120;
end
else if (in[8]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b1001100; //4
speed = 140;
bpm = 49999999/speed*120;
end
else if (in[9]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0100100; //5
speed = 150;
bpm = 49999999/speed*120;
end
else if (in[10]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0100000; //6
speed = 160;
bpm = 49999999/speed*120;
end
else if (in[11]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0001111; //7
speed = 170;
bpm = 49999999/speed*120;
end
else if (in[12]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0000000; //8
speed = 180;
bpm = 49999999/speed*120;
end
else if (in[13]==1)begin
hex100 = 7'b1001111; //1
hex10 = 7'b0001100; //9
speed = 190;
bpm = 49999999/speed*120;
end
else if (in[14]==1)begin
hex100 = 7'b0010010; //2
hex10 = 7'b0000001; //0
speed = 200;
bpm = 49999999/speed*120;
end
else if (in[15]==1)begin
hex100 = 7'b0010010; //2
hex10 = 7'b1001111; //1
speed = 210;
bpm = 49999999/speed*120;
end
else if (in[16]==1)begin
hex100 = 7'b0010010; //2
hex10 = 7'b0010010; //2
speed = 220;
bpm = 49999999/speed*120;
end
else if (in[17]==1)begin
hex100 = 7'b0010010; //2
hex10 = 7'b0000110; //3
speed = 230;
bpm = 49999999/speed*120;
end
else begin
hex100 = 7'b0100100; //s
hex10 = 7'b0110000; //e
hex0 = 7'b1110001; //l
speed = 60;
bpm = (49999999)/((counttap/49999999)*32)*160;
end
end
always @ (posedge clock) begin
counter1 <= counter1 + 1;
//increases or decreases tempo using keys
if(reset == 0) begin
counttap = 1;
end
if(tapup == 0) begin
counttap = counttap + 1;
end
if(tapdown== 0)begin
counttap = counttap - 1;
end
//turns LEDs on in sequence
if (counter1 <= bpm/14*1) begin
state = 0;
state[0] = 1;
end
else if (counter1 <= bpm/14*2) begin
state = 0;
state[1] = 1;
end
else if (counter1 <= bpm/14*3) begin
state = 0;
state[2] = 1;
end
else if (counter1 <= bpm/14*4) begin
state = 0;
state[3] = 1;
end
else if (counter1 <= bpm/14*5) begin
state = 0;
state[4] = 1;
end
else if (counter1 <= bpm/14*6) begin
state = 0;
state[5] = 1;
end
else if (counter1 <= bpm/14*7) begin
state = 0;
state[6] = 1;
end
else if (counter1 <= bpm/14*8) begin
state = 0;
state[7] = 1;
end
else if (counter1 <= bpm/14*9) begin
state = 0;
state[6] = 1;
end
else if (counter1 <= bpm/14*10) begin
state = 0;
state[5] = 1;
end
else if (counter1 <= bpm/14*11) begin
state = 0;
state[4] = 1;
end
else if (counter1 <= bpm/14*12) begin
state = 0;
state[3] = 1;
end
else if (counter1 <= bpm/14*13) begin
state = 0;
state[2] = 1;
end
else if (counter1 <= bpm) begin
state = 0;
state[1] = 1;
end
//resets counter1 when it hits 50 million
else if (counter1 == bpm) begin//50M (2seconds)
state[0] = 0;
counter1 <= 0;
end
else begin
state[0] = 0;
counter1 <= 0;
end
end
endmodule
Step 3: Pin Assignments
Open up the pin planner window in Quartis and assign your inputs and outputs to the pins specified in this image.
Step 4: Test
Compile the code and send it to your Altera board. Turn on SW0 and if everything is working correctly the HEX displays should read "060", the green LED's should be streaming from side to side at 60 beats per minute, and the speaker should be clicking when the outer green LED's are lit.
Step 5: Operating
This metronome has preset tempos ranging from 60 to 230 beats per minute in intervals of 10. The switch furthest right is 60 BPM's and as you progress left they increase by 10. Do not have more than one switch up at a time.
If all switches are off the HEX display should read "SEL'. This means select mode has been activated so you can input a custom tempo. It starts at 0 BPM and to increase the tempo press or hold KEY3 and to decrease use KEY2. You can reset to 0 BPM using KEY0 while in select mode.
Step 6: Explanation of Code
To implement the use of the switches, use an always block with if and else if statements for the inputs coming from every switch. Within each statement are the outputs for the Seven Segment Display for that tempo, an integer 'speed' defining the beats per minute and an integer 'bpm' that converts 'speed' into an integer usable for the counter that determines the output of the LEDs and audio. The else statement, which is active when all switches are off, activates the select function on the device, which uses the 'counttap' integer from another block to manually increase and decrease the tempo.
To control the manual increase and decrease set forth through the 'counttap' integer, use an always block with if statements controlling a counter that increases by 1 when the 'tapup' input (Set as KEY3) is pressed, and decreases by 1 when the 'tapdown' input (Set a KEY2) is pressed. For the sequence of LEDs, use an always block with if and else if statements and assign a state for each of the eight LEDs. Using the 'bpm' given earlier, create a sequence using each state one by one left to right, then right to left. Then use another else if statement to reset it, enabling it do another cycle. For the audio output, make an or statement which is active at the leftmost LED and the rightmost LED, using the states corresponding to them.