Ich versuche gerade eine universell einsetzbare und möglichst korrekte Klasse für'n HC-SR04 zu erstellen, aber scheitere gerade etwas an der Berechnung :longline:
Der Grundwert der Schallgeschwindigkeit beträgt 34326 Meter pro Sekunde bei trockener Luft und 20°C.
Bedeutet also: Zur korrekten Berechnung wie lange ein Signal unterwegs war hängt von sowohl Lufttemperatur als auch Feuchtigkeit ab. Ersteres mit aufzunehmen erscheint mir daher logisch, letzteres nicht unbedingt?
Auch habe ich bei der allgemeinen Berechnung gerade einen Knoten im Kopf.... Irgendwie finde ich über Google unterschiedliche Werte und bin jetzt total verwirrt
Da der Echo gesendet und wieder empfangen wird werden die vergangenen Microsekunden (der relevante Teil) durch 2 geteilt um die Entfernung zum Objekt zu beziffern. Der Teil ist soweit klar, aber mit welchen Werten muss man da rechnen? Im Netz finden sich Angaben wo time_elapsed durch 0.000058 für cm geteilt wird und durch 0.000148 für inches - aber wieso, woher stammt dieser Wert?
class Sonar_Ranger:
"""
This class encapsulates a type of acoustic ranger. In particular
the type of ranger with separate trigger and echo pins.
A pulse on the trigger initiates the sonar ping and shortly
afterwards a sonar pulse is transmitted and the echo pin
goes high. The echo pins stays high until a sonar echo is
received (or the response times-out). The time between
the high and low edges indicates the sonar round trip time.
Adjusting the interval between measurements increases the speed
of the reading. Increasing the speed will also increase CPU usage.
Setting it too low will cause errors.
"""
def __init__(self,
gpio,
trigger_pin,
echo_pin,
range_min=2,
range_max=400,
unit='cm',
temperature=20,
average=False,
telemetry,
status,
settings,
):
self.gpio = gpio
self.trig = trigger_pin
self.echo = echo_pin
self.range_min = range_min
self.range_max = range_max
self.unit = unit
self.temperature = temperature
self.average = average
self.telemetry = telemetry
self.status = status
self.settings = settings
# 343 m/s (29.155 ms/cm) speed of sound in dry air at 20C
self.speed_of_sound = 34326
self.gpio.setup(self.trig, self.gpio.OUT)
self.gpio.setup(self.echo, self.gpio.IN)
self.start_time = datetime.now()
self.gpio.add_event_detect(self.echo, self.gpio.BOTH, self.callback)
def callback(self, channel):
if self.gpio.input(self.echo) == 1:
self.start_time = datetime.now()
else:
self.end_time = datetime.now()
self.delta = self.end_time - self.start_time
self.time_elapsed = delta.seconds + delta.microseconds / 1E6
# Calc the duration of the recieved pulse, divide the result by 2 (round-trip)
if self.unit == 'cm':
metric = 0.000058
elif self.unit == 'inch':
metric = 0.000148
self.distance = self.time_elapsed / metric
self.telemetry['distance'] = self.distance
def measure_average(self, count=3):
c=1
distance=0
while (c <= count):
self.ping()
time.sleep(0.040)
if self.distance:
distance = distance + self.distance
time.sleep(0.05)
c+=1
self.distance = distance/count
def ping(self, pulse=0.00005):
self.start_time=datetime.now()
self.end_time=datetime.now()
self.distance=None
self.gpio.output(self.trig, self.gpio.HIGH)
time.sleep(pulse)
self.gpio.output(self.trig, self.gpio.LOW)
def print_distance(self):
if self.distance:
if (int(time.time()) - self.status['announce_time']) >= self.settings['distance_announce_time']:
if self.distance > self.range_max or self.distance < self.range_min:
print('Distance: out of range %.2f' % self.distance)
else:
print('Distance: %.2f %s' % (self.distance, self.unit))
self.status['announce_time'] = int(time.time())
def run(self):
while True:
time.sleep(self.settings['distance_measure_time'])
if not self.status['stop_ping']:
if self.average:
self.measure_average()
else:
self.ping()
Alles anzeigen