tl;dr: It seems like you need to send a null bit (0) to terminate the communication with this board.
In the downloads section, I found a .nxc file, which I assume is a NXT code file.
In the main loop, they configure the I2C port and a "touch sensor" (I believe this is to figure out how to synchronize the text with the motor). In that, there is a main loop in which they call DispLetter
.
This is the DispLetter
function:
void DispLetter (const byte & letter[])
{
int nbytes;
// Wait for the end of previously sent data
while(I2CStatus(I2Cport, nbytes)==STAT_COMM_PENDING);
// Write buffer to send to PCF8574
byte WriteBuf[];
ArrayBuild(WriteBuf, I2CAddr8574, letter);
for(int i=1; i<ArrayLen(WriteBuf); i++)
{
WriteBuf[i] ^= 0xff;
}
I2CWrite(I2Cport, 0, WriteBuf);
}
Let's read this code! First of all, it seems to make sure that the I2C port is connected, which we don't really have to worry about in our case since that's platform-specific.
After that, they create an array called WriteBuf[]
that will store the data to be sent to the controller. Then we come across a function called ArrayBuild
. Looking that up, it combines I2CAddr8574
and letter
and places it into the WriteBuf
array. (Click here for documentation for that function.) Please note that the I2CAddr8574
is just a byte containing 0x70 (the address of the chip), so we will not have to do this step since the Arduino handles the address. So, you will just have to send the letter
array to the controller, ignoring the WriteBuf
and ArrayBuild
!
Let's figure out how letter
is passed. In the main loop, they had this code:
DispLetter(L_);
DispLetter(E_);
DispLetter(G_);
DispLetter(O_);
That must display "LEGO." Let's figure out what L_
is defined as. At the beginning of the document, they have this defined:
// Display patterns
// Each byte represents a column of dots
// Bit set to 1 means lit LED.
// Least significant bit is at top of column.
// Last byte must be all 0
// Maximum number of bytes par pattern: 15
byte L_[] = {0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0};
byte E_[] = {0xff, 0x89, 0x89, 0x89, 0x89, 0x81, 0x81, 0};
byte G_[] = {0x7e, 0x00, 0x81, 0x81, 0x81, 0x81, 0x91, 0x90, 0x72, 0};
byte O_[] = {0x7e, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x7e, 0};
byte La_[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0};
byte Ea_[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0};
byte Ga_[] = {0x72, 0x90, 0x91, 0x81, 0x81, 0x81, 0x81, 0x00, 0x7e, 0};
byte Oa_[] = {0x7e, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x7e, 0};
byte N_[] = {0xff, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xff, 0};
byte X_[] = {0x80, 0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x80, 0};
byte T_[] = {0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0};
As you can see, they listed out how the dots are configured. There's a max of 15 bytes (I assume including the null bit).
There's one more piece of code that we haven't talked about:
for(int i=1; i<ArrayLen(WriteBuf); i++)
{
WriteBuf[i] ^= 0xff;
}
So it goes through each bit, and does something to it. That is the shorthand for this:
WriteBuf[i] = WriteBuf[i] ^ 0xff;
No, that is not an exponent. That is an exclusive OR, a bitwise operator. A bitwise operator is basically where it "overlays" the two binary sequences and it does a special computation on them. If the nth bit of each input number is 1 or the nth bit of each input number is 0, the nth output bit is 0. If the nth bit of one input number is 1 and the nth bit of the other input number is 0, then the nth bit of the output is 1.
Since 0xff = B11111111, it will essentially reverse the values of each bit. You can avoid this if you say that a bit set to 0 is on, instead of a bit set to 1 (like they do in the example code). A minor adjustment that just makes your life a bit easier :)
After that, you can write that array to the I2C bus and it should display the data!