Connect the switches to the GPIO using a method similar to the one we used in Chapter 9, Using Python to Drive Hardware, for the D-Pad controller. A circuit diagram of the switches is as follows:
How you connect to the Raspberry Pi's GPIO will depend on how your motor/servo drive is wired up. For example, a Rover-Pi robot with an H-bridge motor controller can be wired up as follows:
Control side of the module – connecting to the Raspberry Pi GPIO header |
|||||||
ENA |
IN1 |
IN2 |
IN3 |
IN4 |
ENB |
GND |
5V |
None |
Pin 15 |
Pin 16 |
Pin 18 |
Pin 22 |
None |
Pin 6 |
None |
Four additional proximity/collision sensors can be connected to the Raspberry Pi GPIO
as follows:
Proximity/collision sensors – connecting to the Raspberry Pi GPIO header |
|||||||
R_FWD |
L_FWD |
R_BWD |
L_BWD |
GND |
|||
Pin 7 |
Pin 11 |
Pin 12 |
Pin 13 |
Pin 6 |
If you wired it differently, you can adjust the pin numbers within the code, as required. If you require additional pins, then any of the multipurpose pins, such as RS232 RX/TX (pins 8 and 10) or the SPI/I2C, can be used as normal GPIO pins, too; just set them as input or output, as normal. Normally, we just avoid using them, as they are often more useful for expansion and other things, so it is sometimes useful to keep them available.
You can even use a single GPIO pin for all your sensors if you are just using the following example code, since the action is the same, regardless of which sensor is triggered. However, by wiring each one separately, you can adjust your strategy based on where the obstacle is around the robot or provide additional debug information about which sensor has been triggered.
Create the following avoidance.py script:
#!/usr/bin/env python3 #avoidance.py import rover_drive as drive import wiringpi2 import time opCmds={'f':'bl','b':'fr','r':'ll','l':'rr','#':'#'} PINS=[7,11,12,13] # PINS=[L_FWD,L_BWD,R_FWD,R_BWD] ON=1;OFF=0 IN=0;OUT=1 PULL_UP=2;PULL_DOWN=1 class sensor: # Constructor def __init__(self,pins=PINS): self.pins = pins self.GPIOsetup() def GPIOsetup(self): wiringpi2.wiringPiSetupPhys() for gpio in self.pins: wiringpi2.pinMode(gpio,IN) wiringpi2.pullUpDnControl(gpio,PULL_UP) def checkSensor(self): hit = False for gpio in self.pins: if wiringpi2.digitalRead(gpio)==False: hit = True return hit def main(): myBot=drive.motor() mySensors=sensor() while(True): print("Enter CMDs [f,b,r,l,#]:") CMD=input() for idx,char in enumerate(CMD.lower()): print("Step %s of %s: %s"%(idx+1,len(CMD),char)) myBot.cmd(char,step=0.01)#small steps hit = mySensors.checkSensor() if hit: print("We hit something on move: %s Go: %s"%(char, opCmds[char])) for charcmd in opCmds[char]: myBot.cmd(charcmd,step=0.02)#larger step if __name__ == '__main__': try: main() except KeyboardInterrupt: print ("Finish") #End