ReverseKeyBorg - Turn your PiCy into a PiCy Type R
So you have RemoteKeyBorg, but you want to be able to have your PicoBorg based robot able to reverse?
Well the answer is to add some relays and get yourself ReverseKeyBorg.
ReverseKeyBorg is a replacement for the client half of RemoteKeyBorg, which is set up to drive two pairs of relays to give us both forward and reverse control on two wheels.
You will need to add a total of four single-pole double-throw relays (often called SPDT relays) to the circuit, one for each drive output.
We sell appropriate relays in pairs, remember to buy two pairs, not just one ;¬)
The new relays should be connected like so:
Click to enlarge
When done each motor should be connected to a pair of relays, and all four relays should be controlled from the PicoBorg.
Now your PiCy is a bona fide PiCy Type R :D
Since this script replaces the functionality of RemoteKeyBorgC.py, you will need to have RemoteKeyBorgS.py running on the Pi connected to your picoBorg.
Here's the code, you can download the RemoteKeyBorgS script file as text here.
Save the text file on your Raspberry Pi as RemoteKeyBorgS.py
Make the script executable using
and run on the Raspberry Pi with the PicoBorg using
Now we have sorted out the wiring, we need to download the script code:
Now we are all ready, run the script using:
on Linux or you favoured method under Windows.
The settings in ReverseKeyBorgC.py are similar to RemoteKeyBorgC.py, if the communications are not working you may need to change the network settings as outlined in RemoteKeyBorg, note that some of the line numbers will be close but different.
If motors are turning the wrong way, the following procedure should correct the problem:
If you have problems with the Raspberry Pi restarting when you try and move a motor, you may need to add resistors in series with the motors as shown in the main PiCy article.
You can download ReverseKeyBorgC.py as text here.
Well the answer is to add some relays and get yourself ReverseKeyBorg.
ReverseKeyBorg is a replacement for the client half of RemoteKeyBorg, which is set up to drive two pairs of relays to give us both forward and reverse control on two wheels.
Adding the relays to PiCy
You will need to add a total of four single-pole double-throw relays (often called SPDT relays) to the circuit, one for each drive output.
We sell appropriate relays in pairs, remember to buy two pairs, not just one ;¬)
The new relays should be connected like so:
When done each motor should be connected to a pair of relays, and all four relays should be controlled from the PicoBorg.
Now your PiCy is a bona fide PiCy Type R :D
Setting up the Raspberry Pi
Since this script replaces the functionality of RemoteKeyBorgC.py, you will need to have RemoteKeyBorgS.py running on the Pi connected to your picoBorg.
Here's the code, you can download the RemoteKeyBorgS script file as text here.
Save the text file on your Raspberry Pi as RemoteKeyBorgS.py
Make the script executable using
chmod +x RemoteKeyBorgS.py
and run on the Raspberry Pi with the PicoBorg using
sudo ./RemoteKeyBorgS.py
Get the script running
Now we have sorted out the wiring, we need to download the script code:
cd ~ wget -O ReverseKeyBorgC.py http://www.piborg.org/downloads/ReverseKeyBorgC.txt chmod +x ReverseKeyBorgC.pyAlternatively download the code here, and save the file as ReverseKeyBorgC.py, on Linux you will also need to make the script executable
Now we are all ready, run the script using:
~/ReverseKeyBorgC.py
on Linux or you favoured method under Windows.
Checking things are working
The settings in ReverseKeyBorgC.py are similar to RemoteKeyBorgC.py, if the communications are not working you may need to change the network settings as outlined in RemoteKeyBorg, note that some of the line numbers will be close but different.
If motors are turning the wrong way, the following procedure should correct the problem:
- Press and hold
UP
:
- If the left wheel goes the wrong way, swap the drive numbers for
leftDrivePos
andleftDriveNeg
. - If the right wheel goes the wrong way, swap the drive numbers for
rightDrivePos
andrightDriveNeg
. - If you made any changes, re-run the script and try again, if problems persist swap
leftDrivePos
withrightDrivePos
andleftDriveNeg
withrightDriveNeg
and start from the top of this list again.
- If the left wheel goes the wrong way, swap the drive numbers for
- Press and hold
LEFT
, if the left wheel is going forward (PiCy rotates to the right) swapleftDrivePos
withrightDrivePos
andleftDriveNeg
withrightDriveNeg
and start from the top of this list again.
If you have problems with the Raspberry Pi restarting when you try and move a motor, you may need to add resistors in series with the motors as shown in the main PiCy article.
The source
You can download ReverseKeyBorgC.py as text here.
#!/usr/bin/env python # coding: Latin-1 # Load library functions we want import socket import time import pygame # Settings for the ReverseKeyBorg client broadcastIP = '192.168.0.255' # IP address to send to, 255 in one or more positions is a broadcast / wild-card broadcastPort = 9038 # What message number to send with (LEDB on an LCD) leftDrivePos = 1 # Drive number for left motor positive relay leftDriveNeg = 2 # Drive number for left motor negative relay rightDrivePos = 3 # Drive number for right motor positive relay rightDriveNeg = 4 # Drive number for right motor negative relay interval = 0.1 # Time between keyboard updates in seconds, smaller responds faster but uses more processor time regularUpdate = True # If True we send a command at a regular interval, if False we only send commands when keys are pressed or released # Setup the connection for sending on sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # Create the socket sender.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Enable broadcasting (sending to many IPs based on wild-cards) sender.bind(('0.0.0.0', 0)) # Set the IP and port number to use locally, IP 0.0.0.0 means all connections and port 0 means assign a number for us (do not care) # Setup pygame and key states global hadEvent global moveUp global moveDown global moveLeft global moveRight global moveQuit hadEvent = True moveUp = False moveDown = False moveLeft = False moveRight = False moveQuit = False pygame.init() screen = pygame.display.set_mode([300,300]) pygame.display.set_caption("RemoteKeyBorg - Press [ESC] to quit") # Function to handle pygame events def PygameHandler(events): # Variables accessible outside this function global hadEvent global moveUp global moveDown global moveLeft global moveRight global moveQuit # Handle each event individually for event in events: if event.type == pygame.QUIT: # User exit hadEvent = True moveQuit = True elif event.type == pygame.KEYDOWN: # A key has been pressed, see if it is one we want hadEvent = True if event.key == pygame.K_UP: moveUp = True elif event.key == pygame.K_DOWN: moveDown = True elif event.key == pygame.K_LEFT: moveLeft = True elif event.key == pygame.K_RIGHT: moveRight = True elif event.key == pygame.K_ESCAPE: moveQuit = True elif event.type == pygame.KEYUP: # A key has been released, see if it is one we want hadEvent = True if event.key == pygame.K_UP: moveUp = False elif event.key == pygame.K_DOWN: moveDown = False elif event.key == pygame.K_LEFT: moveLeft = False elif event.key == pygame.K_RIGHT: moveRight = False elif event.key == pygame.K_ESCAPE: moveQuit = False try: print 'Press [ESC] to quit' # Loop indefinitely while True: # Get the currently pressed keys on the keyboard PygameHandler(pygame.event.get()) if hadEvent or regularUpdate: # Keys have changed, generate the command list based on keys hadEvent = False driveCommands = ['X', 'X', 'X', 'X'] # Default to do not change if moveQuit: break elif moveLeft: # Left in reverse, right in forward driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'ON' driveCommands[rightDrivePos - 1] = 'ON' driveCommands[rightDriveNeg - 1] = 'OFF' elif moveRight: # Left in forward, right in reverse driveCommands[leftDrivePos - 1] = 'ON' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 1] = 'ON' elif moveUp: # Both in forward driveCommands[leftDrivePos - 1] = 'ON' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'ON' driveCommands[rightDriveNeg - 1] = 'OFF' elif moveDown: # Both in reverse driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'ON' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 1] = 'ON' else: # None of our expected keys, stop driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 1] = 'OFF' # Send the drive commands command = '' for driveCommand in driveCommands: command += driveCommand + ',' command = command[:-1] # Strip the trailing comma sender.sendto(command, (broadcastIP, broadcastPort)) # Wait for the interval period time.sleep(interval) # Inform the server to stop sender.sendto('ALLOFF', (broadcastIP, broadcastPort)) except KeyboardInterrupt: # CTRL+C exit, inform the server to stop sender.sendto('ALLOFF', (broadcastIP, broadcastPort))