Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Umite Keypad and interrupts
Page 1 of 2 | |||||
Author | Message | ||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I think this one is for Geoff. Would it be possible to amend the KeyPad command to allow a null value for the interrupt routine: e.g. KeyPad KeyCode,,r1,r2,r3,r4,c1,c2,c3[c4]. I would like to be able to read a value from the keypad inside the interrupt routine without generating another interrupt. Either that or an "interrupt on/off" command. The keypad function works just fine otherwise. David M. |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3196 |
I don't understand what you are looking for David. You can get the last keypress from within the interrupt routine by examining the variable "KeyCode". If you hang around in the interrupt for long enough the variable KeyCode will change to the next keypress - but spending too much time in an interrupt is not recommended. You can also examine and change KeyCode outside the interrupt routine. Nothing special happens when the interrupt is called, all the interrupt does is tell you that a key has been pressed and that KeyCode has been updated. If you do not want to use an interrupt you can put nothing in there. eg: KEYPAD_INTERRUPT: IRETURN As with most things on the Maximite/Micromite, you need to experiment to understand the subtleties. Geoff Geoff Graham - http://geoffg.net |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Thank you Geoff. I have been trying to emulate a polled i2c version of the keypad and as a consequence was trying to complete my task within the interrupt routine. Believe me I do a lot of experimenting. This time, the trees got in the way of the wood. By leaving the interrupt routine empty, I can use the keycode as you say, in the main programme or a sub. I'll post the project when done. It uses the uMite keypad, uMite lcd and i2c RTC. It doesn't leave many pins for other things. Ordinarily I'd just use i2c anyway but thought I'd try uMite hardware combo. David M. |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
@ MOBI - Was supposed to get back to you in email, but have been busy. Have not forgotten you. Will try to get back to this soon... Smoke makes things work. When the smoke gets out, it stops! |
||||
robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2350 |
... and, of course, one can process a keystroke (in polled mode) then set KeyCode to an unused value (such as -1). you then just need to wait for KeyCode to change value again to indicate the next keypress - i've not tried this, but it looks fairly obvious that it should work ok. btw, is there any order/combination of LCD INIT and KEYPAD that can be used where the two will allow sharing of the LCD data pins yet not interfere with each other? if LCD INIT is called second, will it reassign the function of the driven set of keypad pins, such that keypad functions will still work if diodes are inserted? rob :-) |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
It works fine that way Rob. I'm doing that on UV lamp exposure controller now I'm working on now - code below. I just set it to 99 and loop till "keypress" returns as other than 99. I also got it to assign the 99 to another variable and convert it to a string but that's unnecessary - I just haven't changed it from some playing I was doing. The 24 pin Pic's looking a bit cluttered too you might notice, but it's handling the standard 4x4 keypad and 4x20 LCD display fine. There's also a pin being used for a lamp relay and one for a buzzer - there's still a couple left! You can't see it on the photo but that cursor is flashing nicely and steps through the mins/secs entry as it's done and does entry error checking too. The empty line under it has the "Countdown" on it when the lamps are ON - all very well lined up now that Geoff's given us the STR$ function with optional leading zeroes - great! The code works fine as is but it would never pass "Programming 101" . There are a heap of "naughties" in it yet that I'd like to get rid of. Greg LCD INIT 2,3,4,5, 23,24
lcd clear Keypad KeyCode, Key_Int, 15,16,17,18,6,7,9,10 mins$ = "00": secs$ = "00" timeset = 0 'exposure time not yet set badentry = 0 led = 14 'pin no. for lamps-ON led buzz = 21 'pin no. for buzzer display_menu: settick 0,0 lcd cmd 12 'make cursor invisible (turn off) if timeset = 0 then LCD 1,1, " Time set = __:__ " LCD 2,c20, "" LCD 3,1, "Set Time - Press A" lcd 4,c20, "" else lcd 1,1, " Time set = "+ mins$ +":"+ secs$ lcd 2,c20, "" LCD 3,1, " Lamps ON - Press B " LCD 4,1, "Reset time - Press A" endif keycode$ = "99" do 'wait for keypress loop until keycode$ <> "99" if keycode = 20 goto set_time if keycode = 21 goto lamps_ON if keycode = 23 goto display_menu set_time: settick 0,0 mins$= "": secs$= "" 'reset variables lcd 2,c20,"" lcd 3,1, " Enter set time " lcd 4,1, " MENU - Press D " lcd 1,13, "" 'set cursor at 'mins' position lcd cmd 15 'turn cursor on secflag = 0 'check_key flag for seconds input for count = 1 to 2 'get the two mins digits keycode$ = "99" do 'wait for keypress loop until keycode$ <> "99" check = keycode check_key (check,count,secflag) mins$ = mins$ + keycode$ 'builds mins$ lcd 1,13, mins$ 'display 1st mins digit next lcd cmd 20 'move cursor past ":" secflag = 1 'check_key flag for seconds input for count = 1 to 2 'get the two secs digits keycode$ = "99" do 'wait for keypress loop until keycode$ <> "99" check = keycode check_key (check,count,secflag) secs$ = secs$ + keycode$ 'display 1st secs digit lcd 1,16, secs$ 'display current secs$ string next lcd cmd 12 'make cursor invisible (turn off) timeset = 1 'timer set flag '---------------------end of set_time: sub check_key (code,cnt,insecs) if code = 23 then goto display_menu if code > 9 then goto set_time 'display_menu if code > 5 and cnt =1 and insecs =1 goto set_time if code > 9 and cnt =2 and insecs =1 goto set_time end sub '---------------------- lamps_ON: if timeset = 1 then LCD 3,1, " Lamps ON - Press B " LCD 4,1, "Reset time - Press A" else goto set_time endif keycode$ = "99" do 'wait for keypress loop until keycode$ <> "99" if keycode = 20 then goto set_time if keycode = 21 then setpin led,DOUT 'make lamp pin digital out setpin buzz,DOUT 'make buzzer pin digital out lcd 3,1, " - LAMPS ON - " lcd 2,1, "Countdown = "+ mins$ +":"+ secs$ lcd 4,1, "Lamps OFF - Press C " pin(led) = 1 'turn on lamps-ON led for i=1 to 3 'buzz "lamps-ON" - 3 short beeps pin(buzz)=1: pause 200 pin(buzz)=0: pause 200 next mins = val(mins$): secs = val(secs$) totsecsrem = (mins*60)+secs 'total secs for countdown settick 1000,countdown 'interrupt every second keycode$="99" do 'wait for keypress loop until keycode$ <> "99" if keycode$ = "22" then lamps_OFF if keycode$ = "23" then lamps_OFF endif 'end of lamps-ON sub lamps_OFF settick 0,0 'stop countdown interrupt pin(21) = 1: Pause 1000 '1 long beep = "lamps OFF" pin(21) = 0 pin(14) = 0 'turn lamp LED off setpin 14,0 setpin 21,0 lcd 3,1, " - LAMPS OFF - " lcd 4,1, " MENU - Press D " end sub keycode$="99" do 'wait for keypress loop until keycode$ <> "99" if keycode$ = "23" then goto display_menu countdown: totsecsrem = totsecsrem - 1 remminsec = totsecsrem/60 dispmins = fix(remminsec) 'discard dec. pt & right of it dispsecs = cint((remminsec - dispmins)*60) lcd 2,13, str$(dispmins,2,0,"0") +":"+ str$(dispsecs,2,0,"0") if totsecsrem = 0 then lamps_OFF ireturn Key_Int: 'key press detected keycode$ = str$(keycode) ireturn |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
My version allows a RTC register to be selected by a 2 digit decimal number, then input a 2 digit BCD value and if the # key is pressed,(accept), the routine writes the BCD value to the register. Simple! This allows alarm values to be set as well. David M. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
This version lets you select any RTC register and alter its value via uMite Keypad. The aim was to use uMite keypad and LCD. Frankly, I'd prefer i2c LCD unless using the 44 pin Pic as not too many I/O pins are left for outside world control. It doesn't have "time-out" facilities but that wouldn't be hard to include. As it stands, it is little more than a clock but once again, individual applications are easily enough programmed in. The main part is the ability to select and change individual registers. Option autorun on
Option break 3 Dim RTCbuff(6) ' Received data is stored here Dim bcd rtc = &b1101000 LCD init 21,22,23,24,15,16 I2C OPEN 100,100 ' Start up the I2C module KeyPad keycode,kp_int,2,3,6,7,9,10,14 'Main Do If keycode = 10 Then set_rtc() I2C WRITE rtc, 0, 1, 0 ' Request the time If MM.I2C <> 0 Then Error "PCF8563 not responding" I2C READ rtc, 0, 7, RTCbuff(0) ' Get the time as 7 bytes bcdtemp = RTCBuff(0) And &H7F ' Get just the bits that we want sec$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16) bcdtemp = RTCBuff(1) And &H7F min$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16) bcdtemp = RTCBuff(2) And &H3f hours$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16) bcdtemp = RTCBuff(4) And &H3f day$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16) bcdtemp = RTCBuff(5) And &h1F month$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16) bcdtemp = rtcbuff(6) year$ = Str$((bcdtemp \ 16) * 10 + (bcdtemp Mod 16) + 2000) If Len(sec$)<2 Then sec$ = "0" + sec$ If Len(min$)<2 Then min$ = "0" + min$ t$ = hours$+":"+min$+":"+sec$+" " D$ = day$+"/"+month$+"/"+year$+" " LCD 1,1,t$ LCD 2,1,d$ Loop 'end_main Sub set_rtc() 'read RTC register and new time value LCD clear: LCD cmd 14 LCD 2,1,"Register ? " GoSub get_two_bytes register = left*10 + right LCD 1,1,"# to Accept " keycode = 99 Do While (keycode <0 Or keycode>11): Loop If keycode <> 11 Then:keycode = 99: Exit Sub:EndIf LCD clear LCD 2,1,"Value ? " GoSub get_two_bytes BCD = left*16 Or right LCD 1,1,"# to accept " keycode = 99 Do While (keycode <0 Or keycode>11): Loop If keycode <> 11 Then: keycode = 99: LCD clear: Exit Sub: EndIf I2C write rtc,0,2,register,bcd End Sub get_two_bytes: Do While keycode < 0 Or keycode >9 : Loop left = keycode LCD data left+48 keycode = 99 Do While keycode < 0 Or keycode >9 : Loop right = keycode LCD data right+48 Return kp_int: IReturn David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
Thanks David, that's going to be handy for another project where I need real-time. My "timer" is purely that, just entry of minutes and seconds, turn ON, countdown, turn OFF - break countdown if wanted. Good for up to 99 minutes (or more if program is modded) and with one second accuracy. No real-time involved. I've tidied up the code a bit (below) but if anyone wants to show me how to do it much more neatly I'm all ears. It's working OK but there's a couple of bugs. For some reason I have to press the 'D' key three times to return to MENU and the 'B' key twice to start the countdown after having already counted down the first time. I also get a "Not in interrupt" error occasionally which bombs it out. Any ideas gratefully appreciated. Here's the "tidied" code. Greg 'UVTimer - Author: Greg Yaxley
'Program to enter, display & control exposure time for 'a UV lamp box using a 4x4 keypad & 4x20 LCD display. 'MicroMite Basic V15-28 pin. '---------------------------------------------- LCD INIT 2,3,4,5, 23,24 lcd clear Keypad KeyCode, Key_Int, 15,16,17,18,6,7,9,10 mins$ = "00": secs$ = "00" timeset = 0 'exposure time not yet set led = 14 'pin no. for lamps-ON led buzz = 21 'pin no. for buzzer display_menu: settick 0,0 lcd cmd 12 'make cursor invisible (turn off) if timeset = 0 then LCD 1,1, " Time set = __:__ " LCD 2,c20, "" LCD 3,1, "Set Time - Press A" lcd 4,c20, "" else lcd 1,1, " Time set = "+ mins$ +":"+ secs$ lcd 2,c20, "" LCD 3,1, " Lamps ON - Press B " LCD 4,1, "Reset time - Press A" endif get_keycode if keycode = 20 goto set_time if keycode = 21 goto lamps_ON if keycode = 23 goto display_menu set_time: settick 0,0 mins$= "": secs$= "" 'reset variables lcd 2,c20,"" lcd 3,1, " Enter set time " lcd 4,1, " MENU - Press D " lcd 1,13, "" 'set cursor at 'mins' position lcd cmd 15 'turn cursor on secflag = 0 'flag for seconds input false for count = 1 to 2 'get the two minutes digits get_keycode check_key (keycode,count,secflag) mins$ = mins$ + keycode$ 'build mins$ lcd 1,13, mins$ 'display 1st mins digit next lcd cmd 20 'move cursor past ":" secflag = 1 'flag for seconds input true for count = 1 to 2 'get the two seconds digits get_keycode check_key (keycode,count,secflag) secs$ = secs$ + keycode$ 'display 1st secs digit lcd 1,16, secs$ 'display current secs$ string next lcd cmd 12 'make cursor invisible (turn off) timeset = 1 'timer set flag '----------end of set_time:------------------ lamps_ON: if timeset = 1 then LCD 3,1, " Lamps ON - Press B " LCD 4,1, "Reset time - Press A" else goto set_time endif get_keycode if keycode = 20 then goto set_time if keycode = 21 then setpin led,DOUT 'make lamp/relay pin digital out setpin buzz,DOUT 'make buzzer pin digital out lcd 3,1, " - LAMPS ON - " lcd 2,1, "Countdown = "+ mins$ +":"+ secs$ lcd 4,1, "Lamps OFF - Press C " for i=1 to 3 'buzz "lamps-ON" - 3 short beeps pin(buzz)=1: pause 200 pin(buzz)=0: pause 200 next mins = val(mins$): secs = val(secs$) totsecsrem = (mins*60)+secs 'total secs for countdown pin(led) = 1 'turn ON lamp LED & relay settick 1000,countdown 'interrupt each second for countdown get_keycode 'check for lamps-OFF request if keycode$ = "22" then lamps_OFF if keycode$ = "23" then lamps_OFF endif '-------end of lamps_ON:------------- get_keycode if keycode$ = "23" then goto display_menu countdown: totsecsrem = totsecsrem - 1 'decrement 1 sec each interrupt remmins = totsecsrem/60 'convert to mins & mins fraction dispmins = fix(remmins) 'extract the mins dispsecs = cint((remmins-dispmins)*60) 'convert fraction to secs lcd 2,13, str$(dispmins,2,0,"0") +":"+ str$(dispsecs,2,0,"0") if totsecsrem = 0 then lamps_OFF ireturn Key_Int: 'key press detected keycode$ = str$(keycode) ireturn sub get_keycode keycode$ = "99" do 'wait for keypress loop until keycode$ <> "99" end sub sub check_key (code,cnt,insecs) if code = 23 then goto display_menu if code >9 then goto set_time if code >5 and cnt =1 and insecs =1 goto set_time 'bad entry if code >9 and cnt =2 and insecs =1 goto set_time 'bad entry end sub sub lamps_OFF settick 0,0 'stop countdown interrupt pin(14) = 0 'turn OFF lamp LED & relay pin(21) = 1: Pause 1000 '1 long beep = "lamps OFF" pin(21) = 0 setpin 14,0 setpin 21,0 lcd 3,1, " - LAMPS OFF - " lcd 4,1, " MENU - Press D " dispmins = 0: dispsecs = 0 end sub |
||||
bigmik Guru Joined: 20/06/2011 Location: AustraliaPosts: 2914 |
Gday Lads, Just noticed that Rockby Electronics have those keypads on special this week for a pack of 10 for $6.50.. See their newsletter Newsletter Regards, Mick Mick's uMite Stuff can be found >>> HERE (Kindly hosted by Dontronics) <<< |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
That's pretty good Mick - only 4x3's though, pity they don't have 4x4's for a similar price - can't win them all. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I printed off your timer code and have been trying to work through it. (Is it a PCB exposure timer?) It looks to me like too much is being done in interrupt routines. I had my knuckles wrapped by Geoff (and rightly so) earlier wrt keypad interrupts. I wonder if there are time constraints on uM interrupts. Geoff did say not to hang around too long in an interrupt which is why I wrote the keypad interrupt routine as simply Kp_Int: IReturn and use the variable KeyCode in the main (or sub) routine. You shouldn't have to press the Keypad keys more than once to get a response. It sounds like a timer interrupt or similar is blocking the keypad interrupt. Just wondering. I need to examine your code in more depth. Unfortuantely, the wind is blowing quite hard directly from the wind turbines, and thinking is not easy at the moment. David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
Yes it's for a collimated UV lamp box to expose resist coated PCB's - I'm hoping to get good enough resolution to do the 40 pin 0.4mm pitch pads for the flex connector socket for the 5" TFT Maximite screens - time will tell! It could be the length of the SETTICK interrupt routine but that's only called once a second. The problem is it's also looping waiting for any STOP keypad presses in the meantime while it's counting the seconds down. I'll keep chasing it but I want to get onto doing the box - I've got all the bits here now. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
You should be able to get good resolution for your etching. I guess you are using the Kinsten photo resist boards. Just using mono laser print and lightly oiled post printing, I got good fine tracks for the PIC32 100 pin TQFP. I used UV LEDS for the light but I believe ordinary fluoros work just as well. I'll rehash my bread board and replace the 12 keys with a hex pad and 20x4 LCD instead of the 16X2. I can easily dump your programme in so you can use me as a sounding board. It makes following someone else's programme easier if you have the same hardware set up. David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
Yes I'm using the Kinsten coated boards. Whether I'll be able to get good enough resolution to do a decent job of the 0.4mm pitch of the 40 pin flex connector, I'm not sure. The 100 pin TQFP chip of the Colour Maximite has 0.5mm pitch so it's not quite as tight but certainly getting down there. Thanks for the offer to duplicate things, we should be able to sort it out properly. The pin numbers I'm using are on the previous listing - you could add an LED onto pins 14 & 21 to see the other outputs (again, on the listing). I'd think a timer keypad/LCD combination would be a common requirement for a lot of control projects so it should be useful for others too. Geoff's direct Basic commands to control them have certainly made things easier. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Yes, I agree, however unless you are using the 44 pin PIC32, the I/O pins are a bit short on, but as I2C is already provided for the RTC, it doesn't take much to add other I/O to the I2C bus. I'm about half way through populating the bread board - lots of jumper wires. That's why I like I2C, all on a common bus and only one plug instead of lots of individual jumpers. I reckon you will get good enough resolution with the 0.4mm spacing but I don't know about the hand soldering bit, the 0.5 was bad enough. What are you using for your exposure artwork? Paper? Graphic paper, Transparency? David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
Well unless you need to use the 28 pin DIP chip, the 44 pin chip is an easy alternative, pretty much the same price and easier to source. It's lead spacing isn't too bad either at 0.8mm, assuming you're happy to use SMD's - but these days you need to be able to use SMD's and in some ways they're easier - no drilling. There are still four pins available on the 28 pin DIP anyway so you could still add I2C peripherals with them. To keep the keypad connections to the breadboard a bit neater, I peeled two sets of four leads off one of those 40pin terminated ribbon cables (male/female terminations). You can plug four at a time too - if you keep the pins consecutive If you use a single eight it's not flexible enough. On the keypad end I soldered an eight pin, right-angle header - pins underneath and facing back in. The female lead-ends connect there and it makes it easy to connect/disconnect to change projects. There are four standoffs holding it above the desk. The soldering is going to be interesting. It'll certainly be a flood-and-then-wick job I'd say, and if I get any bridges persisting - well I'll face that when it happens we're in this for fun anyway aren't we! For the artwork I'll start with transparencies and see how it goes - I've got some of that green Pulsar TRF foil that I might have a go at densifying the toner with too. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
@ Greg, As you can see, I got the jungle running - not pretty but it works. I got your programme in and yes, it does do a few quirky things and hangs up/ bombs out etc. I had never heard of the TRF foil. It look like the cat's whisker for fine PCB traces. Pity my laser mono is a Brother and the toner will not iron onto blank PCB no how. Never mind, Kinsten, NaOH developer, and HCl H2O2 etchant works for me - no "big bangs" here so far. Now, on to the programme... David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
|
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Sorry, It does sound a bit harsh. Actually, I think your programme is "nearly there" and I do like the neat way you enter the minutes and seconds. The HCl is 30%(same as builders use for cleaning concrete) and the H2O2 is 3% (off the shelf from the supermarket). I think Downwind did an article on TBS on making PCBs and may have included the concentration and mixing ratio. If I can't find it on TBS, I have it in an obscure folder on the PC somewhere. ============= I checked my archives and the ratio is two parts H2O2 to one part HCl. (add the HCl to the H2O2) David M. |
||||
Page 1 of 2 |
Print this page |