2019-09-28 09:25 AM
Hi,
I try to work with the JSN-SR04T distance sensor. The working principle is very simple :
For the moment, I use a simple us timer and a counter incremented by the interrupt of the timer. Each us, I read the state of the echo pin. If state is High, I count until state is Low. Work fine but my guess is that we can do better.
I try with a triggered timer but I am confused with all the options in CubeMX.
How can I have a timer who start when the echo pin is rising and stop when he is falling and get the count of the timer ? Witch event should I read ?
Thanks,
Lionel
2019-09-28 11:22 AM
Use one TIM in PWM mode, define the pulse width as 10us on CH1 (output), connect that to the CH2 (input) pin with a resistor, and then connect that to the sensor pulse in/out pin. Configure CH2 as input capture using the same timebase, but define the period to about 50 ms. CH2 will give you two interrupts, one at approx time zero, and a second when the return comes back, or 38ms if nothing.
2019-09-29 06:00 AM
Hi
Thanks, you confirm that it is possible with only one timer. I try to do what you said but there are several PWM mode and also several input capture mode. Could you make a template CubeMX project for a STM32F4x ? So I can see the right options and adapt to my configuration.
Thanks,
Lionel
2019-09-29 07:10 AM
I'm not using CubeMX, you should perhaps review the assorted HAL, or LL, examples and merge.
For F4 I'd be using the SPL, perhaps look at the servo input/output code I've previously published.
2019-09-30 12:56 AM
Hi
Well, here is my first try for the input capture part. It work almost good ! But sometimes, ICValue_High is greater than ICValue_Low. So, I suspect that the timer don't stop after the second reading. How can I configure the timer for a start at the first reading and a stop at the second reading ?
See my configuration in the picture and the code below :
int main(void)
{
// .... All initializations
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);
while (1)
{
}
}
uint32_t ICValue_High = 0;
uint32_t ICValue_Low = 0;
uint32_t IC_Diff = 0;
uint16_t IC_Index = 0;
uint32_t distance_cm;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
if (IC_Index == 0)
{
/* Get the 1st Input Capture value */
ICValue_High = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
IC_Index = 1;
}
else
if (IC_Index == 1)
{
/* Get the 2nd Input Capture value */
ICValue_Low = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
/* Diff capture computation */
IC_Diff = (ICValue_Low - ICValue_High);
/* Distance */
distance_cm = (IC_Diff*40)/1000;
IC_Index = 0;
}
}
}
2019-09-30 06:38 AM
Hi again !
I try a new version with PWM pulse to activate the sensor and input capture for the response.
I defined a 60 ms period and a 1 us time step for more precision for the result (APB2 clock is 100 MHz).
I use CH3 for the 10 us PWM pulse (but not sure for the pulse value) = pin PA10 (trigger)
I use CH2 for the rising input capture = pin PA9 (echo)
I use CH1 for the falling input capture = pin PA9 (echo)
Problem is that I am a little confused when I must Start and Stop the different Channel !
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_3);
with the callback :
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
The duration of the echo should be :
duration = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) - HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
My CubeMX configuration in the picture joined.
Thanks,
Lionel
2019-10-03 05:31 AM
Hi,
Nobody have an idea of what is wrong in my CubeMX configuration ?:sad_but_relieved_face:
Thank,
Lionel