3

I'm trying to interface my Leonardo with a "Mindsensors Magic Wand" - 8 LEDs connected to a PCA8574AN chip. On the manufacturer's page, they say it's compatible with Arduino, however no instructions or code are given. http://www.mindsensors.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=120

I've connected the SDA, SCL, 5v, and GND connectors on the arduino to the device, but have had no luck in communicating with it. None of the LEDs light up regardless of input.

I can verify that power is being supplied. The i2c address of the device is 0x70. Code is below.

#include "Wire.h"
#define TWBR=400000L
void setup() {
  // put your setup code here, to run once:
 Wire.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
  Wire.beginTransmission(0x70);
  Wire.write(32);
  Wire.endTransmission();
}

1 Answer 1

2
+100

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!

5
  • Hi,If i'm understanding it correctly, the way to go is to write the byte for the LEDs I want activated, then 0x00. I'm just trying to display a static pattern at the moment. #define TWBR=400000L #include "Wire.h" void setup() { // put your setup code here, to run once: Wire.begin(); } void loop() { // put your main code here, to run repeatedly: delay(2000); Wire.beginTransmission(0x69); Wire.write(0x12); Wire.write(0x00); Wire.endTransmission(); } This doesn't work, is it what you meant? Thanks.
    – Tim
    Commented Feb 17, 2015 at 11:50
  • @Tim that is what I meant... I must have overlooked something in the code. I'll look at it later tonight if I have time. Commented Feb 17, 2015 at 19:15
  • 1
    @Tim sorry just got time today to look back at it. 1.) the address is 0x70, not 0x69. 2.) The only other thing that I can think of is, in the examples, they always send the data to 0x0 and then the first byte is the address (0x70). 3.) Ignore the advice in my post about the last bit being a 0: that just is supposed to shut it off... right! Further than that I don't have a lot of other ideas. Commented Feb 20, 2015 at 23:31
  • @Tim did you fix it? What fixed it? Commented Feb 20, 2015 at 23:34
  • Haven't yet. Will try again today.
    – Tim
    Commented Feb 20, 2015 at 23:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.