Adafruit Mini 8x8 LED Matrix is simple graphical display with I2C interface. To prepare image for display is not straightforward. Every row is represented by one byte but columns are shifted by one. First column is bit 7 but second column is bit 0 in byte.
Used driver chip HT16K33 can control 16x8 displays so we will need just every second row.
Application will show schema of display where you can switch LED on and off and you will see result on display connected to Raspberry Pi 2 and you will see byte value for every line. Application will run on regular computers without I2C bus too.
Hardware setup
You will need to do some soldering. Please follow instructions on Adafruit web (https://learn.adafruit.com/adafruit-led-backpack). There are more similar Matrix displays so you will need to follow right one. Wiring is very simple. Raspberry Pi already contains pull up resistors for I2C bus so you need just connect 3.3 V to VCC, GND to GND, SDA to SDA and SCL to SCL. Check Raspberry Pi pinout on my favorite interactive pinout diagram (http://pi.gadgetoid.com/pinout). It is recommended to use separate power supply for external hardware because of limited current from Raspberry Pi. Do not use 5 V. It can destroy Rapsberry Pi.
Application
Setup your PC to work with Windows 10 IoT Core (http://ms-iot.github.io/content/win10/SetupPC.htm).
Start new Project with Windows Universal Blank App template
Add reference to Windows IoT Extension SDK
User Interface
User interface is simple grid 8 rows and 9 columns. Last column is for row byte value.
<Grid Width="450" Height="400" Name="_matrix">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
We will fill grid using Ellipse and TextBlock objects in code behind. Ellipses will represent LEDs and TextBlock will show byte value for row.
for (int i = 0; i < MATRIX_SIZE; i++)
{
TextBlock tb = new TextBlock();
tb.Text = "0x00";
tb.HorizontalAlignment = HorizontalAlignment.Center;
tb.VerticalAlignment = VerticalAlignment.Center;
tb.SetValue(Grid.RowProperty, i);
tb.SetValue(Grid.ColumnProperty, MATRIX_SIZE);
_matrix.Children.Add(tb);
_matrixRowValue[i] = tb;
for (int j = 0; j < MATRIX_SIZE; j++)
{
Ellipse led = new Ellipse();
led.Width = 40;
led.Height = 40;
led.HorizontalAlignment = HorizontalAlignment.Center;
led.VerticalAlignment = VerticalAlignment.Center;
led.Fill = _off;
led.SetValue(Grid.RowProperty, i);
led.SetValue(Grid.ColumnProperty, j);
led.PointerPressed += Led_PointerPressed;
_matrix.Children.Add(led);
}
}
I2C communication
If you want to sommunicate with I2C device you need to know address of device and communication speed. Object _matrixDevice is type of I2cDevice class.
// I2C bus settings
// Address of device is 0x70
I2cConnectionSettings settings = new I2cConnectionSettings(0x70);
// Using standard speed 100 kHZ
settings.BusSpeed = I2cBusSpeed.StandardMode;
// Get device on bus named I2C1
string aqs = I2cDevice.GetDeviceSelector("I2C1");
var dis = await DeviceInformation.FindAllAsync(aqs);
_matrixDevice = await I2cDevice.FromIdAsync(dis[0].Id, settings);
If you gate I2CDevice you can write and read bytes from it. If getting device fails you run your application on device with no I2C support but user interface can still work.
Here is piece of code changing LED on display. This code runs in response to clicking or touching ellipse representing LED in grid on screen.
private void setMatrixData(int row, int column, byte state)
{
// shift columns in grid to columns on device
column = (column + 7) & 7;
// write state to matrix
_matrixData[row, column] = state;
byte rowData = 0x00;
//calculate byte
for (int i = 0; i < MATRIX_SIZE; i++)
{
rowData |= (byte)(_matrixData[row, i] << (byte)i);
}
// show byte value for row
_matrixRowValue[row].Text = String.Format("0x{0:X2}", rowData);
// if we have not real display return
if (_matrixDevice == null)
{
return;
}
// write value to display
_matrixDevice.Write(new byte[] { (byte)(row*2), rowData });
}
Full code is available on https://github.com/bechynsky/AdafruitMini8x8LEDMatrixW10IoTCore
Comments