This week's assigment was to make multiple boards and have them talk to each other. As the latest version of Marlin firmware for 3d printers supports I2C, so I chose it for the network I would use for this excercise. One of my long term goals is to design my own motherboard for my 3d printer, and being able to use I2C networking with it would let me increase the capacity of the printer even further.
I2C network is one of the few different solutions for making separate digital integrated circuits talk to eachother. There needs to be atleast one master chip, but as long as they take turns, its possible to have multiple masters on the network. Then there needs to be slaves on the network. For my final project, each of the features could be its own circuit connected only by the 2 lines needed for the I2C network.
The slaves can then be much more dedicated, for example one can be just the voltage measuring, with its results being delivered to the master for processing. With enough address space for 1008 slave devices, its possible to spread things out.
As I finally have my final project locked down, I took the opportunity to try out the different features I plan to make for it. For my final project, I am making the multimeter, so the features I am trying are the voltage, resistance, ampere measurements in addition to the short-circuit checking.
As I started looking into programming my network with Arduino I ran into a minor problem; the wire.h library is not supported for ATtiny 45 or 44. As I use tiny45 for my slave chips, this is a problem. Fortunately I did find a user written library that adapted things for the ATtiny chips. http://playground.arduino.cc/Code/USIi2c
So while I can use the basic wire.h library for the master board, I need to use this TinyWireS library for the ATtiny chips. For future reference, there is also a TinyWireM library for using the ATTiny chips as master, but I figure the master board needs most room for code. By default the Arduino IDE doesn't have support for barebones AtMega328 chip that I use as my master, I needed to install additional chip libraries http://playground.arduino.cc/Main/ArduinoOnOtherAtmelChips These libraries were installed into Arduino IDE, by adding the board manager urls into Arduino IDE settings. As shown in the figure.
While the Arduino boards have the ATmega328 chip in them, the libraries for them in the Arduino IDE assumes specific components at the expected pins. To use the default Arduino libraries that come with the IDE I would have to make my board partially identical to the Arduino board.
With the barebones library, there are no predefined pins, and one is free to use the chip as one sees fit.
Of these libraries, the minicore one was that had the support for the ATmega328p I was using as my master chip. But on this page you can find the support for pretty much all the different AVR chips. From the 4 boards I designed I managed to make 3, the master, beep and volt boards, the ampere measurement board needs a shunt resistor that is not in the lab inventory. Since I didnt use a simple slave board, but made unique boards designing them and making them took more time than I anticipated, not to mention I found a design flaw in my master board, that required the making of a new master.
As one of my extracurricular projects, I have been working on a hat for the raspberry zero I use to program my chips. This board takes advantage of the fact that raspberry pi itself already has the capacity for serial communications making a ftdi cable unnecessary, and ISP programming meaning one doesnt need to have a separate programmer made earlier to make a programmer. This solves the chicken or the egg problem with the programming sticks from the 4th week. This is why I named it AVR origin. Since raspi also has the pins for I2C I have also brought them to the hat, allowing one to include it in the I2C network.
For this weeks assignment I had to make a new board, I ordered some ATtiny841 chips from Digikey, as it has an integrated I2C slave functionality plus hardware UART for me to work with. While the basic ATtiny44 pinout is close enough to use in the design, getting AVRdude to work with it takes some tweaking. As such the AVRdude doesnt have the code for the 841 included in its config file so it needs to be added.
The data that needs to be added for AVRdude into its avrdude.conf file. But also if you use Arduino as your programming IDE you'll need to add couple libraries. You need to add into the arduino settings, additional boards manager URLs, this address. http://drazzy.com/package_drazzy.com_index.json It lets you download the support for the ATtiny chips, including the ATtiny841.
In addition to that I needed to use WireS Library by Orangkucing, it allowed me to use the ATtiny841 as a slave. In my final network I had two slaves, one failed master board as a slave that was missing its pull up resistors from its design for the I2C network. Also the ATtiny841 board designed to be a slave.
The Wire library for the master boards is part of the Arduino IDE itself, and the WireS library is a direct drop-in version of it for the ATtiny841 chip.
With all the troubles I had with the I2C networking I really needed to dig deep in the internet to find what I needed and I ran into the website by Nick Gammon, where he explained in detail several different things about electronics. For making my Master board work the way I wanted, I combined his code for basic master operation and his code for I2C network scanner. This allowed me to make the master independent of the slaves, as I didnt need to pre-define the slaves addresses to it. Then I added a loop, that used all the found addresses to page the slaves in the network, this way the number of the boards in the network is irrelevant to the master.
The feed that is given out by the master board, after it scans the I2C netowrk and reports the boards it found, and talked to them to get the numbers
The two slaves have addresses 50(0x32) and 60(0x3c)
The slave code was originally written for chips that had both master and slave functionalities hardwired in the chip, like the ATmega328p chips I was using on my master boards. But the WireS library I linked earlier proved to be identical enough for using in place of the normal wire library in arduino for the ATtiny841 chip.
The 841 slave board didnt have a clock chip on it, instead I pulled the three pins related with the clock to pads to make it easier to test them. In case I had problems with the clock not running properly, I could then measure the exact clock frequency. But having the whole network running on their internal 8Mhz clock made it work neatly. I figure in my future designs I will include the test pads as well even if I dont put the external clock on.
For this week's group project the idea was to combine two projects, since I didnt see any of this year's students in the lab using I2C I had to rely on my raspi project for it.
In this picture you can see the the raspberry pi i2c debug command for scanning the i2c network, and it detecting two slaves in the network. 0x32 and 0x3c Just like the original master identified them. This now means that one can program the raspi to use different sensors that have a i2c capacity.
In this screenshot I used i2cdetect command to verify that the raspi sees the 0x3c slave board, with the ATmega328 chip as it has full i2c hardware implementation. I tried doing this with the ATtiny841 chipped slave, that had the address of 0x32, but since it only has a partial hardware implementation I dont think it communicated as properly with the raspi.
The dump command asks the chip to dump out the contents of all its i2c visible registries, and we can see registry 0x04 having a value of FF
With the set command I tell the slave board to set the registry at 0x55 to a value of 0x50. The purpose of the -y is to skip the "you sure you want to do this?" question and the value 1 indicates the used bus for I2C
Now we take an another dump of the chip registries, and see that the chip has received the message, and its registries have changed... just not the way one expected as the 0x17 registry got the value of FF. After a while of research, I found the reason. It is essentially a problem similar to the british english and american english. The barebones chip of ATmega328 speaks TWI, and the Raspberry PI speaks SMBus. Both are implementations of the I2C, and similar enough that the raspi can see the chips in the network, but different enough that without compensating for the translation by making proper code in a program or in chip firmware, the two cannot communicate flawlessly.
Still the raspi was able to send a proper message to the chip, and the chip was able to act on it enough to change a registry value.