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 : PIO for quadrature encoders
Page 3 of 4 | |||||
Author | Message | ||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6783 |
The PIO devices are effectively processors in their own right. They have nothing to do with the CPU cores unless you are transferring data to or from them. They can even handle their own GPIO pins. On top of that, each of the four state machines in each PIO can also runs relatively independently, although the program space is a bit limited. You can still have, say, 3 state machines running one program and the fourth running a different program. I don't know who thought these PIOs up, but it's a brilliant idea. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
@Mick No kidding @Volhout Not an issue but just curious as to how/why 32 hex values are printed when starting the PIO code? Not being printed by MMBasic. |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Phenix, See here for an explanation: Bug in assembler It seems like the assembler only writes the PIO code into memory when you use the option "list". And option list shows a list of the PIO program in hexadecimal form. Without list...no program. I am sure Peter will fix this soon, but he is at the moment not able to fix bugs. Patience... Volhout PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Mick, It is not only the PIO's that are brilliant. Actually this piece of PIO code, with the JMP table, is also a brilliant idea. Volhout PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Phenix, This is the code for up to 4 decoders. The MMBasic PIO assembler is not used in this code, since the PIO code is mature. I hope the code is self-explanatory '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 PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Oh fantastic..THANK YOU Tomorrow, I'll hook-up a slave encoder and test the electronic gearing |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Hey Harm, This is working beautifully Spend as much as you want on a Siemens S7-1500 but it still won't do this |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Phenix, That is a firm statement. But remember the S7 is a system, that may have an inferior motor controller, for much money, but it is more than just that. So now you have the building blocks to make an even greater system. I am very curious to see your system growing, so keep us informed. Always willing to help, Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
@Volhout I have been severely punishing this system to verify the integrity of the encoder count...absolutely solid There is a 3rd encoder channel which is the index pulse, used for precise "homing". The pulse only occurs one time/revolution. I have it tied to an input-interrupt which captures the count. Naturally, this is only useable at very low speeds but it's perfect for checking for lost encoder counts. A future enhancement might be for the PIO to latch a pre-loaded register to set the counter to a predetermined value when the index signal happens? Pre_load_value = [32bit INT] Arm_the_PIO_index_latch Move_the_motor_until_index_pulse_occurs Transfer_Pre_load_value_to_PIO_count_register I am accustomed to 1KHz/2KHz/4KHz PID sample rates but I notice that many machine controllers use 250Hz or lower. I have been experimenting with 250Hz and it's perfectly smooth and very responsive. Once I eliminate the slow PWM and switch to an external DAC, a single Pico should be able to handle 4 high-performance axes with ease. You made this a wonderful week for me, Harm |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Phenix, Setting X to a pre-defined value does not require any changes to the PIO program. You have to perform 3 actions: 1/ write the desired count to the TX FIFO 2/ force the PIO to read the TX FIFO into the Output Shift Register (OSR) with a direct command 3/ force the PIO to copy the OSR value into the X register with a direct command. This direct command does the actual update. 1/ and 2/ are not time critical. But it is best to execute 3/ when the decoder is not actively counting (motor halted). Example code (tested in the single decoder program). 'set defined position in register X under control of the keyboard if a$="s" then input "desired count ";cnt% pio write 1,0,1,cnt% 'write the count cnt% in the fifo pio execute 1,0,&h8080 '= assemble "pull" (moves FIFO to OSR register) PIO execute 1,0,&hA027 '= assemble "mov X, OSR" moves the OSR value to X a$="" end if Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Hey Harm, The above has been working beautifully, until...I just tried a cnt% < 0 and with it being a 64bit integer, the system doesn't like it. If I force-feed it &hFFFFFC18, I get the expected -1000D but the 64bit version, I get a crash & burn. |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6783 |
As a RAF doctor once told my dad, "If it hurts that much then don't do it". :) (It may be only a story!) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
The fifo is 32 bit.so you would need a 32 bit value. But unless you write float to the fifo, that would not matter I guess. It would just mask off the 32 most significant bits. I guess… Volhout Edited 2024-05-16 03:03 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
@Volhout Yeah I thought that this should work: axval="-500" tststr=bin2str$(int32,val(axval),big) pio write 1,0,1,str2bin(int32,tststr,BIG) But this is what I get: Any value => 0 works fine |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Forgot to mention that this works fine: pio write 1,0,1,&hFFFFFDDA I get -550 |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Phenix, This works for me 'set defined position in register X under control of the keyboard if a$="s" then input "desired count ";cnt% cnt%=cnt% and &hffffffff 'concatenate to 32 bits pio write 1,0,1,cnt% 'write the count cnt% in the fifo pio execute 1,0,&h8080 '= assemble "pull" (moves FIFO to OSR register) PIO execute 1,0,&hA027 '= assemble "mov X, OSR" moves the OSR value to X a$="" end if Volhout Edited 2024-05-16 04:46 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
@Volhout Man, I must totally suck I mask all the time and was absolutely sure I tried this Works perfectly. Many, many thanks again. Now, where did I put that job-application for McDonalds |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Hey Harm Just an FYI; there appears to be some kind of pipeline thing happening. This is new territory, for me, in that; I'm experimenting with a low-ish sample-rate of 250Hz. Drove me crazy for awhile because I was observing motor overshoot (albeit very small) at the end of deceleration. No amount of PID tuning would eliminate it but then I discovered that my position reading was one-sample behind. I went from a single read To a double read Beautiful...no more overshoot |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4225 |
Hi Phenix, Yes, I have seen this before, in my SSTV decoder, and there it was sufficient to read only 1 sample extra. So the 4 in the FIFO, and the 5'th being on it's ways from X to ISR to FIFO. So if you make the data array 1 larger. DIM dat%(4) Then read 5 (not 4) from the FIFO, and use the 5'th value in the array. PIO READ 1,0,5,dat%() posi=dat%(4) You should be fine too... Volhout Edited 2024-05-24 19:27 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Hi Harm, Works great, thanks again I have a machine on the way, it's gonna be the first all-PicoMite controlled. Yaskawa motors feature 17bit Encoders A good test for the PIO PicoMites to replace obsolete OMRON and Rexroth motion controllers plus the PLC Profibus is also history. Loaded-up in Ireland, yesterday. No summer for me |
||||
Page 3 of 4 |
Print this page |