Author Topic: Reading Keypad MPLab Assembly  (Read 11946 times)

0 Members and 1 Guest are viewing this topic.

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Reading Keypad MPLab Assembly
« on: February 25, 2024, 03:30:36 pm »
In a previous post I showed a nice box (https://www.eevblog.com/forum/mechanical-engineering/mitutoyo-982-537-1-dro-display-with-series-572-linear-scales/msg5287843/#msg5287843  ).  I'd like to use that keypad now.  My device of choice is an enhanced, mid-range PIC16F1xxx using MPLab Assembly 8.92.

Attached are two images of how the pads are arranged according to the 9-conductor FFC numbered L to R, 1..9.  There seem to be 2 sets: SetA = conductors 1..5 and SetB = 6..9, i.e., 20 combinations for 20 keys.

In previous projects reading smaller keysets, I just converted the key/port pin to a number and used a jump table.  I could easily do the same with four jump tables or a table of tables as described years ago by Peter Anderson at Johns Hopkins.

My question: Is there a simpler, perhaps more obvious way?  I am not adverse to adding a new chip that would convert the 9-inputs to a 5-bit number.  If so, please recommend a multiplexer chip that can do that.

EDIT: Added a single table that may be clearer.



« Last Edit: February 25, 2024, 05:59:53 pm by jpanhalt »
 

Offline jwet

  • Frequent Contributor
  • **
  • Posts: 834
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #1 on: February 25, 2024, 08:35:41 pm »
It depends how code starved you are.  I did a lot of assembly with <2k or ROM. 

Here is something to try perhaps, if not smaller, might be easier to understand than just a bunch of RETLW   code statements.

You can observe that all the numbers are either an 8 or a 9.  You could branch somewhere and decode the things.  Its likely that all numbers get handled the same way so after decoding them, you'll fall through to some common code (append digit).

The cursor keys are almost all 7's, you could do similar two stage decode.

You'll probably find that you end up with the same size.

Look up tables are pretty efficient, especially if you run them through a c compiler- good C compilers use tricks like folding, etc and can improve your logic.  You can do all the same in assy.

Have fun.
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #2 on: February 25, 2024, 09:24:56 pm »
I love coding in Assembly.  It's fun and relaxing.  While modern PIC's have much more room, I enjoy the challenge of keeping the code tight.  The instruction set for enhanced 16F  PIC's was improved a little. 

I just worked out a bit of code to do what I want.  Basically I need to convert a set PORT pin to a bit position, not binary value, to keep the table small.  That doesn't take a lot of code for bits 0..3 (i.e., Set B in the revised single table).  From there, it's a typical jump  table.

When I get something working, I will post it here.  Right now, it's about time to receive Sunday calls from my children and start dinner.

John
 

Offline Benta

  • Super Contributor
  • ***
  • Posts: 6599
  • Country: de
Re: Reading Keypad MPLab Assembly
« Reply #3 on: February 25, 2024, 11:12:26 pm »
Dunno why you have a problem with this.
It's obviously a 4 x 5 matrix. Super easy to decode (hardware-wise).

Whether you then use the result in a table or bitwise is up to you.
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #4 on: February 25, 2024, 11:27:10 pm »
So far as I know, the PIC 16F1xxx chips do not have hardware decoding.  Can you give a simple example?  It's obvious how to do it with 2 ports and some firmware, and that is what my rough code does.
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #5 on: February 26, 2024, 10:23:22 pm »
UPDATE

I've fiddled with the 4x5 table and came up with this.  It is untested.
Code: [Select]
Keyboard
;Use hypothetical PORTB for the 4 switches of the 4X5 matrix
;after key press, jump to ISR, and process PORTB(4) and PORTC (5) 
;delay 40 msecs for debounce
 
     lsrf      PORTB,w        ;STATUS,0 has state of RB0
     andlw     0x07           ;PORTx > lsrf > if WREG,2 set
     btfsc     WREG,2         ;0001    0000   0000     
     movlw     3              ;0010    0001   0001
                              ;0100    0010   0010       
                              ;1000    0100   0011
     btfsc     PORTC,S1       
     bra       DoS1
     btfsc     PORTC,S2
     bra       DoS2
     btfsc     PORTC,S3
     bra       DoS3
     btfsc     PORTC,S4
     bra       DoS4
     btfsc     PORTC,S5
     bra       DoS5
     bra       Main           ;exit ISR or ERR --> exit ISR
DoS1
     brw                     
     bra       ESC
     bra       _SET
     bra       Num0
     bra       Num7
DoS2
     brw     
     bra       ALM               
     bra       Right
     bra       Num3
     bra       Num8
DoS3
     brw
     bra       Dec                       
     bra       ENT
     bra       Num2
     bra       Num9
DoS4
     brw
     bra       Inc
     bra       CLR
     bra       Num1
     bra       Num4
DoS5
     brw
     bra       Left
     bra       ChgSign
     bra       Num6
     bra       Num5

ESC
_SET
ALM
ENT
CLR
Right
Left
Inc
Dec
ChgSign
Num0
Num1
Num2
Num3
Num4
Num5
Num6
Num7
Num8
Num9
Err
     nop
     bra       Main
« Last Edit: February 26, 2024, 11:02:47 pm by jpanhalt »
 

Offline Benta

  • Super Contributor
  • ***
  • Posts: 6599
  • Country: de
Re: Reading Keypad MPLab Assembly
« Reply #6 on: February 26, 2024, 11:03:51 pm »
I don't know the PIC, nor its assembly language.

But the way to do it works like this (you need an input port with interrupt capability!)
The ports you're using must be bidirectional.

All pins from your keyboard need pull-up resistors, say, 47 kohm.

Connect 5 pins to the interrupt capable input port. Connect 4 pins to another port and set the pins to output, low.

If a key is pressed, the input port will issue an interrupt.
Wait a moment (debouncing) and read the port and store.

Reverse the ports, making the first one output, low, and make the the second port input. Read the second port and store.

End the interrupt.

You now have the coordinates of the pressed key in your 5 x 4 matrix.

Decoding it should be trivial.
 
The following users thanked this post: jpanhalt

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #7 on: February 26, 2024, 11:45:24 pm »
Thanks.

The PIC16F1xxx  ("Enhanced mid-range") are just 14-bit core, 8-bit MCU's, which forces quite a bit of banking and occasional paging compared to 16-bit cores, and of course real 16-bit MCU's.  They have limited math, but the instruction set is easy to remember, and they have one level of interrupt. That has not been a problem for me as a hobbyist. (The 12F5xx and 16F5xx do not have interrupts.)

I am pretty familiar with using that type of interrupt and will integrate it into my "Main" routine.  The whole purpose of this project is to control infeed of a lathe while threading, particularly while doing female threads with a small tpi (i.e., 8 tpi).  More than a decade ago, I did that with a simple dial indicator where all I monitored was to detect the change from + to -.   That worked, but was clumsy.  I am fitting those old Mitutoyo scales from my mill to my lathe, and they output the Mitutoyo SPC format in mm only.  So, there is a lot more to entering a preset and testing when that endpoint is reached.

The parts of this project are pretty much done.  Now, all I have to do is glue them together.  Overall, the Assembly code is pretty compact.  The limits are 00.000" +/- 0.0005", with a maximum of 99 cm.  The Mitutoyo scales read to 0.01 mm, but that's resolution, not accuracy.

John
« Last Edit: February 26, 2024, 11:47:34 pm by jpanhalt »
 

Offline Benta

  • Super Contributor
  • ***
  • Posts: 6599
  • Country: de
Re: Reading Keypad MPLab Assembly
« Reply #8 on: February 26, 2024, 11:58:17 pm »
A tip when decoding:
Use shift/rotate instructions to find the right key. That will eliminate the risk of multiple keypresses falsely/out-of-range being decoded.
« Last Edit: February 26, 2024, 11:59:58 pm by Benta »
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #9 on: March 10, 2024, 03:26:56 pm »
UPDATE

The algorithm was implemented on breadboard using IOC registers, but not an interrupt at this time.  That made debugging a bit easier.  In its final embodiment, it will be interrupt based, so the keyboard can be active most of the time. 

Attachments show the progress.  No picture of the solderless breadboard is included as that would be an embarrassment.  I switched to the PIC16F1783 to get 28 pins, all of which have IOC capability.  A new LCD 192x64 with SPI capability (ST7525 controller) should be here in a few days and should be mounting-hole compatible with the existing GLCD LCD.  I like that series of controller.  They are fast and generally require only one CS pin.

Attachments:
1) Faceplate of the now repurposed device shown earlier (OP320-A/OP320-A-S)
2) Keyboard pinout (Word doc)
3) Schematic (Eagle)
4) Breadboard wiring (Eagle)
5) Code (MPLab 8.92 Assembly)

EDIT: There's a typo in the 2nd attachment. A and B are reversed,  Everything was developed as shown, but I had penciled in  PORTB for A and visa versa.  When I posted here, I changed one but not the other.  I will leave it be and the error should be obvious.
EDIT2: Added attachment with dimensions for SparkFun large protoboard so FFC from keypad lines up with holes in the board.
« Last Edit: March 12, 2024, 11:33:05 am by jpanhalt »
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #10 on: November 14, 2024, 02:22:07 pm »
PERPLEXING BUG

I have continued development of my Mitutoyo project.  The PCB used previously was too small to accomodate parts needed for reading the scales, so I wired up another (attached image).  Checked it out, plugged it in, no smoke, and it seemed to work with one big exception.  RA2 read asif it was RA3.  That is, pressing the SET key  read as ESC and so forth.  ESC (RA3) read as ESC  and all the other keys mapped to RA0, RA1, and RA3 read correctly.  Head scratching time.

No shorts, but the watch window for IOCAF confirmed that setting any key mapped to RA2 was read as if mapped to RA3.  Wiring and shorts were tested for more times than I could remember.  I pulled up the last working version of the coe (10/20/24) and that worked fine.  I compared code for the relevant section and found no changes that could do that.  Finally, I compared the entire code, thinking that perhaps I had defined (#Define) something wrong.  (All code is MPLAB 8.92 Assembly.)  The only difference is that the 10/20 code was running at 8 MHz and the current revised code was at 16 MHz.  NB: I usually include an option in Processor Setup for both internal oscillators.

I changed the frequency to 8 MHz and bingo, it worked (see attached captures and focus on IOCAF).  I tried some NOP delays in the read section, and that didn't help.  I have not tested that exhaustively.

I can think of some crazy hypotheses for that behavior, like cross talk or bad solder joints, but would first like to throw it out to the crowd and see what you think.

John
 

Offline macboy

  • Super Contributor
  • ***
  • Posts: 2336
  • Country: ca
Re: Reading Keypad MPLab Assembly
« Reply #11 on: November 14, 2024, 07:50:25 pm »
I don't see any pull up or pull down resistors on your board, and no mention of using any internal pull ups of the PIC. Are you using any? If not, then inputs not actively connected by the key currently being pressed are just floating in the breeze, and that is a problem. 
 
The following users thanked this post: jpanhalt

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #12 on: November 14, 2024, 08:23:04 pm »
Weak pull-ups are enabled in code for inputs (WPUA and WPUB), which is essential for the algorithm to work at all.  What concerns me is the frequency dependency.  If it was just too fast, then why only one row?  Is there that much variance between port pins?  And if that, why just RA2 going to RA3 and not something more random?

Although I hate to consider it, maybe it is crappy soldering on the input to one or both pins?  (I have been soldering wires for over 72 years.)  If that, then why the frequency dependency?  With a fresh mind (e.g., tomorrow about 1AM ET), I will play more with NOP's.  I am the sort of person who simply can't accept operation at 8 MHz and not 16 MHz without understanding why.  Once I know why, I will go with what works or change it to work at 16 MHz.  (The GLCD screen doesn't work without delays at 32 MHz.  There is no way to read the ready bit using SPI.)
« Last Edit: November 14, 2024, 08:24:46 pm by jpanhalt »
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #13 on: November 15, 2024, 12:37:10 am »
@macboy

You may be onto something.  The internal pull-ups are quite weak (maybe 50k).  I was going to insert nops to delay between setting PORTA as input and clearing IOCAF (P).  Then my ICD3 decided to act up, and that usually takes a clear head and a lot of time to rectify.  If the nop's help, then it's clearly a speed factor, and RA3 must just be enough slower to be picked up as the signal.  That doesn't explain completely why it only happens with row RA2, but it's a start.  If that gets to the answer, adding stronger pull-ups will be simple.   Will update tomorrow, if possible. 

ICD3 doesn't act up that frequently, but when it does, I sometimes have to resort to removing and reloading the entire MPLab 8.92  suite.  Then, I have to rollback a .jam file because of Microchip's errors in the most recent version affecting that series of chips (16F17xx).

John
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly
« Reply #14 on: November 15, 2024, 03:17:37 am »
@macboy
I couldn't get to sleep without trying.  Spent the past 3 hours getting the ICD3 working again and 5 minutes to test the code.

Apparently, that was it.  Added a few nop's and it runs fine now at 16 MHz.  Now to try some external pull-ups to confirm that's the problem.

Here's the modified code,  The most of the nop's are right after I make PORTA,0..3 inputs.

Code: [Select]
GetRow
     movlb     1              ;                                            |B1
     movlw     b'00011111'    ;                                            |B1
     xorwf     TRISB          ;set PORTB to output, IOC inactive for OP's  |B1
     movlw     b'00001111'    ;                                            |B1
     xorwf     TRISA          ;change PORTA to input                       |B1
     movlb     7              ;                                            |B7
;11/14/24
     nop
     nop
     nop
     nop
;end 11/14/24
     clrf      IOCBF          ;                                            |B7
     clrf      IOCAF          ;should reset only after release             |B7
     nop
     btfss     INTCON,IOCIF   ;wait for positive edge on release           |B?
     bra       $-1            ;                                            |B?
     decf      IOCAF,w        ;test for valid data                         |B7
     andwf     IOCAF,w        ;check for 2^n                               |B7
     btfss     STATUS,2       ;zero if single bit set                      |B7
     goto       Err
;convert bit#3 to value = 3 (see note at end for 5 bits)
     lsrf      IOCAF,w        ;STATUS,0 has state of IOCAF,0               |B7
     andlw     0x07           ;if RB4 was set, clears WREG,3               |B7
     btfsc     WREG,2         ;0001 --> 0000 --> 0000                      |B7
     movlw     3              ;0010 --> 0001 --> 0001                      |B7
                              ;0100 --> 0010 --> 0010                      |B7
                              ;1000 --> 0100 --> 0011                      |B7                             
     movlb     0              ;                                            |B0
     return       

Edit: I swapped ports about 2 weeks ago and forget to change the comments  The code was correct and comments are now correct.
« Last Edit: November 15, 2024, 04:00:44 am by jpanhalt »
 

Offline jpanhaltTopic starter

  • Super Contributor
  • ***
  • Posts: 4308
  • Country: us
Re: Reading Keypad MPLab Assembly [SOLVED]
« Reply #15 on: November 15, 2024, 02:09:33 pm »
Same set up and tested how many NOP's were needed.  Only one NOP (250ns) right after setting TRISA,0..3 was needed.  Removed all five NOP's and error came back.  Added a 22k pull-up to RA3, error disappeared.  Added 22k pull-up only to RA2 and error occurred.  Added 22k to both and error disappeared.  That behavior could be repeated.

Conclusion:  The internal weak pull-up on RA3 was lazy.  For the time being, I will put weak pull-ups only on RA0..RA3.  In any final design, weak pull-ups will be added to both  RA0..RA3 and RB0..RB4.  Lesson learned.

EDIT: PIcture to prove it. :)
EDIT2: Another way to see how the Columns and Rows are mapped (attached).
« Last Edit: November 17, 2024, 06:45:17 pm by jpanhalt »
 

Offline Atlan

  • Frequent Contributor
  • **
  • Posts: 697
  • Country: sk
Re: Reading Keypad MPLab Assembly
« Reply #16 on: November 15, 2024, 10:07:10 pm »
Put 1k pullup resistors there.  On the lathe, there will be all kinds of interference when turning on the motor.  The internal pullup resistors will be insufficient, and will cause false button closures.  Personally, I also put capacitors to the buttons.
P. S. Add 100n to gnd on reset pin
« Last Edit: November 15, 2024, 10:12:22 pm by Atlan »
FNIRSI 1013D Always provide a picture or video with the problem where the parameters of the oscilloscope are visible, and a picture of the diagnostic screen with the values.
Firmware is here (or not) https://github.com/Atlan4/Fnirsi1013D/tree/main/latest%20firmware%20version
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf