MCP23017 Setup

hi,

could someone please advice me how to setup the mcp230217 correctly?
i do have multiple MCPs connected in a row. if i use the code below, i can switch all pins/banks to inputs, and it works great.

this part is mostly from nick gammon, it sets all bank as input

// expander configuration register
ic2_mcp_write_both (MCPAdr, Mcp_Reg_IOCON, 0b01100000);	// mirror interrupts, disable sequential mode

// enable pull-up on switches
ic2_mcp_write_both (MCPAdr, Mcp_Reg_GPPUA, 0xFF);	// pull-up resistor for switch - both ports

// invert polarity
ic2_mcp_write_both (MCPAdr, Mcp_Reg_IOPOLA, 0xFF);	// invert polarity of signal - both ports

// enable all interrupts
ic2_mcp_write_both (MCPAdr, Mcp_Reg_GPINTENA, 0xFF);	// enable interrupts - both ports

but what i want is i.e.

  • mcp1 ->

  • bank A = output,

  • bank B = output

  • mcp2 ->

  • bank A = input,

  • bank B = input

  • mcp3 ->

  • bank A = output,

  • bank B = input

  • mcp4 ->

  • bank A 0-3 = output 4-7 = input,

  • bank B 0-3 = input 4-7 = output

All interrupts should be mirrored. and set to open-drain (ODR=1)
i think 'sequential mode' has to be disabled.
all inputs should be active-low.

i want to access the banks and ports via "one-side-reading or -writing", the code above shows "write_both" but i want to write to i.e. only bank A and set a Pin to 1 or 0.

the values to the above functions for the registers should be in decimal, not hex or binary - only the values.

second questions, how do i manipulate later on the single pin for an output to set them to 1 or 0?

best regards.

the values to the above functions for the registers should be in decimal, not hex or binary - only the values.

You can pass values in any number base, it does not matter. It is just that hex is so much easier to use than decimal for manipulating bits.

second questions, how do i manipulate later on the single pin for an output to set them to 1 or 0?

You use bit manipulation http://playground.arduino.cc/Code/BitMath only with the values you read and write to the expander not the internal ports. So to set a bit read, logic or it with a 1 in every bit you want to set and then write the result back. To clear a bit read the register and logic and it with a number that has a zero in every bit you want to clear and a one in the bits you don't want to clear.

ok thanks.

but the main question is not answered yet.

i want to access the banks and ports via "one-side-reading or -writing", the code above shows "write_both" but i want to write to i.e. only bank A and set a Pin to 1 or 0.

So only write a byte and not an int.

no, my question is about HOW to setup the banks correctly. which byte do i have to send for my needed example setup.

bank A 0-3 = output 4-7 = input,

So in the data direction register ( IODIRA ) or address 0 you need to write a 1 in each bit you want an input and a 0 in each bit you need to be an output. To help 1 looks like an I for input and 0 looks like an O for output.
So you need to write the bit pattern 1111 000 in that address, you can express this as 0xF0 in hex or 240 in decimal.

Have you got the data sheet? Go through the registers and set the bits you want.

To get it to only write one register at a time:-
Look at the code for the function ic2_mcp_write_both and change the name to ic2_mcp_write and only write one byte not two or an int.

that means, i have to write for:

  • mcp1 →

  • bank A = output,

  • bank B = output

ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRA, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRB, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUA, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUB, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLA, 0b00000000); // Output 1=High
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLB, 0b00000000); // Output 1=High
  • mcp2 →

  • bank A = input,

  • bank B = input

ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRA, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRB, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUA, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUB, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLA, 0b11111111); // INPUT Low=1
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLB, 0b11111111); // INPUT Low=1
  • mcp3 →

  • bank A = output,

  • bank B = input

ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRA, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRB, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUA, 0b00000000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUB, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLA, 0b00000000); // Output 1=High
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLB, 0b11111111); // INPUT Low=1
  • mcp4 →

  • bank A 0-3 = output 4-7 = input,

  • bank B 0-3 = input 4-7 = output

ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRA, 0b11110000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IODIRB, 0b00001111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUA, 0b11110000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPPUB, 0b00001111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLA, 0b11110000); // Output 1=High INPUT Low=1
ic2_mcp_write (MCPAdresse, Mcp_Reg_IPOLB, 0b00001111); // Output 1=High INPUT Low=1

and for all together:

ic2_mcp_write (MCPAdresse, Mcp_Reg_IOCON, 0b11100000);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPINTENA, 0b11111111);
ic2_mcp_write (MCPAdresse, Mcp_Reg_GPINTENA, 0b11111111);

i also changed

byte ic2_mcp_write_both (uint8_t adr, const byte reg, const byte data )
{
 Wire.beginTransmission (adr);
 Wire.write (reg);
 Wire.write (data);  // port A
 Wire.write (data);  // port B
 return Wire.endTransmission (true);
}

to

byte ic2_mcp_write (uint8_t adr, const byte reg, const byte data )
{
 Wire.beginTransmission (adr);
 Wire.write (reg);
 Wire.write (data);
 return Wire.endTransmission (true);
}

is that all right?
what is the meaning of “const byte …” instead of “byte …” for the parameters?

i do not meant alone “how to write a value to them”, i although meant “are the values correct”.

"what is the meaning of "const byte ..." instead of "byte ..." for the parameters?"
const means the value is stored in flash memory so the sketch can't change it.

what is the sense behind? why in void test(const …?

what is, if i do a

for (byte i=0; i<100; i++)
{
   test(i);
}

this is dynamically, what is stored in flash here?

As written, nothing.
If you had

dataArray[i] = test[i];

then dataArray would get values stored

Or if

test(i);
// was a function call, then something might happen, for example
void test (byte value){
analogWrite (ledPin, value); // change an LED brightness level up or or down
}

CrossRoads:

void test (byte value)

{
analogWrite (ledPin, value); // change an LED brightness level up or or down
  }

what is the difference to this?

void test (const byte value)
{
  analogWrite (ledPin, value); // change an LED brightness level up or or down
}

(use my for-loop above).

what is the difference to this?

Nothing. But if you were to try this:-

void test (const byte value)
{
  analogWrite (ledPin, value); // change an LED brightness level up or or down
  for(int i=0;i<30;i++){
  value +=1;
  analogWrite (ledPin, value);
}
}

Then because value was declared as a const you would get an error. Basically any variable declared as a const can not be changed.

ah, i believe i unterstand.

to change "value" like you did in your example, than i'd better use a pointer?!

No just don't define the value as a const and it will be fine. A const is like saying this is not to be changed and if an attempt is made to change it you get an error.

ok. thanks for explanation. i did not knew it before, that i could use const in parameters declaration for a function/method.

my mcp-setup still went me crazy...