-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Roboterbau mit RPi - Tutorial

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847

    Roboterbau mit RPi - Tutorial

    Anzeige

    Ich werde in diesem Threat (ist übrigens mein 700ster) den Aufbau meines "PinselBot" beschreiben, um anderen die Möglichkeiten den Bot nachzubauen bzw. Anregungen für Weiterentwicklungen zu geben. Es soll dargestellt werden, dass es im Grunde nicht besonders schwer ist, Module bzw. Sensoren direkt an die GPIO Schnittstelle des Raspberri Pi anzuschliessen und damit einen autonomen Roboter aufzubauen.

    ACHTUNG: Die GPIO Pins dürfen mit einer Spannung von max 3,3 Volt im Eingang (Input) betrieben werden, höhere Spannung führt im schlimmsten Fall zur Zerstörung des RPi's!!! Ich übernehme keine Verantwortung, sollte jemand meiner Anleitung folgen und durch fehlerhafte Verkabelung sein Board zerstören.

    Als Buch für den Anfänger empfehle ich "Durchstarten mit Raspberry Pi" von Erik Bartmann ISBN: 978-3-86899-410-0 (dies soll keine Werbung sein, aber ich finde das Buch sehr gut). Ich gehe davon aus, dass das RPi mit Raspian "Wheezy" vorbereitet ist und eine WLAN Verbindung zum Netzwerk besteht.

    Beginnen möchte ich mit dem Antrieb:

    Einkaufsliste:

    Neben dem Raspbery Pi benötigst du
    - RP5/6 Fahrgestell inkl. Motoren und Batteriehalter
    - Motortreiber L298N fertig aufgebautes Modul
    - Mobiles Ladegerät
    - Female to Female Kabel
    - USB Kabel Ladegerät-RPi
    - 6 Stk. Akkus vom Typ AA

    Weiters habe ich mir aus 2mm Plexiglas eine 220x100mm grosse "Plattform" geschnitten. Darauf kommen RPi und Motortreiber, befestigt mit z. B. Klettband. Aja, Distanzbolzen zur Besfestigung der Plattform am Fahrgestell braucht man auch noch.

    Die Verkabelung ist relativ einfach, weil man in dieser Phase noch kein Steckbrett benötigt wird, siehe Fotos.
    Zu beachten ist, dass das Massekabel vom RPi kommend an die Masse des L298N geklemmt wird, sonst funktioniert das Ganze nicht.

    Noch die GPIO-Library installieren:
    von http://pypi.python.org/pypi/RPi.GPIO herunterladen

    in der Console
    $ tar zxf RPi.GPIO-0.x.x.tar.gz
    $ cd RPi.GPIO-0.x.x
    $ sudo python setup.py install

    Nachdem das erledigt ist, kann das Programm ins /pi/home Verzeichnis kopiert werden:
    Code:
    #Get the GPIO module
    import RPi.GPIO as GPIO
    
    #Get the time module
    import time
    
    #A routine to control a pair of pins
    def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
      if FirstState == "1":
        GPIO.output(int(FirstPin),True)
      else:
        GPIO.output(int(FirstPin),False)
    
      if SecondState == "1":
        GPIO.output(int(SecondPin),True)
      else:
        GPIO.output(int(SecondPin),False)
      #Just retur
      return
    
    ####Main body of code
    
    #Get rid of warnings
    GPIO.setwarnings(False)
    
    #Set the GPIO mode
    GPIO.setmode(GPIO.BOARD)
    #Set the pins to be outputs
    GPIO.setup(19,GPIO.OUT)
    GPIO.setup(21,GPIO.OUT)
    GPIO.setup(23,GPIO.OUT)
    GPIO.setup(24,GPIO.OUT)
    
    while True:
    
        ControlAPairOfPins("19","1","21","0")
        ControlAPairOfPins("23","1","24","0")
        print "Drehung nach rechts"
        time.sleep(1)
    
        ControlAPairOfPins("19","0","21","0")
        ControlAPairOfPins("23","0","24","0")
        print "Stop"
        time.sleep(1)
    
        ControlAPairOfPins("19","0","21","1")
        ControlAPairOfPins("23","0","24","1")
        print "Drehung nach Links"
        time.sleep(1)
    
        ControlAPairOfPins("19","0","21","0")
        ControlAPairOfPins("23","0","24","0")
        print "Stop"
        time.sleep(1)
    
        ControlAPairOfPins("19","1","21","0")
        ControlAPairOfPins("23","0","24","1")
        print "Geradeaus vorwaerts"
        time.sleep(1)  
    
        ControlAPairOfPins("19","0","21","0")
        ControlAPairOfPins("23","0","24","0")
        print "Stop"
        time.sleep(1)
    
        ControlAPairOfPins("19","0","21","1")
        ControlAPairOfPins("23","1","24","0")
        print "Geradeaus rueckwaerts"
        time.sleep(1)
    
        ControlAPairOfPins("19","0","21","0")
        ControlAPairOfPins("23","0","24","0")
        print "Stop"
        time.sleep(1)
    Das Programm kennt nur Vollgas und Stop, die Geschwindigkeit kann nicht reguliert werden.

    Gestartet wird mit dem Befehl
    $sudo python motor.py

    Achtung: Der Roboter bewegt sich, sofern alles richtig gemacht wurde!

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847
    ... und weiter geht's.

    Wie man das Ultraschallmodul SRF04 anhängt, habe ich hier beschrieben:
    http://www.roboternetz.de/community/...ernungsmessung

    Wenn man das Modul mit 3,3 Volt betreibt, benötigt man noch immer kein Steckbrett - allerdings ist damit eine zuverlässige Messung nur bis Entfernungen bis ca. 50 cm möglich.

    Wenn man nun Antrieb und Entfernungsmessung nach meinen Vorgaben aufgebaut hat, müsste folgender Code schon funktionieren - der Bot fährt nun autonom durch die Gegend und weicht Hindernissen aus:
    Code:
    import time
    import RPi.GPIO as GPIO
    GPIO.setwarnings(False)
    
    def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
      if FirstState == "1":
        GPIO.output(int(FirstPin),True)
      else:
        GPIO.output(int(FirstPin),False)
    
      if SecondState == "1":
        GPIO.output(int(SecondPin),True)
      else:
        GPIO.output(int(SecondPin),False)
      return
    
    print "Ultraschallmessung mit SRF04"
    
    while True:
    
    #Messung Start
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(14,GPIO.OUT)
        GPIO.setup(15,GPIO.IN)
    
        GPIO.output(14, False)
    
        time.sleep(0.5)
    
        GPIO.output(14, True)
        time.sleep(0.00001)
        start = time.time()
        GPIO.output(14, False)
    
        while GPIO.input(15)==0:
          pass
    
        start = time.time()
    
        while GPIO.input(15)==1:
          pass
    
        stop = time.time()
        elapsed = stop-start    
        distance = elapsed * 17000
    
        print "Abstand: %.1f cm" % distance
    #Messung Ende
    
        if distance < 20:
            
        #Motor stop
            GPIO.setmode(GPIO.BOARD)
            GPIO.setup(19,GPIO.OUT)
            GPIO.setup(21,GPIO.OUT)
            GPIO.setup(23,GPIO.OUT)
            GPIO.setup(24,GPIO.OUT)
            ControlAPairOfPins("19","0","21","0")
            ControlAPairOfPins("23","0","24","0")
            print "Stop"
            time.sleep(1)
        #Stop Ende
        
        #Drehung rechts
            GPIO.setmode(GPIO.BOARD)
            GPIO.setup(19,GPIO.OUT)
            GPIO.setup(21,GPIO.OUT)
            GPIO.setup(23,GPIO.OUT)
            GPIO.setup(24,GPIO.OUT)
            ControlAPairOfPins("19","1","21","0")
            ControlAPairOfPins("23","1","24","0")
            print "Drehung nach rechts"
            time.sleep(1)
        
        else:
            
        #Motor vorwaerts
            GPIO.setmode(GPIO.BOARD)
            GPIO.setup(19,GPIO.OUT)
            GPIO.setup(21,GPIO.OUT)
            GPIO.setup(23,GPIO.OUT)
            GPIO.setup(24,GPIO.OUT)
            ControlAPairOfPins("19","1","21","0")
            ControlAPairOfPins("23","0","24","1")
            print "Geradeaus vorwaerts"
        #Vorwaerts Ende
    - - - Aktualisiert - - -

    Kommen wir nun zum LCD-Display:

    Nicht unbedingt notwendig, macht aber schon was her...

    Benötigt wird:
    - Mini Steckbrett, meins hat unten ein Doppelklebeband
    - LCD, möglich sind 16x1 oder 16x2 oder 16x4 (braucht viel Platz) Zeichen
    - Stiftleiste zum Auflöten
    - Timmerpoti 10kOhm
    - Male to Female Kabel
    - Male to Male Kabel

    Der Aufbau ist sehr gut hier beschrieben, hat mir auch geholfen:
    http://learn.adafruit.com/drive-a-16...ry-pi/overview

    Testcode von Adafruit:
    Code:
    #!/usr/bin/python
    
    #
    # based on code from lrvick and LiquidCrystal
    # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
    # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
    #
    
    from time import sleep
    
    class Adafruit_CharLCD:
    
        # commands
        LCD_CLEARDISPLAY         = 0x01
        LCD_RETURNHOME         = 0x02
        LCD_ENTRYMODESET         = 0x04
        LCD_DISPLAYCONTROL         = 0x08
        LCD_CURSORSHIFT         = 0x10
        LCD_FUNCTIONSET         = 0x20
        LCD_SETCGRAMADDR         = 0x40
        LCD_SETDDRAMADDR         = 0x80
    
        # flags for display entry mode
        LCD_ENTRYRIGHT         = 0x00
        LCD_ENTRYLEFT         = 0x02
        LCD_ENTRYSHIFTINCREMENT     = 0x01
        LCD_ENTRYSHIFTDECREMENT     = 0x00
    
        # flags for display on/off control
        LCD_DISPLAYON         = 0x04
        LCD_DISPLAYOFF         = 0x00
        LCD_CURSORON         = 0x02
        LCD_CURSOROFF         = 0x00
        LCD_BLINKON         = 0x01
        LCD_BLINKOFF         = 0x00
    
        # flags for display/cursor shift
        LCD_DISPLAYMOVE         = 0x08
        LCD_CURSORMOVE         = 0x00
    
        # flags for display/cursor shift
        LCD_DISPLAYMOVE         = 0x08
        LCD_CURSORMOVE         = 0x00
        LCD_MOVERIGHT         = 0x04
        LCD_MOVELEFT         = 0x00
    
        # flags for function set
        LCD_8BITMODE         = 0x10
        LCD_4BITMODE         = 0x00
        LCD_2LINE             = 0x08
        LCD_1LINE             = 0x00
        LCD_5x10DOTS         = 0x04
        LCD_5x8DOTS         = 0x00
    
        def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 21, 22], GPIO = None):
        # Emulate the old behavior of using RPi.GPIO if we haven't been given
        # an explicit GPIO interface to use
        if not GPIO:
            import RPi.GPIO as GPIO
           self.GPIO = GPIO
            self.pin_rs = pin_rs
            self.pin_e = pin_e
            self.pins_db = pins_db
    
            self.GPIO.setmode(GPIO.BCM)
            self.GPIO.setup(self.pin_e, GPIO.OUT)
            self.GPIO.setup(self.pin_rs, GPIO.OUT)
    
            for pin in self.pins_db:
                self.GPIO.setup(pin, GPIO.OUT)
    
        self.write4bits(0x33) # initialization
        self.write4bits(0x32) # initialization
        self.write4bits(0x28) # 2 line 5x7 matrix
        self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
        self.write4bits(0x06) # shift cursor right
    
        self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
    
        self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
        self.displayfunction |= self.LCD_2LINE
    
        """ Initialize to default text direction (for romance languages) """
        self.displaymode =  self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) #  set the entry mode
    
            self.clear()
    
    
        def begin(self, cols, lines):
    
        if (lines > 1):
            self.numlines = lines
                self.displayfunction |= self.LCD_2LINE
            self.currline = 0
    
    
        def home(self):
    
        self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
        self.delayMicroseconds(3000) # this command takes a long time!
        
    
        def clear(self):
    
        self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
        self.delayMicroseconds(3000)    # 3000 microsecond sleep, clearing the display takes a long time
    
    
        def setCursor(self, col, row):
    
        self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]
    
        if ( row > self.numlines ): 
            row = self.numlines - 1 # we count rows starting w/0
    
        self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
    
    
        def noDisplay(self): 
        """ Turn the display off (quickly) """
    
        self.displaycontrol &= ~self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def display(self):
        """ Turn the display on (quickly) """
    
        self.displaycontrol |= self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noCursor(self):
        """ Turns the underline cursor on/off """
    
        self.displaycontrol &= ~self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def cursor(self):
        """ Cursor On """
    
        self.displaycontrol |= self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noBlink(self):
        """ Turn on and off the blinking cursor """
    
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noBlink(self):
        """ Turn on and off the blinking cursor """
    
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def DisplayLeft(self):
        """ These commands scroll the display without changing the RAM """
    
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
    
    
        def scrollDisplayRight(self):
        """ These commands scroll the display without changing the RAM """
    
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);
    
    
        def leftToRight(self):
        """ This is for text that flows Left to Right """
    
        self.displaymode |= self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);
    
    
        def rightToLeft(self):
        """ This is for text that flows Right to Left """
        self.displaymode &= ~self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def autoscroll(self):
        """ This will 'right justify' text from the cursor """
    
        self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def noAutoscroll(self): 
        """ This will 'left justify' text from the cursor """
    
        self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def write4bits(self, bits, char_mode=False):
            """ Send command to LCD """
    
        self.delayMicroseconds(1000) # 1000 microsecond sleep
    
            bits=bin(bits)[2:].zfill(8)
    
            self.GPIO.output(self.pin_rs, char_mode)
    
            for pin in self.pins_db:
                self.GPIO.output(pin, False)
    
            for i in range(4):
                if bits[i] == "1":
                    self.GPIO.output(self.pins_db[::-1][i], True)
    
        self.pulseEnable()
    
            for pin in self.pins_db:
                self.GPIO.output(pin, False)
    
            for i in range(4,8):
                if bits[i] == "1":
                    self.GPIO.output(self.pins_db[::-1][i-4], True)
    
        self.pulseEnable()
    
    
        def delayMicroseconds(self, microseconds):
        seconds = microseconds / float(1000000)    # divide microseconds by 1 million for seconds
        sleep(seconds)
    
    
        def pulseEnable(self):
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)        # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, True)
        self.delayMicroseconds(1)        # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)        # commands need > 37us to settle
    
    
        def message(self, text):
            """ Send string to LCD. Newline wraps to second line"""
    
            for char in text:
                if char == '\n':
                    self.write4bits(0xC0) # next line
                else:
                    self.write4bits(ord(char),True)
    
    
    if __name__ == '__main__':
    
        lcd = Adafruit_CharLCD()
    
        lcd.clear()
        lcd.message("Pinsel's\n RPi Bot")
    Wenn "Pinsels's RPi Bot" auf dem Diplay steht, ist alles richtig aufgebaut.

    Als Goody noch ein Programm, das die US-Messwerte im Display ausgibt:

    Code:
    from time import sleep
    
    class Adafruit_CharLCD:
    
        # commands
        LCD_CLEARDISPLAY         = 0x01
        LCD_RETURNHOME         = 0x02
        LCD_ENTRYMODESET         = 0x04
        LCD_DISPLAYCONTROL         = 0x08
        LCD_CURSORSHIFT         = 0x10
        LCD_FUNCTIONSET         = 0x20
        LCD_SETCGRAMADDR         = 0x40
        LCD_SETDDRAMADDR         = 0x80
    
        # flags for display entry mode
        LCD_ENTRYRIGHT         = 0x00
        LCD_ENTRYLEFT         = 0x02
        LCD_ENTRYSHIFTINCREMENT     = 0x01
        LCD_ENTRYSHIFTDECREMENT     = 0x00
    
        # flags for display on/off control
        LCD_DISPLAYON         = 0x04
        LCD_DISPLAYOFF         = 0x00
        LCD_CURSORON         = 0x02
        LCD_CURSOROFF         = 0x00
        LCD_BLINKON         = 0x01
        LCD_BLINKOFF         = 0x00
    
        # flags for display/cursor shift
        LCD_DISPLAYMOVE         = 0x08
        LCD_CURSORMOVE         = 0x00
    
        # flags for display/cursor shift
        LCD_DISPLAYMOVE         = 0x08
        LCD_CURSORMOVE         = 0x00
        LCD_MOVERIGHT         = 0x04
        LCD_MOVELEFT         = 0x00
    
        # flags for function set
        LCD_8BITMODE         = 0x10
        LCD_4BITMODE         = 0x00
        LCD_2LINE             = 0x08
        LCD_1LINE             = 0x00
        LCD_5x10DOTS         = 0x04
        LCD_5x8DOTS         = 0x00
    
        def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 21, 22], GPIO = None):
        # Emulate the old behavior of using RPi.GPIO if we haven't been given
        # an explicit GPIO interface to use
        if not GPIO:
            import RPi.GPIO as GPIO
           self.GPIO = GPIO
            self.pin_rs = pin_rs
            self.pin_e = pin_e
            self.pins_db = pins_db
    
            self.GPIO.setmode(GPIO.BCM)
            self.GPIO.setup(self.pin_e, GPIO.OUT)
            self.GPIO.setup(self.pin_rs, GPIO.OUT)
    
            for pin in self.pins_db:
                self.GPIO.setup(pin, GPIO.OUT)
    
        self.write4bits(0x33) # initialization
        self.write4bits(0x32) # initialization
        self.write4bits(0x28) # 2 line 5x7 matrix
        self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
        self.write4bits(0x06) # shift cursor right
    
        self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
    
        self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
        self.displayfunction |= self.LCD_2LINE
    
        """ Initialize to default text direction (for romance languages) """
        self.displaymode =  self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) #  set the entry mode
    
            self.clear()
    
    
        def begin(self, cols, lines):
    
        if (lines > 1):
            self.numlines = lines
                self.displayfunction |= self.LCD_2LINE
            self.currline = 0
    
    
        def home(self):
    
        self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
        self.delayMicroseconds(3000) # this command takes a long time!
        
    
        def clear(self):
    
        self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
        self.delayMicroseconds(3000)    # 3000 microsecond sleep, clearing the display takes a long time
    
    
        def setCursor(self, col, row):
    
        self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]
    
        if ( row > self.numlines ): 
            row = self.numlines - 1 # we count rows starting w/0
    
        self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
    
    
        def noDisplay(self): 
        """ Turn the display off (quickly) """
    
        self.displaycontrol &= ~self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def display(self):
        """ Turn the display on (quickly) """
    
        self.displaycontrol |= self.LCD_DISPLAYON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noCursor(self):
        """ Turns the underline cursor on/off """
    
        self.displaycontrol &= ~self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def cursor(self):
        """ Cursor On """
    
        self.displaycontrol |= self.LCD_CURSORON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noBlink(self):
        """ Turn on and off the blinking cursor """
    
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def noBlink(self):
        """ Turn on and off the blinking cursor """
    
        self.displaycontrol &= ~self.LCD_BLINKON
        self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
    
    
        def DisplayLeft(self):
        """ These commands scroll the display without changing the RAM """
    
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
    
    
        def scrollDisplayRight(self):
        """ These commands scroll the display without changing the RAM """
    
        self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);
    
    
        def leftToRight(self):
        """ This is for text that flows Left to Right """
    
        self.displaymode |= self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);
    
    
        def rightToLeft(self):
        """ This is for text that flows Right to Left """
        self.displaymode &= ~self.LCD_ENTRYLEFT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def autoscroll(self):
        """ This will 'right justify' text from the cursor """
    
        self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def noAutoscroll(self): 
        """ This will 'left justify' text from the cursor """
    
        self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
        self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
    
    
        def write4bits(self, bits, char_mode=False):
            """ Send command to LCD """
    
        self.delayMicroseconds(1000) # 1000 microsecond sleep
    
            bits=bin(bits)[2:].zfill(8)
    
            self.GPIO.output(self.pin_rs, char_mode)
    
            for pin in self.pins_db:
                self.GPIO.output(pin, False)
    
            for i in range(4):
                if bits[i] == "1":
                    self.GPIO.output(self.pins_db[::-1][i], True)
    
        self.pulseEnable()
    
            for pin in self.pins_db:
                self.GPIO.output(pin, False)
    
            for i in range(4,8):
                if bits[i] == "1":
                    self.GPIO.output(self.pins_db[::-1][i-4], True)
    
        self.pulseEnable()
    
    
        def delayMicroseconds(self, microseconds):
        seconds = microseconds / float(1000000)    # divide microseconds by 1 million for seconds
        sleep(seconds)
    
    
        def pulseEnable(self):
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)        # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, True)
        self.delayMicroseconds(1)        # 1 microsecond pause - enable pulse must be > 450ns 
        self.GPIO.output(self.pin_e, False)
        self.delayMicroseconds(1)        # commands need > 37us to settle
    
    
        def message(self, text):
            """ Send string to LCD. Newline wraps to second line"""
    
            for char in text:
                if char == '\n':
                    self.write4bits(0xC0) # next line
                else:
                    self.write4bits(ord(char),True)
    
    
    if __name__ == '__main__':
    
        lcd = Adafruit_CharLCD()
    
    GPIO_TRIGGER = 14
    GPIO_ECHO = 15
    
    adjustment = 7
    
    print "Ultraschallmessung mit SRF04"
    
    while True:
    
        GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
        GPIO.setup(GPIO_ECHO,GPIO.IN)
    
        GPIO.output(GPIO_TRIGGER, False)
    
        time.sleep(0.5)
    
        GPIO.output(GPIO_TRIGGER, True)
        time.sleep(0.00001)
        start = time.time()
        GPIO.output(GPIO_TRIGGER, False)
    
        while GPIO.input(GPIO_ECHO)==0:
          pass
    
        start = time.time()
    
        while GPIO.input(GPIO_ECHO)==1:
          pass
    
        stop = time.time()
    
        elapsed = stop-start
        
        distance = elapsed * 17000 + 8
        distance = distance - adjustment
    
        print "Abstand: %.1f cm" % distance
        time.sleep(1)
    
        GPIO.cleanup()
    
    
    
        lcd.clear()
    #    lcd.message("  Adafruit 16x2\n  Standard LCD")
        lcd.message("Pinsel's\n RPi Bot")
    - - - Aktualisiert - - -

    Dann noch das vorerst letzte und schwierigste Modul: Der Mini Servo

    Hier ist ein klein wendig Bastelarbeit notwendig um das US-Modul auf dem Servoarm zu befestigen. Aus Sperrholz oder Kunststoff habe ich mir ein passendes "U" ausgeschnitten und mit dem Servoarm verschraubt - siehe Fotos. Neben diesem Teil benötigt man noch ein

    - Mini Servo
    - BC548 NPN Transistor
    - 2 Stk. Kohlewiderstand 1K

    Die Widerstände verwendet man als Spannungsteiler, weil der Servo nur mit 5 Volt betrieben werden kann. Die Verkabelung ist in der Anlage ersichtlich - hier möchte ich mich für die Handskizzen entschuldigen, ich denke dass sie ihren Zweck trotzdem erfüllen.

    Hier ein Programm, um den Servo zu testen:

    Code:
    import RPi.GPIO as GPIO
    import time
    
    GPIO.setmode(GPIO.BOARD)
    GPIO.setwarnings(False)
    
    GPIO.setup(26, GPIO.OUT)
    GPIO.output(26, True)
    
    while True:
        for i in range(1, 100):
            GPIO.output(26, False)
            time.sleep(0.001)
            GPIO.output(26, True)
            time.sleep(0.02)
    
        for i in range(1, 100):
            GPIO.output(26, False)
            time.sleep(0.0015)
            GPIO.output(26, True)
            time.sleep(0.02)
    
        for i in range(1, 100):
            GPIO.output(26, False)
            time.sleep(0.002)
            GPIO.output(26, True)
            time.sleep(0.02)
    Der Ablauf dieses Programms ist hier ersichtlich: http://www.youtube.com/watch?v=VA_2pQ9W4g4
    Wenn der Servo etwas zuckt ist dies normal, ich habe keinen Weg gefunden dieses zu beseitigen. Hier wäre schon ein Ansatz mein Projekt zu verbessern.

    Sind alle Komponenten und Sensoren aufgebaut, steht einem Probelauf nichts mehr im Weg.
    Program dazu kann ich nicht hochladen, *.py ist eine nicht erlaubte Datei - sollte jemand den Code wollen, einfach PN mit der Emailadresse an mich senden.

    Das war's vorerst, sollte jemand Anregungen, Kritik oder Verbesserungsvorschläge haben - einfach posten. Ich wünsche viel Erfolg beim Nachbau

  3. #3
    Benutzer Stammmitglied Avatar von Defiant
    Registriert seit
    17.04.2005
    Ort
    Hamburg
    Beiträge
    41
    Interessant. Ich benutz die gleiche Plattform mit dem R-Pi. Nur habe ich für die PWM-Erzeugung und Beobachtung der Spannung (Notabschaltung) noch einen 5V AVR dazwischen.Und mein R-Pi wird vom normalen Akku mitversorgt.Kann es sein, daß dir die Schutzdioden am L298 fehlen?

    - - - Aktualisiert - - -

    Interessant. Ich benutz die gleiche Plattform mit dem R-Pi. Nur habe ich für die PWM-Erzeugung und Beobachtung der Spannung (Notabschaltung) noch einen 5V AVR dazwischen.Und mein R-Pi wird vom normalen Akku mitversorgt.Kann es sein, daß dir die Schutzdioden am L298 fehlen?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847
    Du hast Recht, die fehlen. Wäre nett, wenn du eine Skizze/Beschreibung vom sicheren Aufbau beifügen könntest - Danke.

  5. #5
    Benutzer Stammmitglied Avatar von Defiant
    Registriert seit
    17.04.2005
    Ort
    Hamburg
    Beiträge
    41
    Das RN Wiki hat was dazu:http://www.rn-wissen.de/index.php/Ge...tkreis_L298Ach ja: Dein Servo zuckt vermutlich, da deine PWM vom Timing zu ungenau ist: Ich vermute z.B. anstatt 1.5ms bekommst du mal 1.4ms/1.6ms oder schlimmer. Deswegen habe ich den AVR dazwischen.Das sollte sich mit einem Oszilloskop messen lassen.Ich bin erstaunt, daß du nur mit dem R-PI ohne RTOS den SRF auslesen kannst, welche Genauigkeit bekommst du hin?

    - - - Aktualisiert - - -

    Das RN Wiki hat was dazu:http://www.rn-wissen.de/index.php/Getriebemotoren_Ansteuerung#Ansteuerung_mit_dem_Sc haltkreis_L298Ach ja: Dein Servo zuckt vermutlich, da deine PWM vom Timing zu ungenau ist: Ich vermute z.B. anstatt 1.5ms bekommst du mal 1.4ms/1.6ms oder schlimmer. Deswegen habe ich den AVR dazwischen.Das sollte sich mit einem Oszilloskop messen lassen.Ich bin erstaunt, daß du nur mit dem R-PI ohne RTOS den SRF auslesen kannst, welche Genauigkeit bekommst du hin?

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847
    OK, Danke für die Anleitung.

    Das SRF04 hat eine Genauigkeit von +/- 0,5 cm. Wobei die Ungenauigkeit mit zunehmenden Abstand grösser wird. Ist aber in diesem Fall für die Hinderniserkennung ausreichend, es wird ein Besenstiel in 1,5 Meter Entfernung erkannt.

    Btw: Warum werden deine Posts doppelt angezeigt?

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.02.2006
    Beiträge
    982
    Ich wuerde so repetitive tasks und genaue timings (z.B. Servos, Sensoren, etc..) auch eher auf einen kleinen AVR auslagern..und den PI fuer groessere Rechenaufgaben und Datenmengen (z.B. Navigation) frei halten.
    Nam et ipsa scientia potestas est..

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847

    Linienverfolgung

    Als vorerst letztes Modul möchte ich euch noch meine Lösung für eine Linienverfolgung präsentieren.

    Ich habe mich für eine fertig verlötete Platine mit 2 CNY70 entschieden: http://www.generationrobots.com/pob-...ine-Sensor.cfm
    Im Lieferumfang ist noch ein Sharp Abstandsensor, diesen werde ich mich zu einem späteren Zeitpunkt zuwenden, da es nicht so einfach ist, einen analogen Sensor an die GPIO Pins anzuschliessen.

    Diese Platine kann direkt an 3,3 Volt angeschlossen werden und somit wird auch für diese Anwendung kein Steckbrett benötigt. Als Input Pins werden noch die letzten verbleibenden mit der Nummer 7(links) und 12(rechts) verbunden. Damit sind mit Ausnahme der I2C Pins alle belegt, sollte jemand meinen "Vollausbau" nachgemacht haben.

    Programm zum testen der Sensoren:
    Code:
    import RPi.GPIO as GPIO
    
    import time
    
    GPIO.setwarnings(False)
    
    GPIO.setmode(GPIO.BOARD)
    
    GPIO.setup(7,GPIO.IN)
    GPIO.setup(12,GPIO.IN)
    
    while True:
    
        input_re = GPIO.input(12)
        input_li = GPIO.input(7)
        
        print input_re
        print input_li
        
        time.sleep(1)
    Ich habe natürlich ein Programm geschrieben, womit der Bot einer Linie folgt - Video hier: http://www.youtube.com/watch?v=oXrxMo1iL-8

    Sollte jemand den Code verwenden wollen, PN mit Emailadresse an mich.

    Video mit bessere Qualität: http://www.youtube.com/watch?v=AcXeF...ature=youtu.be
    Geändert von pinsel120866 (27.01.2013 um 11:52 Uhr)

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    27.08.2006
    Alter
    69
    Beiträge
    83
    Hallo Pinsel,

    guter Bericht zum raspberry pi.
    Ich plane in Zukunft auch den Aufbau mit dem raspberry und dem Gertboard.
    Zur Zeit beschäftige ich mit dem Gertboard.

    Im Übrigen finde ich die ARM Serie (Cubieboard, Hackberry und Raspberry pi) sehr gut.

    Schaun wir mal.
    Gruß
    Kurt

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von pinsel120866
    Registriert seit
    18.12.2007
    Ort
    Hohenems
    Alter
    51
    Beiträge
    847
    Nun kann auch die Geschwindigkeit geregelt werden!
    Danke an tucow für die Unterstützung!

    Lösung zum Steuern der Motoren des Pinselbots mittels Software-PWM:

    Benötigt wird die Lib pizypwm.py, die sich im Anhang befindet. Einfach ins selbe Verzeichnis wie die Programmdatei legen.

    Der nun angepasste Testcode für die Motoren sieht nun so aus:
    Code:
    import RPi.GPIO as GPIO
    
    import time
    import signal
    
    from pizypwm import *
    
    def endProcess(signalnum = None, handler = None):
        first.stop()
        second.stop()
        third.stop()
        fourth.stop()
    
        GPIO.cleanup()
        exit(0)
    
    signal.signal(signal.SIGTERM, endProcess)
    signal.signal(signal.SIGINT, endProcess)
    
    first = PiZyPwm(20000, 19, GPIO.BOARD)
    second = PiZyPwm(20000, 21, GPIO.BOARD)
    third = PiZyPwm(20000, 23, GPIO.BOARD)
    fourth = PiZyPwm(20000, 24, GPIO.BOARD)
    
    GPIO.setwarnings(False)
    
    GPIO.setmode(GPIO.BOARD)
    
    GPIO.setup(19,GPIO.OUT)
    GPIO.setup(21,GPIO.OUT)
    GPIO.setup(23,GPIO.OUT)
    GPIO.setup(24,GPIO.OUT)
    
    while True:
        
        first.start(50)
        second.start(0)
        third.start(50)
        fourth.start(0)
        print "Drehung nach rechts"
        time.sleep(1)
    
        first.start(0)
        second.start(0)
        third.start(0)
        fourth.start(0)
        print "Stop"
        time.sleep(1)
        
        first.start(0)
        second.start(50)
        third.start(0)
        fourth.start(50)
        print "Drehung nach Links"
        time.sleep(1)
    
        first.start(0)
        second.start(0)
        third.start(0)
        fourth.start(0)
        print "Stop"
        time.sleep(1)
    
        first.start(50)
        second.start(0)
        third.start(0)
        fourth.start(50)
        print "Geradeaus vorwaerts"
        time.sleep(1)
        
        first.start(0)
        second.start(0)
        third.start(0)
        fourth.start(0)
        print "Stop"
        time.sleep(1)
    
        first.start(0)
        second.start(50)
        third.start(50)
        fourth.start(0)
        print "Geradeaus rueckwaerts"
        time.sleep(1)
    
        first.start(0)
        second.start(0)
        third.start(0)
        fourth.start(0)
        print "Stop"
        time.sleep(1)
    Geändert von pinsel120866 (09.02.2013 um 15:41 Uhr)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. wie soll ich mit dem Roboterbau anfangen
    Von el barto im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 3
    Letzter Beitrag: 06.02.2015, 18:15
  2. Pinsel's RPi Bot
    Von pinsel120866 im Forum Vorstellungen+Bilder von fertigen Projekten/Bots
    Antworten: 16
    Letzter Beitrag: 10.02.2013, 08:16
  3. Android auf dem RPI
    Von pinsel120866 im Forum Raspberry Pi
    Antworten: 1
    Letzter Beitrag: 11.12.2012, 21:43
  4. Gesucht: Hilfe für Roboterbau mit Raspberry Pi
    Von haering im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 11
    Letzter Beitrag: 23.04.2012, 19:01
  5. Grundlagen / Tutorial für µC-Programmierung mit C
    Von Zecher im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 26.03.2005, 22:02

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •