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 : Enter short text
Page 1 of 2 | |||||
Author | Message | ||||
rea23 Newbie Joined: 16/09/2022 Location: SwitzerlandPosts: 26 |
Hi A short text, e.g. a name, is to be entered on a 2.4" display without touch screen. One possibility is shown in the listing. Maybe someone has a more elegant solution for this? '***************************************************** ' INPUT a short text e.g. a name w/o KBD or Touch ' Use of three buttons: Left, Right and Enter ' ---------------------------------------------------- ' Display 2.4", 320 x 240 ILI9341 (from MikroShop) ' works with ILI9488 driver only (Portrait mode)! ' Colors are inverted ! (255-RGB=iRGB) ?? cheap LCD ' MMBasic on Pi Pico with USB-C and on board RGB-LED! ' Test Buzzer: ok with SUB BUZZ ' 6.10.2022: Moving Cursor: two buttons < and > ' 09.11.2022: < / > button, 3rd button for Enter ' 10.11.2022: Display limit l/r ok ' Sometimes bouncing ===> 100 nF // to switches, ok ' New name: Move over margin </>, then Enter button '***************************************************** 'OPTIONS: 'OPTION SYSTEM SPI GP18,GP19,GP16 'OPTION LCDPANEL ILI9488, P, GP15, GP14, GP13 !! false driver, but works ' setpin GP23, dout 'RGB-LED, on board SETPIN GP3, dout 'Buzzer setpin GP4, intl, move_r, pullup 'Button > setpin GP1, intl, move_l, pullup 'Button < setpin GP2, intl, take, pullup 'Button Enter, pin4, GND: pin3 ' !! inverted colors because of "false" driver for LCD!! Take RGB values CONST black_= RGB(255,255,255) 'black inv. CONST green_= RGB(255,127,255) 'green inv. CONST yellow_= RGB(0,0,255) 'yellow inv. dim letter as string length 1 'letter for name dim newname as string Dim z, no, fini, t as Integer 'counter, number, flag, toggle print mm.ver, " RC9" print mm.info$(lcdpanel), " should be ILI9341, but then 240x240 only!?" print mm.info$(flash), " SD does not work" print mm.info$(touch), "Touch does not work" abc$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 'choice of letters x = 148 'cursor position at begin dx = 12 'spacing ytxt = 60 'y-position of text dy = 20 'distance cursor to text no = 13 'number of letter/cursor position t = 0 'toggle cls black_ 'display black, iRGB of (0,0,0) box 0,0,320,240,1, yellow_ 'FILL not possible on this display! FONT 2, 1 text 4, ytxt, abc$,,,, green_, black_ 'ABCDE...Z text x, ytxt+dy, "^",,2,, yellow_, black_ do do while t = 0 'wait on toggle/button pause 10 loop text x, ytxt+dy, "^",,2,, yellow_, black_ letter = mid$(abc$,no,1) if t = 1 then t=0 newname = newname + letter setpin GP2, off end if text 4, 110, newname,,2,, yellow_, black_ pause 10 setpin GP2, intl, take, pullup if fini = 1 then exit do loop text 4, 16, "New name is: "+newname,,2,, yellow_, black_ print "New name:", newname end '>>>>>>>>>>>>>>>>>>>>>>>>> FINITO >>>>>>>>>>>>>>>>>>>>>>> sub move_r 'interrupt, move cursor t=0 no = no + 1 if x < (320-2*dx) then text x, ytxt+dy, " ",,2,, yellow_, black_ text x+dx, ytxt+dy, "^",,2,, yellow_, black_ x=x+dx else text x, ytxt+dy, " ",,2,, yellow_, black_ no = 33 letter = "" 'to the right, over Z fini = 1 'flag endif End sub sub move_l 'interrupt, move cursor t=0 no = no - 1 if x > 12 then text x, ytxt+dy, " ",,2,, yellow_, black_ text x-dx, ytxt+dy, "^",,2,, yellow_, black_ x=x-dx else text x, ytxt+dy, " ",,2,, yellow_, black_ no = 33 letter = "" 'to the right, over Z fini = 1 'flag endif End sub sub take 'interrupt to catch the letter t=1 'toggle z=z+1 'counter BUZZ(1, 100) 'buzzer 500Hz, 100 ms end sub SUB BUZZ(freq,length) 'produces 0.5ms pulses on GP3 local i for i = 1 to length 'freq falls with higher numbers pulse GP3, 1 'freq = 0.5 is 1kHz pause freq next End sub Edited 2022-11-27 21:32 by rea23 |
||||
TimD Newbie Joined: 23/02/2021 Location: United KingdomPosts: 27 |
Hi, I've always found it frustrating trying to enter text using left & right buttons - a much quicker and friendlier method is to use a rotary encoder. This will still need only 2 I/O pins, but it adds a little more complexity to your code. I haven't used one personally, but you should be able to find plenty of information on the web and in this forum - indeed, there was a thread about this recently. You could even use one that incorporates a momentary push switch as your 'enter' button - then you've got everything in one controller, and if you intend to house your circuit in a box then you'll only need to drill a single hole to mount it, rather than have to make 3 separate cut-outs for the push buttons. Kind regards, Tim. |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9063 |
TimD's idea is excellent, and that is how I would go about it for this kind of text entry, but separate buttons is very simple and easy to manage in code, so I can see why you went in that direction. Rotary-encoders need a bit more code to decipher what they are doing, but as TimD said, there are examples here on the forum if you do a search. With any luck, someone in the know with rotary-encoders, will link to one of those threads, or post example code here for you to experiment with. I too, have not really done anything with them, otherwise I would post some code. Smoke makes things work. When the smoke gets out, it stops! |
||||
panky Guru Joined: 02/10/2012 Location: AustraliaPosts: 1094 |
For absolute minimum pin count, you could use an IR receiver and a spare remote you may have floating around. You could use just left, right and enter or decode in software the number keys into letters (like the old early mobile phones). Doug. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1593 |
Geoff's Super Clock uses 'keyboard' touch buttons to enter text. It works quite well. Bill Keep safe. Live long and prosper. |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1783 |
Not elegant, just a bit shorter. Still needs work. 'Character Selector - brief press pin 4 button to save character, ' long press after last character to save name & exit CLS Font 2 '12x20 SetPin 4,din,pullup :SetPin 5,din,pullup :SetPin 6,din,pullup For n=1 To 52:carat$=carat$+" ":Next 'Make marker MID$(carat$,26)="^" x=14 : done=0 vpos = 100 For n=2 To 27 'make A - Z Text n*MM.Info(FONTWIDTH),vpos,Chr$(n+63) Next Text 1,vpos+MM.Info(FONTHEIGHT),Mid$(carat$,x) Do Do While Pin(4) And Pin(5) And Pin(6) : Loop ' wait for a button press If Pin(6)=0 Then Inc x,-1 If x<1 Then x=1 :Print x, Text 2*MM.Info(FONTWIDTH),vpos+MM.Info(FONTHEIGHT),Mid$(carat$,27-x) Do : Loop Until Pin(6) 'wait for button release EndIf If Pin(5)=0 Then Inc x, 1 If x>26 Then x=26 :Print x, Text 2*MM.Info(FONTWIDTH),vpos+MM.Info(FONTHEIGHT),Mid$(carat$,27-x) Do : Loop Until Pin(5) 'wait for button release EndIf If Pin(4)=0 Then Timer = 0 name$=name$+Chr$(x+64) Print x,Chr$(x+64),name$ Do : Loop Until Pin(4) Or (Timer > 1500) 'wait for button release or finished If Timer > 1500 Then done=1 EndIf Loop Until done Text 100, vpos+3*MM.Info(FONTHEIGHT),name$ Print name$ |
||||
Tinine Guru Joined: 30/03/2016 Location: United KingdomPosts: 1646 |
Bluetooth....Phone...job done |
||||
Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 813 |
Have any of you ever seen this concept here? This is a "Filewalker " PDA: https://linuxdevices.org/new-euro-pda-boasts-linux-gsm-gprs-gps/ It works with a rotary encoder AND three buttons for index, middle and ring fingers. I think this input is genius! Frank |
||||
rea23 Newbie Joined: 16/09/2022 Location: SwitzerlandPosts: 26 |
Thank you for the many good ideas and the shortening of the program. I have to think about what I want to use. But the idea to use a rotary encoder is really tempting. |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3527 |
For those who have no access to a rotary encoder: you can use a analog input and measure the voltage at a potmeter connected to 3.3V and 0. A potmeter (and knob) have enough resolution to select individual characters (1 of 26). PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 3527 |
For those who have no access to a rotary encoder: you can use a analog input and measure the voltage at a potmeter connected to 3.3V and 0. A potmeter (and knob) have enough resolution to select individual characters (1 of 26). Poor mans rotary.... PicomiteVGA PETSCII ROBOTS |
||||
TimD Newbie Joined: 23/02/2021 Location: United KingdomPosts: 27 |
A potentiometer is nice idea, especially since the cursor is travelling a line of letters with stops at each end - so turn it fully left and it's at 'A', turn it fully right and it's at 'Z' - there's no wrap-around to contend with. You'd just have to ensure that it's linear rather than logarithmic, otherwise you'd need some extra maths in the code to keep the spread of the letters equally spaced around the travel of the potentiometer! Kind regards, Tim. |
||||
vegipete Guru Joined: 29/01/2013 Location: CanadaPosts: 1082 |
An extra choice for DELETE would be useful too, in case the user mis-enters a character. Visit Vegipete's *Mite Library for cool programs. |
||||
TimD Newbie Joined: 23/02/2021 Location: United KingdomPosts: 27 |
And wouldn't you need an 'End' option as well, to allow for variable length names? Unless the intention is just to let it time out and accept what's been entered after a certain period of inactivity. I think this would end up resembling a classic arcade game's 'name registration' screen for the high scores! Kind regards, Tim. |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1783 |
A button can be added to the pot. input without using an extra pin. Add resistors (about 1/10th of pot. value) between the top and bottom ends of the pot. to the rails and put the button from wiper to ground. The bottom resistor ensures voltage can only reach zero when the button is pressed. The top resistor prevents a short if the button is pressed while the wiper is at the top. A short press enters the letter and a long one enters the name, as in the above program. Edit Forget that. Two buttons can be added to the pot. input without using any extra pins. Use the second to delete the last letter. The top button inputs 3V3 and the lower 0V while the pot goes from 0.16V to 3.14V. Edited 2022-11-29 17:23 by phil99 |
||||
rea23 Newbie Joined: 16/09/2022 Location: SwitzerlandPosts: 26 |
Yes, TimD and phil99, it's a clever idea. And I like to turn instead of clicking. I will do it with a potentiometer and one switch. Many thanks |
||||
rea23 Newbie Joined: 16/09/2022 Location: SwitzerlandPosts: 26 |
I made the circuit with a 10k potentiometer and R1k to 3.3 V and R1k to AGND. A button from wiper to ground is inserted. The setting of the letters works fine. But the transfer in the name always results in "?". Something in the program is terribly wrong and my old brain can't find the error. ' *************************************** ' Text input with poti (TimD and phil99) ' ADC0, 1k-10k-1k gives (measured): ' 0.2790...3.0080 V over poti ' Switch down on lower R1k: 0.0130 V ' Poti works ok ==> shows A...Z ' Newname shows ??? instead '**************************************** SetPin GP26, AIN 'ADC0 at pin31 ' !! inverted colors because of "false" driver for LCD!! Take RGB values CONST black_= RGB(255,255,255) 'black inv. CONST green_= RGB(255,127,255) 'green inv. CONST yellow_= RGB(0,0,255) 'yellow inv. dim letter as string length 1 'letter for name dim newname as string newname = "" cls black_ 'display black, iRGB of (0,0,0) box 0,0,320,240,1, yellow_ FONT 2, 1 Again: do mvolt=int(1000*pin(31)) 'millivolt diff=3008-279 'measured min/max du=diff/25 '26-1 between u=int(mvolt/du)-1 'first # should be 1 letter=chr$(u+64) 'A is chr$(65) text 4, 100, "Letter is: " + letter,,2,, yellow_, black_ 'is ok, A...Z pause 100 loop until mvolt < 220 'leave the loop Take: newname = newname + letter '??? only, letter lost text 4, 16, "New name is: " + newname,,2,, yellow_, black_ goto Again 'How to save the name? ===> long press end |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8579 |
Hasn't the action of leaving the loop loop until mvolt < 220 'leave the loop changed the letter? |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 1783 |
Using Peter's insight and adding provision for a second button (top one in the above diagram) to delete the last letter. It should work as you intend with your current wiring. The extra lines should not matter. ' *************************************** ' Text input with poti (TimD and phil99) ' ADC0, 1k-10k-1k gives (measured): ' 0.2790...3.0080 V over poti ' Switch down on lower R1k: 0.0130 V ' Poti works ok ==> shows A...Z ' Newname shows ??? instead '**************************************** SetPin GP26, AIN 'ADC0 at pin31 ' !! inverted colors because of "false" driver for LCD!! Take RGB values Const black_= RGB(255,255,255) 'black inv. Const green_= RGB(255,127,255) 'green inv. Const yellow_= RGB(0,0,255) 'yellow inv. Dim letter As string length 1 'letter for name Dim newname As string newname = "" CLS black_ 'display black, iRGB of (0,0,0) Box 0,0,320,240,1, yellow_ Font 2, 1 Again: Do NewLetter = 0 : finished = 0 mvolt=Int(1000*Pin(31)) 'millivolt If (mvolt > 220) And (mvolt < 3100) Then 'Read letter if no buttons pressed diff=3008-279 'measured min/max du=diff/25 '26-1 between u=Int(mvolt/du)-1 'first # should be 1 letter=Chr$(u+64) 'A is chr$(65) Text 4, 100, "Letter is: " + letter,,2,, yellow_, black_ 'is ok, A...Z Pause 100 EndIf If mvolt < 220 Then 'If lower button pressed add current letter Timer = 0 Do mvolt=Int(1000*Pin(31)) 'millivolt If Timer > 1500 Then Finished = 1 Loop While (mvolt < 220) And (finished = 0) 'wait for button release NewLetter = 1 Print newname EndIf If mvolt > 3100 Then 'If upper button pressed remove last letter Timer = 0 Do mvolt=Int(1000*Pin(31)) 'millivolt If Timer > 1500 Then Finished = 1 Loop While (mvolt > 3100) And (finished = 0) 'wait for button release If Len(newname) > 0 Then newname = Left$(newname, Len(newname)-1) Text 4, 100, "Letter is: " + letter,,2,, yellow_, black_ 'is ok, A...Z Print newname NewLetter = 1 EndIf Loop Until (NewLetter =1) Or (Finished =1) 'leave the loop Take: newname = newname + letter '??? only, letter lost Text 4, 16, "New name is: " + " ",,2,, yellow_, black_ Text 4, 16, "New name is: " + newname,,2,, yellow_, black_ If Finished = 0 Then GoTo Again Print newname Text 4, 200, "Saved name is: " + newname,,2,, yellow_, black_ 'How to save the name? >=== long press End edit got something wrong in the delete letter loop but otherwise seems ok. Edited 2022-12-04 17:26 by phil99 |
||||
rea23 Newbie Joined: 16/09/2022 Location: SwitzerlandPosts: 26 |
@matherp: Yes, we have to define what happens if mvolt < 220 (switch down). But if I insert a line "IF mvolt < 220 THEN letter=letter" at the end inside the loop, the same behavior can be seen. @phil99: It's strange, but I get the error: [31] Print If(mvolt > 220) And (mvolt < 3100) Then 'Read letter if no buttons pressed Error : IF is not declared And indeed, MM Edit or the interpreter knows nothing about a command IF or ENDIF/END IF. I don't no what happens. Edit: False alarm: After a restart of MM Edit the program works as intended. Thank you very much. Edited 2022-12-04 20:47 by rea23 |
||||
Page 1 of 2 |
Print this page |