Communicate digital data between an Arduino and a PWM module using an I2C bus.
The Arduino I/O pins allow it to bridge the gap directly between digital information and physical signals. However, it can also transmit data to and from other computational devices. The previous examples have implicitly used USB and an asynchronous serial UART for downloading programs and looking at text output. But even simpler bus standards, such as I2C and SPI are useful for connecting an Arduino to I/O modules or even other Arduinos.
This capability is useful for rapid prototyping, since many interface functions are available in modular form. For example, there exist modules:
Using digital busses essentially makes the Arduino a node in a network comprising multiple computers, possibly including a host desktop or laptop. Each type of link has different characteristics:
In general, using a device-level serial bus requires using two libraries: one to handle the I2C or SPI data transfer, and one to handle the specific protocol for the device. If no device library is available, then this involves understanding the datasheet for the particular device well enough to implement the required protocol. This can be as simple as emitting a few bytes to write a value to a device register, but sophisticated devices can require elaborate programs to handle a variety of messages. For example, a real-time clock-calendar chip can have dozens of registers available over an I2C bus to keep track of time and set alarms.
This exercise will use the Adafruit 815 16 channel 12-bit PWM driver with I2C interface. This module is based on the PCA9685 I2C-bus controlled 16-channel LED controller. Adafruit provides their own tutorial, and library source code on github.
Adafruit_PWM
sketch included with the exercise. This is the
pwmtest example from Adafruit-PWM-Servo-Driver-Library, slightly modified into a self-contained sketch.
If you have cloned the course materials from github, it will be in the same folder as this page, or it can be
downloaded directly. Be sure to fetch all top-level
files.This example is more about becoming comfortable using vendor libraries than the electronics, given how simple it is to make the electrical connections.
For a challenge, clone the original Adafruit library from github and install it in your Arduino IDE libraries path, then try compiling the original unmodified example.