[SOLVED] Keypad with mcp23008 and arduino - Page 1
Forum section: electronics / projects

author: Moriambar
author_rank: Unknown
timestamp: October 21, 2018, 04:10:20 pm
content: Hi there.I have a really nasty problem with using a 4x4 matrix keypad with themcp23008GPIO expander, using the specificAN1081application note, and I feel like an idiot.I build the circuit as suggested, ie I have 4 pullups (2.2k) on the row pins (which are gpio 7 to 4) and no pullups to the 0-3 pins which are connected to the columns of the matrix.Using the scope I found out that the configuraiton bits are set fine by the MCU and the custom library works fine.Basically what happens is this:I start with the exact values for the mcp23008 registers as the one shown in table 1, page 4 of the AN. This means having set the row pins as inputs and the column input as outputs, as well as the interrupt registers. One thing that confuses me a bit is that the GPPU register, which represents the internal pullups of the component is set for the columns but they nevertheless read 0 as value (probably because they're outputs).Anyway, then I press the key. The interrupt gets correctly raised and I'm able, from the arduino, to read back the GPIO values. I am thus able to read which row has a pressed key inside of it.Now comes the tricky part. As per page 9 of the application note, I need to switch the values of some registers: IO DIRection, and the interrupt ones. The situationshouldlook like as table 3 on page 6butprobing columns and rows I was able to determine that, as soon as I send the write command for the IODIR register, with flipped bits, both of the row and column pins are set back to 1, instead of being both 0. So I am not able to detect to which column the pressed key belongs.I tried this many times, with different keys and the same result. I actually probed the connections (checking for continuity when a key was pressed) and had no luck there.Is there anything I am missing? Is there anyway I can help you help me.Thanks a lot for anyone reading this.Cheers

author: bson
author_rank: Unknown
timestamp: October 21, 2018, 09:43:11 pm
content: Make sure you're writing the right registers. The easiest way to check is with an LA, a scope that can decode I2C, or a simplified sniffing device like for example a Bus Pirate:https://www.adafruit.com/product/237?gclid=EAIaIQobChMIyIHO1r6Y3gIVgXp-Ch1sqwY5EAQYBCABEgJ6yvD_BwEThe MCP23008 can operate in two different modes: auto increment the register after each write (handy for initialization off a table), or maintain the same register - usually the GPIO register, so you can keep feeding it output values. It sounds like you keep writing bytes to it and end up scribbling over the registers due to auto increment. Each time you change register you need to start a new write transaction.

author: Moriambar
author_rank: Unknown
timestamp: October 21, 2018, 10:05:33 pm
content: Quote from: bson on October 21, 2018, 09:43:11 pmHi, thanks for your reply. I do have a logic analyzer (albeit a cheap one… it works though) and I definitely write the right registers (perhaps I should've mentioned it more clearly, but the serial communication goes exactly as I expect), each write operation with its start condition.Nevertheless, perhaps I can disable the autoincrement feature (SEQOP bit in IOCON register, right?) since it can do no harm, but this does not explain why the startup configuration goes well, ie why reading back the configuration bytes yields exactly table 1 while afterwards it does not: the same methods are called, shouldn't it work always or always fail?Thanks again for your answer, hopefully I'll be able to test something in around 20 hours.

author: Ian.M
author_rank: Super Contributor
timestamp: October 21, 2018, 10:39:21 pm
content: I bet you are wishing you'd chosen a dumb 8 bit I2C I/O expander like PhilipsPCF8574(A). No data direction registers, status registers, configuration registers, autoincrement, or other crap, just an 8 bit open drain bidirectional port with internal pullups.

author: TJ232
author_rank: Frequent Contributor
timestamp: October 22, 2018, 04:30:07 am
content: I the past I had some strange MCP23008 behaviors and Ian.M it's right, it's very easy to implement a matrix keyboard with PCF8574You can find a detailed tutorial about such a implementation here:4×4 Matrix Keyboard for ESP8266.In this particular case the target MCU was ESP8266, but it's a valid option for any other one.

author: Moriambar
author_rank: Unknown
timestamp: October 22, 2018, 06:22:29 am
content: Are you saying that MCP23008 cannot do the job and the PCF8754 is best suited? Anyway I think this is not a real solution, I mean either the MCP23008 cannot do the job (which is fine, then I can switch the component) or it can, and in the latter case I think it's best to learn why it does not work (at least I learn something). Unfortunately I'm also committed to the mcp at this moment (I enthusiastically bought many as I needed them throughout the project).Thanks though: now I know about the PCF8754, for the futureCheers

author: Ian.M
author_rank: Super Contributor
timestamp: October 22, 2018, 08:01:27 am
content: The MCP23008 can do the job, its jut that its a PITA to get it configured correctly. Unless code space in the MCU is an issue, there's no reason to swap to the PCF8574.It should be noted that if you are bringing up I2C for the first time, on an unfamiliar MCU, or writing a bit-banged implementation, a PCF8574 is a very useful chip to have for testing, no matter what the final slave device(s) will be, as its just about the dumbest read/write capable slave device out there, so all you have to do is concentrate on the MCU code and the signals on the I2C bus, without having to consider the possible complexities of configuring a slave device. I recommend ordering a few, and assembling one on a board with an 8 way DIP switch, to ground its I/Os, and an octal buffer driving eight LEDs (with series resistors), . Put a different colour LED on the /INT pin. Fit jumpers for the slave address and socket the PCF8574 so you can swap it for a PCF8574A.

author: Moriambar
author_rank: Unknown
timestamp: October 22, 2018, 09:44:18 am
content: No, I don't have space issues, nor this is my first I2C implementation. I do have a ton of mcp23008s though (used elsewhere in the project with no problems), so I'm still not keen to make the switch just yet, but I'll be doing it only if there's no other viable alternatives. thanks.

author: Ian.M
author_rank: Super Contributor
timestamp: October 22, 2018, 01:04:34 pm
content: Show us your code for the keypad MCP23008's initialisation and AN1081 based key interrupt, key scanning and key release detection. There's probably something hinky in the initialisation, or how you are reconfiguring the MCP23008 after the key interrupt. Tell us where to get any 3rd party libraries.Also, how is the MCP23008 INT pin connected to the Arduino, and what have you done with the MCP23008's reset pin?

author: bson
author_rank: Unknown
timestamp: October 23, 2018, 02:35:52 am
content: Totally agree on the PCF8574. Easiest device to work with, ever.Well, this side of a '595.

author: Moriambar
author_rank: Unknown
timestamp: October 23, 2018, 06:11:26 am
content: Quote from: Ian.M on October 22, 2018, 01:04:34 pmHi. Of course you're right and there were some problems with the configuration (my mistake in reading the AN, I'm such a dumbass), and also about the mcp23008 complexity.Unfortunately I am ill, and in bed, and I cannot check anything else. But thanks for your insight, I hopefully will be able to settle this on the next few daysCheers

author: Moriambar
author_rank: Unknown
timestamp: October 23, 2018, 05:57:40 pm
content: Yes, it ultimately was a configuration problem. Thanks to all who replied: you made me search up a new component and made me learn something usefulCheers