FPGA : RC Servo and Stepper motor control in Verilog


It’s been a while since my last post … 8 months more exactly, which is probably one of the biggest gap in recent years… Having 2 kids is taking its toll on my hobby ! 🙂

A couple of months ago I did a tricky soldering job for a friend, to fix the wire / jack of his hi-fi ear phones, and I almost made a post about it… and then I realised, “hold on, is this how lame I have become, blogging about something as trivial as tricky tiny wire soldering ?”.

So here is something slightly more interesting, that I managed to work on this past week-end: my first foray into FPGAs !

More than 1 year ago I bought one of these cheap FPGA Mini Board from eBay (29GBP with an USB Blaster included), and then it took me a while to decide what language to use VHDL or Verilog ?

This week-end I was looking for something to do quickly in a couple of free hours, and I had enough of being blocked on the perfect choice, so I decided to go with Verilog, as apparently is “simpler” and “less verbose”…

I have no idea if it was the right decision or not, but I’m so happy I could move forward, as I’m now impressed at how easy it is to do certain things with a FPGA.

Judge for yourself from the code below (sorry no syntax colouring, Verilog seems to be too hardcore for WordPress 🙂 ):

module counter(clock, reset, led, servoPin, stepperPins);

/////////// 3 bit/LED counter ///////////////
localparam SECOND_DIVIDER = 50000000;

input clock, reset;
output [2:0] led;
reg [2:0] secondsCounter;
reg [31:0] clockCount1;

always @ (posedge clock)
begin
	if(secondsCounter == 3'b111 || reset == 0)
		secondsCounter <= 1'b0;

	clockCount1 = clockCount1 + 1'b1;
	if(clockCount1 == SECOND_DIVIDER)
		begin
			clockCount1 <= 1'b0;
			secondsCounter <= secondsCounter + 1'b1;
		end
end

assign led = ~secondsCounter;

/////////// RC Servo ///////////////

parameter TICK_CLOCK_DIVIDER = 195;  // 50000000/1000/256 = 195.31

output servoPin;
reg servoPin;

//Using the "ClkTick", we instantiate a 12-bits counter that increments at every tick.
//Each tick lasts 3.9µs, so 256 ticks lasts 1ms, and the 12 bits counter "TicksCount" rolls-over every 16ms.
//Just what we need to generate a new pulse regularly.
reg [31:0] clockCount2;
reg [11:0] ticksCount = 1'b0;
always @ (posedge clock)
begin
	if(clockCount2 == TICK_CLOCK_DIVIDER) // a "tick" has happened
		begin
			ticksCount <= ticksCount + 1'b1;
			clockCount2 <= 1'b0;
		end
	else
		clockCount2 <= clockCount2 + 1'b1;
end

// 4'b0001 out of 12 bits, already corresponds to 256 = 1ms pulse
// the remaining 8 bits will have a value from 0 to 255, for a total between (1ms, 2ms), exactly what a RC servo needs
always @ (posedge clock) servoPin <= (ticksCount < {4'b0001, secondsCounter, 5'b00000});

/////////// Stepper Motor - half step method (using 28BYJ-48) ///////////////

parameter STEPPER_DIVIDER = 50000; // every 1ms

output [3:0] stepperPins;
reg [3:0] stepperPins;

reg [31:0] clockCount3;
reg [2:0] step;	// 8 positions for half steps

always @ (posedge clock)
begin
	if(clockCount3 >= STEPPER_DIVIDER * (secondsCounter + 1))
		begin
			step <= step + 1'b1;
			clockCount3 <= 1'b0;
		end
	else
		clockCount3 <= clockCount3 + 1'b1;
end

always @ (step)
begin
	case(step)
		0: stepperPins <= 4'b1000;
		1: stepperPins <= 4'b1100;
		2: stepperPins <= 4'b0100;
		3: stepperPins <= 4'b0110;
		4: stepperPins <= 4'b0010;
		5: stepperPins <= 4'b0011;
		6: stepperPins <= 4'b0001;
		7: stepperPins <= 4'b1001;
	endcase
end

endmodule

This code does 3 things in parallel:

  1. a simple binary count with the 3 LEDs on the board, from 0 to 7
  2. controls a RC Servo, where the position is dependent on the value in the previous counter
  3. controls a Stepper motor, where the speed is dependent again on the previous counter

 

I’m sure there are other applications where a micro-controller is much easier to use than a FPGA or CPLD, but in the case of several simple but parallel and time sensitive tasks like the above you can’t beat an FPGA !

Just imagine on an Arduino or similar, the interrupts and all the programming gymnastics that need to be done to make sure that the timings stay within margins…

Also, I’m quite surprised at how easy writing Verilog turns out to be… yes, it does take a while to grasp the fact that you’re actually changing the hardware, not programming a CPU to do certain things, and I’m also sure that there are many and complex subtleties in Verilog that take years to master, but still… I wouldn’t have dreamed to be able to do these 3 tasks in a day, in my first attempt !!!

 

For those interested in reproducing this example:

  • The board is called “EP2C5 Mini Board” and has a EP2C5T144C8 Cyclone II FPGA on it
  • I used a standard, 9grams micro RC Servo
  • I used a 28BYJ-48 stepper motor and it’s driver (you can purchase these as a bundle for very cheap on dealextreme or banggood)
  • I used the free edition of Quartus II from Altera, version 13.0 SP 1 (be careful, later versions do not support Cyclone II FPGAs anymore)
  • I created a simple project, pasted all this code as a single module (it would of course be cleaner to separate the RC Servo and stepper control code into independent modules)
  • made the “Top level entity” in the General configuration page equal to “counter” (the name of my module)
  • used the Pin Planner to assign the inputs/outputs as follows:
    • clock Input PIN_17
    • led[2] Output PIN_3 
    • led[1] Output PIN_7 
    • led[0] Output PIN_9 
    • reset Input PIN_144 
    • servoPin Output PIN_40
    • stepperPins[3] Output PIN_69 
    • stepperPins[2] Output PIN_70
    • stepperPins[1] Output PIN_71 
    • stepperPins[0] Output PIN_72

 

As usual, thanks for reading, and do let me know if you have any feedback !

 

FPGA_Servo-Stepper

FPGA_Servo-Stepper

11 Responses to FPGA : RC Servo and Stepper motor control in Verilog

  1. Ritvars says:

    Than You for posting. Nice tutorial for one, who make first steps in FPGA world.

  2. serge says:

    could you please tell me what frequency of the clock did you choose? and i dont quite understand how you connected the servo to the board :/

  3. Can you please give me the block diagram of the system? I’m doing a project on this topic.

  4. Can you please give the block diagram? I’m doing a project on this topic.

  5. Pingback: PGA : RC Servo and Stepper motor control in Verilog -Use Arduino for Projects

  6. Jag says:

    Yo, I can’t seem to find Contact info so I’m just leaving a comment on your most recent post.

    Anyway, I noticed that you seemed to have directly connected a WiiMote’s camera to the NXT in this post https://trandi.wordpress.com/2011/05/12/wiimote-ir-camera-with-lego-nxt-brick-lejos/

    Is that correct? Or do you have some sort of go-between? I’ve been working with these sorts of projects for years and have been trying to find someone who’s done this before, but you’re the first person I’ve found.

    • trandi says:

      That is correct, nothing in between, the NXT reads the IR Camera directly through I2C.
      As you can see on the post, I had some issues with the values of the pullup resistors, but that’s about it.

      Dan

      • Jag says:

        Whoah! Fast reply, thanks. I currently don’t have access to my NXT, but I have access to everything else I’ll need (resistors, WiiMote, soldering iron…)

        Pullup resistors aside, how did you go about doing this? I couldn’t seem to find a post detailing your steps, but I’m assuming it’s similar to the process for connecting the Nunchuk?

      • trandi says:

        Have a look at this post https://trandi.wordpress.com/2011/04/03/the-wiimote-and-fez-domino/ detailing how to extract the IR Camera from the WiiMote and put it on its own board. It’s not super complex, but not trivial either…

        Once you have the camera on the boar with the cristal, capacitors, resistors and all the rest, you just hack any Lego NXT wire and connect it as you say, the same as for the Nunchuk ( https://trandi.wordpress.com/2010/10/18/nxt-lejos-nunchuck/).

        Hope this helps, Dan

        On 18 October 2014 10:35, Robotics / Electronics / Physical Computing wrote:

        >

      • Jag says:

        Ah, yeah, I found that post a bit later, sorry >.< It's almost 3AM, I should stop asking questions and get some sleep xD

        Anyways, looks super promising! I don't yet understand the purpose of including the crystal oscillator–I thought the NXT was supposed to provide the clock signal–but then again, this is only my third time dealing with I2C data connections, so a lot of reading should help. Thanks so much, I'll be sure to get some rest and fully read your posts before asking more questions!

  7. Pingback: A servo motor and stepper controller with a $10 FPGA | Fuzzy Hypothesis Online

Leave a comment