Attiny2313 Ultrasonic distance (HR-SR04) example

As part of my robot project I need a small microcontroller to do som basic task like measuring distance using a HR-SR04 sensor. I plan to use a raspberry pi as main controller for that robot and as is runs a linux kernel is is not realtime and might be inaccurate for this application. The goal is to have the microcontroller send the measured distance over i2c to the raspberry pi.
180px-HC-SR04

The Ultrasonic module works as explained in the following diagram:

hr-sr04 timing

Lot’s of different examples regarding the HR-SR04 and microcontrollers can be found on the internet. Unfortunately a lot of them are incomplete or contain bad code. So here is yet another example 🙂

Below you can find a very basic schema with a attiny2313, the HR-SR04, an ISP connector and a led with a resistor.

attiny2313_hr-sr04_bb

I used a USBasp device to program the attiny2313 with the following code:

The logic that is executed is straight forward. Distance measurements are done in cycles of 70ms. The cycle is managed using the 16 bit timer of the attiny. See line 43, 44 and 49. This makes the timer go round in an endless loop of 70ms. That’s because the timer is reset (CTC mode on line 43) as soon as it reaches the value of OCR1A line 49.

At the end of each timer loop the method  ISR(TIMER1_COMPA_vect) is called. That method sends the pulse to trigger the HR-SR04 module, line 32-34. The pulse is not required to take exactly 10µs. I found that under 10µs is a problem and that 20µs still worked. 12µs is a safe choice.

The echo pin of the HR-SR04 is connected to the ICP (Input Capture Interrupt) pin of the Attiny2313. Line 45 tells the Attiny2313 to call method  ISR(TIMER1_CAPT_vect) when the signal on the ICP pin goes from 0 to 1 (raising edge). The method contains a if stament to see if it was called during a raising edge or falling edge. On a raising edge it switches the ICP to falling edge detection and then stores the start time. On a falling edge it switches the ICP to raising edge detection and gets the end time to calculate the distance in millimeters.

Then in the main while loop the dist value is evaluated to turn the led on or off. That’s all! In the next article I will discuss how to connect multiple HR-SR04 sensors but still use one timer.

Sources:

  1. http://microhobby.net/30-01-2011/projects/the-distance-measurement-tool/
  2. http://www.robosoftsystems.co.in/wikidocs/index.php?title=Ultrasonic_Sensor_(HC-SR04)
  3. http://extremeelectronics.co.in/avr-tutorials/interfacing-ultrasonic-rangefinder-with-avr-mcus-%E2%80%93-avr-tutorial/

 

2 thoughts on “Attiny2313 Ultrasonic distance (HR-SR04) example

  1. Martin

    I used above sample(code and circuit on breadboard). My LED is constantly ON. Could this be a problem with #define F_CPU 8000000UL or the fact that when I compile, i get this error(sck period):

    c:> avrdude -p attiny2313 -P usbasp -c usbasp -u -U flash:w:kood.hex

    avrdude: warning: cannot set sck period. please check for usbasp firmware update
    .
    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.01s

    avrdude: Device signature = 0x1e910a
    avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

    To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: warning: cannot set sck period. please check for usbasp firmware update
    .
    avrdude: reading input file “kood.hex”
    avrdude: input file kood.hex auto detected as Intel Hex
    avrdude: writing flash (536 bytes):

    Writing | ################################################## | 100% 0.36s

    avrdude: 536 bytes of flash written
    avrdude: verifying flash memory against kood.hex:
    avrdude: load data flash data from input file kood.hex:
    avrdude: input file kood.hex auto detected as Intel Hex
    avrdude: input file kood.hex contains 536 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.16s

    avrdude: verifying …
    avrdude: 536 bytes of flash verified

    avrdude done. Thank you.

  2. Martin

    I finally found out what was wrong. The global variables have to be declared volatile so that they would be accessible in the functions.

    PS: If you want the LED to turn off, if an objekt gets to close, you can give a greater value to “distance” variable on rising edge.

     

Leave a Reply

Your email address will not be published. Required fields are marked *