Some problems with centipede Library

Hi, i hope this is the right place for my topic because i use centipede library for command multiple inputs/outputs.

I didn’t find centipede shield in europe, so i bought this shield:

But the problem is this:
If i use pin from 16 to 47 (chip 1 and 2) all works well, but if i try to use pin from 0 to 16, same commands are send to pin from 48 to 63.
So it appears that chip 0 and chip 3 works together.

for example this sketch:

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
#include <Wire.h>
#include <Centipede.h>
#include "Console.h"

Centipede CS; // create Centipede object


#define HIGH_VAL 0x0 // Invert values because sainsmart works with negative value
#define LOW_VAL 0x1 // Invert values because sainsmart works with negative value

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
Console.begin();
digitalWrite(13, HIGH);

Wire.begin(); // start I2C
CS.initialize(); // set all registers to default


CS.portMode(0, 0b0000000000000000); // set all pins on chip 0 to output
CS.portMode(1, 0b0000000000000000); // set all pins on chip 1 to output
CS.portMode(2, 0b0000000000000000); // set all pins on chip 2 to output
CS.portMode(3, 0b0000000000000000); // set all pins on chip 3 to output

CS.portWrite(0, 0b1111111111111111); // set all pins on chip 0(1°centipede) to 1 (sainsmart works with negative value)
CS.portWrite(1, 0b1111111111111111); // set all pins on chip 1(1°centipede) to 1 (sainsmart works with negative value)
CS.portWrite(2, 0b1111111111111111); // set all pins on chip 2(1°centipede) to 1 (sainsmart works with negative value)
CS.portWrite(3, 0b1111111111111111); // set all pins on chip 3(1°centipede) to 1 (sainsmart works with negative value)
//TWBR = 12; // uncomment for 400KHz I2C (on 16MHz Arduinos)

}


void loop()
{ 
for (int i = 0; i < 16; i++) {
CS.digitalWrite(i, HIGH_VAL);
Console.println(i);
delay(500);
}

for (int i = 0; i < 16; i++) {
CS.digitalWrite(i, LOW_VAL);
Console.println(i);
delay(500);
} 

for (int i = 48; i < 64; i++) {
CS.digitalWrite(i, HIGH_VAL);
Console.println(i);
delay(500);
}

for (int i = 48; i < 64; i++) {
CS.digitalWrite(i, LOW_VAL);
Console.println(i);
delay(500);
} 
}

It should enable first pins of chip0, and then chip3.

But this is the result:

My WIP sketch for command outputs from http request produces the same result:

I tried to contact the guy that developed the shield but he doesn’t help me.

Do you have some idea of what could be the problem and how i can solve it?

Thanks.

PS: I forgot to write that i’m using an Arduino Yun.

leen15: So it appears that chip 0 and chip 3 works together.

Sounds like there may be a problem on the board? Each chip has a set of address lines, and each chip must have a unique address to be accessed properly. If there were a board problem or poorly soldered pin, chip 3 could end up with the same address as chip 0, so that that a command to chip 0 also goes to chip 3.

I assume that writing specifically to chip 3 does nothing?

Look at the [MCP23017 Datasheet]http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf]MCP23017 Datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf). The address lines are A0 through A2. Might be worth it to inspect the board to see if there are any soldering problems on those pins? I'm going to guess that there is a problem with the A1 pin on chip 3.

It is the same thing that i think... On kikstarter the pcb design is different from produced pcb, so i cannot verify that the circuit is correct (it's obviously 2 layer).. :sob:

Writing on chip 3 does nothing as you said (and you can see on youtube video that i linked)

I'll try to see with a multimeter if pin A0 to A2 on chip 0 and chip 3 are connected together.

Thanks for your suggestion.. if pcb it's not correct, it's a big problem because my home automation project is stopped for this issue :disappointed_relieved:

I see that a guy has tried to replicate centipede shield here: http://forum.arduino.cc/index.php?topic=177677.msg1320562#msg1320562

Somebody know if this circuit is correct? I'm thinking to produce myself the pcb at this point!

Ok maybe i found the problem.
If you look at the attached picture and zooming here:

You can see that on chip3 pin A0 and A1 are connected to pin VSS (GND) of chip2 instead of VDD (5V) !!
So the adress of chip3 is 000 instead of 011 :frowning:

Wrong PCB… Now i need to find another solution :frowning:

Looking where your arrow is pointing, there appears to be a solder bridge between the first two pins in that corner. A quick touch with a clean soldering iron (no solder on the tip) should clean that up. It could make a world of difference.

If it really is a board layout issue, you could try repairing it, but that is a very difficult proposition: unsolder and lift the wrong pin from the board, or cut the trace leading to it if it's visible, then attach a fine jumper wire from the pin to the right signal. But that is a drastic step, I would be in touch with the board builder first. But if you get no satisfaction from him, then it would be easier than designing a new board.

leen15: On kikstarter the pcb design is different from produced pcb, so i cannot verify that the circuit is correct (it's obviously 2 layer).. :sob:

Are you referring to the layout picture on the KickStarter page? I would hope the actual board layout is different, because the trace routing on that image is horrible! :o

ShapeShifter: Looking where your arrow is pointing, there appears to be a solder bridge between the first two pins in that corner. A quick touch with a clean soldering iron (no solder on the tip) should clean that up. It could make a world of difference.

If it really is a board layout issue, you could try repairing it, but that is a very difficult proposition: unsolder and lift the wrong pin from the board, or cut the trace leading to it if it's visible, then attach a fine jumper wire from the pin to the right signal. But that is a drastic step, I would be in touch with the board builder first. But if you get no satisfaction from him, then it would be easier than designing a new board. Are you referring to the layout picture on the KickStarter page? I would hope the actual board layout is different, because the trace routing on that image is horrible! :o

I thought that the problem was the bridge, but after follow the pcb i saw that is right that bridge exists, because address of chip3 should be X11 where X is the dynamic pin that is assigned from address jumper. The problem instead is that these 2 pins are connected to GND instead of VCC, so result address is X00, that is the same of chip0.

Layout is very similar of the kickstarter page... :roll_eyes: I tried to contact 10 times board builder but no answer received (If board is wrong, i would like to have a refund!! :confused: )

Now i'll try to create a new board, if i find the right schematic and how can solder smd components.. :(

leen15: Layout is very similar of the kickstarter page... :roll_eyes:

That's unfortunate. I see so many things that are awful in that layout -- the way the thin VCC trace is daisy-chained from chip to chip, forking apart at odd angles (can you say acid trap?) and those same skinny traces feed all of the I/O headers! I hope you are running your relay boards with their own power supply, because if they are drawing power from those I/O headers, it will be introducing all sorts of transients on the power supplies to the chips. (And where are the bypass capacitors for those chips?) And of course, the lowest number ports, which are the most likely to be used, have the longest traces that will affect the most other devices.And ground isn't much better, but at least most of them run to a common ground point without daisy chaining between chips. And the analog mux? What's it doing on the opposite corner of the board from the analog input? It should be as close as possible to the analog pins, without that long trace going by all of the noisy digital and power signals. This looks to be a very amateurish board, I wouldn't be surprised if it's the first time he's ever made one. ::)

But enough of that, the one thing I see right on the layout image is that the address lines for I/O 48 through 63 is correct, they are both tied to Vcc. It's a pity [u]that[/u] part of the layout didn't make it to the final board. >:(

I tried to contact 10 times board builder but no answer received (If board is wrong, i would like to have a refund!! :confused: )

Now that's very distressing. I'll bet you're not the only one trying to get your money back. No wonder he isn't responding -- he could be bankrupt.

Now i'll try to create a new board, if i find the right schematic and how can solder smd components.. :(

If you're going to throw out the board, you might as well try to fix it by lifting the two pins and connecting them to Vcc. I would've suggested trying to cut the traces rather than lift the pins, but based on the rest of the layout, the ground trace probably continues on under the chip and you can't cut the trace there. So unsoldering them and lifting them is probably the way to go. You just have to be careful not to overheat the pad and lift the pad from the board, as that will could break any path going under the chip (but that could be fixed with another jumper wire.)

Fixing the board would be a lot easier than building a new one. But then, of course, you will still have the bad power and analog trace routing and lack of bypass capacitors. While more expensive and more work, you're bound to end up with a better board.

I just took a closer look at the board, and I think I might have figured out what happened. If you follow the traces on the layout picture on the KickStarter page, the A0 and A1 of that chip are tied together, then go to pin 10 of chip 2, which then goes to Vcc on the header. That looks correct. But if you look at the pinout of the chip, pin 10 is ground, not Vcc! On that layout he has all of the power and ground pins for those chips reversed!

He must have caught that problem, and fixed the swapped signals, but he didn't catch the trace running to those address pins. Looking at the photo of the finished board under the udpates tab, it's clear that those address pins are still connected to pin 10 of the second chip. Therefore, they have the wrong polarity on them. How unfortunate.

What gets me is how a few people are posting on the page that they got the board and it works. I'm going to guess they haven't used all of the outputs and perhaps never addressed that last chip?

Looking more closely at the reward levels, I see he must have been using Fritzing for the board layout. That explains A LOT. It's a useful program for sketching out simple schematics and making nice pictorial views of a breadboard, but it's not anything I would use for designing a board that is to be produced and sold to the public. (I wouldn't even use it to make a board for my own use.) This smacks of being done entirely on the board layout view, without looking at the resulting schematic.

I think that at this point, the only thing to do is draw and make a new board. :roll_eyes:

Did you see the schematic posted here?

http://forum.arduino.cc/index.php?topic=177677.msg1320562#msg1320562

If this could works, i can build a new pcb from that schematic, that i hope resolve all my problems.. I'm building a home automation "kit" for some friends (and maybe sell it, why not?) that include obviously this multiplexer for work with lots of inputs and outputs.

I'm also thinking how can I use more than 2 of this shield (more than a total of 8x MCP23017) but no ideas for works with more addresses because i see from datasheet that only last 3 digits of address can be set.. :stuck_out_tongue_closed_eyes:

leen15: Did you see the schematic posted here?

http://forum.arduino.cc/index.php?topic=177677.msg1320562#msg1320562

The schematic looks like a reasonable starting point, but I have not studied it in detail. I have also not translated that long thread, so I haven't read any of the follow-on comments. A few concerns and questions:

  • There should be some bypass capacitors at each chip's power pin
  • It probably wouldn't hurt to have some extra bulk capacitance on the board
  • On the I/O headers, power is on one end, ground on the other. I would probably re-arrange them so they match the pinout of the SainSmart relay boards which seem to put power and ground together on one end
  • I've not gone back and looked at the data sheet, but I would assume INTA and INTB are open collector outputs from the chips? If not, there will be trouble bussing them together.
  • the RESET pins of the chips are tied high. I would consider connecting them to the shield RESET pin, so that they are reset to an idle state when the processor board is reset. Always good to have known start-up states. Or even better, bring the RESET line to a digital I/O pin to allow the sketch to reset the chips at will (see the last bullet about I2C.)
  • And the biggest one: if I were designing the board, I would use the MCP23*S*17 version instead, which uses SPI. I don't like I2C, I've had too many problems with it where noise or other issues causes the bus to lock up. If a chip gets in a bad state where it's confused and holding the SDA line low, it stops the whole bus. If you can detect that this happens, you can sometimes release the bus by making the SCL line GPIO and bit-banging a bunch of clock cycles. Or sometimes resetting the chips on the bus helps (another reason to have processor control of the reset line.) I've had many problems with I2C, but never with SPI.

I'm also thinking how can I use more than 2 of this shield (more than a total of 8x MCP23017) but no ideas for works with more addresses because i see from datasheet that only last 3 digits of address can be set.. :stuck_out_tongue_closed_eyes:

Take a look at THIS PAGE, particularly something like the PCA9516. It is an I2C bus expander chip, with one master port, and four additional slave ports, each with their own enable line. Connect the master port to the Arduino, and pairs of boards off the slave ports. Enable one slave port at a time to talk to each pair of boards. I've used the PCA9515, which is a single port version of this: I used a pair of them to act as a two-bus switch. The PCA9516 looks to be four of them in a single package. You would be able to talk to 32 chips that way (8 boards.)

On the other hand, if you go with SPI, you don't have to worry about that, you just need more chip select lines. To reduce pin count, you can can drive them with a demultiplexer chip or a ring counter. Or even a shift register where you pre-load all but one bit high, then shift the low bit each time you want to step to another chip.

Thank you very very much for all these informations! :) I'll read all and I'll try to find the best solution for my use. I have to build a new board from zero so i can make it for my scope and not to adapt my project to other generic boards. :smiling_imp:

If you're building a custom board from scratch, let me plant another bug in your ear... :grin:

Intelligent I/O boards with a mutli-drop bus. 8)

Put a '328P processor on the board, along with some MCP23S17 SPI port expander chips and some analog conditioning circuitry. Connect the serial port of the '328 to an RS-485 transceiver, and put two connectors on the board so you can daisy chain them. Hook them up to an RS-485 port on the main controller Arduino, and then you can hang a large number of these boards off of one main controller board.

The sketch running on the I/O boards would be very simple: it receives a message from the master controller to set it's outputs, and replies with a message giving the state of the inputs. The main board addresses and talks to one slave at a time, circularly alternating between them.

I think that now you're moving up to a too much difficult level for my electronic skills :grin:

My scope is to have the most small and efficient board for connect input and output expansions avoiding to increase the complexity of the system and create too much pcbs.. or maybe i try :D

I didn't find so much example on how to use more than 8 MCP23S17 on arduino, and i dont understand why?

From my research, typical dimension of big home automation uses about 150-160 in/out, so maybe control 10x MCP23S17/MCP23017 could be enough, but i would like to keep pcb more simple as possible so that for who is enough a single board of 4x chips can pay less. :stuck_out_tongue:

leen15:
I think that now you’re moving up to a too much difficult level for my electronic skills :grin:

Just trying to push the envelope and get you thinking… 8)

I didn’t find so much example on how to use more than 8 MCP23S17 on arduino, and i dont understand why?

Probably because it takes a lot of chip select lines. 8 chip selects plus MISO, MOSI, and SCK, and that puts you at 11 pins already. You need to start getting creative after that. Rather than dedicate an I/O pin for each chip, you can take advantage of the fact that you only want one line to be active low at a time. So, in reality, four address bits can get you access to 16 expander chips, giving you 256 inputs/outputs. If you put four chips on one board, you can use two address bits to select the board, and two address bits to select the chip.

The attached shows a quick sketch of how it could be done with a dual 2 to 4 line decoder. Address line A2 and A3 go to the board-level decoder. They select one of four outputs to go low when CS goes low, the other lines stay high regardless of CS. The four outputs go to a jumper block, where only one horizontal pair of pins should be shorted, this is how you select the board address. The selected signal goes to the enable input of the chip-level decoder. There, address lines A0 and A1 select which of the four chip selects should go low to select the chip. The addressing would be:

  • 0 - Board0, CS0
  • 1 - Board0, CS1
  • 2 - Board0, CS2
  • 3 - Board0, CS3
  • 4 - Board1, CS0
  • 5 - Board1, CS1
  • 15 - Board3, CS3

From my research, typical dimension of big home automation uses about 150-160 in/out, so maybe control 10x MCP23S17/MCP23017 could be enough, but i would like to keep pcb more simple as possible so that for who is enough a single board of 4x chips can pay less. :stuck_out_tongue:

It makes sense to break it up into smaller boards. The larger the board, the more expensive it is, the more channels that may be unused, and the more things on it that can fail over time. By breaking it up, you only have to build up as much as you need, and you only need to swap out the one board instead of the whole thing if something should fail.

4board4chipDecoder.png

It's a great idea! I'm also thinking that with a PCA9516A and a selector on each board i could use i2c for command until 512 in/out pins that i think should be enough for every type of use and i could make sandwitch standard 4x chips board. :)

I need to think a loooot! :grinning:

Now you've got me thinking...

It sounds like you really want to stick with I2C. Rather than the PCA9516A on a main board, distributing the bus to other boards, I would consider putting the PCA9515A on each board. The I2C bus from the Arduino processor goes to all of the PCA9515A chips, one on each board. But only one of them gets enabled at a time, using a similar decoder as on the bottom half of the diagram above. You could use a 74HC138 to decode 3 address lines to 8 select lines, or even a 74HC154 to decode 4 address lines to 16 selects. 16 boards with 4 chips each is one heck of a lot of I/O - that's 1024 I/O bits!

But then I thought of a simpler idea. Make the boards just like the schematic you proposed, but change the address select jumper. Instead of a two position jumper that sets A2 high or low, take the bottom half of the decoder I drew, feeding the board select lines through the jumper block, and then feed the selected line to the A2 address line of each chip. When you put an address value on the address lines, the one addressed board will have A2 low, so that the chips on that board have I2C addresses of 32 through 35; while all of the other boards will have A2 high, so that the chips on those boards have I2C addresses of 36 through 39. That will give conflicting addresses to the non-addressed boards, but the key is to always used I2C addresses 32 through 35, and never use 36 through 39. That way, the conflicting addresses don't really matter, as they will never be accessed when in that state.

The general idea with either multiplexing idea is that you put an address out on the address select lines, then address the chips on the board as addresses 32 through 35. When it's time to write to another board, put that board's address on the address lines, and again write to I2C addresses 32 through 35.

In either of these addressing styles, you wouldn't need to control the overall CS signal, just tie that enable input of the decoder low to keep it active. One board will always be addressed, but that doesn't matter because even if you have other devices on the I2C bus, you still have the I2C address to differentiate between devices.

Thinking on your suggestions, I’ve got another idea for simplify components.
If i understand, I should send 16 selects to every single board, and define every board what is, but if i have to build a dynamic system where every board can be added without user modifications, maybe this could be simpler:

  • I send 4 address lines to all boards
  • I put a 4 way dip switch on every board for define address
  • I add a “chip” that compare if 4 address lines is equal to 4 way dip switch value and set A2 of MCP to low if it’s ok

so for selected board I can use MCP as 000 - 011, and for disabled boards they have 1xx.

With this i have to send only 4 pins to every board (+ i2c) that can be put in sandwitch, for a total of 16 board.

What do you think? What “chip” i can use to compare if 4 address is equal to dip switch value of the board? Something like this? http://www.farnell.com/datasheets/1870913.pdf

Actually, what I was suggesting is very close to what you just drew. There would be one decoder chip on each board, so only the four address lines are needed between boards. The downside to my scheme is needing a 2x16 header to select the address, and the danger of misplacing the jumper and generating an invalid address.

Your idea should work, take less room, less connections, and be harder to misconfigure. The big difference is that the address select line is now active high instead of active low. If it were being used as an SPI chip select, it would need to be inverted. But if you are feeding it into A2, that won't be necessary, you just have to address the chips slightly differently: 0xx is disabled, and valid addresses are 100, 101, 110, and 111.

I had briefly considered your scheme, but dismissed it because I didn't spend enough time looking for a suitable chip. I was only searching for an equality comparator, and the only one I found compared 8 bits. I thought that was physically too big of a chip and too many wasted inputs. I forgot about that magnitude comparator, which is a very useful chip. (I made a traffic light controller with one over 30 years ago, before I had access to microprocessors: a 555 slowly incremented a 4 bit counter, which was fed into the A side of that chip. The B side was hard-wired to 0111. Then the green light was controlled by the less than output, yellow by equals, and red by greater than. Green would be on for 3 counts, yellow for 1, and red for 4 counts. The opposite direction was wired with opposite sense, off of the same counter. It worked great and only needed a few chips.)

I think your drawing is a great solution! You just have to use A2 as high for the active board.

Ok, so if i’m not so far from the final solution, this is what i quickly drawn until now. What do you think? :blush:

PS: If i use watchdog in code, should reset also MCP chips if they are connected to arduino reset pin?

leen15: Ok, so if i'm not so far from the final solution, this is what i quickly drawn until now. What do you think? :blush:

Looks pretty good. :sunglasses: I do have a few constructive comments:

  • Add bypass capacitors to each chip.
  • It looks like you are powering the board and everything connected to the I/O headers from the 5V output of the Yun. I wouldn't do that, it's going to be too much of a load, especially if you have a stack of these boards. Put a separate 5V connector on this board and don't connect to the Yun's 5V pin. As a compromise you can power just the chips from the on-board 5V, and have a separate connector for the I/O header power. However, be aware that the Yun's 5V output is really only about 4.5V because there is a polarity protection diode in series with that pin.
  • The signals between the DIP switch and the B inputs of the address comparator will be floating when a switch is open, which is not good. Normally, one would use pullup resistors on those lines, and the common side of the DIP switch would go to ground. If you really want the common side to go to 5V as you drew it, then you would need pulldown resistors.
  • I'm concerned about J2: it looks like you are grounding out the 3.3V and IOREF lines (as well as the unconnected pin.) The Yun will NOT be happy about that!
  • You have the I2C signals connected to A4 and A5. That works for a '328P based Arduino, but the Yun with its '32U4 processor puts the I2C signals on the larger digital I/O connector, after AREF. (You have them labeled on your board layout.) You may want to flop your layout vertically so that the I2C lines don't have to run as far -- put the chips by the upper digital side and the connectors below them.

And finally, a discussion about the physical form factor. You're using a standard shield layout. But if you look at the vertical profile of a Yun, you'll see that the Ethernet and USB connectors extend higher than the connectors on a more standard Arduino. This may cause problems plugging in a shield unless you use a connector with extra long pins. Even so, using a through hole DIP switch will put one row of the pins that extend through the board directly on top of the USB connector, requiring even longer stacking connector pins to prevent a short. I would avoid putting anything on the bottom of the board (or extending through the board) in the vicinity of the USB or Ethernet connectors (or in the vicinity of the Yun's 6-pin ICSP connector.)

As an alternative to using extra long connectors, I see that the left side of your shield is mostly unused. It will be tight, but if it were cut off right next to the SCL pin, you may be able to fit the board next to the Ethernet and USB connectors, and use regular stackable headers. In that case, your address decoder and DIP switch would need to move, and space is becoming an issue. Maybe put the decoder on the bottom of the board, and use a low profile surface mount DIP switch? Or perhaps make an irregular shaped board where the areas for the Ethernet and USB connector are cut away, and the address decoder is on a tab that extends between the connectors?

PS: If i use watchdog in code, should reset also MCP chips if they are connected to arduino reset pin?

Looking at section 8.0.6 of the '32U4 datasheet, it looks like the watchdog reset pulse is only internal to the chip, it does not cause a pulse on the external reset pin. That section of the datasheet shows a timing diagram, and the RESET line doesn't change during the displayed sequence. Some other processors I've used do generate an external pulse, but it looks like this one doesn't.

So it doesn't look like you can count on the watchdog to reset your port expander chips. The safest bet might be be to connect the reset pins to a digital I/O pin. That way, at the beginning of setup() you can manually pulse the pin to put things in a known state. It may also be helpful to be able to manually reset them if you should run into an I2C bus lockup.