/***************************************************************************** source::worx libPiGPio Copyright © 2022 c.holzheuer chris@sourceworx.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Uses: pigpiod_if2 by joan2937, pigpio @ abyz.me.uk https://abyz.me.uk/rpi/pigpio sigslot by 2017 Pierre-Antoine Lacaze https://github.com/palacaze/sigslot pigSonar based on: https://github.com/OmarAflak/HC-SR04-Raspberry-Pi-C- ***************************************************************************/ #include #include /** * @brief pigSonar::pigSonar * * * Beschreibung HC-SR04: * Das Ultraschall Modul HC-SR04 eignet sich zur * Entfernungsmessung im Bereich zwischen 2cm und ca. * 3m mit einer Auflösung von 3mm. Es benötigt nur eine * einfache Versorgungsspannung von 5V bei einer * Stromaufnahme von <2mA. Nach Triggerung mit einer * fallenden Flanke (TTL - Pegel) misst das Modul * selbstständig die Entfernung und wandelt diese in ein * PWM Signal welches am Ausgang zur Verfügung steht. * Ein Messintervall hat eine Dauer von 20ms. Es können * also 50 Messungen pro Sekunde durchgeführt werden * * https://www.mikrocontroller.net/attachment/218122/HC-SR04_ultraschallmodul_beschreibung_3.pdf */ pigSonar::pigSonar() { } pigSonar::pigSonar( pigpio::bcm_t trigger, pigpio::bcm_t echo ) { init( trigger, echo ); } pigSonar::~pigSonar() { //detach_pin( ) //?? doch wg .callback } void pigSonar::init( pigpio::bcm_t trigger, pigpio::bcm_t echo ) { _pinEcho.init( echo ); //_pinEcho.set_callback( this, rising ); _pinTrig.init( trigger ); _pinTrig.set_level( low ); delay_millis( 500 ); } void pigSonar::stop() { _active = false; } void pigSonar::start( double thresh ) { _active = true; std::thread thrd( [=]() { while( _active ) { double dist = distance(); if( dist < thresh ) sigValue( dist ); delay_millis( 50 ); } } ); thrd.detach(); } double pigSonar::distance( int timeout ) { // erholungspause delay_millis( 10 ); // ein 10 ms pulse löst die messung aus _pinTrig.set_level( high ); delay_micros( 10 ); _pinTrig.set_level( low ); //_timer.start(); _now = get_current_tick(); // busy waiting ?? while ( _pinEcho.get_level() == low && _timer.elapsed_millis() < timeout ) //while ( _pinEcho.get_level() == low ) ; //_timer.start(); _now = get_current_tick(); while( _pinEcho.get_level() == high ) ; uint32_t tof = get_current_tick() - _now; //double tof = _timer.elapsed_micros(); _dist = 100 * ( ( tof /1000000.0 ) * 340.29 ) / 2; return _dist; } /* void pigSonar::trigger( pigpio::bcm_t bcm, uint32_t level ) { double duration = _timer.elapsed_micros(); // Convert the time into a distance _dist = (duration/2) / 29.1; // Divide by 29.1 or multiply by 0.0343 //double inches = (duration/2) / 74; // Divide by 74 or multiply by 0.0135 } */ /** Die Variante mit WiringPi ist erheblich genauer. Warum? Timer? Code: https://github.com/OmarAflak/HC-SR04-Raspberry-Pi-C- dort: Distance is 27.4614 cm. Distance is 27.4614 cm. Distance is 27.4614 cm. Distance is 27.4614 cm. Distance is 27.4784 cm. Distance is 27.4784 cm. Distance is 27.4614 cm. Distance is 27.4784 cm. Distance is 27.4614 cm. Distance is 27.4784 cm. Distance is 27.4614 cm. Distance is 27.4784 cm. Distance is 27.4614 cm. hier (busy wait): distance: 28.21 distance: 25.9811 distance: 28.3121 distance: 28.2441 distance: 28.4482 distance: 27.9889 distance: 28.0569 distance: 28.0059 distance: 28.2441 distance: 25.3346 distance: 28.0059 distance: 29.0608 distance: 27.9718 distance: 28.0399 distance: 27.9889 Die eigene Variante _ohne_ busy wating mit callback ist logischerweise auch nicht besser. double Sonar::distance(int timeout) { delay(10); digitalWrite(trigger, HIGH); delayMicroseconds(10); digitalWrite(trigger, LOW); now=micros(); while (digitalRead(echo) == LOW && micros()-now