Introduction
Programmable System on Chip (PSoC) is a component that mixes a CPU core (ranging from an 8-bit device to a dual-core 32-bit ARM Cortex-M4) and a configurable mixed-signal array. This way of designing is very powerful – while the CPU is used for computational tasks, peripherals are routed and used without any CPU load.
I would like to show you a pretty simple device, an ultrasonic range finder. Internal components of the PSoC can be arranged in a way that the measurement is taken periodically in the background and CPU is used only for the initial components’ setup and a final result collection. Very low cost (ca. $4) PSoC 4 CY8CKIT-049 42XX Prototyping Kit is used, https://www.cypress.com/documentation/development-kitsboards/psoc-4-cy8ckit-049-4xxx-prototyping-kits .
How does it work
Ultrasonic module
Ultrasonic ranging module HC-SR04 is a very popular module for hobbyists. It provides a fairly easy to use interface – besides from power and ground pins (5V power supply), there are two pins named Trigger and Echo. Trigger accepts a 10 us wide pulse to start the distance measurement. Echo sets the output to a logic high, proportional to the distance of an object to the module.
Trigger controls an ultrasonic transmitter and internally the trigger pulse starts an 8 cycle sonic burst. Waves travel distance from the transmitter to an object (or more object) from which they reflect. These waves travel the same distance back to the receiver that detects them. Finally, Echo pin provides a pulse with the same length as the travel time of the waves (both directions).
In ideal conditions, the speed of sound is about 343 m/s at 20 Centigrade. Wikipedia has an article with all the equations and some table values: https://en.wikipedia.org/wiki/Speed_of_sound
I am going to describe the pulse generation and processing in the following text.
Because the PSoC kit is powered from the USB port and already has a 5 V supply, it can be directly attached the HC-SR04 module to it using 4 wires.
Schematics
Here is the schematics captured in PSoC Creator, which is the IDE pro PSoCs. Unlike traditional IDEs, one part of the design is capturing the internal schematics to be programmed in the chips (an optionally also external connection, but these are just for reference – for example the switch and LED with a resistor). The on-board switch and LED are not used, I only keep them on the schematics, because these are the only user interface components of this development kit.
To keep the bill of material on minimum, UART is used for sending the measured data over the kit’s on board UART<>USB converter. Any terminal software serves as a display, I used common 115 200 Bd/s, 8 data bits, no parity and 1 stop bit.
Note: Bootloadable component reveals I used a bootloader – the kit has no integrated programmer, just a USB to serial converter. It works great until you accidentally overwrite the code and need a separate programmer to upload it back (I haven’t experienced this, yet).
Trigger
The first part is to generate the Trigger signal. I used a 100 kHz clock to drive a PWM. Period is set to 50 000 and Compare to 1. Why these numbers? 100 kHz means a period of 1 / 100 000 = 10 us . This setting will drive the PWM output high for 1 period of 10 us and then low for 500 ms (50 000 periods of 10 us). Effectively, ultrasonic measurement will be triggered every half a second.
Echo
The Echo pin on the ultrasonic module is connected to a Timer Counter component, actually to 4 inputs of it. The circuit provides the following function: when a pulse arrives, it resets the counter to zero. It also starts the counter and counts as long as the capture pin is in logic high. The actual count depends on the frequency of the connected clock source. When the Echo pin gets back to logic zero, it stops the counter, ends the capture and generates an interrupt.
Now comes the fun part. Let’s say the speed of sound is ca. 340 m/s at 20 Centigrade. 340 m/s = 34 000 cm/s . If I want to measure distances with a 1 cm resolution (note: claimed resolution of the HC-SR04 module is 0.3 cm), it will take 1 / 34 000 of a second (which is a period of 34 kHz oscillator).
However, the sound travels the distance twice. From the transmitter to the distant object and the reflection goes back to the receiver. This is why I chose a half clock frequency of only 17 kHz – the counter already measures periods divided by two. All this is set up in order to get the timer output value as the module to object distance in centimetres directly.
Timer_Echo is a 16-bit counter and values from 1 to 65535 cm are more than enough for this kind of measurement. The ultrasonic module has a range of a few meters, but it is hard to measure the exact range indoors as the waves get reflected also by surrounding objects. Based on my tests, minimum distance is ca 5 cm.
Firmware
The PSoC firmware is straightforward. It starts all the components (timer, PWM and serial port module), registers an interrupt service routine (ISR) for the Echo timer and than loops in an endless cycle.
As soon as the timer finishes the time capture event, the ISR just sets a flag for the main program so it knows when to print the measured distance. No math is done in the code.
/* Ultrasonic range meter David Koudela, 2019 */ #include "project.h" #include <stdio.h> uint8_t echo_flag = 0; uint16_t echo_distance; char serial_output[20]; CY_ISR( Timer_Int_Handler ) { // read centimeters echo_distance = Timer_Echo_ReadCapture(); echo_flag = 1; Timer_Echo_ClearInterrupt ( Timer_Echo_INTR_MASK_CC_MATCH ); } int main(void) { CyGlobalIntEnable; /* Enable global interrupts. */ // Start up code - enable UART, PWM and Timer used for ultrasonic module UART_Start(); Timer_Echo_Start(); PWM_Trigger_Start(); // Registration of Timer ISR Timer_Echo_Int_StartEx( Timer_Int_Handler ); for(;;) { // if a distance was measured, print the distance and clear the flag while ( echo_flag == 1 ) { sprintf(serial_output, "%d cm", echo_distance); UART_UartPutString(serial_output); UART_UartPutCRLF(0u); CyGlobalIntDisable; /* Disable global interrupts, so the flag gets cleared. */ echo_flag = 0; CyGlobalIntEnable; /* Enable global interrupts after the flag is cleared. */ } } } /* [] END OF FILE */
Test setup
In order to test the circuit, I built a simple setup. The circuitry has been installed into a paper box from a Raspberry Pi power supply.
The ultrasonic sensor needs to see the surrounding world.
And here is the final test layout.
The PSoC is connected to a laptop, which shows a terminal program. Every half a second, new distance to object is sent. The reflection is made using the green cube (which I borrowed from our daughter). A tape measure is used to compare the PSoC output to the reality.
Video
Here is a video proof of a working circuit.
As you can see, there is a slight offset (ca 1 cm) on the overall length and there is also a difference made by a different speed of sound that set (I measured at 26 Centigrade with almost 70 % of relative humidity). The offset could be set by a simple adding or subtracting a constant to the measured value (which I didn’t want to touch in this example) and the adjustment to a different speed of sound could be done by changing the Timer_Echo clock frequency (in this case make it slightly higher).
I also wasn’t always able to hold the sensor and the cube in a straight line to get a perfect refection (when the value suddenly jumps +/- 30 cm).
The sensor was the cheapest one I could get, so I wasn’t expecting a super precise measurement. When reflected from a larger object (a wall in my case), it is possible to measure up to ca. 5 meters.
Please find the project files (a complete workspace for PSoC Creator) in the attached archive.
Thanks for reading and watching.
David
Top Comments