Lab 5: Inverted Pendulum PID Control In this lab we will be learning about PID (Proportional Integral Derivative) control and using it to keep an inverted pendulum system upright. We chose an inverted pendulum system because the control requirements are similar to those of your balancing robot. In part one of this lab we will go over the inverted pendulum system and how it works and in part two we will learn about PID control loops, how to tune them and use one to balance the inverted pendulum system. Part 1: Inverted Pendulum System An inverted pendulum is a pendulum that has it's center of mass above its pivot point. It is usually mounted with the pivot point on a moving cart, as shown below. Figure 1- Inverted Pendulum System The inverted pendulum is unstable and will fall over unless a force (F) is applied. We will be using the inverted pendulum to learn to tune our PID control loops. Although the masses and forces may be different for the inverted pendulum system than for your balancing robot, the method for tuning the system is the same.
Lab Apparatus Figure 2- Inverted Pendulum Rig In this lab, our inverted pendulum will be driven using a stepper motor and a programmable motor drive, which will be controlled by an Arduino. An optical encoder is mounted on the pendulum shaft to determine its position and there are two photo sensors on each side of the slider track to ensure it does not hit the end. The model numbers of all the major equipment are listed below. 5034-348 Applied Motion Stepper Motor 2035 XD Step Motor Drive exposition Step Motor Drive Software Manual Arduino Uno TRDA- 20R1N1024RZD Inverted Pendulum encoder EE- SX771 photo sensors The sections below explain the equipment in more detail and go over how to use them.
2035 XD Stepper Motor Driver The 2035XD Stepper Motor Driver is capable of driving 2 motors. It's datasheet can be found at: http://www.applied- motion.com/sites/default/files/hardware- manuals/2035xd_hardware_manual.pdf Usually, stepper motors are controlled by sending pulses to the motor at a given frequency. Each time there is a pulse, the motor takes a step. However, using the programmable motor driver allows us to operate in two different modes: Pulse/Quadrature or Run/Stop. Pulse/Quadrature mode is the basic stepper motor mode where each pulse from the Arduino corresponds to a step. The frequency of these pulses and the size of the steps is what controls the motor speed. This is useful as it allows you to keep track of the motor position by counting how many steps have been taken. Run/Stop mode allows you to control the stepper motor as you would a DC motor, by simply inputting the desired speed. This mode allows the motor to spin faster than in Pulse/Quadrature mode. The motor connection used in this lab allows you to use either mode to balance the inverted pendulum. It can be seen below. Figure 3- Arduino - Motor Driver wiring diagram In our case, the indexer with sourcing outputs is the Arduino. When operating in Pulse/Quadrature mode, the STEP+ pin is connected to an Arduino PWM output, DIR+ is connected to a digital high or low output and COM is connected to ground. When the PWM signal goes low, a pulse is sent to the motor drive and the motor takes a step. In this mode, the speed of the motor is limited by the PWM frequency of the Arduino. You can change the PWM frequency, however, the motor itself can only handle a PWM frequency of about 1000Hz in this mode.
In order to keep the inverted pendulum upright, we will need the motor to be able to rotate quickly and change its speed on the fly. Since this is not possible with the Pulse/Quadrature mode, we will be using the Run/Stop mode for this lab. The pin wiring when operating in Run/Stop mode is shown below: DIR+ pin: is connected to a high or low digital output from the Arduino. If the pin is high the slider will move forwards and if the pin is low it will move backwards. STEP+ pin: is connected to a high or low digital output from the Arduino. This is now the GO/STOP signal. If the pin is set high the motor will rotate and if it is set low it will stop. COM is connected to ground. AIN: Is not shown on the diagram above, but is used to control the speed. It is should be connected to an analog signal between 0 and 5V. In our case, it will be connected to a PWM signal from the Arduino which can vary between 0 and 255. When it is maximum (5V or PWM of 255) the motor will be running at maximum speed. These pins are already connected to the motor, but the Arduino pin connections will need to be done by you. Once you have connected your Dir+, Step+ and Ain pins to the Arduino pins, you are ready to set- up the motor driver software. exposition Software The exposition software is used to program the motor drive. It is very simple to use and can be downloaded from the following link: http://www.applied- motion.com/products/software/exposition When you first download and open the program you will see something that looks like this.
Figure 4- exposition Software Interface If the program has trouble finding the serial port, it is probably because the motor controller is connected to the wrong COM port. The exposition software only works with COM1- COM4 so if your motor controller is not connected to one of those ports then the exposition software won't detect it. To change the COM port, go to Control Panel - Device Manager - Ports(COM & LPT). Right click on Prolific USB- Serial Comm Port and click Properties- Port Settings - Advanced. You should see the following window.
Figure 5 - Changing Arduino COM Port You can now change the COM Port number of the motor driver. Connect it to COM1,2,3, or 4. At least one of them should be free. If none of them are free, try switching some of your other USB connections. Now you should be able to open the exposition software and have it automatically find the serial port. In the software interface above, ST1 is the step or speed input, depending on the mode you are operating in, DR1 is the direction input (either high or low) and AN1 is the analog speed control. The AIN pin is only required if you want to change the speed during operation. If you want to run at a constant speed, you don't need to use the AN1 pin. Remember this motor controller can control two motors so ST2,DR2 and AN2 would be for the second motor. Let's configure the exposition software to control one motor in Run/Stop mode. To do this, the interface should look like this:
Figure 6- exposition software Run/Stop mode configuration Notice in the above configuration, the speed is set to 10 rev/s and the analog speed control input is enabled. To set those inputs, you need to click on the ST1 input and click on Run/Stop mode. You will then see this box. Figure 7- Run/Stop Mode Inputs
The AIN signal is the 0-5V analog signal that will control the speed. In our case this signal will come from the Arduino. However, the Arduino can only output a digital voltage (on/off), so the analog voltage signal required is simulated using a PWM. The PWM is a DC voltage whose duty cycle (the amount of time it is high) is determined by the PWM input, which ranges from 0-255. See figure below. So a value of 0 corresponds to 0V and a value of 255 corresponds to 5V. See figure below. Figure 8- Arduino PWM schematic Because it is a digital voltage simulating an analog voltage, it may cause choppy motion at lower PWM values. To avoid this, we have added a low pass filter to smooth out the PWM signal. The low pass filter essentially removes the high frequency (AC) component of the signal and leaves only the low frequency (DC) component. The figure below shows the filtered (bottom) and unfiltered (top) PWM signals.
Figure 9- Low pass filtered PWM data You may want to remember this trick if you find your robot motion is choppy due to a PWM signal. Now that you understand how the hardware and software interface, let's implement it to control the motor. Using the Arduino to Control the Motor The ultimate goal of this lab is to use a PID loop to control the slider motion and keep the pendulum upright, but first we will work on simply controlling the slider motion. An easy way to control the slider motion is to have interrupts connected to the photo sensors on either side of the track. The code below will run the slider and cause it to stop and change direction every time one of the photo sensors triggers, i.e. it gets too close to either end of the track. Since the action required if the slider hits either photo sensor is the same, stop and switch direction, they we wired together. This means we only need to use one interrupt to for both of them. They were connected to interrupt 0 (digital pin 2) on the Arduino to run this code.
Figure 10- Arduino code to move slider back and forth In this case pin 4 on the Arduino is connected to the go/stop pin (high = go, low = stop), pin 5 is connected to the analog input signal (speed) and pin 7 is connected to the direction pin (high is forward, low is backwards). For the interrupts to function properly, you need to configure interrupt0 before you configure interrupt1. In this case, the interrupts have been set to trigger on a falling edge. This is because the photo sensors output pins have a pull- up resistor (connecting the output to the power source) so they are high when there is nothing obstructing the light (i.e. when the red light is on) and go low when the slider moves in front of it. You require a pull- up resistor for these photo sensors, otherwise the difference in voltage between the unobstructed and obstructed states is too small for the Arduino to register.
Try connecting these pins to your Arduino and see if you can get the code above working. Play around with the maximum voltage and the AIN signal (Arduino PWM value) to see how it affects the slider speed. Once you have it working you are ready to connect the inverted pendulum encoder so you can determine its angle and ultimately ensure it remains upright. Inverted Pendulum Encoder The encoder used for the inverted pendulum is a medium duty incremental optical encoder (TRDA- 20 Series). The data sheet can be found at: http://www.automationdirect.com/static/catalog/21- sensor- encoder- rotary.pdf This encoder is a quadrature encoder with 1024 pulses per revolution (PPR). You may remember quadrature encoders from Lab 4. Just in case you have forgotten we will go over it briefly. A quadrature encoder has two output channels (A and B), which are 90 out of phase. See image below. Figure 11- Quadrature Encoder Channels Having two channels allows you to determine the direction of rotation. If the pulse on channel A comes before the one on channel B (A leads B), the disk is rotating clockwise. If the pulse in channel B comes before the one on channel A (B leads A), the disk is rotating counter clockwise. The pulses per revolution (PPR) of an encoder denotes the number of pulses triggered on each channel in one revolution of the motor. You may recall that the Arduino interrupts can operate in four modes. These are summarized below. LOW to trigger the interrupt whenever the pin is low CHANGE to trigger the interrupt whenever the pin changes value RISING to trigger when the pin goes from low to high FALLING for when the pin goes from high to low
For a 1024 PPR encoder, the PPR is only actually 1024 if you have an interrupt on only one channel and you trigger on only one edge (rising or falling). If you read one channel and both rising and falling edges (i.e. change mode), you would get 2048 PPR. If you read both channels and both rising and falling edges, you would get 4096 PPR. For this encoder 4096 is the maximum resolution. This encoder also has a Z channel which gives the absolute position of the encoder with respect to a single point of reference. The encoder connections are as follows: Figure 12- Encoder wiring diagram This connection is called a Totem Pole Connection and is explained in more detail in the datasheet. The input power supply is between 4.75-30 VDC so it was connected to the Arduino 5V output. In order to read the values from the output channels (OUT A and OUT B) you will need to use the Arduino Interrupts. Unfortunately, the Arduino Uno only has two interrupts and we already used one to read the photo sensors on either side of the track. There are a few things you can do to free up interrupt pins to read the encoder: 1) You can configure other Arduino pins to function as interrupts. There is documentation online, but a good place to start is the PinChangeInt Arduino Library: http://playground.arduino.cc/main/pinchangeint#.uzydq_ldxz4 2) You can simply poll the photo sensors in your main routine to see if they triggered. This way you don't need to have them connected to the interrupts and you can use both interrupts to read the encoder. 3) You can only have an interrupt attached to one of the encoder channels instead of both. This would decrease your maximum resolution by 1/2. Once you have decided how to free up interrupts, you are ready to start writing code to read the encoder channels. The Arduino rotary encoder page has some good sample code to determine motor direction by reading the two channels: http://playground.arduino.cc/main/rotaryencoders. It has examples for interrupts on one or both channels.
Remember that reading channels A and B will only give you relative position to where you started, not an exact position. Usually you would want to start the pendulum upright so that would be a value of zero i.e. your reference point. The code in Appendix A reads both encoder channels and outputs the position relative to the center (pendulum in the vertical position). Lab Deliverables After completing this lab you should know how to move the slider on the track, use the photosensors to ensure it doesn't hit either it and read the encoder position. You are not required to demonstrate or submit anything for this lab, but you will need to understand how to control the inverted pendulum before you can begin to balance it. If you are comfortable with all of this, you can move on to Part 2: PID Control and Tuning for the Inverted Pendulum System.
Appendix A: Pendulum Encoder Code