June 12, 2013 | AVR Programming , Python |

Talking to Ultrasonic Distance Sensor HC-SR04 using an ATtiny84

In a previous post, I talked about interfacing an Arduino with the HC-SR04 ultrasonic distance sensor. This time, I will do the same, but using an ATtiny84 and C code - no Arduino hardware or libraries.

The HC-SR04 works as follows:

  • Send a 10us HIGH pulse on the Trigger pin.
  • The sensor sends out a “sonic burst” of 8 cycles.
  • Listen to the Echo pin, and the duration of the next HIGH signal will give you the time taken by the sound to go back and forth from sensor to target.

Here, the PB0 pin is used to send out the 10 us pulse. To measure the width of the echo pulse, we can use a pin-change interrupt and a timer. Here is the idea:

  • Setup pin change interrupt PCINT0 so that any logical change on pin will cause an interrupt.
  • Send a 10 us pulse to the trigger pin.
  • Loop till the PCINT0 interrupt sets a flag to indicate that measurement is done.
  • In the PCINT0 interrupt, start an 8-bit timer when you see a rising edge - ie., the echo pulse has gone from low to high. The 8-bit timer is setup to use the overflow interrupt.
  • The 8-bit counter overflows every time it reaches 255, and so when that interrupt fires, we add 255 to a running 32-bit counter value.
  • In the PCINT0 interrupt, stop 8-bit timer when you see a falling edge - ie., the echo pulse has gone from high to low. Update 32 bit count, and set flag to indicate that the measurement is done.
  • The measured pulse width is in terms of a counter value, and we can convert that into seconds, since we know the clock speed. This time value is then used to calculate the distance.

The distance is then sent using serial communications on pin PB1 - I've covered this part in a previous post. This is also the reason we cannot use the 16-bit timer to measure the pulse width - it's already being used for serial communications. Plus it's fun to learn how to use the 8-bit timer to count large values, right? ;-)

Here is the schematic:

And the breadboard looks like this:


The full C code is listed below:

This is the Makefile that goes along with the above code. It is similar to the ones posted before - I've just added some extra linker flags to support full printf formatting.

And here is the Python code used to plot the data:

The Python code is a minor modification to what I posted before on the subject.

You can get the ATtiny84 at element14.


Need help with a hardware project or product? Drop us an email at We offer consulting services on AVR and Nordic nRF BLE - hardware design, firmware development, prototyping, PCB design/assembly, sourcing and manufacturing. We can help you bring your product to market!

Bluey nRF52 BLE IoT dev board

Check out our Bluey nRF52 BLE development board with built-in Accelerometer/Gyroscope, Temperature/Humidity and Ambient Light sensors. It's a fabulous tool to learn Nordic nRF52 BLE programming and explore IoT technologies.


We love hearing from our readers. Email us at for questions or comments on this article. If you found this article useful, please support us by buying some of our hardware products.

Please sign up for updates

Once in a while, we will send you an email update on the latest Electronut Labs projects and products. Your email address will never be shared or abused, ever.

2016 Electronut Labs. All rights reserved.