Lab 6 Report
Lab 6 Report
EXPERIMENT 6:
STEPPER MOTOR CONTROL
GROUP 8
Stepper motors are ideally suited for precision control. This motor can be operated in
forward/reverse with controllable speed from a BASIC Stamp or any other microcontroller
through a transistor driver circuit. Some of the applications for this motor include educational
experimentation, robotics and precision mechanical control. The #27964 is a Unipolar (4
phase) 12 VDC, 150 mA motor that takes 3.6 degrees per step [5].
ULN2003
OBJECTIVES
1. To design digital circuits in FPGA to control stepper motor
2. To use Verilog as a design entry in Altera Quartus II Software
3. To simulate the circuit using Altera Quartus II Software
4. To download the design on Altera DE2 board
EQUIPMENT/SOFTWARE USED
1. Altera Quartus II software
2. Altera DE2 board
3. Parralax 4 Phase 12- Volt 75 Ohm Unipolar Stepper Motor
4. ULN 2003
PROCEDURE
1. Verilog code for module “step”, ”divider”, and ”stepper” in appendix 6A are compiled.
An overview diagram is shown by using netlist viewer in Figure 3 below.
stepper:sl
1 clk
dir dir
divider:dl
osc osc
3. The diagram is downloaded to Altera DE2 Board. A circuit is connected to the board as
shown in Figure 5 and below to run the motor.
Figure 5: Stepper motor connection.
4. Observation:
I. SW16 is used to choose the stepper motor operation mode. 0 for continuous
mode, 1 for step mode
II. SW15 is used to set the direction of rotation of the stepper motor. When SW15 is
off, the stepper motor will rotate in clockwise direction. When SW15 is on, the stepper
motor will rotate in anti-clockwise direction.
III. SW17 is used to control the movement of the stepper motor in step mode. When
SW17 is off, the stepper motor will not rotate. When SW17 is toggled on, the motor
will rotate 3.75° (half step).
IV. The 4 LEDs shows different output when the motor run in different direction.
When the motor rotates in clockwise direction, the LEDs light up in the sequence of
0011, 1001, 1100, 0110 repeatedly. When the motor rotates in anti-clockwise direction,
the LEDs light up in the sequence of 0011, 0110, 1100, 1001 repeatedly.
1. Verilog code for the module in appendix 6B are compiled. An overview diagram is
shown by using netlist viewer in Figure 6 below.
4. Observation:
I. SW16 is to choose the mode of operation, 0 for continuous and 1 for step.
For step mode, SW17 is used to control the motor movement, 0 will stop the
motor and 1 will rotate the motor.
II. The S12, SW13 and SW14 are used to set the speed of the motor.
III. SW15 is used to set the direction of the stepper motor. When SW0 is off,
the motor rotates in clockwise direction. When SW1 is on, the motor rotates in
anti-clockwise direction. The second 7-segment from the right is used to shows
the direction of rotation of the motor as shown in Figure 10 below.
Clockwise: Anti-
clockwise:
IV.SW10 is used to reset the LCD. The speed, direction and running mode of
the motor are shown on the LCD screen. Whenever there is a change, the LCD
need to be reset in order to display the changes. The LCD display for all
possible combinations are shown in Figure 11 below.
Figure 11: LCD display for activity 2.
Discussion
1. Stepper motors are discreetly driving DC motors. We have several coils grouped in
"phases" groups. The motor must rotate, one step at a time, by energizing each stage in
a series.
2. The output voltage of Altera DE2 board is not enough to rotate the stepper motor.
Therefore, ULN2003 is used to scale up the voltage that feed into the stepper motor.
The IC is connected between the output from Altera DE2 board and the stepper motor.
The ULN2003 is an array of seven NPN Darlington transistors capable of 500mA, 50V
output. For swapping inductive loads it features common-cathode fly-back diodes. The
12V Unipolar Stepper Motor is the motor we used in this test. The IC's COM pin is
therefore attached to the 12V power supply.
3. In activity 1, the excitation mode of the stepper motor is half step. Half step excitation
is alternating single and dual phase operation resulting in steps that are half the basic
step angle. Due to the smaller step angle, this mode provides twice the resolution and
smoother operation. Half stepping produces roughly 15% less torque than dual phase
full stepping. Figure below shows half step operation of the motor in clockwise
direction [7].
4. In activity 2, when the continuous mode of the stepper motor is chosen, the motor works
in dual phase mode of full step operation. In full step operation, the motor moves
through its basic angle, which is 7.5° for the stepper motor we used in this experiment.
In dual phase mode, also known as “two-phase on, full step” excitation, the motor is
operated with both phases energized at the same time. This mode provides improved
torque and speed performance. Dual phase excitation provides about 30% to 40% more
torque than single phase excitation but does require twice as much power from the
driver. Figure below shows dual phase mode of full step operation in clockwise
direction.
Figure 13: Stepper motor operation in dual phase full step mode.
5. The stepper motor rotates one step for each clock pulse. Therefore, when the motor run
in continuous mode in activity 1 and activity 2, the speed of the stepper motor can be
changed by changing the input frequency of clock pulse. In activity 2, when the input
frequency of clock pulse is fixed, the speed of the motor can be changed by choosing
different bit of output of the frequency divider designed previously using Verilog code.
Conclusion
In conclusion, we learned how to model virtual circuit in FPGA to power stepper
motor through this experiment. In Activity 1, we learned how to write the Verilog code to
control a stepper motor's movement. We learned to write the Verilog code in Activity 2, to
monitor the stepper motor speed, direction, mode (continuous or step).
Appendix
/***********************************************************************/
input CLOCK_50,RST_LCD;
input reset, mode, dir, move; //reset when asserted brings the shaft to reference position.
stepper s1(.clk (clk), .clk_1 (clk_1),.reset (reset),.dir (dir),.mode (mode),.move (move),.phaseout (phaseout),.seg_out(HEX0));
LCD_DISP
( .iCLK(CLOCK_50),.iRST_N(RST_LCD),.LCD_DATA(LCD_DATA),.LCD_RW(LCD_RW),.LCD_EN(LCD_EN),.LCD_RS(LCD_RS),.speed(speed),.dir(dir
),.mode(mode),.LCD_BLON(LCD_BLON),. LCD_ON(LCD_ON) );
endmodule
/***********************************************************************/
/***********************************************************************/
reg clk,clk_1;
begin
case(speed)
3'b000 :num=3'b000;
3'b001 :num=3'b001;
3'b010 :num=3'b010;
3'b100 :num=3'b011;
endcase
clk_1 = count[22];
count = count + 1;
if (num==3'b000)
clk = 0;
else
clk = count[22-num];
end
endmodule
/***********************************************************************/
/***********************************************************************/
input dir,mode;
output [7:0]LCD_DATA;
reg mLCD_Start;
reg mLCD_RS;
wire mLCD_Done;
//assign dispDone=0;
//assign INDEX=0;
parameter LCD_INTIAL = 0;
parameter LCD_LINE1 = 5;
begin
if(!iRST_N)
begin
LUT_INDEX <= 0;
mLCD_ST <= 0;
mDLY <= 0;
mLCD_Start <= 0;
mLCD_DATA <= 0;
mLCD_RS <= 0;
end
else
begin
if(LUT_INDEX<LUT_SIZE)
begin
case(mLCD_ST)
0:
begin
mLCD_Start <= 1;
mLCD_ST <= 1;
end
1:
begin
if(mLCD_Done)
begin
mLCD_Start <= 0;
mLCD_ST <= 2;
end
end
2:
begin
if(mDLY<18'h3FFFE)
else
begin
mDLY <= 0;
mLCD_ST <= 3;
end
end
3:
begin
mLCD_ST <= 0;
end
endcase
end
else
//dispDone=1;
LUT_INDEX<=4;
end
end
always
begin
begin
case(LUT_INDEX)
// Initial
// SPEED
LCD_LINE1+6:
case (speed)
endcase
// dir=ccw(counterclockwise) / cw(clockwise)
LCD_LINE1+14:
if (dir==1)
else
if (dir==1)
else
// Change Line
// Line 2
LCD_LINE2+9:
if (mode==0)
else
LCD_LINE2+10:
if (mode==0)
else
LCD_LINE2+11:
if (mode==0)
else
LCD_LINE2+12:
if (mode==0)
else
endcase
end
end
LCD_Controller
(.iDATA(mLCD_DATA),.iRS(mLCD_RS),.iStart(mLCD_Start),.oDone(mLCD_Done),.iCLK(iCLK),.
iRST_N(iRST_N),.LCD_DATA(LCD_DATA), .LCD_RW(LCD_RW),.LCD_EN(LCD_EN),.LCD_RS(LCD_RS) );
endmodule
/***********************************************************************/
/***********************************************************************/
// CLK
// Host Side
input [7:0]iDATA;
input iRS,iStart;
input iCLK,iRST_N;
output LCD_RW;
output LCD_RS;
// Internal Register
reg preStart,mStart;
/////////////////////////////////////////////
/////////////////////////////////////////////
begin
if(!iRST_N)
begin
preStart<= 1'b0;
Cont <= 0;
ST <= 0;
end
else
begin
preStart<= iStart;
if({preStart,iStart}==2'b01)
begin
end
//////////////////////////////////
if(mStart)
begin
case(ST)
1:
begin
ST <= 2;
end
2:
begin
if(Cont<CLK_Divide)
else
ST <= 3;
end
3:
begin
LCD_EN <= 1'b0;
Cont <= 0;
ST <= 0;
end
endcase
end
end
end
endmodule /***********************************************************************/
/***********************************************************************/
input clk,clk_1,reset,dir,mode;
input move;
initial seg_out=7'b1001111;
initial phaseout=4'b1100;
begin
if (mode==0)
begin
if (dir==1) //clockwise
else //anticlockwise
end
else
begin
if (move==0)
begin
if (dir==1)//clockwise
else//anticlockwise
end
end
end
begin
if(reset==0)
phaseout=4'b1000;
end
else
begin //reset=1
if (mode==0)
begin
if (dir==0)
else
end
else
begin
if(move==0)
begin
case (position)
4'b1000 :
if (dir==0)
begin
phaseout=4'b1100; //ledr=phaseout;
end
else
begin
phaseout=4'b1001; //ledr=phaseout;
end
4'b1100 :
if(dir==0)
begin
phaseout=4'b0100; //ledr=phaseout;
end
else
begin
phaseout=4'b1000; //ledr=phaseout;
end
4'b0100 :
if (dir==0)
begin
phaseout=4'b0110; //ledr=phaseout;
end
else
begin
phaseout=4'b1100; //ledr=phaseout;
end
4'b0110 :
if (dir==0)
begin
phaseout=4'b0010; //ledr=phaseout;
end
else
begin
phaseout=4'b0100; //ledr=phaseout;
end
4'b0010 :
if (dir==0)
begin
phaseout=4'b0011; //ledr=phaseout;
end
else
begin
phaseout=4'b0110; //ledr=phaseout;
end
4'b0011 :
if (dir==0)
begin
phaseout=4'b0001; //ledr=phaseout;
end
else
begin
phaseout=4'b0010; //ledr=phaseout;
end
4'b0001 :
if (dir==0)
begin
phaseout=4'b1001; //ledr=phaseout;
end
else
begin
phaseout=4'b0011; //ledr=phaseout;
end
4'b1001 :
if (dir==0)
begin
phaseout=4'b1000; //ledr=phaseout;
end
else
begin
phaseout=4'b0001; //ledr=phaseout;
end
default:
$display("invalid input");
endcase
end
end
end
end
begin
if (reset==0)
begin
position=4'b1000;
end
else if (reset==1)
begin
position=phaseout;
end
end
endmodule