
There are barriers between a railroad train and a pedestrian or car crossing.
In this project we will realize a system that simulate the operation of automatic barriers for railways trains.
We will design this system using:
two ultrasonic sensors hc-sr04 for the detection of the arrival of the train.
two servomotors to lower or raise the barriers
HC-SR04 sensor
Supply power module
test plate
connecting wires
toy train
To do the assembly, we connected:
the VCC pin to the 3.3V pin of ESP32
the Trig pin to pin D5 of ESP32
the ECHO pin to pin D18 of ESP32
the GND pin to the GND pin of ESP32
For the second sound sensor HC-SR04:
the VCC pin to the 3.3V pin of ESP32
the Trig pin to pin D22 of ESP32
the ECHO pin to pin D23 of ESP32
the GND pin to the GND pin of ESP32
For the first servomotor:
red wire: power supply wire to be connected to the 5V terminal of the power supply module
brown wire: wire to connect to the GND pin of ESP32
Yellow: Positioning signal wire connected to pin D4 of ESP32
For the second servomotor:
red wire: power supply wire to be connected to the 5V terminal of the power supply module
brown wire: wire to connect to the GND pin of ESP32
Yellow: Positioning signal wire connected to pin D21 of ESP32
For LEDs:
the terminals (-) of the LEDs to GND of ESP32
the (+) terminal of the first red LED to pin D2 of ESP32
the (+) terminal of the second red LED to pin D19 of ESP32
Here are the micropython programs that allow you to:
calculate the distance between the HC-SR04 sensor and the detected object
raise or lower barriers
turn LEDs on or off
esp32-barrieres.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import machine from hcsr04 import HCSR04 from machine import Pin from servo import Servo import utime sensor1 = HCSR04(trigger_pin=5,echo_pin=18,echo_timeout_us=1000000) sensor2 = HCSR04(trigger_pin=22,echo_pin=23,echo_timeout_us=1000000) servo1_pin = machine.Pin(4) servo2_pin = machine.Pin(21) my_servo1 = Servo(servo1_pin) my_servo2 = Servo(servo2_pin) led1=Pin(2,Pin.OUT) led2=Pin(19,Pin.OUT) i1=90 i2=90 while True: distance1 = sensor1.distance_cm() distance2 = sensor2.distance_cm() if distance1<4 and distance1>0: # If the hc-sr04 sensor detects the arrival of the train while i1 > 0: led1.value(1) # Turn on the red LED my_servo1.write_angle(i1) # lower the barrier utime.sleep_ms(10) i1-=1 else: # Absent from train while i1 < 90: led1.value(0) # Turn off the red LED my_servo1.write_angle(i1) # raise the barrier utime.sleep_ms(10) i1+=1 if distance2<4 and distance2>0: # If hc-sr04 sensor detects detecte the arrival of train while i2 > 0: led2.value(1) # Turn on the red LED my_servo2.write_angle(i2)# lower the barrier utime.sleep_ms(10) i2-=1 else: # en absent the train while i2 < 90: led2.value(0)# Turn off the red LED my_servo2.write_angle(i2) # raise the barrier utime.sleep_ms(10) i2+=1 |
servo.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
from machine import PWM import math # originally by Radomir Dopieralski http://sheep.art.pl # from https://bitbucket.org/thesheep/micropython-servo class Servo: """ A simple class for controlling hobby servos. Args: pin (machine.Pin): The pin where servo is connected. Must support PWM. freq (int): The frequency of the signal, in hertz. min_us (int): The minimum signal length supported by the servo. max_us (int): The maximum signal length supported by the servo. angle (int): The angle between the minimum and maximum positions. """ def __init__(self, pin, freq=50, min_us=600, max_us=2400, angle=180): self.min_us = min_us self.max_us = max_us self.us = 0 self.freq = freq self.angle = angle self.pwm = PWM(pin, freq=freq, duty=0) def write_us(self, us): """Set the signal to be ``us`` microseconds long. Zero disables it.""" if us == 0: self.pwm.duty(0) return us = min(self.max_us, max(self.min_us, us)) duty = us * 1024 * self.freq // 1000000 self.pwm.duty(duty) def write_angle(self, degrees=None, radians=None): """Move to the specified angle in ``degrees`` or ``radians``.""" if degrees is None: degrees = math.degrees(radians) degrees = degrees % 360 total_range = self.max_us - self.min_us us = self.min_us + total_range * degrees // self.angle self.write_us(us) |
hc-sr04.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import machine, time from machine import Pin __version__ = '0.2.0' __author__ = 'Roberto S鐠嬶箯chez' __license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0" class HCSR04: """ Driver to use the untrasonic sensor HC-SR04. The sensor range is between 2cm and 4m. The timeouts received listening to echo pin are converted to OSError('Out of range') """ # echo_timeout_us is based in chip range limit (400cm) def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30): """ trigger_pin: Output pin to send pulses echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor echo_timeout_us: Timeout in microseconds to listen to echo pin. By default is based in sensor limit range (4m) """ self.echo_timeout_us = echo_timeout_us # Init trigger pin (out) self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None) self.trigger.value(0) # Init echo pin (in) self.echo = Pin(echo_pin, mode=Pin.IN, pull=None) def _send_pulse_and_wait(self): """ Send the pulse to trigger and listen on echo pin. We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received. """ self.trigger.value(0) # Stabilize the sensor time.sleep_us(5) self.trigger.value(1) # Send a 10us pulse. time.sleep_us(10) self.trigger.value(0) try: pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us) return pulse_time except OSError as ex: if ex.args[0] == 110: # 110 = ETIMEDOUT raise OSError('Out of range') raise ex def distance_mm(self): """ Get the distance in milimeters without floating point operations. """ pulse_time = self._send_pulse_and_wait() # To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.34320 mm/us that is 1mm each 2.91us # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582 mm = pulse_time * 100 // 582 return mm def distance_cm(self): """ Get the distance in centimeters with floating point operations. It returns a float """ pulse_time = self._send_pulse_and_wait() # To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.034320 cm/us that is 1cm each 29.1us cms = (pulse_time / 2) / 29.1 return cms |