joeyoung / arduino_keypads

arduino libraries for keypad interface on I2C bus
GNU General Public License v3.0
153 stars 102 forks source link

Option to also use arduino ports? #13

Open salautom opened 2 years ago

salautom commented 2 years ago

I made some modifications for myself because I need a keypad of 10 rows and 8 columns

maybe an option to add this to your code??

byte colPins[COLS] = {-4, -5, -6}; //connect to the column pinouts of the keypad (negative values are ports on the arduino itself) negative numbers are arduino pins.

modified 3 functions:

// individual pin setup - modify pin bit in IODIR reg. void Keypad_MC17::pin_mode(byte pinNum, byte mode) { if (pinNum > 127) { pinMode(abs(pinNum-256), mode); } else { word mask = 0b0000000000000001 << pinNum; if( mode == OUTPUT ) { iodir_state &= ~mask; } else { iodir_state |= mask; } // if mode _wire->beginTransmission((int)i2caddr); _wire->write( IODIRA ); _wire->write( lowByte( iodir_state ) ); _wire->write( highByte( iodir_state ) ); _wire->endTransmission();
} } // pin_mode( )

void Keypad_MC17::pin_write(byte pinNum, boolean level) { if (pinNum > 127) { digitalWrite(abs(pinNum-256), level ? HIGH : LOW); } else { word mask = 1<<pinNum; if( level == HIGH ) { pinState |= mask; } else { pinState &= ~mask; } port_write( pinState );
} } // MC17xWrite( )

int Keypad_MC17::pin_read(byte pinNum) { if (pinNum > 127) { return digitalRead(abs(pinNum-256)); } else { _wire->beginTransmission((int)i2caddr); _wire->write( GPIOA ); _wire->endTransmission( ); word mask = 0x1<<pinNum; _wire->requestFrom((int)i2caddr, 2); word pinVal = 0; pinVal = _wire->read( ); pinVal |= ( _wire->read( )<<8 ); pinVal &= mask; if( pinVal == mask ) { return 1; } else { return 0; } } }

joeyoung commented 2 years ago

Interesting idea, thanks. I'll leave this issue open here for anyone else to see the approach. If there's additional interest, I can incorporate it in the library.

There is also an alternative way to get large keyboards using more than one port expander. I found that scanning speed with big keyboards is poor with ATMega328 arduinos but may be ok with faster cpus.

Assamita81 commented 1 year ago

I'm working on a project that ideally would required a 9x9 keypad, so I could use that feature, but I'm not sure I'm skilled enough to understand what @salautom did. I could get away with an 8x8 matrix plugged into a PCF8575 and do a small separate matrix for row 9 and column 9 buttons directly plugged into the arduino. So far I haven't been able to build a working 8x8 keypad with the PCF module, but I haven't tested this library yet (I tested a couple others). When I return home, I'll test this one, see if this is the winner.

joeyoung commented 1 year ago

I have not tried the method mentioned above, but it should work OK. An alternative which would use the existing libraries but adds another PCF8575, connect the ninth row and column to the second PCF8575. The second PCF8575 would have a 9x2 matrix keymap if you have access to the wiring of the 9th row and column keys separate from the 8x8 matrix. If instead you have a 9x9 keypad with only 9 row and 9 column wires, then you'd share the rows (or columns) of the first 8 and add the 9th row(or column) plus the last column(or row) on the second PCF8575. Some of the other examples show how to set up multiple keypad objects on separate I/O expanders.

joeyoung commented 1 year ago

I should also add to the comment above that for the case when you can access the wiring (the second possibility mentioned by Assamita81) the existing libraries Keypad_I2Ca can be used for the 8x8 keypad and the library Keypad can be used with the direct i/o pins for the extra 18 keys. Fewest pins would be to arrange the direct i/o as a 3x6 matrix.

Assamita81 commented 9 months ago

Hi. I'm back. I've had so much bad experience with PCF8575 that I'm giving up on them. I'm moving onto trying the MCP23017 instead, I just ordered 5 of them to test them. Any chance to have the possibility of an 8x8 matrix, considering they have 16 I/O ports? I've seen in your keypad documentation that you only mention the bits for 8 of the pins (21 to 28). I'm assuming that library won't work for a 6x6 or 8x8 matrix, will it? and if so, what would the other 8 bits be?