28
Student Workbook 1 Controlling a Motor with your Raspberry Pi In this exercise you will show how the Raspberry Pi’s GPIO port may be used along with a motor control chip to control a DC motor. The concept of Pulse Width Modulation will be introduced and you will learn how PWM can be used to control the speed of the motor. Finally you will use some push buttons connected to the Raspberry GPIO port to provide a simple human machine interface to control the speed and direction of the motor. The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 pins in all, and they are used for a variety of different things. It isn’t important to remember what all the pins do, but it is important to note how they are numbered. If necessary, prepare your Raspberry Pi by performing the following tasks: Insert the prepared SD(HC) memory card into the card slot on the underside to the Raspberry Pi Connect the USB Keyboard and Mouse to the two USB sockets Connect the computer monitor or TV screen to the HDMI socket using the HDMI cable However, do not connect the power supply to the Micro USB socket at this stage.

Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Embed Size (px)

Citation preview

Page 1: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

1

Controlling a Motor with your Raspberry Pi In this exercise you will show how the Raspberry Pi’s GPIO port may be used along with a motor control chip to control a DC motor. The concept of Pulse Width Modulation will be introduced and you will learn how PWM can be used to control the speed of the motor. Finally you will use some push buttons connected to the Raspberry GPIO port to provide a simple human machine interface to control the speed and direction of the motor. The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 pins in all, and they are used for a variety of different things. It isn’t important to remember what all the pins do, but it is important to note how they are numbered.

If necessary, prepare your Raspberry Pi by performing the following tasks:

Insert the prepared SD(HC) memory card into the card slot on the underside to the Raspberry Pi

Connect the USB Keyboard and Mouse to the two USB sockets

Connect the computer monitor or TV screen to the HDMI socket using the HDMI cable

However, do not connect the power supply to the Micro USB socket at this stage.

Page 2: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

2

Step 1 – Simple On/Off motor control In this exercise you will use your Raspberry Pi to turn a DC motor on and off, and control the direction of rotation of the motor by using the L293D motor control (H-Bridge) chip.

The L293D chip can control two motors independently (although you will use it to control just one motor), and it allows a separate power supply to be used for the motors to that used for the chip itself. This is important because the power available from the Raspberry Pi’s GPIO port is sufficient to power the chip, but it is not powerful enough to run a motor. There are three control inputs for each motor – Enable, Input A, and Input B. This allows the direction of the motor to be controlled as follows.

Enable Input A Input B Motor Behaviour

Off On or Off On or Off Stopped

On On Off Turn Forwards

On Off On Turn Backwards

On Off Off Stopped

On On On Stopped

Therefore the direction the motor turns depends on whether Input A or Input B is “On”, provided that Enable is “On”. If both Input A and Input B are “Off”, the motor is turned off, but the same is true if both Input A and Input B are “On”. If Enable is “Off” then it doesn’t matter what state Inputs A and B are in, the motor will always be turned off.

Page 3: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

3

Please make sure your Raspberry Pi is turned off and the power supply disconnected before proceeding. Build the circuit for this exercise by performing the following tasks:

Insert the L293D chip into the breadboard so that its pins straddle the gap down the centre of the breadboard

Connect one end of the Black wire to pin number 6 on the GPIO header and connect the other end to the ground rail on the left side of the breadboard

Connect one end of the Red wire to pin number 2 on the GPIO header and connect the other end to the power rail on the right side of the breadboard

Connect one end of the Orange wire to the power rail on the right side of the breadboard and connect the other end to the breadboard next to pin number 16 on the L293D chip

Connect one end of the Purple wire to the power rail on the right side of the breadboard and connect the other end to the breadboard next to pin number 9 on the L293D chip

Connect one end of the Black wire to the ground rail on the left side of the breadboard and connect the other end to the breadboard next to pin number 5 on the L293D chip

Connect one end of the Green wire to pin number 16 on the GPIO header and connect the other end to the breadboard next to pin number 15 on the L293D chip

Connect one end of the Blue wire to pin number 18 on the GPIO header and connect the other end to the breadboard next to pin number 10 on the L293D chip

Connect the motor to the breadboard so that one wire is next to pin number 11 on the L293D chip and the other wire is next to pin number 14 on the L293 chip. It isn’t important which war round you connect the motor wires

Connect the battery pack to the power rails down the left side of the breadboard so that the black wire is connected to the ground rail, and the red wire is connected to the power rail. Be careful not to short circuit the battery pack.

Connect one end of the Red wire to the power rail on the left side of the breadboard (which carries power from the battery pack) and connect the other end to the breadboard next to pin number 8 on the L293D chip

Page 4: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

4

The finished circuit is shown below.

Page 5: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

5

Connect the power supply to the Micro USB socket on the Raspberry Pi and turn the power supply on

Allow your Raspberry Pi to boot up and then log in and launch the Graphical User Interface (GUI). If you’re not sure how to do this please follow the instructions in Step 2 of the Setup Guide

Click on the LXDE icon on the bottom left corner of the screen – this will display the “Start Menu”

Click on “Run”

Page 6: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

6

You will now see the “Run” dialog box displayed in the centre of the screen.

Type “sudo idle3” in the Run dialog box and click “OK” or press Enter

Once the “Python Shell” window appears, do the following:

Type “import RPi.GPIO as GPIO” at the Python prompt and press Enter This imports the GPIO Python library so you can program the GPIO interface

Type “GPIO.setmode(GPIO.BOARD)” at the Python prompt and press Enter

This means that you can reference the GPIO header pins by their pin numbers

Type “GPIO.setup(16, GPIO.OUT)” at the Python prompt and press Enter

This sets GPIO pin number 16 as an Output pin

Type “GPIO.setup(18, GPIO.OUT)” at the Python prompt and press Enter

This sets GPIO pin number 18 as an Output pin

Type “GPIO.output(16, 0)” at the Python prompt and press Enter

This turns pin 16 “Off” (digital state “0”)

Page 7: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

7

Type “GPIO.output(18, 1)” at the Python prompt and press Enter

This turns pin 18 “On” (digital state “1”) When this line is typed in and Enter is pressed, the motor will start turning. Take note of what direction it is running

Type “GPIO.output(18, 0)” at the Python prompt and press Enter

This turns pin 18 “Off” (digital state “0”) When this line is typed in and Enter is pressed, the motor will stop turning

Type “GPIO.output(16, 1)” at the Python prompt and press Enter

This turns pin 16 “On” (digital state “1”) When this line is typed in and Enter is pressed, the motor will start turning again, but in the opposite direction.

Type “GPIO.output(16, 0)” at the Python prompt and press Enter

This turns pin 16 “Off” (digital state “0”) When this line is typed in and Enter is pressed, the motor will stop turning

You can carry on entering commands to turn the motor on and off if you want.

When you’re finished, click on “File” and then “Exit” to close the Python Shell window and exit IDLE3

Shutdown your Raspberry Pi (refer back to Step 4 of the Setup Guide if you can’t remember how to do this)

Page 8: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

8

Step 2 – Controlling the speed of the motor using Pulse Width Modulation (PWM) In the previous part of this exercise you were able to turn the motor on and off, and make it change direction. In this part of the exercise you are going to control the speed of the motor using Pulse Width Modulation (PWM). You might think that the best way to control the speed of a motor would be to vary the voltage, but using this method is problematic because it takes a minimum voltage to get the motor started, and if the voltage is then reduced to make the motor run slowly, the torque produced by the motor at low voltages is very small. A much better way of controlling the speed of the motor is to very quickly switch the power to the motor on and off. The comparative ratio of the time the power is on to the time the power is off is called the Duty Cycle and this determines the speed of the motor. The plot of voltage against time for duty cycles of 100%, 90%, 50%, 10% and 0% are as follows:

So for a duty cycle of 100%, the power is applied 100% of the time and the motor runs at full speed. For a duty cycle of 90%, the power is applied 90% of the time, so the power delivered to the motor is 90% of the maximum. For a duty cycle of 50%, the power is applied 50% of the time, so the power delivered to the motor is 50% of the maximum. For a duty cycle of 10%, the power is applied 10% of the time, so the power delivered to the motor is 10% of the maximum. For a duty cycle of 0%, the power is applied 0% of the time, or in other words the motor us turned off. The Raspberry Pi is capable of PWM output on GPIO pin number 12, and when the PWM signal is applied to the “Enable” pin on the L293D chip, the chip will modulate the power sent to the motor accordingly.

Page 9: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

9

Please make sure your Raspberry Pi is turned off and the power supply disconnected before proceeding. In this exercise you will use Pulse Width Modulation (PWM) to control the speed of the motor This exercise follows on from the previous exercise, so start with the circuit from the previous exercise and perform the following tasks:

Remove the Purple wire from the breadboard.

Connect one end of the Yellow wire to pin number 22 on the GPIO header and connect the other end to the breadboard next to pin number 9 on the L293D chip

The finished circuit is shown below.

Page 10: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

10

Connect the power supply to the Micro USB socket on the Raspberry Pi and turn the power supply on

Allow your Raspberry Pi to boot up and then log in and launch the Graphical User Interface (GUI). If you’re not sure how to do this please follow the instructions in Step 2 of the Setup Guide

Launch IDLE3 by typing “sudo idle3” in the Run dialog box as you did in the previous exercise (Step 1)

Page 11: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

11

In the previous exercise (Step 1) you entered Python commands directly at the Python prompt. This worked fine, but it meant that if you wanted to run a series of commands more than once, you had to type them in each time. In this exercise you will enter Python commands in to a file which you can save. This means that if you want to run the commands more than once, all you have to do is open the saved file and “Run” it.

In the Python Shell window, click on “File” and then “New Window”

Type the following Python commands into the new code window Import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.output(22,1) GPIO.output(16,0) GPIO.output(18, 1) time.sleep(5) GPIO.output(18, 0) time.sleep(2) GPIO.output(16,1) time.sleep(5) GPIO.output(16,0) GPIO.cleanup() Most of these lines of code should be familiar to you from the previous exercise (Step 1). The last line simply closes the GPIO port when the program has finished with it. This prevents error messages being generated next time the program is run

Click on “File” and then “Save”

Type “motor” into the Save dialog box and click “Save”

As soon as you do this you will notice the title of the code window change from “Untitled” to “motor.py - /home/pi/motor.py”

Page 12: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

12

Your code window should now look like this

Click on “Run” and then “Run Module”

After a short delay, the motor will run at full speed for a few seconds in one direction, pause for a short time, and then run at full speed for a few seconds in the opposite direction

Click anywhere on the code window to bring it to the front

Delete the line “GPIO.output(22,1)” and replace it with motor=GPIO.PWM(22,50) motor.start(10)

This sets up PWM on GPIO pin 22 with a frequency of 50 Hz, and starts the motor with a duty cycle to 10%

Insert the following line just before the “GPIO.cleanup()” line:

motor.stop() This stops the PWM output

Click on “File” and then “Save”

Page 13: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

13

Your code window should now look like this

Click on “Run” and then “Run Module”

After a short delay, the motor will run very slowly for a few seconds in one direction, pause for a short time, and then run very slowly for a few seconds in the opposite direction

You can try using different values for the duty cycle by changing the parameter of the “motor.start(X)” command. The higher the duty cycle, the more power will be delivered to the motor and the faster it will run.

Page 14: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

14

Now, suppose you wanted the motor to run forwards at duty cycle of 10% for 10 seconds, then pause for 1 second, then forwards with a duty cycle of 50% for 5 seconds, then pause for 1 second, then backwards at a duty cycle of 30% for 10 seconds, and then stop. The Python code for doing this is given below. Some comments have been added to make the code easier to follow. # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) motor=GPIO.PWM(22,50) # run motor forwards at 10% for 10 seconds motor.start(10) GPIO.output(16,0) GPIO.output(18,1) time.sleep(10) GPIO.output(18,0) motor.stop() # pause for 1 second time.sleep(1) # run motor forwards at 50% for 5 seconds motor.start(50) GPIO.output(16,0) GPIO.output(18,1) time.sleep(5) GPIO.output(18,0) motor.stop() # pause for 1 second time.sleep(1) # run motor backwards at 30% for 10 seconds motor.start(30) GPIO.output(18,0) GPIO.output(16,1) time.sleep(10) GPIO.output(16,0) motor.stop() # cleanup and close GPIO GPIO.cleanup() This Python code will work fine, and like all the code you have written so far, it is executed from the top, line by line, all the way to the bottom. Look at the code that makes the motor run forwards at 10% for 10 seconds, and then look at the code that makes the motor run forwards at 50% for 5 seconds. The code is identical, apart from some of the numbers inside the brackets. Instead of repeating blocks of code like this, it is much better to reorganize the code using functions. A function is a series of commands that performs the same operation on whatever parameters are passed to it, and can be thought of as a program within a program.

Page 15: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

15

For example, you can reorganize the Python code above by defining two functions – one to make the motor run forwards at a specified duty cycle for a specified time, and the other to make the motor run backwards at a specified duty cycle for a specified time. The resulting program is as follows. # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) motor=GPIO.PWM(22,50) # define a function to make motor run forwards # at duty cycle of "speed" for "duration" seconds def forwards(speed,duration): motor.start(speed) GPIO.output(16,0) GPIO.output(18,1) time.sleep(duration) GPIO.output(18,0) motor.stop() # define a function to make motor run backwards # at duty cycle of "speed" for "duration" seconds def backwards(speed,duration): motor.start(speed) GPIO.output(18,0) GPIO.output(16,1) time.sleep(duration) GPIO.output(16,0) motor.stop() # run motor forwards at 10% for 10 seconds forwards(10,10) # pause for 1 second time.sleep(1) # run motor forwards at 50% for 5 seconds forwards(50,5) # pause for 1 second time.sleep(1) # run motor backwards at 30% for 10 seconds backwards(30,10) # cleanup and close GPIO GPIO.cleanup()

Edit your existing code so that it is the same as shown above

Click on “File” and then “Save”

Page 16: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

16

Your code window should now look like this

Click on “Run” and then “Run Module”

After a short delay, the motor will run very slowly in one direction for about 10 seconds, pause, run much faster in the same direction for about 5 seconds, pause, run more slowly in the opposite direction for about 10 seconds and then stop

Using functions in this way can help simplify code and make it much easier to write and understand. By defining the “forwards(x,x)” and “backwards(x,x)” functions in the code above, the motor can be programmed to run at a specified speed for a specified time in a specified direction by a single line of code.

Try programming the motor to run at different speeds for different periods of time using the “forwards(x,x)” and “backwards(x,x)” functions

When you have finished, close the code window by clicking on “File” and then “Close”

If you have made any changes to the code since the last time you saved you will be asked if you want to save before closing

Click “Yes” if you want to save your changes, or “No” if you want to close without saving

Click on “File” and then “Exit” to close the Python Shell window and exit IDLE3

Shutdown your Raspberry Pi (refer back to Step 4 of the Setup Guide if you can’t remember how to do this)

Page 17: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

17

Step 3 – Adding a “User Interface” to allow direct control of the motor In the previous part of this exercise you programmed the motor to perform a predetermined sequence of operations, and to make any changes to the sequence of operations required that the Python code be changed accordingly. In this part of the exercise you will create a very simple user interface in the form of three pushbutton switches which will allow the user to directly control the motor and interact with it. This is an example of a simple human-machine interface as found in many modern electronic products. The function of the individual buttons may be changed by editing the Python code, but once the program is running the system will “wait” for the user to press one of the buttons and then perform the operation or sequence of operations assigned to that button. Please make sure your Raspberry Pi is turned off and the power supply disconnected before proceeding. In this exercise you will use three push button switches connected to the GPIO pins on your Raspberry Pi to directly control the motor

This exercise follows on from the previous exercise, so start with the circuit from the previous exercise and perform the following tasks:

Insert the three push button switches into the breadboard so that they straddle the gap down the centre of the breadboard

Connect one end of the Orange wire to pin number 1 on the GPIO header and connect the other end to the power rail on the right side of the breadboard

Connect one end of the Grey wire to the power rail down the right side of the breadboard and connect the other end to the breadboard next to the bottom right terminal of the lowermost push button switch

Connect one end of the Purple wire to the power rail down the right side of the breadboard and connect the other end to the breadboard next to the bottom right terminal of the middle push button switch

Connect one end of the Brown wire to the power rail down the right side of the breadboard and connect the other end to the breadboard next to the bottom right terminal of the uppermost push button switch

Connect one end of the Grey wire to pin number 11 on the GPIO header and connect the other end to the breadboard next to the top left terminal of the lowermost push button switch

Connect one end of the Purple wire to pin number 13 on the GPIO header and connect the other end to the breadboard next to the top left terminal of the middle push button switch

Connect one end of the Brown wire to pin number 15 on the GPIO header and connect the other end to the breadboard next to the top left terminal of the uppermost push button switch

Insert a 10K Ohm (10,000 Ohm) resistor into the breadboard so that one end connects with the Grey wire going to pin number 11 on the GPIO header and the other end connects to the ground rail on the left side of the breadboard

Page 18: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

18

Insert a 10K Ohm (10,000 Ohm) resistor into the breadboard so that one end connects with the Purple wire going to pin number 13 on the GPIO header and the other end connects to the ground rail on the left side of the breadboard

Insert a 10K Ohm (10,000 Ohm) resistor into the breadboard so that one end connects with the Brown wire going to pin number 15 on the GPIO header and the other end connects to the ground rail on the left side of the breadboard

The finished circuit is shown below.

Connect the power supply to the Micro USB socket on the Raspberry Pi and turn the power supply on

Allow your Raspberry Pi to boot up and then log in and launch the Graphical User Interface (GUI). If you’re not sure how to do this please follow the instructions in Step 2 of the Setup Guide

Launch IDLE3 by typing “sudo idle3” in the Run dialog box as you did in the previous exercises (Steps 1 & 2)

Page 19: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

19

In the Python Shell window, click on “File” and then “Open”

Then select your previously saved file called “motor.py” and click “Open”

Click on “File” and then “Save As…”

Type “motorinterface” into the Save dialog box and click “Save”

Edit the existing code by copying, pasting, deleting and inserting until your code listing looks like this # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setup(11, GPIO.IN) GPIO.setup(13, GPIO.IN) GPIO.setup(15, GPIO.IN) motor=GPIO.PWM(22,50) # prepare to start motor motor.start(50) GPIO.output(16,0) GPIO.output(18,0) print("Press Ctrl+C to exit") # wait for user input try: while True: if (GPIO.input(11)): # run motor forwards GPIO.output(16,1) if (GPIO.input(13)): # turn motor off GPIO.output(16,0) GPIO.output(18,0) if (GPIO.input(15)): # run motor backwards GPIO.output(18,1) # stop motor and cleanup GPIO except KeyboardInterrupt: print("Exiting now...") motor.stop() GPIO.cleanup()

Click on “File” and then “Save” Most of the Python code you have just entered should be familiar to you from previous parts of this exercise of from previous exercises. The “while Ture:” statement sets up an infinite loop and the code within the loop will be executed repeatedly until the user interrupts the loop by pressing “Ctrl + C”. The code within the loop checks if any of the buttons are pressed by reading the state of GPIO pins 11, 13 and 15, and if a button is pressed, the appropriate code within the “if” statement is executed.

Page 20: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

20

The “while” loop is placed inside a try clause to allow you to deal with the exception (or error) that is generated when the user terminates the program by pressing “Ctrl+C”. The error handling code is placed within the except clause, and in this case the code simply informs the user that the program is exiting (by printing a message on the Python Shell window), stops the motor, and cleans up the GPIO port (which prevents error messages being generated next time the program is run).

Your code window should now look like this

Click on “Run” and then “Run Module”

After a short delay the message “Press Ctrl+C to exit” appears in the Python Shell window. The program is now running and waiting for user input.

Press the uppermost button - the motor will start turning

Press the middle button - the motor will stop turning

Press the lowermost button - the motor will start turning in the opposite direction

What do you think will happen if you press the uppermost button while the motor is running?

Have a look back at the Python code and at the way the L293D chip’s inputs are used to control the motor and see if you can figure out what will happen

Now go ahead and press the uppermost and see what happens…

Was it what you expected to happen?

Page 21: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

21

You might have expected the direction of rotation of the motor to have instantly reversed, but instead the motor stopped. This is due to the way the L293D chip controls the motor according to the state of the two inputs “A” and “B”

Enable Input A Input B Motor Behaviour

Off On or Off On or Off Stopped

On On Off Turn Forwards

On Off On Turn Backwards

On Off Off Stopped

On On On Stopped

When you press the lowermost button (which is connected to GPIO pin 11), GPIO pin 16 is turned “On” and this pin is connected to input “A” on the L293D chip. If you now press the uppermost button (which is connected to GPIO pin 15), GPIO pin 18 is turned “On” and this pin is connected to input “B” on the L293D chip. Therefore the end result is that both inputs “A” and “B” on the L293D chip are “On” and this turns the motor off. The only way now to get the motor running again is to press the middle button (which will turn both inputs “A” and “B” on the L293D chip “Off”) and then press either of the other two buttons to start the motor.

Press the middle button to “reset” the motor controls.

Now press one of the other two buttons make the motor start turning again

When you have finished, press Ctrl+C (i.e. press and hold the “Ctrl” key, and at the same time press the “C” key) to exit the program

The message “Exiting now…” will be displayed on the Python Shell window

Click anywhere on the code window to bring it to the front You have programmed the buttons to allow the user to start and stop the motor in either direction. At the moment, however, the duty cycle (or speed of the motor) is set in the Python code to 50 and can not be changed via the user interface. Suppose instead you want the user to be able to control the speed of the motor using the buttons. There are three buttons available, so the first thing to do is to decide which function to assign to each of the buttons. One simple way of achieving this would be to assign the following functions to the buttons: Uppermost Button Increase speed of the motor each time button is pressed

If motor is stopped (speed=0), motor will start at low speed If motor is already at maximum speed (speed=100), motor remains at maximum speed

Middle Button Emergency Stop Lowermost Button Decrease speed of the motor each time button is pressed If motor is stopped (speed=0), motor remains stopped Simply writing down what you want to achieve can help when it comes to writing the Python code. It can also be very helpful to write what you want to achieve in the form of a System Flowchart, which is a graphical representation of how the program is executed and the different paths that may be taken depending on user input or the value of various variables. A simplified flowchart for the modified user interface is shown on the following page.

With the help of the description of the desired behaviour and the system flowchart on the following page, see if you can edit the Python code to reprogram the user interface (buttons) so that the user can increase and decrease the speed of the motor

Page 22: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

22

Upper Button

Pressed?

Middle Button

Pressed?

Lower Button

Pressed?

Ctrl+C

Pressed?

Speed=0

Set Speed

START

Increase Speed

(max=100)

Sleep 0.05s

Set Speed

Decrease Speed (min=0)

Set Speed

While True

STOP

Yes

No

Yes

No

No

No

Yes

Yes

Page 23: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

23

Here is the code for the reprogrammed user interface # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setup(11, GPIO.IN) GPIO.setup(13, GPIO.IN) GPIO.setup(15, GPIO.IN) motor=GPIO.PWM(22,50) # prepare to start motor speed=0 # new motor.start(speed) # changed GPIO.output(16,1) # changed GPIO.output(18,0) print("Press Ctrl+C to exit") # wait for user input try: while True: if (GPIO.input(11)): # decrese speed # changed speed=speed-1 # new if (speed<0): # new speed=0 # new motor.ChangeDutyCycle(speed) # new if (GPIO.input(13)): # emergency stop # changed speed=0 # new motor.ChangeDutyCycle(speed) # new if (GPIO.input(15)): # increase speed # changed speed=speed+1 # new if (speed>100): # new speed=100 # new motor.ChangeDutyCycle(speed) # new time.sleep(0.05) # new # stop motor and cleanup GPIO except KeyboardInterrupt: print("Exiting now...") motor.stop() GPIO.cleanup() Most of the Python code above is fairly straightforward. The only statement that you haven’t come across before is the “motor.ChangeDutyCycle(speed)” statement which allows you to change the duty cycle of the PWM (and hence the speed of the motor) while the motor is running

Edit the existing code by copying, pasting, deleting and inserting until your code listing looks like as shown above. I have indicated where new lines of code have been inserted, and where existing lines of code have been changed to help you, but you do not need to include these comments

Page 24: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

24

Click on “File” and then “Save”

Click on “Run” and then “Run Module”

After a short delay the message “Press Ctrl+C to exit” appears in the Python Shell window. The program is now running and waiting for user input.

Press and hold the uppermost button

The motor will start running and increase in speed for as long as you hold the button down, or until it reaches its maximum speed

Press and hold the lowermost button

The motor will slow down for as long as you hold the button down, or until it stops completely

Start the motor again by pressing and holding the uppermost button until you reach the desired speed

Press the middle button

The motor will stop immediately

Continue to investigate the human machine interface to satisfy yourself that the buttons are controlling the motor in the way you expect them to.

When you have finished, press Ctrl+C (i.e. press and hold the “Ctrl” key, and at the same time press the “C” key) to exit the program

The message “Exiting now…” will be displayed on the Python Shell window

Click anywhere on the code window to bring it to the front

Now see if you can reprogram the user interface so that when you press the middle button, the motor not only stops immediately if it is running, but also when it is started again (by pressing the uppermost button) it turns in the opposite direction

This requires the inputs “A” and “B” to the L293D chip to be reversed. In other words, if input “A” is “On” and input “B” is “Off”, to change the direction of rotation of the motor requires that input “A” is “Off” and input “B” is “On”. Inputs “A” and “B” to the L293D chip are connected to GPIO pins 16 and 18 respectively, so to make the motor change direction you have to find a way of reversing the state of GPIO pins 16 and 18. To “read” the state of an output pin you can use the command “GPIO.input(x)” where “x” is the GPIO pin number, and to reverse the state of the pin (i.e. turn it “Off if it is “On”, or turn it “On” if it is “Off” you can use the operator “not”. Therefore to reverse the state of GPIO pins 16 and 18, you can use the following commands:

GPIO.output(16, (not GPIO.input(16))) GPIO.output(18, (not GPIO.input(18)))

Insert the two lines of code in the “if (GPIO.input(13)):” clause after the line “motor.ChangeDutyCycle(speed)”

Page 25: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

25

Your code should now look like this. I have indicated where new lines of code have been inserted but you do not need to include these comments # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setup(11, GPIO.IN) GPIO.setup(13, GPIO.IN) GPIO.setup(15, GPIO.IN) motor=GPIO.PWM(22,50) # prepare to start motor speed=0 motor.start(speed) GPIO.output(16,1) GPIO.output(18,0) print("Press Ctrl+C to exit") # wait for user input try: while True: if (GPIO.input(11)): # decrese speed speed=speed-1 if (speed<0): speed=0 motor.ChangeDutyCycle(speed) if (GPIO.input(13)): # emergency stop and change direction # changed speed=0 motor.ChangeDutyCycle(speed) GPIO.output(16, (not GPIO.input(16))) # new GPIO.output(18, (not GPIO.input(18))) # new if (GPIO.input(15)): # increase speed speed=speed+1 if (speed>100): speed=100 motor.ChangeDutyCycle(speed) time.sleep(0.05) # stop motor and cleanup GPIO except KeyboardInterrupt: print("Exiting now...") motor.stop() GPIO.cleanup()

Click on “File” and then “Save”

Click on “Run” and then “Run Module”

After a short delay the message “Press Ctrl+C to exit” appears in the Python Shell window. The program is now running and waiting for user input.

Page 26: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

26

Press and hold the uppermost button

The motor will start running and increase in speed for as long as you hold the button down, or until it reaches its maximum speed

Press the middle button

The motor will stop immediately

Press and hold the uppermost button

The motor will start running in the opposite direction and increase in speed for as long as you hold the button down, or until it reaches its maximum speed

Try stopping and reversing the direction of the motor a few times.

Does it work consistently?

You should find that sometimes the motor changes direction, and sometimes it doesn’t! The reason for this behaviour is that the code in the if (GPIO.input(13)):” clause will be executed on each cycle of the “while” loop as long as the middle button is pressed, and if the button is pressed long enough for the “wjile” loop to go through two cycles, the direction will first be reversed, and then reversed again, meaning that the direction of rotation of the motor will be back to where it was originally.

See if you can come up with a way to solve this problem There may be a number of ways to solve the problem, but one very simple way would be to add a short delay directly after the GPIO output pins are reversed. This should give time for the user to release the middle button before the “while” loop has time to cycle round again. It would also be a good idea to tell the user that the direction of rotation of the motor has been changed by printing a message on the Python Shell window

Insert the following two lines of code after “GPIO.output(18, (not GPIO.input(18)))”

print("Changing direction...") time.sleep(1)

Page 27: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

27

Your code should now look like this. I have indicated where new lines of code have been inserted but you do not need to include these comments # import modules import time import RPi.GPIO as GPIO # setup GPIO and PWM GPIO.setmode(GPIO.BOARD) GPIO.setup(16, GPIO.OUT) GPIO.setup(18, GPIO.OUT) GPIO.setup(22, GPIO.OUT) GPIO.setup(11, GPIO.IN) GPIO.setup(13, GPIO.IN) GPIO.setup(15, GPIO.IN) motor=GPIO.PWM(22,50) # prepare to start motor speed=0 motor.start(speed) GPIO.output(16,1) GPIO.output(18,0) print("Press Ctrl+C to exit") # wait for user input try: while True: if (GPIO.input(11)): # decrese speed speed=speed-1 if (speed<0): speed=0 motor.ChangeDutyCycle(speed) if (GPIO.input(13)): # emergency stop and change direction speed=0 motor.ChangeDutyCycle(speed) GPIO.output(16, (not GPIO.input(16))) GPIO.output(18, (not GPIO.input(18))) print("Changing direction...") # new time.sleep(1) # new if (GPIO.input(15)): # increase speed speed=speed+1 if (speed>100): speed=100 motor.ChangeDutyCycle(speed) time.sleep(0.05) # stop motor and cleanup GPIO except KeyboardInterrupt: print("Exiting now...") motor.stop() GPIO.cleanup()

Click on “File” and then “Save”

Click on “Run” and then “Run Module”

Page 28: Setting up your Raspberry Pi - RS Online · The GPIO pins are located at one corner of the Raspberry Pi, as shown below. There are 26 ... In the previous part of this ... Allow your

Student Workbook

28

After a short delay the message “Press Ctrl+C to exit” appears in the Python Shell window. The program is now running and waiting for user input

Investigate the behaviour of the system and check that it behaves in the way you expect it to

You should find now that pressing the middle button consistently causes the direction of rotation of the motor to reverse, and that each time the middle button is pressed, the message “Changing direction…” is displayed on the Python Shell window

When you have finished, press Ctrl+C (i.e. press and hold the “Ctrl” key, and at the same time press the “C” key) to exit the program

The message “Exiting now…” will be displayed on the Python Shell window

Click anywhere on the code window to bring it to the front

Now see if you can reformat the Python code by defining functions for “increasespeed”, “decreasespeed” and “stopandchangedirection” and calling these functions from within the “while” loop. Refer back to the previous part of this exercise (Step 2) if you can’t remember how to define a function

When you have finished running your modified code, press Ctrl+C (i.e. press and hold the “Ctrl” key, and at the same time press the “C” key) to exit the program

Click anywhere on the code window to bring it to the front

Close the code window by clicking on “File” and then “Close”

If you have made any changes to the code since the last time you saved you will be asked if you want to save before closing

Click “Yes” if you want to save your changes, or “No” if you want to close without saving

Click on “File” and then “Exit” to close the Python Shell window and exit IDLE3

Shutdown your Raspberry Pi (refer back to Step 4 of the Setup Guide if you can’t remember how to do this)