![]() |
Forum Index : Microcontroller and PC projects : Quadrature multichannel decoder for PicoMite using PIO
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
|
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
HI I've been away for long while on this topic of trying to use the RP2040 PicoMite for Quadrature multichannel decoding using PIO. I'll try to upload a post from this BackShed Forum I got last year to try to get started. Regards Allie |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
https://www.thebackshed.com/forum/ViewTopic.php?PID=225098#225098#225063 I don't think this worked the way I expected. I assumed you could click on it and it would open. I'll try something else. I'll go back to the other post from last year and Hi lite and try to save it. regards allie |
||||
dddns Guru ![]() Joined: 20/09/2024 Location: GermanyPosts: 379 |
You could try this Edited 2025-05-22 08:56 by dddns |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
PhenixRising Guru Joined: 07/11/2023 Location: United Kingdom Posts: 1183 Posted: 04:13am 19 Aug 2024 Copy link to clipboard Print this post Quote This code will handle 4 encoders on the RP2040 Picomite Quote 'Quadrature multichannel decoder for PicoMite using PIO 'this is a 4 channel quadrature decoder for MMBasic V5.08.00 or newer 'running on a PicoMite or PicoMiteVGA usinf PIO 1 'Original PIO source: https://github.com/p-o-l-e/quadrature-decoder '30-4-2024 Volhout 'system initialisation --------------------------------------------------------- 'program PIO 1 program_PIO 'program the code in PIO 1 'quadrature decoders generic settings PIO_f%=63e6 'frequency = 63MHz PIO_s%=0 'shift register (shift in left) PIO_e%=PIO(execctrl gp0,wrp_tgt,wrap) 'start and stop of the loop 'start quadrature decoders (uncomment the needed decoders) start_sm0 : sm0=1 'start decoder on GP0 and GP1 'start_sm1 : sm1=1 'start decoder on GP2 and GP3 'start_sm2 : sm2=1 'start decoder on GP4 and GP5 'start_sm3 : sm3=1 'start decoder on GP26 and GP27 'main MMBasic code ------------------------------------------------------------- 'this code is just a demo that shows the position of the quadrature decoders 'the selected decoder positions are printed on the console 'type "r" to reset the decoders to 0 'main loop do a$=inkey$ 'just for control 'get the data from the fifo and print if sm0 then print str$(read_fifo(0),12,0); 'get data from decoder if sm1 then print str$(read_fifo(1),12,0); 'get data from decoder if sm2 then print str$(read_fifo(2),12,0); 'get data from decoder if sm3 then print str$(read_fifo(3),12,0); 'get data from decoder 'just some pause pause 100 'any delay needed 'reset position (PIO X register) under control of keyboard if a$="r" then 'press r to zero position if sm0 then pio execute 1,0,&hA023 '= assembly "mov X, null" (zero X reg) if sm1 then pio execute 1,1,&hA023 '= assembly "mov X, null" (zero X reg) if sm2 then pio execute 1,2,&hA023 '= assembly "mov X, null" (zero X reg) if sm3 then pio execute 1,3,&hA023 '= assembly "mov X, null" (zero X reg) a$="" end if loop while a$="" 'exit when any key not r end ' subroutines ------------------------------------------------------------------- 'this function returns the actual count of decoder n function read_fifo(n) as integer local dat%(3) pio read 1,n,4,dat%() 'read whole fifo read_fifo = dat%(3) 'last data in fifo if read_fifo>2147483647 then inc read_fifo,-4294967296 '2'th complement end function 'this subroutine programs the quadrature decoder program for PIO1 into 'PIO program memory sub program_PIO 'this is the PIO program in machine code dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, &h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0) 'here the program is programmed in memory pio program 1,p%() wrap=27 'end of the program wrp_tgt=16 'start of the program loop end sub 'this subroutine starts state machine 0 quadrature decoder on gp0 and gp1 sub start_sm0 'uses GP0,GP1, assign pins in MMBasic setpin gp0,pio1 setpin gp1,pio1 'assign pins in PIO pin_sm0%=PIO(pinctrl 0,0,0,gp0) 'configure and start PIO pio init machine 1,0,PIO_f%,pin_sm0%,PIO_e%,PIO_s%,wrp_tgt pio start 1,0 end sub 'this subroutine starts state machine 1 quadrature decoder on gp2 and gp3 sub start_sm1 'uses GP2,GP3, assign pins in MMBasic setpin gp2,pio1 setpin gp3,pio1 'assign pins in PIO pin_sm1%=PIO(pinctrl 0,0,0,gp2) 'configure and start PIO pio init machine 1,1,PIO_f%,pin_sm1%,PIO_e%,PIO_s%,wrp_tgt pio start 1,1 end sub 'this subroutine starts state machine 2 quadrature decoder on gp4 and gp5 sub start_sm2 'uses GP4,GP5, assign pins in MMBasic setpin gp4,pio1 setpin gp5,pio1 'assign pins in PIO pin_sm2%=PIO(pinctrl 0,0,0,gp4) 'configure and start PIO pio init machine 1,2,PIO_f%,pin_sm2%,PIO_e%,PIO_s%,wrp_tgt pio start 1,2 end sub 'this subroutine starts state machine 3 quadrature decoder on gp26 and gp27 sub start_sm3 'uses GP26,GP27, assign pins in MMBasic setpin gp26,pio1 setpin gp27,pio1 'assign pins in PIO pin_sm3%=PIO(pinctrl 0,0,0,gp26) 'configure and start PIO pio init machine 1,3,PIO_f%,pin_sm3%,PIO_e%,PIO_s%,wrp_tgt pio start 1,3 end sub When I tried to get this working I got Errors stopping it. I'll try it again to find the Errors Regards Allie |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
I found one Error that stops it now. It stopped on this line *** dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, &h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0) It stopped here*** dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, It stopped there with the *** Error : Expected closing bracket I tried for 3 days to find out why it stopped with this Error. I checked all the code with no luck of getting it to work. I checked mmbasic manual. Regards Allie |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
The line suffered from wordwrap. You need to put it back into one line. VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
The new Line Continuation feature in recent firmware is one way to put it back into one line. Add <space><underscore> at the break and the interpreter or editor will put it back together. dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, _ &h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0) Saved 1527 bytes > LIST '... other code Dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015,&h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0) > Edited 2025-05-22 11:20 by phil99 |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1192 |
Great to see that someone else is using quad-decode ![]() |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1192 |
You need to use the link button for links to be clickable and you can apply your own description. ![]() |
||||
dddns Guru ![]() Joined: 20/09/2024 Location: GermanyPosts: 379 |
Can this be used for the cheap 1€ decoders as well? |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1192 |
Should work for any 2-channel encoder with a 90° phase offset. The problem with many of the panel-type encoders is the mechanical indenting which has a kind-of contact bounce effect. Not a problem here because it's not a hokey interrupt-driven solution. It's fast ![]() |
||||
dddns Guru ![]() Joined: 20/09/2024 Location: GermanyPosts: 379 |
The (china) ones that are soldered on a PCB, typically have some sort of hardware denouncing already |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
A couple of other encoder decoding options from Peter and TassyJim & Volhout. 'Here is MatherP's patented switch-bounce immune rotary encoder I/F code option default integer const false=0 const true=1 const in0=3 'encoder pins pulled high so should be reading high in detent positions, centre pin connected to ground const in1=2 'swap the pin definitions as required to get the correct sense of rotation ' init: setpin in0,intB,rint 'enable interrupts on both edges of both pins setpin in1,intB,rint rotatedright=false rotatedleft=false resetenc=true value=0 lastvalue=0 print value ' MAIN: Do if value <> lastvalue then print value lastvalue=value endif Loop end ' sub rint: pin0=NOT pin(in0) 'reverse sense to get positive logic pin1=NOT pin(in1) if pin0 then if pin1 and not resetenc then 'in0 and in1 both active if rotatedleft and not rotatedright then value=value-1 rotatedleft=false endif if rotatedright and not rotatedleft then value=value+1 rotatedright=false endif else 'only in0 active if resetenc and not rotatedleft then rotatedright=true resetenc=false endif endif else if pin1 then 'only in1 active if resetenc and not rotatedright then rotatedleft=true resetenc=false endif else 'both off so reset rotatedleft=false rotatedright=false resetenc=true endif endif if pin(in0)=pin0 or pin(in1)=pin1 then goto rint 're-enter if another change has happened almost immediately ireturn ' simple encoder reading TassyJim Nov 2022, updated Volhout SetPin 2, DIN, PULLUP' setup RB as an input SetPin 1, INTB, RInt, PULLUP' setup an interrupt when RA goes high Do ' < main body of the program > Loop Sub RInt ' Interrupt to decode the encoder output ' If Pin(2) = 1 Then If Pin(2) = Pin(1) Then Value = Value + 1 ' clockwise rotation Else Value = Value - 1 ' anti clockwise rotation EndIf Print Value End Sub |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4918 |
@phill, The Quadrature decoder code you posted only decodes a single encoder, and is suitable for up to 1000 counts per second on a pico. These code snippets are very nice for a rotary encoder knob on a apparatus. Simple, and MMBasic. For decoding multiple encoders, like in a CNC machine (where counting could be faster), the PIO version is preferable, since it works independent of the ARM (and is 1000x faster). Volhout Edited 2025-05-22 18:29 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1192 |
Hi Harm, Would be be able to read 12 encoders on the RP2350? ![]() |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4918 |
Hi Phenix, I see no reason why it could not. For 12 encoders you need 24 GPIO pins. To do anything useful with the pico besides decoding you would definitely need a RP2350B. Volhout PicomiteVGA PETSCII ROBOTS |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 43 |
Thanks for the reply I tried with no luck on MMBasic V5.08.00 but I didn't use the <space><underscore> at the break as phil99 posted on his next post. I'll try it when I come home from work today. I tried to open the UF2 file on the new Version of MMBasic V6.00.xx. I can't find a program to open it. I downloaded a few programs with no luck. Regards Allie |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4918 |
Hi Allie, You may have been confused with the different versions. The " _ " underscore to make the lines longer only works in 6.00.02rc24 (the latest rc). If you are using 5.08.00 then do following: Run the program You will get an error Press F4 (that will open the editor) Move the cursor to the first character on the "&h001A0015....." line Press <backspace> on the keyboard The editor will glue the 2 lines together, but the end of the line is invisible. You will have a working program now. You can run it (F2). I would suggest you save the program Press F1 Save "quadrature.bas" You will have saved the program with the glued line, and next time you load it, the problem will not occur. Volhout . PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1192 |
I see no reason why it could not. For 12 encoders you need 24 GPIO pins. To do anything useful with the pico besides decoding you would definitely need a RP2350B. Volhout Oh sure. I just wasn't sure if there was some other caveat ![]() |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |