Designing and Making Three Different ATtiny45 Based Boards in Order to Communicate via I²C

After Emma’s lecture, I designed three different MCU boards. I drew schematics and layouts using Eagle. Board's features:

I got confused several times and wondered which ATtiny pin refers to which Ardunio pin. Showing PWM pins as well, these pin keys helped:

I²C bridge

I²C slave w/ phototransistor

I²C slave w/ RGB LED

I drilled two holes into the board in order to jump over traces. I didn’t want to use 0 Ω resistors to bridges traces. A wire on the board's backside connects the traces.

PCB milling and producing was a mishap. The end mill was old and traces were super rough. I smoothed traces using a cutter which in turn was too rude. Several traces were damaged. I used a multimeter to check traces and connections. Soldering some wires, I repaired broken traces. The phototransistor didn’t properly work. I changed its orientation in order to fix the problem.

Please download original Eagle design files here.

Programming an I²C Network Based on Arduino and TinyWire Libraries

After reflecting about serial communication and I²C, I decided to use I²C. Emma told us that I²C got most advantages compared to asynchronous serial communication and SPI. It just uses two wires and a master device (bridge) would be able to support up to 1008 slave devices. A 4 pin header would connect devices’ VCC, GND, SDA (data) and SCL (clock). I²C is synchronized communication. A first byte sends a device’s address followed by several data bytes. Each slave device has his own address.

Arduino provides a Wire library. This library empowers an Arduino board to communicate via I²C. Fortunately, ATtiny series are supported by a modified library called TinyWire. There’s a TinyWireM library which should be used by a master device and a TinyWireS which should be used by some slave devices.

I made a lot of research. Most important sources were:

First I tested my boards using a standard AVR Terminal command: avrdude -c usbtiny -p t45. All boards seemed to properly work.

Calibration of internal clock and serial communication

Using an Arduino script, I tested master to computer serial communication as well. I downloaded and installed the TinyWire libraries in order to communicate via I²C using ATtiny45 microcontrollers. I modified Aser Nabil’s Arduino script in order to test master to computer serial communication a second time.

All MCU boards didn’t have an external clock. I calibrated the bridge board’s internal clock using an Arduino script written by Zaerc. If you don't have an external clock onboard, please download and use this script to calibrate an internal clock! Run the script (don’t forget to correctly set RX and TX), read the serial monitor output and choose a value in the middle of a stable section. Copy this value into your script’s void setup() section in order to set an internal clock. My ATtiny45 MCU got a stable clock at e.g. OSCCAL= 0x99. Correctly setting the clock provides, among others, a proper serial communication.

I²C—slave sending data to master

My concept was to connect all 3 boards. In order to control light, the master should read data of a slave with a phototransistor onboard and send a command to a slave with a RGB LED onboard.

If it would be dark, light would shine. The darker it would be, the brighter the light would shine.

I had a lot of problems to set up I²C. Due to broken traces, first my slave device with RGB LED onboard didn’t communicate as mentioned above. I soldered pieces of wire onto the broken traces to repair it. That worked. I wrote an Arduino script in order to test the RGB LED and was pleased with blinking lights.

For some reasons the phototransistor didn’t work properly. The data wasn’t suitable in my opinion. I changed its orientation and soldered a new phototransistor onto the board. It didn’t help! This time, the phototransistor didn’t work as expected (I successfully used it before—please see input devices). Or, probably, the communication didn’t work?

Finally, I was able to send bytes from slave to master. I tried to send data from master to slave. Somehow, it worked. I switched on a LED. I tried to send a byte back to the master but couldn’t absolutely tell if it worked. The read data wasn’t clear. I didn’t successfully program a slave receiving data, doing something (e.g. switching on a LED) and sending back data to a master (testing the communication). I tried to implement my network concept described above and spent hours and hours to try and code and try and code.

It was late at night. I didn’t have enough time to document all my experiments. There were plenty of scripts, photos and videos. Please download all scripts here.

Reading an I²C slave input device w/ phototransistor onboard

I read that the TinyWireS library doesn’t work with a delay() command at all!

Anyway, I wanted to give it a last try and set up a I²C network based on the TinyWire libraries. I wrote two scripts. The slave w/ a phototransistor onboard reads the value of the sensor, maps the 10-bit input data to a 8-bit byte and sends it to the master. The master sends the data to the Arduino serial monitor via FTDI.

The slave sent data to the master and I could read it using the Arduino serial monitor. Using a light, I was able to change the input value of the phototransistor. The serial monitor displayed it with long delay. Bright light gave a value of 4 (flash light of my smartphone). No light gave a value of 64. It should be more than 200. So, probably, the phototransistor or the board was faulty. I would have to check the hardware again.

I²C—master controlling a slave w/ a RGB LED

I wrote two more scripts. The master sends a fixed byte to the slave w/ a RGB LED onboard. I set DataP and tried different values of 0, 255, 128, 200, 235. Yes, it worked well. The green LED connected to a PWM pin changed its brightness!

I modified the I²C master script. I ascertained that the TinyWireM library didn’t work with a delay() as well. I removed it and tried it without the command. I successfully sent two different values—valueOne = 5 and valueTwo = 245—to the slave. The green LED changed it brightness in a very irregular way. Please see the video below.

I modified the I²C master script one last time. The bridge should receive data from the slave w/ the phototransistor onboard and send the phototransistor’s value to the slave w/ the RGB LED onbard in order to control the green LED connected to the PWM pin. For some reason, it didn’t work. Using the Arduino serial monitor, I read the value of the phototransistor. Now, it was always 0.

Finally, I wasn’t happy with the I²C network based on the TinyWire libraries. The communication seemed to be irregular and wouldn’t be sufficient to smoothly control a LED with a phototransistor. Besides, using the TinyWire libraries, I wasn’t able to send data from a slave to a master to another slave. Probably, the Wire library would provide a solution but it isn’t compatible with an ATtiny MCU.