Arduino UNO + Centipede Shield (4x MCP23017) addressing issues...

Hello!

I have just taken on the second half of a project within university where I have rigged up a set of light gates connected to the Arduino to measure times and then do speed, distance, time calculations. I'm using the centipede shield by Macetech to provide me with 4 gates (1 per chip) and each uses all 16 ports as inputs from sensors.

So I have a low on all of the chips at initialisation and when something passes the first array and any 1 of the sensors is triggered an interrupt is sent to the arduino and, as per what should happen with the MCP23017 chips, the address of that pin at the time of interrupt should be saved.

This works for a simple simulation where a pulse is sent to one pin to trigger each gate one after the other. At the end it then displays the pin that was triggered and is correct. This is not the case when all pins are used. The details that are presented from the registers make no real sense. I then tried to find a correlation between cryptic numbers rather crudely and discovered that the output that is provided from this addressing changes with every disconnect and reconnect of the arduino(not just a reset button push).

So, what I'm really asking is,

Does anyone have a clue what might be going on?

It always insists that sensor 1 was triggered and then picks a random number of others to mention as well like this ( only every now and then displaying a full 16 bit line as it should... and did with the simulation):

100000001 array 1
1011110000011111 array 2
10001001010100 array 3
100000010000000

In your code, make sure enough time is provided after startup to let all the input sensors settle, then enable the interrupts. Does your code (which you should post) allow multiple events to happen, or is it one shot and have to be reset?

Additionally...are all the inputs connected to something? A floating input can be anything.

Right I have the problem isolated. The interrupt captures on the MCP23017 are not resetting as they should be. Is there a specific way to reset them other than the Microchip suggested read command to clear them with the centipede shield?

// read a byte from the expander
unsigned int expanderRead (const byte address, const byte reg)
{
Wire.beginTransmission (address);
Wire.write (reg);
Wire.endTransmission ();
Wire.requestFrom (address, (byte) 1);
return Wire.read();
} // end of expanderRead

No...the interrupt is latched and reading the two bytes from the interrupted chip is the best way. It can be the end of your ISR and is pretty fast...you may already be reading the GPIO anyway.

I have all inputs connected. In other words I have 64 individual sensors which I am aware are working and sending highs and lows as they should be.

The code is designed to run a set up routine and then a main programme loop which is repeated. At the end of the routine I have an expander read command on all chips to clear them as shown below in my test. I am going to simplify the whole program down to one array again. I will then prove if I can trigger, read, reset and repeat confirming that the chips will reset... Then I can assume something code wise although I cant now see how. :frowning:

This should clear the registers if I am correct according to Nick Gammon's tutorial and the microchip datasheet.

I have the code Serial printing the detail from each chip before the read and after and in my eyes it is not clearing.

Thanks macegr. My lack of knowledge with these things gets frustrating and I usually get by but I cant even find a way to troubleshoot this .

Also, on your chips am I right in thinking that the arduino reset line is not connected to the MCP23017 chips? This is my last resort... If I hardware reset the MCP chips have no option but to zero! This is cowboy style EEE Development... :frowning:

Below is my code to test and prove the expander not resetting... Have I done something silly here?

chip1intA=expanderRead(chip1, INTCAPA);// test to determine if system is zeroing
Serial.println (chip1intA, BIN);
chip1intB=expanderRead(chip1, INTCAPB);
Serial.println (chip1intB, BIN);
chip2intA=expanderRead(chip2, INTCAPA);
Serial.println (chip2intA, BIN);
chip2intB=expanderRead(chip2, INTCAPB);
Serial.println (chip2intB, BIN);
chip3intA=expanderRead(chip3, INTCAPA);
Serial.println (chip3intA, BIN);
chip3intB=expanderRead(chip3, INTCAPB);
Serial.println (chip3intB, BIN);
chip4intA=expanderRead(chip4, INTCAPA);
Serial.println (chip4intA, BIN);
chip4intB=expanderRead(chip4, INTCAPB);
Serial.println (chip4intB, BIN);

chip1intA = 0; //set up storage bytes for MCP23017 interrupt register values
chip1intB = 0;
chip2intA = 0;
chip2intB = 0;
chip3intA = 0;
chip3intB = 0;
chip4intA = 0;
chip4intB = 0;
chip1profile = 0;
chip2profile = 0;
chip3profile = 0;
chip4profile = 0;

expanderRead(chip1, INTCAPA);
expanderRead(chip1, INTCAPB);
expanderRead(chip2, INTCAPA);
expanderRead(chip2, INTCAPB);
expanderRead(chip3, INTCAPA);
expanderRead(chip3, INTCAPB);
expanderRead(chip4, INTCAPA);
expanderRead(chip4, INTCAPB);

chip1intA=expanderRead(chip1, INTCAPA);// test to determine if system is zeroing
Serial.println (chip1intA, BIN);
chip1intB=expanderRead(chip1, INTCAPB);
Serial.println (chip1intB, BIN);
chip2intA=expanderRead(chip2, INTCAPA);
Serial.println (chip2intA, BIN);
chip2intB=expanderRead(chip2, INTCAPB);
Serial.println (chip2intB, BIN);
chip3intA=expanderRead(chip3, INTCAPA);
Serial.println (chip3intA, BIN);
chip3intB=expanderRead(chip3, INTCAPB);
Serial.println (chip3intB, BIN);
chip4intA=expanderRead(chip4, INTCAPA);
Serial.println (chip4intA, BIN);
chip4intB=expanderRead(chip4, INTCAPB);
Serial.println (chip4intB, BIN);

Whatever happened to this project?