Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 03:37 24 May 2025 Privacy Policy
Jump to

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 : Quadrature multichannel decoder for PicoMite using PIO

     Page 1 of 2    
Author Message
allie
Regular Member

Joined: 06/10/2018
Location: Canada
Posts: 43
Posted: 10:16pm 21 May 2025
Copy link to clipboard 
Print this post

 
allie
Regular Member

Joined: 06/10/2018
Location: Canada
Posts: 43
Posted: 10:27pm 21 May 2025
Copy link to clipboard 
Print this post

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: Canada
Posts: 43
Posted: 10:38pm 21 May 2025
Copy link to clipboard 
Print this post

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: Germany
Posts: 380
Posted: 10:56pm 21 May 2025
Copy link to clipboard 
Print this post

You could try this
Edited 2025-05-22 08:56 by dddns
 
allie
Regular Member

Joined: 06/10/2018
Location: Canada
Posts: 43
Posted: 10:57pm 21 May 2025
Copy link to clipboard 
Print this post

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
 print

 '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: Canada
Posts: 43
Posted: 11:39pm 21 May 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 6230
Posted: 11:49pm 21 May 2025
Copy link to clipboard 
Print this post

  Quote  dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015,
&h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0)

The line suffered from wordwrap.
You need to put it back into one line.
VK7JH
MMedit
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2458
Posted: 01:07am 22 May 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1193
Posted: 05:26am 22 May 2025
Copy link to clipboard 
Print this post

Great to see that someone else is using quad-decode  
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1193
Posted: 05:32am 22 May 2025
Copy link to clipboard 
Print this post

  allie said  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


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: Germany
Posts: 380
Posted: 07:15am 22 May 2025
Copy link to clipboard 
Print this post

Can this be used for the cheap 1€ decoders as well?
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1193
Posted: 07:46am 22 May 2025
Copy link to clipboard 
Print this post

  dddns said  Can this be used for the cheap 1€ decoders as well?


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: Germany
Posts: 380
Posted: 07:51am 22 May 2025
Copy link to clipboard 
Print this post

The (china) ones that are soldered on a PCB, typically have some sort of hardware denouncing already
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2458
Posted: 08:10am 22 May 2025
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4919
Posted: 08:27am 22 May 2025
Copy link to clipboard 
Print this post

@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 Kingdom
Posts: 1193
Posted: 08:33am 22 May 2025
Copy link to clipboard 
Print this post

  Volhout said  @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


Hi Harm,

Would be be able to read 12 encoders on the RP2350?  
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4919
Posted: 08:58am 22 May 2025
Copy link to clipboard 
Print this post

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: Canada
Posts: 43
Posted: 10:14am 22 May 2025
Copy link to clipboard 
Print this post

  TassyJim said  
  Quote  dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015,
&h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0)

The line suffered from wordwrap.
You need to put it back into one line.


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: Netherlands
Posts: 4919
Posted: 10:43am 22 May 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 1193
Posted: 02:09pm 22 May 2025
Copy link to clipboard 
Print this post

  Volhout said  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


Oh sure. I just wasn't sure if there was some other caveat  
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025