Archive for February 2017

Stepper Motor Control Service

Today I have been busy developing a stepper motor service class. The service class will allow the Team Seaford robot to play crazy golf.




import RPi.GPIO as GPIO
import time

class ServiceStepMotor:

  PinPhase1 = 14
  PinPhase2 = 15
  PinPhase3 = 17
  PinPhase4 = 16
  
  Steps = [
  [1,0,0,0],
  [1,1,0,0],
  [0,1,0,0],
  [0,1,1,0],
  [0,0,1,0],
  [0,0,1,1],
  [0,0,0,1],
  [1,0,0,1]
  ]

  StepIndex = 0
  
  MotorOnTime = 0.05  
  
  ## Constructor
  # @param self Class pointer
  def __init__(self):
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    
    self.SetPinToOutput(self.PinPhase1)
    self.SetPinToOutput(self.PinPhase2)
    self.SetPinToOutput(self.PinPhase3)
    self.SetPinToOutput(self.PinPhase4)
    pass

  ## Change pin type to output
  # @param self Class pointer
  # @param pin Pin Number  
  def SetPinToOutput(self, pin):
    GPIO.setup(pin,GPIO.OUT)
    self.Off(pin)
    pass
  
  ## Turn output pin On
  # @param self Class pointer
  # @param pin Pin Number  
  def On(self, pin):
    print "On="+str(pin)
    GPIO.output(pin,1)
    pass

  ## Turn output pin off
  # @param self Class pointer
  # @param pin Pin Number
  def Off(self, pin):
    GPIO.output(pin, 0)
    pass
  
  ## Change the output state of a pin
  # @param self Class pointer
  # @param PinNumber GPIO pin number
  # @param PinValue The new value for the GPIO pin  
  def ChangeOuput(self, PinNumber, PinValue):
    GPIO.output(PinNumber, PinValue)  
    pass
  
  ## Move stepper motor
  # @param self Class Pointer
  # @param Direction 1 = Forwards, 0 = Backwards
  def Step(self, direction):
    
    # Increment / decrement step count based on direction
    if (direction):
      # forward
      self.StepIndex += 1
    else:
      # backwards
      self.StepIndex -= 1
    
    # Check if we have passed the end of the steps list  
    if (self.StepIndex >= len(self.Steps)):
      self.StepIndex = 0
    
    # Check if we have reached the start of the steps list
    if (self.StepIndex < 0):
      self.StepIndex = len(self.Steps) - 1
      
    # Set output pin states
    print "StepIndex=" + str(self.StepIndex)
    phase = self.Steps[self.StepIndex]
    self.ChangeOuput(self.PinPhase1, phase[0])
    self.ChangeOuput(self.PinPhase2, phase[1])
    self.ChangeOuput(self.PinPhase3, phase[2])
    self.ChangeOuput(self.PinPhase4, phase[3])
    #for i in range(len(phase)):
    #  self.On(phase[i])
    
    # Delay while motor turns
    time.sleep(self.MotorOnTime)
    pass

The example code below shows how to use the stepper motor service class.

import ServiceStepMotor
sm = ServiceStepMotor.ServiceStepMotor()

print"Start"

print "Step forwards 10 steps"
for i in range(10):
  print "Step forward " + str(i)
  sm.Step(True)
  
print "Step backwards 10 steps"
for i in range(10):
  print "Step backward " + str(i)
  sm.Step(False)
  
print "Finish" 

Pairing PS3 Controller with Raspberry Pi

We used WIFI to control our 2015 Pi Wars robot. Using WIFI was a big mistake. On the day of the competition, there was too much interference and lag. We have learnt from our mistakes. This time we will be using Bluetooth.

We have connected a USB Bluetooth dongle to the Raspberry Pi and using the instructions below connected a Sony Playstation Six Axis Controller.

  • Using micro usb cable plug in the PS3 controller into the raspberry pi
  • Enter the command sudo ./sixpair
  • Disconnect USB cable from PS3 controller
  • Enter the command bluetoothctl
  • Enter the command devices
  • Enter the command agenton
  • Enter the command trust followed by the MAC address of the controller. In my case the MAC address is 00:06:F5:C4:01:3b.
    trust 00:06:F5:C4:01:3b
  • Disconnect the usb cable
  • Press the PS button the top of the controller
  • Confirm the new input device has been succesffully added. Enter the command sudo ls /dev/input you should see JS0 has been added to the list of input devices

Moving Forwards


Our robot is alive and moving. At the heart of the Team Seaford robot control is the ServiceIo class. The ServiceIo class is responsible for controlling the four drive motors. Each motor is connected to a H bridge motor controller. The H bridge controllers require two inputs per motor. The inputs control the direction of travel.

import RPi.GPIO as GPIO
import time

class ServiceIo:
  MotorOnTime = 0.01
  
  # GPIO Pin Numbers
  PinDriveFrontLeftForward = 5    # flf
  PinDriveFrontLeftBackward = 13  # flb
  PinDriveFrontRightForward = 11  # frf
  PinDriveFrontRightBackward = 12 # frb
  PinDriveBackLeftForward = 9     # blf
  PinDriveBackLeftBackward = 10   # blb
  PinDriveBackRightForward = 7    # brf
  PinDriveBackRightBackward = 8   # brb

  ## Constructor
  # @param self Class pointer
  def __init__(self):
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    
    self.SetPinToOutput(self.PinDriveFrontLeftForward)
    self.SetPinToOutput(self.PinDriveFrontLeftBackward)
    self.SetPinToOutput(self.PinDriveFrontRightForward)
    self.SetPinToOutput(self.PinDriveFrontRightBackward)
    self.SetPinToOutput(self.PinDriveBackLeftForward)
    self.SetPinToOutput(self.PinDriveBackLeftBackward)
    self.SetPinToOutput(self.PinDriveBackRightForward)
    self.SetPinToOutput(self.PinDriveBackRightBackward)
    pass
  
  ## Change pin type to output
  # @param self Class pointer
  # @param pin Pin Number  
  def SetPinToOutput(self, pin):
    GPIO.setup(pin,GPIO.OUT)
    self.Off(pin)
    pass
  
  ## Turn output pin On
  # @param self Class pointer
  # @param pin Pin Number  
  def On(self, pin):
    print "On="+str(pin)
    GPIO.output(pin,1)
    pass

  ## Turn output pin off
  # @param self Class pointer
  # @param pin Pin Number
  def Off(self, pin):
    GPIO.output(pin, 0)
    pass
  
  ## Stop all drive motors
  # @param self Class pointer
  def DriveStop(self):
    self.Off(self.PinDriveFrontLeftForward) 
    self.Off(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackRightForward)
    self.Off(self.PinDriveBackRightBackward) 
    pass
  
  ## Drive Forward
  # @param self Class pointer
  def DriveForward(self):
    self.On(self.PinDriveFrontLeftForward)
    self.On(self.PinDriveFrontRightForward)
    self.On(self.PinDriveBackLeftForward)
    self.On(self.PinDriveBackRightForward)
    self.Off(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackRightBackward)
    time.sleep(self.MotorOnTime)
    pass

  ## Drive Backward
  # @param self Class pointer
  def DriveBackward(self):
    self.On(self.PinDriveFrontLeftBackward)
    self.On(self.PinDriveFrontRightBackward)
    self.On(self.PinDriveBackLeftBackward)
    self.On(self.PinDriveBackRightBackward)
    self.Off(self.PinDriveFrontLeftForward)
    self.Off(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackRightForward)
    time.sleep(self.MotorOnTime)
    pass
    
  ## Drive Left
  # @param self Class pointer
  def DriveLeft(self):
    self.On(self.PinDriveFrontLeftForward)
    self.Off(self.PinDriveFrontLeftBackward)
    self.On(self.PinDriveBackLeftForward)
    self.Off(self.PinDriveBackLeftBackward)
    self.On(self.PinDriveFrontRightBackward)
    self.Off(self.PinDriveFrontRightForward)
    self.On(self.PinDriveBackRightBackward)
    self.Off(self.PinDriveBackRightForward)
    time.sleep(self.MotorOnTime)
    pass
      
  ## Drive Right
  # @param self Class pointer
  def DriveRight(self):
    self.On(self.PinDriveFrontRightForward)
    self.Off(self.PinDriveFrontRightBackward)
    self.On(self.PinDriveBackRightForward)
    self.Off(self.PinDriveBackRightBackward)
    self.On(self.PinDriveFrontLeftBackward)
    self.Off(self.PinDriveFrontLeftForward)
    self.On(self.PinDriveBackLeftBackward)
    self.Off(self.PinDriveBackLeftForward)
    time.sleep(self.MotorOnTime)
    pass

The following code show how to use the ServiceIo within a simple program, which responds to user input from the keyboard.

import ServiceIo
import time

io = ServiceIo.ServiceIo()
io.DriveStop()


while True:
  mode = raw_input('Direction (f,b,l,r:')
  if (mode == 'f'):
    io.DriveForward()

  if(mode == 'b'):
    io.DriveBackward()

  if(mode=='l'):
    io.DriveLeft()

  if(mode=='r'):
    io.DriveRight()

  time.sleep(2)
  print("off")
  io.DriveStop()

Configuring a Static IP Address on the Raspberry Pi

A static IP address will ensure that the Raspberry Pi will always have the same IP address. Without a static IP address the DHCP service on your router will randomly assign IP addresses from its IP range. A fixed IP address will make it easier to remotely connect to the Raspberry Pi.

In this example, the IP address for the Raspberry Pi will be set to 192.168.0.17.

  • Edit the interfaces file by entering the following command at the terminal.

    <
    >sudo nano /etc/network/interfaces
  • Change the eth0 settings to
    iface wlan0 inet static
    address 192.168.0.17
    netmask 255.255.255.0
    gateway 192.168.0.1
    broadcast 192.168.0.255
  • Press control + o to save
  • reboot by entering the command
    sudo shutdown -r now

Preparing for Battle

This year Team Seaford will be competing in the non-destructive robot competition Pi Wars 2017, where robot controlled by Raspberry Pi’s will compete in a range of robotics challenges.

The brains for this years robot will be the Raspberry Pi Zero that we won in Pi Wars 2015.

Please, follow our progress as we build our robot.