Die UART Schnittstelle überträgt nun die Distanzmessungen, vorne und hinten vom Raspberry Pico zum Raspberry Zero 2.
![](https://robot-bench.com/wp-content/uploads/2021/11/IMG_20211108_230648-1024x451.jpg)
Raspberry Pico:
import utime
from machine import Pin, UART, Timer
# Wichtig: nimmt man hier: uart = machine.UART(0, 115200)
# kann man nicht mehr per USB auf den Pico zugreifen.
uart = UART(1, 115200)
def ultra(trigger_pin, echo_pin):
trigger = Pin(trigger_pin, Pin.OUT)
echo = Pin(echo_pin, Pin.IN)
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep_us(5)
trigger.low()
while echo.value() == 0:
signaloff = utime.ticks_us()
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0343) / 2
return distance
def return_distance(t):
distance1 = ultra(3, 2)
distance2 = ultra(20, 21)
uart.write(f"front,{distance1},rear,{distance2}\n")
# durch die Initialisierung kann der timer zur Laufzeit gestoppt werden mit timer.deinit()
timer = None
if __name__ == "__main__":
timer = Timer(freq=5, callback=return_distance)
Merke: Verwende keine while True Schleife, sondern ein Timer Objekt. Damit bleibt die Konsole des Pico verfügbar.
Auf der Gegenstelle wird die Distanz empfangen.
Raspberry Zero 2:
import serial
from Sensors.sensor import Sensor
class UltraSonic(Sensor):
def __init__(self):
self._serial = serial.Serial ("/dev/ttyS0", 115200)
def getPort(self):
return self._serial
def read_one(self):
distance = {}
ser = self.getPort()
# Waiting Strings verwerfen
ser.read_all()
received_data = ser.readline() #read serial port
result = str(received_data.decode('utf-8')).split(",")
distance[result[0]] = round(float(result[1]))
distance[result[2]] = round(float(result[3]))
return distance
Nach der Dekodierung des binären Inputs zu UTF-8 lässt sich die Distanz von “rear” und “front” in eine Struktur laden und verarbeiten.
![](https://robot-bench.com/wp-content/uploads/2021/11/image.png)
Damit sind die Voraussetzungen für das autonome Herumfahren gegeben. Die Klassenbibliothek habe ich bereits um die Klasse Automation erweitert:
from Automation.automation_events import AutomationEvents
# Automation Klasse
class Automation:
def __init__(self, programs = None):
self._eventController = AutomationEvents()
self._sensors = {}
self._programs = programs
self.get_programs().set_event_controller(self.get_event_controller())
self._car = None
def set_car(self, car):
self.get_programs().set_car(car)
self._car = car
def get_car(self):
return self._car
def get_event_controller(self):
return self._eventController
def add_sensor(self, sensor_name, sensor_object):
self._sensors[sensor_name] = sensor_object
def get_sensors(self):
return self._sensors
def get_programs(self):
return self._programs
def autoprogram(self, program_name):
result = {}
if self.get_programs():
if program_name == "autoprogram_one":
result = self.get_programs().program_one()
if program_name == "autoprogram_stop":
result = self.get_programs().program_stop()
return result
und hier das Programm “autoprogram_one”: Es ist ganz einfach.
from Automation.automation_events import AutomationEvents
class AutomationPrograms:
def __init__(self):
self._car = None
def set_car(self, car):
self._car = car
def get_car(self):
return self._car
def set_event_controller(self, event_controller: AutomationEvents):
self._event_controller = event_controller
def get_event_controller(self):
return self._event_controller
def get_sensors(self):
return self.get_car().get_sensors()
def program_one(self):
result = {}
sensors = self.get_sensors()
eventcontroller = self._event_controller
for sensor_name in sensors:
sensor_result = sensors[sensor_name].read_one()
result[sensor_name] = sensor_result
event = eventcontroller.find_event("FORWARD", "MOVE")
try:
if result["UltraSonic"]["front"] >= 35:
event = eventcontroller.find_event("FORWARD", "MOVE")
elif result["UltraSonic"]["front"] < 35:
event = eventcontroller.find_event("KOLLISIONFRONT", "OBSTACLE")
elif result["UltraSonic"]["rear"] >= 35:
event = eventcontroller.find_event("BACKWARD", "MOVE")
elif result["UltraSonic"]["rear"] < 35:
event = eventcontroller.find_event("KOLLISIONBACK", "OBSTACLE")
except:
pass
result = event
return result
Die Car Klasse besitzt nun eine Automation, die man während der Initialisierung konfiguriert:
import sys
sys.path.append("..")
import time
from Automation.automation import Automation
from Automation.automation_programs import AutomationPrograms
from car import Car
from Motor.bot_motor import BotMotorController
from Sensors.ultrasonic import UltraSonic
sensor_object = UltraSonic()
programs = AutomationPrograms()
selfDriving = Automation(programs)
selfDriving.add_sensor("UltraSonic", sensor_object)
motorcontroller = BotMotorController(default_speed=45, max_speed=100)
motorcontroller.add_motor("Motor1", 19, 13, 26, True, True, 50)
motorcontroller.add_motor("Motor2", 27, 17, 22, True, False, 50)
newcar = Car("Lukes Car", motorcontroller, None, selfDriving)
newcar.start()
newcar.drive("autoprogram_one")
Die Testfahrt per Automation:
Nachtrag:
Um den Pico (oder den ESP32) mit dem JETSON Nano Board verwenden zu können, muss die UART Schnittstelle: /dev/ttyTHS1 angesprochen werden anstatt /dev/ttyS0.