Tutorial – Raspberry Pi Roboter – Teil 4: Zusammenbau

Im vierten Teil unserer MuRCSPI Raspberry Pi Roboter Reihe geht es darum die Elektronik für den Roboter auf einer Erweiterungsplatine (Hat) unterzubringen und den Roboter fahrbereit zusammenzubauen.

In einem ersten Beispiel Programm soll der Roboter autonom fahren und Hindernissen ausweichen.

Roboter Hat

Die gesamte Elektronik für den Roboter passt auf ein Rasperry Pi Proto Hat. Darauf ist auch noch genug Platz für spätere Erweiterungen. Da nur Fertigmodule zum Einsatz kommen, sind nur Steckverbinder und Drahtverbindungen auf dem Proto-Hat zu verlöten.

Benötigt werden:

  • Raspberry Pi Proto Hat
  • Stiftleisten
  • Buchsenleisten
  • Silberdraht und isolierte Litze
  • Batteriefach 6xAA (MURCS v2) bzw. zwei 3xAA (Dagu Magician)
  • USB Powerpack 5V/1A mit Micro USB Kabel
  • Kabelbinder, Klettband
  • 4 M2.5×30 Schrauben, 8 Muttern M2.5
  • 4 M3x10mm Distanzbolzen (nur Dagu Magician)

Entsprechend einfach ist der Aufbau. So sieht das zusammengelötete Proto-Hat aus:

[pe2-image src=“http://lh3.googleusercontent.com/-uCQJIBp-ues/VYXYxcO5IrI/AAAAAAAANhA/SoyIMNBl6pk/s144-c-o/IMG_5518.JPG“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6162570009030238898″ caption=““ type=“image“ alt=“IMG_5518.JPG“ ]

Die Rückseite zeigt die Verdrahtung des Proto-Hat. Bei dem verwendeten Adafruit Proto-Hat gibt es eine extra Reihe, auf der die Raspberry Pi IOs herausgeführt sind. Das macht die Verdrahtung wesentlich einfacher.

[pe2-image src=“http://lh3.googleusercontent.com/-OgqYEx1c3m4/VYXYjM05nWI/AAAAAAAANgg/CJx-6jiNdac/s144-c-o/IMG_5514.JPG“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6162569764376517986″ caption=““ type=“image“ alt=“IMG_5514.JPG“ ]

Das bestückte Proto-Hat mit dem A/D Wandler Modul, Motor-Treiber und Anschlüssen für Sensoren etc.

[pe2-image src=“http://lh3.googleusercontent.com/-eQBoaY8duPc/VZ2Bf-n-9aI/AAAAAAAANv4/zKwjeU15XEc/s144-c-o/robo-hat.jpg“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6169229450954077602″ caption=““ type=“image“ alt=“robo-hat.jpg“ ]

Der Schaltplan sieht dann so aus:

raspi-roboter

Zusammenbau

Das Proto-Hat wird einfach auf das Raspberry Pi Board gesteckt. Die Verdrahtung von Sensor, Motoren und Motor Spannungsversorgung entnimmt man der folgenden Abbildung. Das Raspberry Pi Board wird hier über ein USB Powerpack versorgt. Die Motorspannungsversorgung besteht aus einem 6xAA Akkupack.

[pe2-image src=“http://lh3.googleusercontent.com/-dpdkKpoyT1Y/VZ2BiqC-BEI/AAAAAAAANwA/3YufM069ApI/s144-c-o/robo-hat-motors-ir-sensor.jpg“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6169229496969724994″ caption=““ type=“image“ alt=“robo-hat-motors-ir-sensor.jpg“ ]

So sieht dann der fertige Roboter auf dem MURCS v2 Chassis aus.

[pe2-image src=“http://lh3.googleusercontent.com/-DZ4_P4-f84k/VYXZGHs1JxI/AAAAAAAANho/TmO7_aBm5kA/s144-c-o/IMG_5524.JPG“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6162570364295915282″ caption=““ type=“image“ alt=“IMG_5524.JPG“ ]

Beim Dagu Magician Chassis ist die untere Ebene mit dem USB Powerpack und zwei in Reihe geschaltete 3xAA Akkupacks belegt. Das besondere bei dem USB Powerpack: Darin befindet sich ein Audioverstärker und ein kleiner Lautsprecher.

[pe2-image src=“http://lh3.googleusercontent.com/-d8ESEe8LFAQ/VZ2BdfunuLI/AAAAAAAANvw/6g1YWZnu3lU/s144-c-o/IMG_5544.JPG“ href=“https://picasaweb.google.com/100614490999857774768/MURCSPi#6169229408300677298″ caption=““ type=“image“ alt=“IMG_5544.JPG“ ]

Die obere Ebene bleibt komplett frei für die Elektronik.

Software Kollisionsvermeider

Den Raspberry Pi betreibe ich normalerweise „headless“ ohne Tastatur und Bildschirm. Über SSH (Putty untet Windows) kann man vom PC aus mit dem Raspberry Pi kommunizieren. Der Datenaustausch erfolgt über SCP (WinSCP bei Windows). Hilfreich ist ein WLAN USB Dongle, dann funktioniert das ganze sogar drahtlos.

Nun kann der Roboter in Betrieb gehen. Fehlt nur noch das passende Programm. Los geht es mit einem Python Sketch für einen Kollisionsvermeider. Es baut auf den beiden Test-Programmen für die Sensorabfrage und die Motoransteuerung.

#!/usr/bin/python
from __future__ import print_function
import time, signal, sys
from pololu_drv8835_rpi import motors, MAX_SPEED 
from Adafruit_ADS1x15 import ADS1x15

def signal_handler(signal, frame):
        print ('You pressed Ctrl+C!')
        sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
#print 'Press Ctrl+C to exit'


OBSTACLE_FAR   =  30   # 30cm
OBSTACLE_NEAR  =  20   # 20cm
OBSTACLE_CLOSE =  10   # 10cm

class ADS1015(object):
  ADS1015 = 0x00  # 12-bit ADC
  ADS1115 = 0x01    # 16-bit ADC

  # Select the gain
  # gain = 6144  # +/- 6.144V
  gain = 4096  # +/- 4.096V
  # gain = 2048  # +/- 2.048V
  # gain = 1024  # +/- 1.024V
  # gain = 512   # +/- 0.512V
  # gain = 256   # +/- 0.256V

  # Select the sample rate
  # sps = 8    # 8 samples per second
  # sps = 16   # 16 samples per second
  # sps = 32   # 32 samples per second
  # sps = 64   # 64 samples per second
  # sps = 128  # 128 samples per second
  sps = 250  # 250 samples per second
  # sps = 475  # 475 samples per second
  # sps = 860  # 860 samples per second
  adc = ADS1x15(ic=ADS1015)

  def __init__(self):
    self.gain = 2048  # +/- 2.048V
    self.sps = 250  # 250 samples per second
    # Initialise the ADC using the default mode (use default I2C address)
    # Set this to ADS1015 or ADS1115 depending on the ADC you are using!

  def read(self, port):
    value = self.adc.readADCSingleEnded(port, self.gain, self.sps)
    return value

class Motor(object):
    speedL = 0
    speedR = 0
    actSpeedL = 0
    actSpeedR = 0
    SPEED_STEP = 10

    def __init__(self):
      self.speedL = 0
      self.speedR = 0
      self.actSpeedL = 0
      self.actSpeedR = 0
 
    def setSpeed(self, sr, sl):
      self.speedL = sr
      self.speedR = sl
      print ("speed", self.speedR, self.speedL)

    def updateMotors(self):
      if self.speedL == 0:
        self.actSpeedL = 0
      elif self.actSpeedL < self.speedL:
        self.actSpeedL += self.SPEED_STEP
      elif self.actSpeedL > self.speedL:
        self.actSpeedL -= self.SPEED_STEP
      if self.speedR == 0:
        self.actSpeedR = 0
      elif self.actSpeedR < self.speedR:
        self.actSpeedR += self.SPEED_STEP
      elif self.actSpeedR > self.speedR:
        self.actSpeedR -= self.SPEED_STEP
      print ("motor lt, rt", self.actSpeedR, self.actSpeedL)
      motors.setSpeeds(self.actSpeedR, self.actSpeedL)
      time.sleep(0.100) 

if __name__ == "__main__":
    print ('roboPi obstacle avoider')
    ads1015 = ADS1015()
    motor = Motor()
    motors.setSpeeds(0, 0)  


    while 1:
        # Read channel 3 in single-ended mode using the settings above
        value = ads1015.read(0)
        distance = 14 / (value/1000 - 0.1)
        print "value: {0:.0f} mV distance: {1:.0f} cm".format(value, distance)

        if value > OBSTACLE_CLOSE:
            motor.setSpeed(0, 0)
            motor.updateMotors() 
            print ('stop') 
            time.sleep(0.5)
            while  distance > OBSTACLE_NEAR:
              value = ads1015.read(0)
              distance = 14 / (value/1000 - 0.1)
              motor.setSpeed(-MAX_SPEED/4, MAX_SPEED/4)
              motor.updateMotors() 

        elif distance > OBSTACLE_NEAR:
            motor.setSpeed(MAX_SPEED/4, MAX_SPEED/4)
            print ('slow') 

        elif distance > OBSTACLE_FAR:
            motor.setSpeed(MAX_SPEED/2, MAX_SPEED/2)
            print ('half speed') 

        else:
            motor.setSpeed(MAX_SPEED, MAX_SPEED)
            print ('max speed') 

        motor.updateMotors()  

Gestartet wird das Programm mit:

sudo python collision-avoider.py

Links

Die weiteren Teile der Serie:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert