LAB: Input Capture - Ultrasonic

Date: 2024-10-10

Author/Partner:

Github: repository link

Demo Video: Youtube link

PDF version:

Introduction

In this lab, you are required to create a simple program that uses input capture mode to measure the distance using an ultrasonic distance sensor. The sensor also needs trigger pulses that can be generated by using the timer output.

You must submit

  • LAB Report (*.pdf & *.md)

  • Zip source files(main*.c, ecRCC.h, ecGPIO.h, ecSysTick.c etc...).

    • Only the source files. Do not submit project files

Requirement

Hardware

  • MCU

    • NUCLEO-F411RE

  • Actuator/Sensor/Others:

    • HC-SR04

    • breadboard

Software

  • Keil uVision, CMSIS, EC_HAL library


Tutorial: USART with Serial Monitor TeraTerm

Understand how to use serial monitor (TeraTerm) to display charicters(string) on PC sent from MCU.


Tutorial: STM-Arduino

We are going to create a simple program that measure distance by using ultrasonic sensor ‘HC-SR04’ and print out result through UART communication.

Procedure

  1. Create a new project under the directory \EC\LAB\TIMER_ICAP

  2. Open Arduino IDE and Create a new program named as ‘TU_arduino_TIMER_ICAP.ino’.

  3. Write the following code.

  4. upload and run.

const int trigPin = 10;   // Trigger pin : PWM out
const int echoPin = 7;    // Echo pin : Interrupt in

unsigned long duration;
float distance;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);

  duration = pulseIn(echoPin, HIGH);
  distance = (float)duration / 58.0;
  
  Serial.printf("duration : %d Distance : ", duration);
  Serial.print(distance);
  Serial.println(" [cm]");
  delay(500);
}

Click on Upload button.

Open ‘Tera Term’ and make New Connection.

Ultrasonic sensor ‘HC-SR04’ get trigger signal as 10[us] pwm through trig pin which generate on D10 pin. Also, you should capture the echo signal on D7 pin and measure its pulse-width to calculate the distance.

Press the reset button(black) and verify the operation. The distance between ultrasonic sensor and obstacle will be shown in Tera Term.

Click on Upload button.

Press the reset button(black) and verify the operation. The distance between ultrasonic sensor and obstacle will be shown in Tera Term.


Problem 1: Create HAL library

Create HAL library

Declare and Define the following functions in your library. You must update your header files located in the directory EC \lib\.

Download Library Header Files

ecCAP2.h

/* Input Capture*/
// ICn selection according to CHn
#define FIRST 1
#define SECOND 2

// Edge Type
#define IC_RISE 0
#define IC_FALL 1
#define IC_BOTH 2

// IC Number
#define IC_1 1
#define IC_2 2
#define IC_3 3
#define IC_4 4

void ICAP_pinmap(PinName_t pinName, TIM_TypeDef **TIMx, int *chN);
void ICAP_init(PinName_t pinName);
void ICAP_setup(PinName_t pinName, int ICn, int edge_type);
void ICAP_counter_us(PinName_t pinName, int usec);
uint32_t ICAP_capture(TIM_TypeDef* TIMx, uint32_t ICn);

Problem 2: Ultrasonic Distance Sensor (HC-SR04)

The HC-SR04 ultrasonic distance sensor. This economical sensor provides 2cm to 400cm of non-contact measurement functionality with a ranging accuracy that can reach up to 3mm. Each HC-SR04 module includes an ultrasonic transmitter, a receiver and a control circuit.

The HC-SR04 Ultrasonic Range Sensor Features:

  • Input Voltage: 5V

  • Current Draw: 20mA (Max)

  • Digital Output: 5V

  • Digital Output: 0V (Low)

  • Sensing Angle: 30° Cone

  • Angle of Effect: 15° Cone

  • Ultrasonic Frequency: 40kHz

  • Range: 2cm - 400cm

Procedure

1. Create a new project under the directory \repos\EC\LAB\LAB_TIMER_ICAP

  • The project name is “LAB_TIMER_ICAP”.

  • Create a new source file named as “LAB_TIMER_ICAP.c”

You MUST write your name on the source file inside the comment section.

2. Include your updated library in \repos\EC\lib\ to your project.

Now, your ecSTM32F4v2.h should be updated with

// EC course Library
#include "ecPinNames.h"
#include "ecRCC2.h"
#include "ecGPIO2.h"
#include "ecEXTI2.h"
#include "ecSysTick2.h"
#include "ecTIM2.h"
#include "ecPWM2.h"
#include "ecICAP2.h"
#include "ecUART2_simple.h"

3. Connect the HC-SR04 ultrasonic distance sensor to MCU pins(PA6 - trigger, PB6 - echo), VCC and GND

Measurement of Distance

The program needs to

  • Generate a trigger pulse as PWM to the sensor.

  • Receive echo pulses from the ultrasonic sensor

  • Measure the distance by calculating pulse-width of the echo pulse.

  • Display measured distance in [cm] on serial monitor of Tera-Term for

    (a) 10mm (b) 50mm (c) 100mm

Configuration

System Clock
PWM
Input Capture

PLL (84MHz)

PA6 (TIM3_CH1)

PB6 (TIM4_CH1)

AF, Push-Pull, No Pull-up Pull-down, Fast

AF, No Pull-up Pull-down

PWM period: 50msec pulse width: 10usec

Counter Clock : 0.1MHz (10us) TI4 -> IC1 (rising edge) TI4 -> IC2 (falling edge)

Circuit Diagram

You need to include the circuit diagram

Discussion

  1. There can be an over-capture case, when a new capture interrupt occurs before reading the CCR value. When does it occur and how can you calculate the time span accurately between two captures?

Answer discussion questions

  1. In the tutorial, what is the accuracy when measuring the period of 1Hz square wave? Show your result.

Answer discussion questions

Code

Your code goes here: ADD Code LINK such as github

Explain your source code with necessary comments.

// YOUR MAIN CODE ONLY
// YOUR CODE

Example Code

/**
******************************************************************************
* @author  SSSLAB
* @Mod		 2023-10-31 by YKKIM  	
* @brief   Embedded Controller:  LAB - Timer Input Capture 
*					 						- with Ultrasonic Distance Sensor
* 
******************************************************************************
*/

#include "stm32f411xe.h"
#include "math.h"
#include "ecSTM32F4v2.h"

uint32_t ovf_cnt = 0;
float distance = 0;
float timeInterval = 0;
float time1 = 0;
float time2 = 0;

#define TRIG PA_6
#define ECHO PB_6

void setup(void);

int main(void){
	
	setup();
	
	while(1){
		distance = (float) timeInterval * 340.0 / 2.0 / 10.0; 	// [mm] -> [cm]
		printf("%f cm\r\n", distance);
		delay_ms(500);
	}
}

void TIM4_IRQHandler(void){
	if(is_UIF(TIM4)){                     // Update interrupt
		__________													// overflow count
		clear_UIF(TIM4);  							    // clear update interrupt flag
	}
	if(is_CCIF(TIM4, 1)){ 								// TIM4_Ch1 (IC1) Capture Flag. Rising Edge Detect
		time1 = __________;									// Capture TimeStart
		clear_CCIF(TIM4, 1);                // clear capture/compare interrupt flag 
	}								                      
	else if(__________){ 									// TIM4_Ch2 (IC2) Capture Flag. Falling Edge Detect
		time2 = __________;									// Capture TimeEnd
		timeInterval = __________; 	// (10us * counter pulse -> [msec] unit) Total time of echo pulse
		ovf_cnt = 0;                        // overflow reset
		clear_CCIF(TIM4,2);								  // clear capture/compare interrupt flag 
	}
}

void setup(){

	RCC_PLL_init(); 
	SysTick_init();
	UART2_init();
  
// PWM configuration ---------------------------------------------------------------------	
	__________;			// PA_6: Ultrasonic trig pulse
	PWM_period_us(TRIG, 50000);    // PWM of 50ms period. Use period_us()
	PWM_pulsewidth_us(TRIG, 10);   // PWM pulse width of 10us
	
	
// Input Capture configuration -----------------------------------------------------------------------	
	__________;    	// PB_6 as input caputre
 	ICAP_counter_us(ECHO, 10);   	// ICAP counter step time as 10us
	ICAP_setup(ECHO, 1, IC_RISE);  // TIM4_CH1 as IC1 , rising edge detect
	__________;  // TIM4_CH2 as IC2 , falling edge detect

}

Results

Experiment images and results

Show experiment images /results

Add demo video link

Reference

Complete list of all references used (github, blog, paper, etc)

Troubleshooting

(Option) You can write Troubleshooting section

Last updated