Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    LOPY HC-SR04 Adaptation

    Scheduled Pinned Locked Moved LoPy
    hc-sr04lopyultrasonic
    13 Posts 4 Posters 4.5k Views 6 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G Offline
      gas
      last edited by

      Hi

      I'm trying to adapt the HC-SR04 library to Lopy but for some reason it just get stuck when reading the Echo pin like never seeing the Pulse
      the code is based on micropython lib
      https://github.com/mithru/MicroPython-Examples/tree/master/08.Sensors/HC-SR04

      Class

      import machine
      from machine import Timer
      
      # Pin configuration.
      
      
      class Ultrasonic:
          def __init__(self, tPin, ePin):
              self.triggerPin = tPin
              self.echoPin = ePin
      
              # Init trigger pin (out)
              self.trigger = machine.Pin(self.triggerPin)
              self.trigger.init(machine.Pin.OUT)
              self.trigger.value(False)
      
              # Init echo pin (in)
              self.echo = machine.Pin(self.echoPin)
              self.echo.init(machine.Pin.IN)
      
          def distance_in_inches(self):
              return (self.distance_in_cm() * 0.3937)
      
          def distance_in_cm(self):
              start = 0
              end = 0
      
              # Create a microseconds counter.
              micros = Timer.Chrono()
              micros.reset()
      
              # Send a 10us pulse.
              self.trigger.value(True)
              Timer.sleep_us(10)
              self.trigger.value(False)
      
              # Wait 'till whe pulse starts.
              while self.echo.value() == 0:
                  start = micros.read_us()
      
              # Wait 'till the pulse is gone.
              while self.echo.value() == 1:
                  end = micros.read_us()
      
              # Deinit the microseconds counter
              micros.stop()
      
              # Calc the duration of the recieved pulse, divide the result by
              # 2 (round-trip) and divide it by 29 (the speed of sound is
              # 340 m/s and that is 29 us/cm).
              dist_in_cm = ((end - start) / 2) / 29
      
              return dist_in_cm
      

      Program

      from machine import Pin
      import time
      import Ultrasonic
      
       sensor1_trigPin = "P20"
       sensor1_echoPin = "P19"
      
      sensor1=Ultrasonic.Ultrasonic(sensor1_trigPin, sensor1_echoPin)
      distance1 = sensor1.distance_in_cm()
      
      
      robert-hhR 1 Reply Last reply Reply Quote 0
      • S Offline
        slagter
        last edited by

        Hi Gas,

        Couple of things that need fixing:

        1. You have to start the Chrono. Insert a "micros.start()" in the Ultrasonic class, just after micros.reset()
        2. Define the pull mode as part of the init of the Pin In and Pin Out: self.trigger.init(machine.Pin.OUT, None)
        3. I would define the pins in the start as: sensor_trigPin = Pin("G16")

        Kind regards,
        Robert

        papasmurphP 1 Reply Last reply Reply Quote 0
        • robert-hhR Offline
          robert-hh @gas
          last edited by

          @gas The other problem is reliable timing, which does not exist on the esp32 or esp8266. At and between every Python statement you may have an extra ~300µs delay due to cache misses.

          1 Reply Last reply Reply Quote 0
          • papasmurphP Offline
            papasmurph @slagter
            last edited by

            @slagter Late response, but anyway: A code example I found for Arduino uses a hardware triggered timer to get the time between trig and echo. Can't the ESP32 do the same thing?

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @papasmurph
              last edited by

              @papasmurph About hardware interrupt latency with this MP port, look here: https://forum.pycom.io/topic/936/pin-interrupt-latency

              papasmurphP 1 Reply Last reply Reply Quote 0
              • papasmurphP Offline
                papasmurph @robert-hh
                last edited by

                @robert-hh But at least it looks like a software problem (potentially solvable via a different approach to handling queueing of events?).

                papasmurphP robert-hhR 2 Replies Last reply Reply Quote 0
                • papasmurphP Offline
                  papasmurph @papasmurph
                  last edited by

                  @papasmurph The principle used in the Arduino is quite different. Can the ESP32 (via Python) support the same as pulseIn? I couldn't see any such link between ports and timers.

                  Somewhat truncated code:

                  // Port configuration
                  pinMode(trigPin, OUTPUT);
                  pinMode(echoPin, INPUT);
                  
                  // Trigger distance sensor (Trig)
                  digitalWrite(trigPin, LOW);
                  delayMicroseconds(2);
                  digitalWrite(trigPin, HIGH);
                  delayMicroseconds(10);
                  digitalWrite(trigPin, LOW);
                  
                  // Read distance pulse (Echo)
                  duration = (float)pulseIn(echoPin, HIGH) / Million;
                  
                  1 Reply Last reply Reply Quote 0
                  • robert-hhR Offline
                    robert-hh @papasmurph
                    last edited by

                    @papasmurph This is a software problem, but somewhere deep buried into the esp-idf. The largest problem is caching of code in flash. The esp cannot execude code from flash. If a section of code is requested, which is not cached, this has to be tranferred into RAM. That causes a latency of typically 300 µs. And as far as I have been told, there is no mechanism to make some code areas sticky. Even if the python scipts themselves are located in RAM, the runtime engine is in flash, as well as other firmware sections. To some extend you could still determine pulse lengths. Look in the board for the DHT11 driver. That's on the level of this Arduino code.

                    papasmurphP 1 Reply Last reply Reply Quote 0
                    • papasmurphP Offline
                      papasmurph @robert-hh
                      last edited by

                      @robert-hh I thought at least internal Flash was directly addressed. I'm aware external Flash is not. Anyway, I made an implementation using this sensor that works rather well, but not with the precision/stability of the Arduino implementation. I can provide the source if anyone's interested.

                      robert-hhR 1 Reply Last reply Reply Quote 0
                      • robert-hhR Offline
                        robert-hh @papasmurph
                        last edited by robert-hh

                        @papasmurph There is no internal flash in the esp32. The external flash is partiallyx memory-mapped, so it looks like internal memory.

                        papasmurphP 1 Reply Last reply Reply Quote 0
                        • papasmurphP Offline
                          papasmurph @robert-hh
                          last edited by

                          @robert-hh The datasheet at https://espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf is not very clear about how Flash is addressed, but there's some Flash.

                          robert-hhR 1 Reply Last reply Reply Quote 0
                          • robert-hhR Offline
                            robert-hh @papasmurph
                            last edited by

                            @papasmurph Yes. I looked into an older data sheet. According to this one, there are variants with embedded flash, internally connected to the SPI controller. So timingwise it behaves like external flash.
                            The model with the number ESP32-D2WD has 16 MBit embedded flash. D/K which one is in the pycom devices. Probably the ones w/o internal flash.

                            papasmurphP 1 Reply Last reply Reply Quote 0
                            • papasmurphP Offline
                              papasmurph @robert-hh
                              last edited by

                              @robert-hh Pick it apart :).

                              1 Reply Last reply Reply Quote 0

                              Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                              Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                              With your input, this post could be even better 💗

                              Register Login
                              • 1 / 1
                              • First post
                                Last post

                              Pycom on Twitter

                              Pycom