RobTillaart / MCP23S17

Arduino library for SPI based MCP23S17 16 channel port expander
MIT License
26 stars 11 forks source link

ESP32-C3 and MCP23S17 #37

Closed Surmi2 closed 6 months ago

Surmi2 commented 6 months ago

I experienced two errors in ESP32-C3 and two MCP23S17 configurations:

  1. Only the constructor instance "MCP23S17(10)" works. In the other cases (Connect A: -5; Connect B: -5) there are error signals.
  2. In the case of a working constructor, there is no error signal (Connect A: 0; Connect B: 0), but in the case of MCP_A.read16() and MCP_B.read16(), the status of GPA7 is simply missing from the list if its value is LOW. For MCP_x.read8(0) and MCP_x.read8(1), the GPA7 and GPB7 states are missing, but only if their value is LOW.
RobTillaart commented 6 months ago

Thanks for the issue It might take a few days before Ihave time to investigate

RobTillaart commented 6 months ago

Are the other pins read correctly?

Relates to problem 2.

RobTillaart commented 6 months ago

Can you provide minimal code that shows problem 1.

What produces -5?

Surmi2 commented 6 months ago

"MCP23S17_two_address.ino" and "MCP23S17_two_select.ino" show the error described in point 1. "DI80.ino" shows the error described in point 2. The error appears on the serial monitor when the GPA7 input goes LOW. In the case of "MCP.read8(0)" and "MCP.read8(1)", the LOW level is not visible on the GPA7 and GPB7 inputs. ​ MCP23S17.zip

RobTillaart commented 6 months ago

try this change to see what is read when -5 is returned

int testConnection(MCP23S17 & mcp)
{
  uint16_t magic_test_number = 0xABCD;

  //  Read the current polarity config to restore later
  uint16_t old_value;
  if (! mcp.getPolarity16(old_value)) return -1;

  //  Write the magic number to polarity register
  if (! mcp.setPolarity16(magic_test_number)) return -2;

  //  Read back the magic number from polarity register
  uint16_t temp;
  if (! mcp.getPolarity16(temp)) return -3;

  //  Write old config to polarity register
  if (! mcp.setPolarity16(old_value)) return -4;

  //  Check the magic connection test
  if (temp != magic_test_number) 
  {
    Serial.println(temp, HEX);
    return -5;
  }

  return 0;  //  OK
}

seeing what is read back might give some insight what happened.

RobTillaart commented 6 months ago

Only the constructor instance "MCP23S17(10)" works. In the other cases (Connect A: -5; Connect B: -5) there are error signals.

Q: So you mean the chip works correctly when you use default hardware SPI.

In the case of a working constructor, there is no error signal (Connect A: 0; Connect B: 0), So it is able to write and read to a register of the device without failing any bits.

In the case of a working constructor, there is no error signal (Connect A: 0; Connect B: 0), but in the case of MCP_A.read16() and MCP_B.read16(), the status of GPA7 is simply missing from the list if its value is LOW. For MCP_x.read8(0) and MCP_x.read8(1), the GPA7 and GPB7 states are missing, but only if their value is LOW.

mmm, GPA7 and GPB7 are the first bits to be read when MSBFIRST. Q: Are the other 7 bits read correctly? Do they appear in the right position?

(using SW SPI) The initial return value of every byte is 0 (== LOW) so it is strange that the LOW is misread,

RobTillaart commented 6 months ago

It reminds me of a problem with the I2C version of the device, version D.

image

However it is not a known issue for the SPI version of the device.

Surmi2 commented 6 months ago

Képernyőkép 2024-02-26 162418

RobTillaart commented 6 months ago

mmm so one device seems to connect and the other doesn't.

Could be a timing problem of the initialization of the SPI library. I do not have an ESP32-C3 to test its behavior. Can you add a delay(1000) after SPI.begin() in setup? Can you reverse the order of the connection tests ?

Surmi2 commented 6 months ago

The first image is the result of "MCP23S17_two select.ino", this image is the product of "...two_address.ino". Képernyőkép 2024-02-26 163355

Surmi2 commented 6 months ago

Interesting! 1sec delay did this: (...select.ino) Képernyőkép 2024-02-26 165253

RobTillaart commented 6 months ago

indeed strange.. Do you have pull up resistors on the IO lines used? Can you check if data in /out are not swapped ?

Surmi2 commented 6 months ago

Q: So you mean the chip works correctly when you use default hardware SPI. - YES! Q: Are the other 7 bits read correctly? Do they appear in the right position? - YES!

"Van felhúzó ellenállásod a használt IO vonalakon?" - YES! ( MCP_A.setPullup16(0xFFFF); MCP_B.setPullup16(0xFFFF); ) "Can you check if data in /out are not swapped ?" - no exchange!

Surmi2 commented 6 months ago

This picture shows when the GPA5-6-7-6 input of MCP_A gets a LOW level one after the other, then the same inputs of MCP_B. The LOW level of the GPA7 simply disappears, it is not there, it is missing from the picture. Képernyőkép 2024-02-26 172749

RobTillaart commented 6 months ago

You are missing a leading zero! Do you print the value of the register as BIN (binary)? Try printing it as HEX

Arduino printing is not superb Have a look at - https://github.com/RobTillaart/printHelpers


Description

The printHelpers library contains a number of functions that help to print data in a way not possible in the standard print library of the Arduino.

Surmi2 commented 6 months ago

Thanks, problem 2 solved. (It wasn't!) I didn't think that in BIN format the serial monitor weeds out the leading zero. No problem in HEX format.

RobTillaart commented 6 months ago

It is in fact the print class that causes the error. When you would print to an SD card or Ethernet stream it also happens.

RobTillaart commented 6 months ago

Problem 1 might be caused by the already used pins by the C3. I have an ESP32 (C1 I think) and it has some pins that are already used.

You could try to use other pins or maybe the pins of the hardware SPI.

Surmi2 commented 6 months ago

Thanks for the help, so I will be able to use the MCP23S17. It would be nice if the hardware addressing would also work, because the ESP32-C3 has few GPIOs and I want to manage five MCP23S17s with it. I am using the harweres SPI pins. (SCK-4, MISO-5, MOSI-6)

RobTillaart commented 6 months ago

use void enableHardwareAddress() to set the IOCR_HAEN bit.

Then it should work by giving each of the 8 mcp23S17's a different set of address pins. Also you must set the address in the constructor, for HW SPI this looks like:

MCP23S17 MCP_0(10, 0);
MCP23S17 MCP_1(10, 1);
MCP23S17 MCP_2(10, 2);
MCP23S17 MCP_3(10, 3);
MCP23S17 MCP_4(10, 4);
MCP23S17 MCP_5(10, 5);
MCP23S17 MCP_6(10, 6);
MCP23S17 MCP_7(10, 7);

It should be possible that all use the same SELECT pin as in the constructors above.

Surmi2 commented 6 months ago

I already tried this way and the compiler gives an error message: "Compilation error: call of overloaded 'MCP23S17(int, int)' is ambiguous MCP23S17 MCP_A(7, 0);"

RobTillaart commented 6 months ago

Use const uint8-t for the address an select pin

Surmi2 commented 6 months ago

"Use const uint8-t for the address an select pin" - I do not really understand this!

Surmi2 commented 6 months ago

MCP23S17 MCP_A(7, 0); MCP23S17 MCP_B(7, 1); This is not good like this?

RobTillaart commented 6 months ago
const uint8_t select = 10;
const uint8_t addr1 = 3;
MCP23S17 mcp(select, addr1);
Surmi2 commented 6 months ago

Total success!!! The solution to problem 1 is that the constructor only accepts variables of the same type, not numeric numbers. However, if only one piece of data is needed, it will also accept it as a number. (Only this one type was working when the problem was reported.) Thanks for the help. (I recommend that the examples also appear this way.)

RobTillaart commented 6 months ago

I recommend that the examples also appear this way.

I need to look which two (or more) constructors cause the ambiguity as that is deeper cause. Might be compiler specific as one is more strict than the other.

RobTillaart commented 6 months ago

Different behavior confirmed: The AVR compiler just gave a warning where the ESP32 gives an error.

Surmi2 commented 6 months ago

Thanks for the information. I'm running version 2.3.2 of the Arduino IDE and it gave me an error when compiling. I was disappointed because I wanted to use the MCP23S17 in ESPHome first, but it turned out that ESPHome does not support the hardware addressing mode, and then it was not possible to use it in Arduino either. But now it works flawlessly. Thanks again for your contribution, I hope these comments will help others.

RobTillaart commented 6 months ago

As the issues are solved I close the issue.