1

Assume I have a STM32F4 with a system clock 8MHz, and time(TIM3_PSC = 39). I'm interfacing the ultrasonic sensor HC-SR04

I'm doing timer interrupt and would like to calculate the distance and the MAX distance that can be calculated.

So my work is : 1/8MHz * TIM32_PSC = 0.000000125 * 40 = 5uS is the timer period.

assuming the following code:

float distance; // in m
    …
void TIM3_IRQHandler(void)
{
    static uint16_t left;
    if (…)
    {
        left = TIM3->CCR1;
    } 
    else
    {
        uint16_t right = TIM3->CCR1;
        distance = ______________________________________________
    }
    TIM3->SR &= ~TIM_SR_CC1IF;
}

so distance should be = (right - left * 340/2)

is that right ?

and for max distance it's MaxDistance = 340m/s / 5uS = 68Meters ?

  • I'm not familiar with ultrasonic ranging. What are `left` & `rigth`? – Tagli Jan 28 '21 at 15:29
  • @Tagli Left and Right sensor reading – andrelamothe Jan 28 '21 at 15:36
  • 1
    Doesn't seem right. (right-left) should be in parenthesis if nothing else, and you definitely mean `us` or `usec`, not `uS` (micro Siemens). But anyway without diving into it too much, that formula seems bogus; the 5us timer period has to be in there somehow, since you don't multiply your left and right values with any physical time unit. You may have better luck finding a qualified answer if you de-localize your question a bit. – dialer Jan 28 '21 at 15:53
  • @dialer I'm getting the difference of Right - Left sensor reading,... then I multiply by physical unit speed of sound 340, and since I have two sensors I divide by 2. – andrelamothe Jan 28 '21 at 16:15

2 Answers2

2

I still don't understand what do left & rigth stand for in your code but here is the the way how I would implement it:

  1. Configure the timer in capture mode with 5 us ticks (or some other value). Don't start it. Enable capture and update (overflow) event interrupts.
  2. When you want to make a measurement, reset timer counter & start timer & trigger signal transfers (in case of multiple sensors, start all of them at the same time)
  3. Wait for capture event interrupts. This should work same for multiple channels (for multiple sensors).
  4. For each capture interrupt, get the corresponding CCR register value as capture[n].
  5. Let the timer run. It will trigger the update (overflow) interrupt eventually.
  6. In the update (overflow) interrupt, look for the channels that you didn't get capture interrupts. The ones you didn't get interrupt are out of range. Stop the timer in update interrupt.
  7. For each captured channel, distance = (capture[n] * 5) * 10^-6 * 340 in meters.
Tagli
  • 2,412
  • 2
  • 11
  • 14
1

Dimensional analysis would help. I'm assuming that your 5us/tick scale is correct - I didn't check. You should be easily able to figure that one out. Hint: count ticks between a button press and button release, then hold down a button for one second :)

  • left and right are in timer tick units for one-way distance - you have to divide these values by 2 if they are the forward+reflected distances,
  • one tick unit is 5us,
  • speed of sound is 340m/s.

Thus:

distance = (right-left) * 5us/tick * 340m/s

      [                s     m ]
[m] = [ (tick-tick) *------*---]
      [               tick   s ]

      [ tick    s     m ]
    = [------*------*---]
      [  1     tick   s ]

      [ m ]
    = [---] = [m]
      [ 1 ]

In C:

// floating point
float distance = (right - left) * 5E-6 * 340.0;

In integers, 1mm would be a reasonable output unit, as there's 1.7mm sound travel per tick. But internal computation needs to be done in dmm (deca-millimeter = 0.1mm) units to retain accuracy.

// integer, in 1mm units
int distance = ((right - left) * (340*5E-6/1E-4) + 5) / 10;

Dimensional analysis:

       [                 m    s    / m          ]
       [ (tick - tick) *---*------/----- + dmm  ]
       [                 s   tick/  dmm         ]
[mm] = [----------------------------------------]
       [                    dmm                 ]
       [                   -----                ]
       [                     mm                 ]

       [         m     dmm        ]
       [ tick *------*----- + dmm ]
       [        tick    m         ]
     = [--------------------------]
       [             dmm          ]
       [            -----         ]
       [              mm          ]

       [               mm  ]
     = [ (dmm + dmm)*----- ] = [mm]
       [              dmm  ]

Again, 1dmm = 0.1mm.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313