-
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pinMode() behavior seems to differ from pinMode8(). #9
Comments
Thanks for filing the issue, (labelled it as question for now) |
Can you print the return value of If it returns false there is something wrong. snippet bool b = mcp.pinMode(0, INPUT);
serial.println(b);
serial.println(mcp.lastError()); |
Hello, thanks for the quick feedback. Also, maybe just partially related, I noticed that both digitalWrite() and digitalRead() examples report the same values for pinMode8(). As a reference I have 2x MCP23008 on the same I2C bus: GPIs are controlled (read) by one chip; relays are controlled (write) by the other chip. All GPI pins are on an open circuit, when closed, the GPI pin connects to a 5v source. |
So if you set all lines to OUTPUT digitalRead(pin) does work as it should with INPUT. Do you have pull up resistors on the IO-lines? You can set them with mcp.setPullup8(0xFF);
or
mcp.setPullup(pin, true); |
Check of the code in the library did not reveal a bug so far when writing 1's for INPUT and 0's for OUTPUT. |
So, to summarize the behavior I see when I have pin0 triggered: All pins methods show the following:
Console returns: 1 0 0 0 0 0 0 0 Single pin methods:
Console returns: 1 1 1 1 1 1 1 1 As said, still with the single pins methods:
Console returns: 1 0 0 0 0 0 0 0 For further reference: I am using an Arduino Uno board for this kind of tests but the final plaform will use ESP32. |
Can you post your test sketch so I understand what is happening (maybe). |
can you add the following (debug) function to mcp23008.h, uint8_t getPinMode8()
{
uint8_t value = readReg(0);
Serial.println(value, HEX);
return value;
} I'll make a develop branch asap which includes this function later. |
develop branch made - https://github.com/RobTillaart/MCP23008/tree/develop (build successful) |
Dude, you're awesomely fast. :) I will probably need some more time later today to test it and provide a feedback. |
Nevermind, i had a few minutes to spare. MCP23008_test version: 0.1.4 FE 1 FE 1 |
They all return what was expected ==> OK, So next test is testing digitalRead(). I will add some code to the test-sketch |
digital read test added, please give it a try |
Thanks a lot for the effort Rob. So the results in this case are:
I have checked the Adafruit 23017 library meanwhile and spotted this: I'm getting super confused right now but I have a bad feeling about how I wired the GPIO right now (I'm quite noob at electronics), maybe you can confirm my assumptions: so I basicallly have the button connected to 5v and to the MCP pin as I was expecting the pin to be "ground". Is that correct? To clarify the last point: if I setPolarity8(0xFF) my digitalRead() results are 00000000 which makes more sense... sadly it does not seem to recognize the pin7 being closed... |
So... sorry to be so verbose but I had a bit of an epiphany:
This works perfectly and my digitalRead() calls return what I expect, that is: 0 0 0 0 0 0 0 1 The following, sadly, does not, as it sets open GPI to 0 but digitalRead() never sees the closed GPI returning: 0 0 0 0 0 0 0 0
|
The adafruit issue should not be a problem in the pinMode code However if the parameter does not match anything nothing is changed.... bool MCP23008::pinMode(uint8_t pin, uint8_t mode)
{
if (pin > 7)
{
_error = MCP23008_PIN_ERROR;
return false;
}
if ((mode != INPUT) && (mode != INPUT_PULLUP) && (mode != OUTPUT)) <<<<<<<<<<< just compare
{
_error = MCP23008_VALUE_ERROR;
return false;
}
uint8_t dataDirectionRegister = MCP23008_DDR_A;
uint8_t val = readReg(dataDirectionRegister);
if (_error != MCP23008_OK)
{
return false;
}
uint8_t mask = 1 << pin;
// only work with valid
if ((mode == INPUT) || (mode == INPUT_PULLUP)) <<<<<<<<<<< just compare
{
val |= mask;
}
else if (mode == OUTPUT) <<<<<<<<<<< just compare
{
val &= ~mask;
}
// other values won't change val ....
writeReg(dataDirectionRegister, val);
if (_error != MCP23008_OK)
{
return false;
}
return true;
} have to attend another task, to be continued. |
mmm, can you check what |
Result of .pinMode() is 1 (so, true) |
Hello @RobTillaart, have you had a chance to further look into this? |
I have cross checked the code with the MCP23017 which is a 16 channel and those match. Had also a look at the Adafruit library which works very similar (same steps).
https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/src/Adafruit_MCP23XXX.cpp void Adafruit_MCP23XXX::pinMode(uint8_t pin, uint8_t mode) {
Adafruit_BusIO_Register IODIR(i2c_dev, spi_dev, MCP23XXX_SPIREG,
getRegister(MCP23XXX_IODIR, MCP_PORT(pin)));
Adafruit_BusIO_Register GPPU(i2c_dev, spi_dev, MCP23XXX_SPIREG,
getRegister(MCP23XXX_GPPU, MCP_PORT(pin)));
Adafruit_BusIO_RegisterBits dir_bit(&IODIR, 1, pin % 8);
Adafruit_BusIO_RegisterBits pullup_bit(&GPPU, 1, pin % 8);
dir_bit.write((mode == OUTPUT) ? 0 : 1);
pullup_bit.write((mode == INPUT_PULLUP) ? 1 : 0); <<<<<<<<<<<<<<<
} Setting the pullup should not cause your problems as the working pinMode8() does not set them either and that call works. So I found no clues in the library code that explain your problem. Is it possible for you to do a test with the Adafruit libray, see if their input example works? |
@federico77 |
Did you test with the Adafruit library? |
I have ordered two MCP23008 to redo input and output tests. Arduino UNO tested
No problems found so far. |
Points of attention
|
rereading the whole thread
The GPI should have a PULLDOWN resistor (1-10 KΩ ) if you have a switch to 5v. MCP.setPullup8(0xFF); will only enable pull ups. |
This book (you can skip a lot of math) might be helpful (at least it helped me to fill gaps) https://www.amazon.com/Practical-Electronics-Inventors-Fourth-Scherz/dp/1259587541/ref=sr_1_1 |
@federico77 |
Hello Rob, I really appreciate your effort with this topic. I have been on holiday recently hence I was a bit absent, I apologize for that. Let me answer to the various points you wrote in the thread:
Will let you know how it goes with the tests as soon as I have the opportunity. Meanwhile I really thank you for your help. |
Hope you enjoyed your holiday! The book might be cheaper at other bookstores, Amazon has a lot of books but not always best price. The previous version is almost the same but might be way cheaper. I could not replicate the pinMode() problem so I wait for your tests. |
Hey Rob, once again tanks a lot for your help. I tested the library by adding 10k resistors to ground on each GPI pin and now I have more consistent results so I believe it all comes down to my poor design... :( I'll keep testing the various pins configurations but I believe the library is not guilty. PS: I bought the book. |
OK, if you think it is solved you may close the issue.
👍 Have fun reading it, it has some serious math, but most is explained very well. |
I released the 0.1.4 with the getPinMode() added |
Hello gents, I am testing this library before using in my project and I am having a problem that seems silly but I can't get my head around it.
What I see is that the digitalRead(pin) example works perfectly when using pinMode8(0x00). On the reverse, when I am using the single pin methods and setting each pin individually with:
MCP.pinMode(0, INPUT);
the resulting digitalRead(pin) is always 1 as return value. Curiously enough, if I set the pinMode as OUTPUT, everything works as expected.
At this point I am not sure if there is something crooked with the library code or if I am doing something wrong (mistunderstanding or problems with my schematics).
Although I believe it is not related, I am using a chip identified as 0x22 on I2C and I also have a 0x21 on the same bus.
Can you please helpme to find out what is going on here?
The text was updated successfully, but these errors were encountered: