|
Forum Index : Microcontroller and PC projects : RP2040 program for Keypad with more than 4x4 keys.
| Author | Message | ||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
The RP2350 MMBasic can utilize large keypads. This provides that for a RP2040. There is bound to be much room for improvement in how it goes about it so any suggestions are welcome. However it seems to get the job done as it is. The initial version was much simpler but the PORT Command and Function GP numbers had to be set one at a time throughout the program. This sets them all at the start. ' KeyPad2040.bas - Program for more than 4x4 Key Pad 'rows = number of rows 'cols = number of columns 'RowPinGP = first of the row GP pin numbers 'ColPinGP = first of the column GP pin numbers 'Key = number of the key that has been pressed. eg. 0 to 19 for 4 columns x 5 rows. 1st row 0 to 3, last 16 to 19. Option base 0 Dim integer n, Key=-1, RowPinGP=0, rows=5, ColPinGP=5, cols=4 For n=RowPinGP To RowPinGP+rows-1 SetPin MM.Info(pinno "GP"+Str$(n)),DOUT 'set the Port out pins Next For n=ColPinGP To ColPinGP+Cols-1 SetPin MM.Info(pinno "GP"+Str$(n)), INTH, Key.Pad, PULLDOWN 'set the Port input pins and ISR Next Execute "Port(GP"+Str$(RowPinGP)+",rows) = 2^rows-1" 'set all row pins high Do ' main processing loop If Key+1 Then Print Key, Hex$(Key) : key=-1 'to retain the value of Key set a flag in the sub and reset it here Loop Sub Key.Pad Local integer y, x For y = 0 To rows-1 'read the rows Execute "Port(GP"+Str$(RowPinGP)+",rows) = 1 << y" Pause 9 'contact bounce delay Execute "x = Cint(Log(Port(GP"+Str$(ColPinGP)+",cols)+.001) / Log(2))" 'read the columns, +.001 prevents divide by zero error Key = y*4+x 'get key no. from row no and col. no. Execute "If Port(GP"+Str$(ColPinGP)+",cols) Then Exit For" Next Execute "Port(GP"+Str$(RowPinGP)+",rows) = 0" 'block further input to prevent double press ' Print y, x,, Key, Hex$(Key) Pause 200 Execute "Port(GP"+Str$(RowPinGP)+",rows) = 2^rows-1" 'prepare for next key input 'Set a flag here if main prog. needs it End Sub End Footnote added 2025-12-31 17:12 by phil99 First error. In the Sub For-Next 2nd last line replace:- Key = y*4+x 'get key no. from row no and col. no. With:- Key = y * cols + x 'get key no. from row no and col. no. |
||||
| Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3331 |
Excellent. This should be posted to https://fruitoftheshed.com Geoff Geoff Graham - http://geoffg.net |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
Thanks Geoff, if no problems or improvements are found I will post it on FoTS. |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
First error. In the Sub For-Next 2nd last line replace:- Key = y*4+x 'get key no. from row no and col. no. With:- Key = y * cols + x 'get key no. from row no and col. no. |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4185 |
Does it need to use Execute? John |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
The initial version didn't use Execute but the GP numbers had to be set individually throughout the program as the Port command and function won't accept a string for the GP number. They do accept Pico pin numbers but then you have to account for the ground pin numbers breaking the sequence. That appeared even more complicated. |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5552 |
@john, Unless you hard code the GP Numbers, the port command needs it. @phill, So LOG(0) causes a dividend by zero error. Didn’t know that. Thanks for educating. Happy new year, must be now in your location.., Volhout Edited 2025-12-31 19:49 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
| Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 1030 |
It would be fantastic if this command could be used as an OPTION. Then you could create a portable device with an LCD and keyboard using ONLY ONE CHIP. Frank |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
I didn't think it would happen at all, but occasionally that line gave a 'Divide by zero' error. I don't know why, perhaps contact bounce. Execute Isn't causing it as it was happening in the first version without Execute. My workaround is an ugly kludge but the error hasn't happened since adding it. |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
Peter did that for the RP2350. |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
Just for fun, how close to log(0) can you get? This was one step too close! > ? log(0.00000000000000000000000000001) Error : Expression syntax Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory Error : Not enough Heap memory *** PANIC *** Out of memory |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4185 |
Instead of Execute "Port(GP"+Str$(RowPinGP)+",rows) = 2^rows-1" I was hoping (well, expecting) such as this would work Port("GP"+Str$(RowPinGP), rows) = 2^rows-1 Does it fail? John |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5552 |
There is an mm.info that translates a pin number to a GPxx. Maybe that can be used for the starting point in the PORT command. Not at home atm, so cannot test. Volhout PicomiteVGA PETSCII ROBOTS |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
> RowPinGP = 0 rows = 5 > Port("GP"+Str$(RowPinGP), rows) = 2^rows-1 Error : Expected a number > Yes, used that for the SETPIN commands but for PORT the numbers must be contiguous. You have to start again after each ground pin. Eg for 8 pins starting with 1 :- PORT(1,2, 4,4, 9,2) as pins 3 and 8 are ground pins. Edited 2025-12-31 20:51 by phil99 |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4185 |
Odd. The PORT command uses getargs which is a macro for makeargs and that reads as if it would work. @matherp - is it a bug / can it be made to work (without too much hassle)? edit: Oh, it's not expecting a string; it wants such as GP0 rather than any variant of "GP0" Does feel worth fixing... those Executes are not lovely. John Edited 2025-12-31 20:49 by JohnS |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10768 |
If you want nxm keypads you can use the RP2350 where they are fully supported. Do you want me to include this functionality on the RP2040? Worst case it increases flash usage by 16Kbytes and reduces A: drive by the same amount. Best case no change in flash usage as this always goes up in 16K chunks |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2900 |
Yes, and the extra pins of the RP2350B makes it better still. The RP2040 can already do 4x4 and most of the time that is enough. |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2026 |