Thursday, January 9, 2014

I2C HC-SR04 Sonar Module: ATtiny85 I2C

In this post I will show you how to cheaply  make an I2C sonar sensor for your Arduino. This will be accomplished by making an I2C controller for an HC-SR04 sensor out of an ATtiny85 (or ATtiny45). Both the sensor and the microcontroller can be found online for a few dollars. Together these two parts can save you money while increasing functionality over premade solutions.

If you have not already done so, check out my previous post on a serial sonar sensor. It also discusses running the NewPing library on an ATtiny (my modified TinyNewPing library). I have also done a post on I2C communication. In fact, I even transmitted data from my PING sensor! Check it out HERE.

1) First off, we need an I2C library for your ATtiny. For this you have a few options, but I will only be using one of them. The regular Wire library will not work on the ATtiny side. However, thanks to some great work  by Arduino users BroHogan and Rambo we do have the TinyWire library. The original library by BroHogan can be downloaded HERE. I have used the Master library from it, but for the Slave library I will be using a fork by Rambo. He added a bit more functionality including an onRequest and an onReceive function (which I use in my examples). Find his library HERE (download zip link is in the bottom right corner).

You will also need the ATtiny core for whatever Arduino IDE you are using. In the past I have used the core from High-Low Tech. Now however I prefer the Google Code core. A recent update allows ATtiny support with Arduino 1.5. Anyway, if you need more details on getting an ATtiny running see my previous posts linked above or click on the ATtiny label.

You need to burn your ATtiny85/45 to 8MHz. This is important for stable I2C communication (consider making my ATtiny programming adapter!). You also need my TinyNewPing library installed.

2) Wiring is simple. Connect the 5V from the Arduino to the VCC of the ATTiny and the PING sensor. Connect all the grounds together. Then connect the Trigger and Echo pins of the PING sensor together and to pin 3 (PB3) of the ATtiny85. Next connect the I2C wires. Connect the ATtiny SCL (PB2) to the Arduino SCL (Arduino Uno: A5 , Arduino Mega2560: 21 , Arduino Due: 21). Connect the ATtiny SDA (PB0) to the Arduino SDA (Arduino Uno: A4, Arduino Mega2560: 20 , Arduino Due: 20). Finally, and very importantly, connect 4.7k (on 5V) ohm pull-UP resistors to the SCL and SDA lines.

3) Now you have the libraries installed. Everything is wired up. The only thing left to do is test it. THIS code goes on the ATtiny. It reads one HC-SR04 sensor and acts as the I2C slave. THIS code goes on your other Arduino. I used a Mega, but you can use whatever you have. It requests the data from the slave and then outputs it to the serial monitor.

That is about it. Assuming everything works, you are ready to go. Using this method, you should be able to get sensor data from many sensors at once using only 2 pins on your Arduino. One thing to remember, since they are not all being controlled by the same Arduino, the sensors are not synchronized. As such, they could interfere with each other if they are pointed in the same direction.

Also, I attempted to control multiple sensors with one ATtiny. This worked, sort of. It was buggy and crashed after 15 seconds or so, I suspect do to a I2C buffer issue. Regardless, it made the code more complicated on both sides and the system wasn't as reliable. Besides (I said to myself), ATtinys can be found fairly cheap (especially surface mount ones). My time is worth something. While I got tired of messing with it, if someone else gets it working let me know. I'd be interested to see your code.

There you have it. A cheap I2C ultrasonic ranger for an Arduino (or I2C master device of your choice). If you use this approach in any of your projects I would love to hear about it in the comments. Of course, if you have problems I will do my best to help you with them.



  1. This is such a great project. I followed the instructions step by step and i have a problem. I bootloaded the attiny 85 at 16mhz instead of 8 and i Power it with 5 volts.
    The problem is that if i daisy chain more than 2 on the same I2c line (they all have pullup resistors and they join the I2c bus with a delay of 10 ms each) The entire line get stuck after a little while.


  2. I would have to look more into it. I've always found I2C troublesome on the ATtiny. I just don't feel like I have a deep enough understanding of it to really help you too much. Perhaps in the code the clock speed is defined and must be changed to 16MHz.

    I would try to get I2C running with that many ATtinys without the sonar (maybe you have already done that). Then I would add the sonar module and code. Maybe the sonar delay is messing with it.

    You'd probably be better off asking on the forum. In this case I don't know that I have the expertise to help you. Thanks for reading!

  3. Hi, I am recently trying to connect attiny84 and a gyroscope via I2C. I use arduino uno as ISP to upload my program to attiny. My problem is, I have import the i2c master library in my program from the arduino website, however, when i compie, it shows errors like,"PIN_USI_SCL' was not declared in this scope" . Which part do I make mistake? Is it the library's problem