Further consideration of HC04 ultrasonic module ranging, hc04 Ultrasonic Ranging
Later, I used 51 to drive this Module Multiple times. Sometimes I needed ranging and used it several times. I always felt that my last program was not very good, so I improved it this time. Although the average value is obtained for the previous measurement multiple times, the error data exists in the middle of the rule.
The previous program is as follows (ranging part ):
U32t = 0;
Inti = 0;
FloatlengthTemp = 0;
Floatsum = 0;
While (I! = 5)
{
TRIG_Send = 1; // high-level output of the sending Port
Delay_Us (20 );
TRIG_Send = 0;
While (ECHO_Reci = 0); // wait for the receiving port to output a high level
OpenTimerForHc (); // enable the timer.
I = I + 1;
While (ECHO_Reci = 1 );
CloseTimerForHc (); // disable the timer
T = GetEchoTimer (); // obtain the time. The resolution is 1 us.
LengthTemp = (float) t/58.0); // cm
Sum = lengthTemp + sum;
}
LengthTemp = sum/5.0;
ReturnlengthTemp;
That is, when the measurement range is exceeded (3.4 meters), the data is definitely not accurate. In addition, if the module does not receive the returned ultrasound for some reason, it will also lead to incorrect data, even if the average value is obtained, if there is a large data in the middle, the calculation results are also inaccurate.
The procedure for using this module again with 51 is as follows:
/* Get the error within 1cm of the current distance from 2018.3.5 */float get_distence () {unsigned long int time_buf = 0; // The total time consumed float distence = 0; // calculate the total distance from float sum = 0; // The total distance from multiple computations uchar I = 0; while (I <NUM) {time_flag = 0; // clear the sr04_start () sign first; // start ranging while (! ECHO); // wait for a 40 kHz pulse. After the signal is triggered, the echo will become a high-level time_0_start (); // when the trig is increased by 10 us, the module starts to emit 8 40 kHz pulses. At the same time, the echo function becomes high-frequency and the timer is enabled. While (ECHO); // wait for the echo signal. when it receives the ECHO signal, the echo changes to a low level. TR0 = 0; // disable the timer if (time_flag! = 0) // continue out of the measurement range; // do not calculate. Discard this measurement and remeasure else // time_flag = 0, not exceeding the measurement range {time_buf = (TH0 * 256) + TL0; distence = time_buf * 0.0168; // (unit: cm) although the speed of sound is 340 m/s, 0.0168 is found to be more accurate, it may be related to the temperature. sum + = distence; I ++ ;}} return (sum/NUM); // obtain the average of NUM times}
In fact, it is to judge whether the timer is interrupted before calculation. If the timer is interrupted, the data is discarded and then measured again. The data obtained in this way is very accurate. The only error is the above calculation of the sound speed, resulting in a 1-2cm error.
16-bit timer, 12 m crystal oscillator, Timer mode 1, counting from 0, maximum to 65535, the time required for an overflow is 0.065 s, the sound speed is 340 m/s. The overflow distance is 22.1 m, which is far beyond the measurement range of the ultrasonic module (0-5 m). Therefore, if an overflow occurs, it can be considered to be out of the measurement range ..
So in the timer interrupt function:
Void TIME0 () interrupt 1 {// TF0 = 0; // Mode 1 hardware is automatically cleared TH0 = 0; TL0 = 0; time_flag ++ ;}
Some operations are simply encapsulated. Start the ranging function to pull the TRIG pin as required
/* Start */void sr04_start () {TRIG = 1; delay_10us (5); // pull height 50us TRIG = 0 ;}
In addition, the timer starts the function. In this function, the Count must be cleared:
/* Enable the timer 0 and clear the previous count before enabling it. Otherwise, the count will be accumulated */void time_0_start () {TH0 = 0; // The count is cleared before enabling TL0 = 0; TR0 = 1; // enable the timer}
Then there is the initialization function of the module. during initialization, it is actually the initialization of the timer. By the way, the TRIG and ECHO pins are set to 0;
Void sr04_init () {TRIG = 0; ECHO = 0; TMOD | = 0X01; // set 1TH0 = 0 in timer 0 mode; // count TL0 = 0 from 0; TR0 = 0; // disable the timer EA = 1; // enable the total interrupt ET0 = 1; // allow the timer to interrupt 0}