Through the aid of the hardware description language (HDL) Verilog and the AMD Vivado Design Suite, an RTL design of a motor controller system for two motors with encoders is realized in an AMD Spartan-7 FPGA.
In this project we are using the Adiuvo Engineering's Embedded System Development Board. It has a Spartan-7 FPGA on board that we will be using as the motor controller system.
The question I invariably get from a few individuals when I post this or similar projects on LinkedIn is essentially: “Why do it the hard way with an FPGA when coding a microcontroller would be so much simpler and faster?”. A fair question. So, we will briefly look at various reasons one would go this route.
After the FPGA vs Microcontrollers debate, we will cover basic concepts on many aspects of a motor driver, an H-Bridge, PWM, encoders, PID feedback control systems, coding and testing, analysis of gathered date, etc. We will then finish off with details of building your own FPGAbot.
FPGA vs MicrocontrollerChoosing the “best” processing technology for a specific product or a deliverable system is crucial to its success in many respects. Factors include support costs, supply chain, profitability, longevity, etc. From an engineering perspective, the typical and most influential factors in the decision making are time, cost, area, and power. Of course, when it comes to learning, trying, and making, use what interests you!
FPGA Advantages
FPGAs are known for their low latency, innate, parallel processing capabilities, and flexibility. Additionally, they provide high deterministic and accurate timing for many independent computational modules, external sensors and actuators, etc. That is why you will find FPGAs are used in many mission -critical applications, such as:
1) Military and Aerospace Systems
- Radar Systems - e.g., Real-time (RT) signal processing and data acquisition.
- Unmanned Aerial Vehicles (UAVs) - e.g., flight control, sensor processing, and secure communications.
- Avionics, Satellites, Missile Guidance Systems, etc.
2) Industrial Control Systems (ICS)
- Real-time control and monitoring of critical infrastructure like power grids, oil refineries, etc.
- Industrial Automation - Machine control, enabling fault detection, redundancy, and fault tolerant control.
- Functional Safety - e.g., fault tolerant systems for automotive and industrial control.
3) Medical Devices
- Diagnostic Imaging Systems - Fast and accurate data processing.
- Patient monitoring - FPGAs provide high-performance, RT monitoring and signal analysis of patient monitoring devices.
- Lifesaving equipment...
- etc.
4 Telecom, etc.
As you can see, many of the mission-critical applications require RT processing, deterministic behavior, low latency, programmability, parallel processing capabilities, security, and power efficiency.
MCU Advantages
For cost sensitive products or the average hobbyist, MCUs are a better choice for cost savings and fast system development turn around.
Microcontrollers use standard programming languages for software development, such as Python/microPython and C/C++. The learning curve for FPGA design (architecture, hardware descriptive languages, timing issues, etc.) is much steeper and requires a great deal of time and experience to perform efficiently.
MCUs are also better suited for peripheral interfacing and performing repetitive tasks. The general-purpose architecture, serial flow of execution, and ease of peripheral integration make the of MCU more attractive to use in non-critical mission systems.
With that covered, let's now dive into the details of the mobile robot motor control system!
High-Level Motor Controller System DesignThis section derives the major external components and FPGA functional modules needed for the mobile robot motor controller design. A high-level schematic of the system is also provided.
Motor Driver
As listed in the components section, the FPGA needs to drive two 12V DC brushed motors separately. The 12V DC motors are what I have used in the past and have found this voltage level gives me the torque I need for my DIY bots. I typically will select the lower RPM motors (e.g., 190 RPMs) as they supply more torque than higher RPM motors.
The L298N H-bridge motor driver is a great candidate to use for driving the 12V motors given that it is inexpensive, much has been written about their use by hobbyists, I have used it myself and have several on hand (!), and ease to interface with.
The L298N is essentially an amplifier that is controlled by small input control voltages (e.g., 3.3v or 5v) at its digital interface, and produces a proportional output in larger DC voltage ranges. The L298N module can operate at a range of 5 to 35V DC (Vs). Since we are using a 12V DC motor, the source voltage will be 12V, Figure 1.
Note: If you are going to enable the 5V power regulator onboard the L298N, then the maximum input DC source shouldn't be over 12V DC. Otherwise, the 5V DC regulator will overheat and shut down.
Encoders
I always purchase the DC motors that are equipped with Hall effect sensors. These sensors allow for measuring the speed and spin direction of each motor. In this design, the encoder feedback is used for the PID algorithm to keep the FPGAbot moving straight and steady. Odometry can also be calculated from this information which I do when interfacing to a main computer running ROS. We will discuss more about how the encoders work and how they are used later in the Technical Review section and the FPGA Motor Controller Design Details section.
Thus, the system will need the following functional elements at minimum:
Top-Level Architecture
- Choice of either (1) using pulse width modulation (PWM) on enables and controlling direction with high and low logic voltage levels on IN1, 2, 3, and 4, (Figure 2a), or (2) using PWMs on all four input ports and setting the enables to logic high (Figure 2b). Although I have created both versions, I will be going with option (1) for this project description (Figure 2b). Why I am choosing option (1) will be explained in the L298N section.
- Input set-points (duty cycle setting for PWM) and rotation direction source signal selector.
- Encoder Counters
- PID feedback control system/algorithm to synchronize the speed of the motors to a setpoint value.
- A digital controller, with is the Spartan-7 FPGA in this case.
For the first two bullets listed above, the logic required to generate the PWM signals from a set-point value, it is very helpful to have a good understanding of how the L298N works. So, this and other background material are covered in the next section (optional reading).
Technical ReviewThis section provides a technical review of the components, and the digital and analog concepts used for interfacing with these components. Knowledge of the information covered in this section is not required to perform the project but aids in understanding of why various modules and logic are created.
L298N Motor Driver
The L298N, as shown in Figure 3, can be categorized as a type of DC amplifier that converts pulse width modulation (PWM) signals at its input, at 0 and 3.3VDC in this case, and converts that proportionally to a steady DC voltage of 0V to Vs as previously mentioned.
The reason that the FPGA's lower output voltage of 0 - 3.3V can drive the TTL logic inputs (IN1 – IN4) and enable A & B is due to the specifications listed in [1] and shown in Figure 4b. It states the following:
Control signal input voltage ranges:
- Logic Low: -0.3V ≤ Vin ≤ 1.5V
- Logic High: 2.3V ≤ Vin ≤ Vss
where, Vss is supplied onboard the L298N module by a 5V DC voltage regulator. Since the FPGA won't be receiving digital data from the L298N a logic level converter is not required.
The L298N is the module that is built around the L298 integrated circuit (I.C.). The L298 I.C. is a high voltage, high current dual full-bridge driver. The L298 I.C. is rated for Vs = 5V to 46V (Figures 2a & 2b), but the L298N module has heat and component restrictions for voltages above 35V.
L298 Dual H-Bridge
Let's take a quick look at the H-Bridge circuit. Not to worry if you don't quite fully grasp the following information, but I thought I would add it for completeness. Additionally, feel free to skip this section if you wish. This is just additional information for those interested.
Figure 5 is a replication of the L298 block diagram from [1]. It shows a mixture of digital circuits (AND and NOT gates) and analog circuits (BJT transistors and resistors). The logic gates and BJT transistors create current flow control circuitry. To better understand the overall function of the current control circuits, a simplified version and explanation of this figure follows.
Figure 6 replaces the current control circuits with conceptual switches. This represents how the H-Bridge circuit functions, and we will also use it to cover the difference between using PWM on the IN pins vs the EN pins.
To create a forward spin of the motor, S1 and S4 need to be closed to complete the circuit (thus, current path) from Vs through the motor then to ground. S3 and S2 remain open as needed. To achieve a reverse spin, we need the opposite situation where S3 and S2 are closed and S1 and S4 are open. Figure 7a & b illustrates this concept.
Relating this circuit analysis back to Figure 6, let's look at the switches as they are implemented with the AND logic gates and the BJT's. The logic equations below are equated to the AND's output which we label here as _d for digital.
- SW1_d = IN1 AND ENA
- SW2_d = NOT IN1 AND ENA
- SW3_d = IN2 AND ENA
- SW4_d = NOT IN2 AND ENA
When any of the SWx_d above equates to a logic high, the corresponding BJT is turned "ON". This is accomplished by the base-emitter becoming forward biased (Vbe surpassing the voltage drop threshold of +0.7v between the base input and emitter output pins). An "ON" transistor acts like a closed switch when the collector's voltage is greater than the base and emitter's voltages, respectively (Vc >> Vb > Ve). See Figure 8.
The switch analogy hopefully helps simplify the digital-transistor control logic. If you are interested and have the background, I suggest finding a good book or reference to learn more about how transistors work and the different types that are available.
Next a quick review of PWM if you need a refresher. If not, you can skip over and go to where we analyze the PWM input options for the L298N.
PWM Review
For variable speed operation of the motors attached to the L298N motor driver, PWM (Pulse Width Modulation) is used. PWM is a digital means to derive a variable analog type voltage. Thus, a square wave, digital signal's duty cycle (logic high time vs total pulse period) is either increased or decreased to modify the average voltage seen across an analog circuit (Figure 9). For example, an NPN's base-emitter junction being turned on longer given a set period, will result in a more current and thus, a larger voltage drop (Vce) across the collector's output connection and the emitter, or ground in this case. Figure 10 illustrates this concept [7].
L298N PWM Input-Response Characteristics
As stated at the start of this article, there are two different methods to obtain variable speed using PWM. Method 1 is to drive the input pins (IN1, 2, 3, & 4) with PWM and set the Enable pins to high, Figure 11a. Method 2 is to set the input pin pairs high and low for correct spin direction and drive the enable pins with PWM for variable speed, Figure 11b.
Using Method 1 gives you the current flow shown in Figures 7a and 7b. The only difference is the amount of current flow time per pulse period from Vs to Gnd.
Using Method 2 gives you a little different response. In the case that you are driving the motor forward, PWM would be active on IN1 and PWM would be held at ground level for IN2. Since ENA is set to logic high by a jumper, the on/off switching is purely controlled by the active PWM signal on IN1. Having both IN2 and ENA set to controlled, steady values (0 & 1), SW3 is always set to "off" or "open" and SW4 is always set to "on" or "closed". However, the NOT gate used for SW4 (~In1 & EnA) will turn on SW2 during the low part of the PWM duty cycle. This takes place when SW1 is turned "off" or "open". Thus, the positive and negative terminals of the motor are held to Gnd. This causes discharge of the opposing, induced electromotive force (EMF) during the SW2 "on" cycle. Such a configuration is helpful for lower RPMs but causes higher current draw at higher RPMs due to the repetitive loss of opposing EMF voltage.
12VDC Encoder Gear Motor
The DC motors we are using for the mobile robot were specifically selected for having magnetic encoders. This is typical for DC motors of this nature. DC motors that require greater precision in motor control use optical encoders.
The rotary magnetic encoders have two Hall effect sensors. They are placed 90 degrees apart relative to the motor's shaft axis. Figure 13 illustrates the concept of how this type of arrangement produces encoder signals that are 90 degrees out of phase.
This figure is simplified in that there are only two magnetic poles used. Most motors with magnetic encoders have tens to hundreds of such poles which increases the resolution of the motor's rotational position. Additionally, some systems will have 4 Hall sensors to add even greater accuracy.
The two signals generated from the Hall effect sensors shown above are designated as channels A and B. These channels have the following characteristics:
- They are 90 degrees out of phase (see Figure 14).
- If A is leading B, then the motor is turning in only one possible direction.
- If B is leading A, then the motor is turning in the opposite direction from the previous bullet.
- The square waveforms’ frequencies are directly proportional to the wheel’s rotational velocity.
Counting the number of pulses that are produced from a single rotation of the motor derives the resolution obtained by the number of physical poles used. This information can be used to estimate the robot's odometry by using accumulated counts (or tics as I like to call them) to count/rotation and using the wheel's diameter (or radius) to calculate its circumference.
FPGA Motor Controller Design DetailsIn this section details on key Verilog code for the mobile robot motor driver system will be covered. This code will be related back to the system block diagram shown in Figure 2a and replicated in Figure 15 below for convenience. In addition, the PID algorithm that I derived works as a lead-follow motor speed comparison system and will be explained in detail.
Verilog Sources Hierarchy
From the initial top-level design shown in Figure 15, the Verilog module hierarchy was derived and then created in AMD Vivado (Figure 16).
External Pin Declarations
Next is the Verilog code for the input and output signal declarations that interface the FPGA to the external world (Figure 17). In this case it is for the L298N, the two 12V DC encoder motors, (Figure 1) and the RC receiver unit (not shown).
No surprises here except for the radio controller (RC) receiver signals (rc_). I always add an RC system to all my bots so that I have the option of testing out various sensors without the use of a main controlling processor. So, I have reserved a switch to enable/disable RC control (rc_en input signal).
Encoder Counter Module
The code used for the encoder counter module originates from fpga4fun.com [9]. There you can find a great explanation along with waveforms describing the logic used. Essentially, oversampling using the system clock, a few logic gates, and D flip-flops (a few extra added for crossing clock domains) are all that is needed to determine count and direction of spin. Figure 18 illustrates the code's implementation.
I also added logic to create a positive count only. This is needed for the PID that we will cover shortly.
RC Signal Select Module
The name for this module is a bit of a misnomer. Initially, the module was only used for taking in the directional signals from the RC module and converting each signal into a two bit value (Figure 19). One bit to indicate whether the left wheel should go forward or backwards and another bit for the right wheel. Each bit is placed in the most significant bit (MSB) of each setpoint (left and right). For now, the left and right motor setpoints coming from this module and going to the PID module are the same value (bits [6:0]). The user setpoint can be changed in the top module by initializing curr_setpt1 & 2 to new values then running Vivado through the synthesis, implementation, and generate bitstream. This process takes around two minutes at most.
PWM Module
As mentioned above, the user setpoint (named curr_setpt1 & 2 at the top-level) is stored in the lower 7-bit of the 8-bit register. Thus, the setpoint takes on a value that ranges from 0 to 127. This value represents the duty cycle of the PWM fed to the L298N. How does the PWM convert the setpoint to the duty cycle time width? That is accomplished with a 7-bit counter in the PWM module. The output of the PWM is logic high initially (counter = 0). When the counter that is being clocked a 256 kHz counts up to the setpoint, then the PWM outputs a logic low until the counter reaches 127. The result is a 2kHz square wave PWM with a duty cycle of setpoint/127.
Just to make things harder on myself :) and save comparison logic to derive the 256 kHz, I used the Vivado Clock Wizard to generate an 8.192 MHz clock from the 100 MHz system clock. This allows for only one bit of the counter in the 256 kHz module to need comparison to logic '1'. The resulting PWM frequency comes out to be 2 kHz which was close to the 1.5 kHz example [2] and works well.
PID
The PID controller module was not as easy as I had thought it would be to design. The issue is the conversion of between setpoint value (0 - 127) and delta counts that are read back every set sampling period T (e.g., 100ms). Figure 21 illustrates the PID feedback loop block diagram in discussion.
The issue here for me was that I didn't see (nor produce) a low error conversion from delta tics (counts)/T back to a setpoint value.
So, instead, I decided to use the setpoint input r[k] as a base value and add a modification value (error value) that is based on the differences in previous counts and current counts of both motors, thus including discrete time analysis/comparison of differences in each motors total counts every period T (velocities).
From my experience of using these small DC encoder motors, I have noticed that one motor tends to have more torque than the other for the same duty cycle setting of the PWM. So, in the PID control algorithm, the more responsive motor is quickly determined, and it is used as the lead motor for matching speed and distance traveled. Thus, a speed modification would only be made to the setpoint input r[k] of the slower motor. Otherwise, the motors would ramp up in speed very quickly.
Let's look at the proposed lead-follow equations, then the pseudo code for this discrete leader-follower motor feedback control loop.
e[k] = Feedback_1[k] - Feedback_2[k]; (1)
where, e[k] is the error calculated at sample period k, and Feedback_n[k] is the motor n's (i.e., n = 1 or 2) encoder counter value at sample period k.
Δx1[k] = Feedback_1[k] - PrevFeedback_1[k-1] (2)
Δx2[k] = Feedback_2[k] - PrevFeedback_2[k-1] (3)
Δx1x2[k] = Δx1[k] - Δx2[k] (4)
where, PrevFeedback_n[k-1] is motor n's encoder count Feedback[k-1] saved at sample period k-1, and Δx1x2[k] is the difference in rotational velocities of motors 1 and 2.
As with the PID control system shown in Figure 21, there are weight values (constants Ki, Ke, and Kv) that are used to multiply equations (1) and (4) before they are summed. The resulting equations therefore are the following (a portion of the code shown in Figure 22):
and the overall equation for the post PD error equation, as we will discuss below is:
u[k] = setpoint[k] + motorNSpdMod (5)
where, N, again, represents the motor's number of 1 or 2.
As you may notice, equation (5) lacks an integral element. I will address how adding the integral to u[k] (equation 5) was key to smoothing out the error oscillations (positive to negative over and over) in the FPGA code section but wasn't considered initially.
After coding up the design in Vivado using Verilog, I made a simulation model for a DC encoder motor and instantiated it twice in the test bench. The motor model sampled PWM wave inputs from the unit under test (UUT) and converted the calculated rotational speed into encoder A/B channel waveforms of corresponding frequency. The encoder waveform channels are fed into the UUT. Additionally, I added a "drag" value that decreased a motor's rotational speed compared to the others. This resulted in a lower encoder count for the slower motor, allowing for some similarity to the real motor and system response. Of course, this is a very simple model since the added resistance to one motor is constant. It would have been advantageous to create at least a simple physics inertia response into the motor model. The model also assumes a constant flat; level surface is used by the mobile robot.
Unfortunately, the response I saw with the robot once on the ground was different from the simulation, as I had figured it would with the given physics less model. So, I turned to the good ole Arduino Mega to help me out with gathering hardware in the loop (HITL) data!
The equation used in the FPGA was tested, modified as needed (e.g., a shorter T, tweaking Ke and Kv values, etc.) and verified in C/C++ using an Arduino Mega MCU with the FPGAbot (minus the FPGA) initially. This made for quicker verification and modification turnaround times. The following snippet of code comes from the Mega testing (function PD_Alg(args)) and represents the lead-follow algorithm (Figure 22).
The lower portion of code where the motorNSpdMod is being checked against a maximum setting value (255 - C_fwdSpd - 20) to prevent the value spiking too high. The value 255 is the max duty cycle value of (0 to 255), the C_fwdSpd is actually the setpoint for the two motors (same values), and 20 is just an arbitrary value that seems reasonable when looking at data from Serial.print()'s scroll by on the Arduino IDE console for debugging as shown in Figure 23 for a 5 foot run of the FPGAbot on the carpet.
From looking at the data printed out, it was apparent that a better response could be realized by tweaking Ke and Kv a little more and perhaps adding an integral element into the mix. So, that is exactly what I did.
FPGA Variation on the Lead-Follow PID Equation Implementation
The results shown in the simulation of before and after adding an integral to the lead-follow equation (5) are illustrated in Figures 23a and b respectively.
The following graphs (Figures 25a and b) charts e[k] (error), dx1dx2 (delta in motor velocities), and u[k] - setpoint (motor mod value). Figure 25b also adds data gathered for Ki*integral[k] (sum of mod values times a fraction) which is listed here in equation (6).
u[k] = setpoint[k] + motorNSpdMod + Ki ΣmotorNSpdMod (6)
It is easy to see from the two figures that the integral dampened the oscillations in error and delta velocities very quickly in this case. This resulted in a very flat u[k] adjustment to the original setpoint.
Lead-Follow FB Control Algorithm Verilog Code
The C/C++ code shown in Figure 22 runs sequentially on the MCU. For that is how they work. To replicate sequential calculations in Verilog, I used a state machine that went from one calculation state to another every 10ns (100 MHz system clock). The algorithm's calculations were spread out in 7 states for 70ns of compute time. I didn't worry about minimizing computation time by a few tens of ns and sacrificing the readability of the code. The time savings would have been three orders of magnitude smaller in time duration compared to the sample period T. So, hopefully you can understand the lead-follow algorithm coded in the pid_module.v. To make it more readable, splitting out calculations into nice and neat stages creates data dependencies, which made for the extra clock cycles needed. Same with MCUs!
To get around using floating numbers for Ki, Ke, and Kv, thus saving quite a bit of the logic resources of the FPGA, I used approximations of these fractional values by shifting right (dividing by 2^n) the error, delta velocities, and integral. However, one needs to be careful on how signed and unsigned variables (registers) are used in Verilog. I won't cover the rules one needs to follow, except for the shifting right of signed variables to perform division by 2^n. The shift right of a negative number, as I found out through my endeavors, will end up giving you a large positive number if you use the logic shift ">>". To prevent that from happening you need to use the arithmetic shift right representation ">>>".
The code in Figures 26a, b, & c illustrates the concepts covered to this point for implementing the PID lead-follow feedback (FB) control algorithm in Verilog and simulated in Vivado (Figure 24a & b). Please take the time to compare the code in Figure 26 (Verilog) against Figure 22 (C/C++).
Now let's do something fun and see how you might go about building the mobile chassis for the FPGAbot. You may have a chassis of your own already or have parts that you can use to make one that differ from what I present. Perhaps you have access to 3D printer to make some of the parts! However, if you need hints and some building plans, that will be supplied in this next section, along with wiring and power information.
Building Your Own FPGAbot!These instructions and images are a subset of what I used to create my Edu-AMR bots that I used to sell under my startup ZenoRobotics, LLC. I made quite a few of these bots all by hand. They are only a subset because it would take many more pages to go through a step by step how to do and what to use.
So, if you ever have any questions, please don't hesitate to contact me here and I will do my best to get back to you as quickly as possible.
Chassis
The ideal setup is to have two additional shelves that connect to the base of the robot. This will give you two compartments plus a top platform to place. The available space, as you will see shortly, is perfect for placing your electrical components (battery, wire, power distribution strip, USB DC buck step down converter, FPGA board, USB cables, etc.). I usually tie everything down with Velcro, thick double-sided tape, and zip ties.
Here are some images of the base I have used before and was used for the FPGAbot. It is made from 26-gauge sheet metal and used metal shears to cut it with. Once all measurements were made and holes were drilled out, the base was then covered with an adhesive vinyl wrap. Prior to adding the vinyl, I used workers gloves to hold the cut sheet metal and sand down all edges, removing anything sharp sticking up with pliers.
*** Important Notes:
- Don't forget to wear some kind of eye protection!
- Use a thick pair of workers gloves.
- Read through instructions to the end before starting! Some things are mentioned a little too late in the process...
I made sure all the edges of the base were covered over with vinyl as well.
I have used thin plywood in the past as well. My first robot base was made of plywood, and I still use that mobile robot today!
In the "Things" section, I listed (including a source link) 12V DC motors with encoders. These come with brackets and wheels. Again, if you have your own, that's cool. I suggest making the height from the base to the bottom of the caster wheel the approximate same distance of the base to the bottom of the motor wheels once installed. This helps stop things from sliding.
I used a hand electric drill to make the holes for all screw holes on the base. I start with a very small drill bit, then use the size that works best for the screws you are going to use. Washers also help if the screw holes are slightly larger than the screw head.
It is best if you are going the route of making a robot base similar to what I am doing here, to make all of the holes prior to adding the vinyl. It gives you a chance to hammer down the edges of the holes and do some lite sanding. NOTE OF CAUTION! Using a hand drill always creates errors as the drill will slide before enough of a start is made to lock it in. To help with this problem, I measure and re-measure the hole placings (I still come out with some misalignment anyway …). I use a pen or permanent marker and the actual bracket itself as a template to mark the holes. This is another great reason to leave the vinyl off initially. You can make marking on sheet metal or wood much more easily than vinyl!
Make sure your brackets are screwed on first before installing the motors, for you won't be able to access these screws when the motors go on.
Use motor screws to attach motors to brackets as shown below. Point 6 pin connectors out the back of the base bottom.
I make a battery shelf for my brick type LiPo 12 to 13 volt, 3000 mAh battery that is installed under the chassis. This approach saves me space because they are a bit bulky.
The shelves were made of acrylic that I bought in sheets and had to hand cut. Acrylic is incredibly hard to cut by hand. So, using 3D printed shelves would be optimal, or some other easier to use material. I just liked how the transparent acrylic looked. Never again though … unless I can acquire some better automated tools.
The holes for the spacers used to hold the battery shelf, as well as the holes for the top shelves should be drilled early in the process as well. Due to the marking simplicity and re-drilling if things don't come out straight enough to work. You will also need to hammer down the edges of the holes and give them a light sanding. You can always place vinyl over the extra holes later.
Power Distribution Unit (PDU)
The cleanest way to manage your power and ground connections is through the use of a power distribution board (or PDU). The part I used can be found in the Things section as well. It doesn't need to be this exact part, but something similar will be very helpful.
On the PDU board has two independent, electrically connected sides. That is so you can put 12V (in this case) positive connections on one side and ground on the other.
Figure 38 shows how the PDU is wired. The power switch, LED power-on indicator, and voltmeter are all optional. Without a power switch, the wiring would differ a little and the system would power up once the battery source is connected.
The wiring for the DC encoder motor from one company is not necessarily the same for another. They don't follow any standard. Figure 39 shows what the wiring is for the motors that are listed in the Things section.
If you use a different motor, make sure you get the wiring specifications that goes with that brand of motor.
To connect the motor power and encoders to the processor (the FPGA in this case) and the L298N, I used a handmade Motor Patch Board that simplified the connections for the user by allowing simple jumper wire connections between the board for sourcing power to the motors, connecting to the encoders, plugging a 6 pin cable that I would buy separately into 6 pin receptive connectors on the board. The wiring for this custom-made patch board is shown in Figure 40.
The good thing is that you can easily get around the patch by connecting the right wires together. This is a little messy and doesn’t make disassembly and reassembly a bit messy, but it works. Figure 40 has the pin names that correspond to the L298N's pins and the motors 1 & 2 encoders that go to one of the FPGA's PMOD. The encoder connections and others are shown in Figure 1 back at the beginning of this "article" or book I would like to call it. Also, looking at the Vivado constraints file "constraint_pwm_s7.xdc" lists the PMOD connections.
You will be able to find the Verilog code for this project on my ZenoRobitics Github site. I have included a link in the Things section for the FPGA code repository.
Figure 41 shows the component placement for the power portion of the FPGAbot.
The final assembled FPGAbot is show in Figure 42. It has the acrylic shelf installed via spacers for the FPGA and multimeter to sit on.
Wrap UpI hope you enjoyed reading through this project material. There was a great deal of information covered across many topics related to motor control systems. Hopefully you were able to learn a thing or two that you weren't aware of previously. I know I did!
If you have the time, try making at least a portion of the project to test out motors and brush up on your FPGA RTL coding skills!
The complete project can be found Here on my Github. I will keep updating the Readme file as time allows. Basic instructions for using the simulator will be found in this file as well.
Adiuvo Engineering and Training, LTD sponsored this amazing project. Other product names used in this publication are for identification purposes only and may be trademarks of their respective companies.
References[1] STMicroelectronics L298 I.C. Data Sheet. www.st.com/resources/datasheet/l298
[2] L298N Motor Driver and PWM Details PDF put out by BYU (Brigham Young University). https://brightspotcdn.byu.edu/cd/87/bbf866d84c06a0c52fa995396f30/l298n-motor-driver-quick-start-v6.pdf
[3] L297 Stepper Motor Controller Datasheet by STMicroelectronics. https://www.st.com/content/ccc/resource/technical/document/datasheet/f9/35/6e/3f/48/18/48/51/CD00000063.pdf/files/CD00000063.pdf/_jcr_content/translations/en.CD00000063.pdf
[4] "What is an H-Bridge". https://www.build-electronic-circuits.com/h-bridge/
[5] "NPN Transistor". https://www.electronics-tutorials.ws/transistor/tran_2.html
[6] "Basics of PWM". https://docs.arduino.cc/learn/microcontrollers/analog-output/
[7] Rechtenwald, G. "Basic DC Motor Circuits". https://cdn.sparkfun.com/assets/resources/4/4/DC_motor_circuits_slides.pdf
[8] "Understanding Resolution In Optical And Magnetic Encoders". https://www.electronicdesign.com/technologies/components/article/21798142/understanding-resolution-in-optical-and-magnetic-encoders
[9] "FPGA Projects: Quadrature Decoder". https://www.fpga4fun.com/QuadratureDecoder.html
Comments