【Follow me Season 2 Episode 1】Task 3: Proximity Detection
[Copy link]
This post was last edited by eew_Ya3s2d on 2024-10-12 10:02
Hello everyone, I am Zheng Gong, a little engineer who is lost in this world.
My family has been quite busy recently. People in middle age are busy all the time. Just as Zhang Ailing wrote in Half a Lifelong Romance, "Men after middle age often feel lonely, because when they open their eyes, they are surrounded by people who rely on them, but there is no one they can rely on." Oh, wait, we are engineers, let's get back to the topic and talk about Task 3 of the first phase of this FM event. I also spent some time studying this task and did some experiments. Let's talk about the principle first.
The circuit diagram is as follows:
The infrared transmission circuit is very simple, using an npn transistor to drive the infrared transmitting tube.
The infrared receiving circuit uses a dedicated chip VSOP383. I found the schematic diagram on the Internet. The block diagram is as follows
It can be seen that there is a bias circuit in the infrared receiving tube, so there will be a bias voltage when there is no transmission. I tested it with a multimeter and found that the voltage is 0.925v. I tested it with white light and found that the infrared receiving tube is not sensitive to white light. Then the specification also says that the device is sensitive to 38kHz infrared light, and you can see the frequency response in the figure below.
The CPX specification states that A10 can be used as the input pin of the proximity sensor.
Finally, by entering the REPL query, we can see that the pin definition is not A10, but IR_PROXIMITY
(P.S. To enter REPL, you can use mu, open the serial port, use ctr + c to pause the program, and then press enter to enter REPL. REPL stands for "Read-Evaluate-Print Loop", which is an interactive programming environment that allows users to enter code and execute it immediately, and then display the results. This is very useful, especially when you need to troubleshoot code or test new ideas.)
So our program idea is actually very clear, that is, use the IR_TX pin, input a 38khz pulse or multiple pulses, and then immediately read the AD value of IR_PROXIMITY. When an object approaches, the reflected light will be superimposed on the chip bias. The closer it is, the larger the AD value will be.
I wrote a simple code before, and the program can run, just as I guessed, the code is as follows:
import analogio
import digitalio
import board
import time
ir_tx = digitalio.DigitalInOut(board.IR_TX)
ir_tx.direction = digitalio.Direction.OUTPUT
proximity = analogio.AnalogIn(board.IR_PROXIMITY)
delay_time = 0.00001
while True:
for i in range(2):
time.sleep(delay_time)
ir_tx.value = True
time.sleep(delay_time)
ir_tx.value = False
proximity_value = proximity.value
print("proximity Level: %d" % proximity_value)
time.sleep(0.1)
The delay value is determined to be 10 microseconds because the period of the 38khz square wave is 26 microseconds, and the time of the high level and the low level is 13 microseconds. It is roughly estimated that the time to enter and exit the time.sleep function is 3 microseconds. The function is used for rough testing and is not too accurate. I used an oscilloscope to test and saw that the waveform is indeed there. The waveform is as follows:
To be honest, this waveform is a little different from what I imagined. Maybe there is no strict isolation between the transmitter and the receiver. So you can see that the voltage of IR_PROXIMITY rises during the transmission. It's just that when I approach, there is a spike when preparing the low level. When I don't approach, there is no spike. When I was trying to study the internal logic, this waveform disappeared. However, I tested the transmission or reception separately, and there was no problem. After a long time, I didn't understand what went wrong. I was very discouraged for a while. I also studied many posts of forum friends, and I felt that they were almost the same. I was even worried that the 38k input was inaccurate. I used pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=35768) to generate an accurate 38k square wave, but there was no response at all. I don't know if there was any problem when I poked it with an oscilloscope.
Coupled with some trivial matters in life and work, I have been delaying it until now. I think the problem still needs to be solved. Since this road is not feasible, we have to create conditions to complete the task, so I bought an ultrasonic distance sensor
As can be seen from the figure, the CS100A ultrasonic chip is used. The use of this chip is also very simple. Input a high level of more than 10US (generally 50US is recommended) to the TRIG pin, and the chip (TP, TN pins) can send out 8 40KHZ ultrasonic pulses, and then (RP, RN) detect the echo signal. When the echo signal is detected, it is output through the ECHO pin.
The distance value can be calculated based on the duration of the high level output by the ECHO pin. That is, the distance value is: (high level time * 340m/s)/2. When the measured distance exceeds the measurement range, CS100A will still output a high level signal through the ECHO pin, and
the width of the high level is about 33ms.
Measurement cycle: When the chip outputs a high-level pulse through the ECHO pin, the next measurement can be performed, so the measurement cycle depends on the measurement distance. When the distance is very close, the pulse width returned by ECHO is narrow and the measurement cycle is short; when the distance is far, the pulse width returned by ECHO is wide, and the measurement cycle becomes longer accordingly.
In the worst case, the object under test is beyond the measurement range. At this time, the pulse width returned is the longest, about 33ms. Therefore, the measurement period in the worst case can be greater than 33ms (for example, the measurement period can be 50ms).
This is the normal waveform.
This is the waveform out of range
The calculation is actually quite simple. The speed of sound waves in the air is 340m/s = 34000cm/1000ms = 34cm/ms. Distance = time x speed. Considering the round trip, distance = time x speed / 2. Finally, distance = time x 17, in centimeters. From this, we can see that 33ms is also 500+m, which is obviously beyond the range we want to detect.
So I wrote the following code to detect the distance
# 发送出发信号,时间是500us,只要比需求长就可以了
ir_tx.value = True
time.sleep(0.0005)
ir_tx.value = False
rx_count = 0
# 等待回复的高电平
while ir_rx.value is False:
time.sleep(0.0001)
rx_count = rx_count + 1
if rx_count > 10000: # 发送高电平之后等待时间太长,认为是发送失败
break
start_time = time.monotonic_ns() #获取高电平开始的时间戳,单位是ns
while ir_rx.value is True:
pass
end_time = time.monotonic_ns() #获取高电平结束的时间戳,单位是ns
duration = round((end_time - start_time)/1000000, 2)
if duration < 0.05: # 时间太短
continue
print(f'duration time:{duration} ms')
distance = round(duration*17.0, 1) # 时间*340m/s(34cm/ms)/2
print(f'distance:{distance} cm')
The code is not complicated. It just sends a start signal, waits for a reply, uses the time.monotonic_ns() function to get the timestamp, and calculates the time difference between the start and end.
The next thing I need to briefly talk about is the code for playing audio. In fact, it is just a reference (reproduction) of some codes.
CircuitPython Audio Out | Adafruit Circuit Playground Express | Adafruit Learning System
Simply put, use AudioOut in the audioio library as the player, and use WaveFile in audiocore or audioio to load the audio file, so that you can play the audio file.
try:
from audiocore import WaveFile
except ImportError:
from audioio import WaveFile
try:
from audioio import AudioOut
except ImportError:
try:
from audiopwmio import PWMAudioOut as AudioOut
except ImportError:
pass # not always supported by every board!
def play_file(filename):
print("Playing file: " + filename)
wave_file = open(filename, "rb")
with WaveFile(wave_file) as wave:
with AudioOut(board.SPEAKER) as audio:
audio.play(wave)
while audio.playing:
pass
print("Finished")
There is nothing much to say about the light alarm. I have mentioned it before. Because the distance test took too long, I didn’t do anything fancy. You can refer to my previous post
【Follow me Season 2 Episode 1】Task 1: Control the onboard colorful LED, light up the marquee and change the color - DigiKey Technology Zone - Electronic Engineering World - Forum (eeworld.com.cn)
Or wait until I submit the task code and copy it directly.
The professional ultrasonic ranging module is quite accurate. I tested it and the accuracy is at the centimeter level.
|