![]() |
Forum Index : Microcontroller and PC projects : Quadrature multichannel decoder for PicoMite using PIO
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
|
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
I did what Volhout said and it seems to work. I have to hook up my cnc x,y,z and rotary table axis encoders to try. May be also modify my MMBasic code to select one of the axis and wait for the input signal. I'm baby sitting my two great granddaughters twins now so I'll try it later. Regards Allie |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
I put in the input "Select sm0 to sm3";sm *** command in the main MMBasic code section in the main loop after do a$=inkey$ I not sure if it was before or after a$=inkey$ Now the program is stuck in a loop, asking for the input. I pressed Esc ** no affect. Then pressed Ctrl and Esc and the program stopped. The next time I ran the program with pressing F2 it went back to the input command asking to input "select sm0 to sm3 it is still in the loop. How do I reset the picomite with out losing the PIO program. I know you can use one of the pins on the 2040, but I want to make sure I don't lose the PIO program as I had to type all of the code in my self. I could not get the * copy to clipboard * to work right, the PIO program went into tera term terminal but not right. When I typed it in myself it was O.K. Regards Allie |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4943 |
Hi Allie, When the pico is stuck, <CTRL>-C will stop the program. Then type SAVE "Quadrature.bas", and the program will be saved on the A:/ drive. The A:/ drive is flash, so it will remain stored, also without power. You can disconnect the pico from power, reset it, whatever... If you need to run the program again: LOAD "Quadrature.bas" RUN Volhout P.S. I think the program allows you to select a number of quadrature decoders, but just at start. You can not dynamically resize them during run. You select that you need 3, and then that is it. When you stop and RUN again, then you can select 4 (or 2)... But not change while the program is running. . Edited 2025-05-23 19:27 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
I had the picomite disconnected from the laptop and it did end the loop. thank you for the info. I have to go to work now so I'll try to work at it when I come home. I want to use the RP2040 PicoMite to count the milling machine x,y,and z encoders then send the count to the color MaxiMite 2 gen 2 which will be the main controller for my milling machine and lath setup. I thought I could put the MMBasic code in the MMBasic section of the main loop to select which axis to count with an input statement. Any thoughts on this? Regards Allie |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4943 |
Hi Allie, The code you have from PhenixRising prints the counts to screen. If you open a serial port on the picomite, you can send the same data to the CMM2. This is the current main loop '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 That would convert to 'serial comms to CMM2 using GP20 and GP21 SETPIN GP21,GP20,COM2 OPEN "COM2:112500" AS #1 'main loop do a$=inkey$ 'just for control 'get the data from the fifo and print if sm0 then print #1,str$(read_fifo(0),12,0); 'get data from decoder if sm1 then print #1,str$(read_fifo(1),12,0); 'get data from decoder if sm2 then print #1,str$(read_fifo(2),12,0); 'get data from decoder if sm3 then print #1,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 In this code you would still use the keyboard of the picomite (or console) to reset the counters. For full automation using the CMM2 you would replace the a$=inkey$ with a$=INPUT(#1,1) or similar. And maybe you want to replace the loop while a$="" with loop To make sure the loop on the pico never stops. Volhout . Edited 2025-05-23 22:16 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1245 |
You really want to send the encoder counts fast enough for the CMM2 to close four MATH.PID loops @ 1ms. A 1KHz loop-rate is a kind of standard for CNC and it is based off of machine bandwidth (mechanical response time). This is also the fastest that we can get with MATH.PID. Edit: Or close all four MATH.PID loops on the PicoMite and have the CMM2 feed command positions to the PIDs. We have the power ![]() Edited 2025-05-24 00:52 by PhenixRising |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
Thanks for the input. I'll work at this on the weekend and then post the results. regards Allie |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
I don't know how to do PID. I would have to learn. I don't need speed for the PicoMite to send the count to CMM2 the way I'm doing it only the PicoMite to count the full count of one axis at a time and then send the total count at the end of the count cycle to the CMM2. Then do the next axis. I'm only doing this as a hobby CNC setup. I like to do it as simple as I can for now to get started and maybe later change things. Can I get your permission to change some of your PIO and MMBasic code to suit my needs. (ie change the n for the count variable to x for x axis and y for y axis and z for the z axis and r for the rotary table.) I'll wait for your reply. Regards Allie |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1245 |
What are you driving? CNC with servo motors cannot work without PID. This is a very simple concept but so few understand it. The PicoMite is capable of out performing many CNC controls on the market. 1000mm/sec with a resolution of one micron. No sweat. How can this be? We really have a serious controller here. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4943 |
Hi Allie, The way the PIO code works is that it counts (all active decoder inputs are active at the same time) everu encoder pulse of every encoder. All in parallel. In case you hold one axis (do not move it) the count will simply not increment or decrement. The count of all axis is send to the screen, -or in your case- send to CMM2 every 100ms. That time is determined by the "PAUSE 100" command in the MMBasic code part I shared above. If you change that to PAUSE 10 it will send the counts every 10 ms (100 per second). In case you want faster than 10ms, you will need to increase the serial port speed. 115200 may not be sufficient. The CMM2 gets the counts of all active axis (from it's serial port), and controls the motors that move. What motors move, is the decision of the CMM2 MMBasic program, which is you writing the program. Assume you want to adjust X. And X is currently at 1000 (just a figure) and needs to go to 2000. Then you power the X motor to move. The count increases to 1100, 1200, 1300.....1900.. but then you are almost there, and do not want to go to far. You slow down the motor 1950 .. 1960 .. 1970.. 1980 .. 1990 .. then you slow down the motor even more .. to a crawl 1995..1998 .. 2000 stop. The behaviour of slowing the motor down (and .. in fact also speeding it up in the beginning) is done with PID control. For the PIO code, and the Pico MMBasic code, you can rename variables, but that is not needed. The same data will arrive in the CMM2 serial port. It is the CMM2 code that must do this all. In the CMM2 code you can name the first count it receives X, the second count = Y, and the third count = Z (if that is how you wired the encoders.). For the pico it does not matter. Regards, Volhout P.S. it may be smart to add a unique character/word/phrase to the numerics, in case the CMM2 get's out of sync, it can re-sync. Otherwise it could confuse X,Y,Z. Every 100ms something like: "XYZ" count 1 count 2 count 3 Where the XYZ is the unique sync word, that also shows the function of the counts. When it comes to speed, this is preferable over long text fragments. Edited 2025-05-27 16:50 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
Thanks for the input. I'll use windows paint program and draw a picture of my design and post it so you can see what I'm trying to do. Regards Allie |
||||
allie Regular Member ![]() Joined: 06/10/2018 Location: CanadaPosts: 59 |
Hi all I just emailed SHERLINE PRODUCTS Customer Service in the USA to ask them if I could use some of their pictures of there Milling Machine and Linear CNC Controllers to post on The Back Shed. I bought a lot of their stuff including 3 CNC Linear Controllers and 8 direction Milling Machine which I'm hooking up to the CMM2 gen 2 and the PicoMite to count the encoders. The Mill uses stepper motors. The reason for the 3 Linear Controllers is they are stand alone programable for one AXIS. I have 3 *** one for X axis, one for y axis and one for the Z axis *** They are able to be interfaced together but only 2 is allowed. I need 3 to be interfaced together (3 axis), so this is where the CMM2 gen2 comes in to control all 3. They all have encoders and this is where the PicoMite comes in to count the 1 thousands of an inch and send the count results to the CMM2 gen2. The CMM2 will control the SHERLINE LINEAR CONTROLLERS to choose which axis to move. The CMM2 will store all the count movements for all axis to an SD card. If I make a chess piece, then CMM2 will have all the info it needs to control the stepper motors using the SHERLINE CONTROLLERS step and direction inputs. CMM2 will output the direction then the step count, to the SHERLINE CONTROLLER. If I get permission from SHERLINE PRODUCTS to use their pictures I'LL draw a diagram of this setup. Regards Allie |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1245 |
Oh, didn't realise that we were talking steppers. What would be the best MMBasic method of generating a given number of pulses at high speed? |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2482 |
BITSTREAM pinno, n_transitions, array%() First fill an array with the pulse widths (in µS) using MATH SET. As you are also sending the pauses between pulses the array size needs to be double the maximum number of pulses you will need at a time. If very long runs need an array bigger than available memory can do in one go, just repeat the BitStream command as many times as needed. n_transitions is the number of pulses and pauses to send from the array at that time. For different speeds prepare several arrays with different pulse widths. As the arrays will be very big you may run out of memory if there are too many. If the low speed arrays are only used briefly for acceleration / deceleration they can be shorter. This assumes you send a direction command to the driver hardware which generates the phases. PIO is another option. I guess then you could also generates the phases in the Pico. . Edited 2025-05-27 22:58 by phil99 |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1245 |
First fill an array with the pulse widths (in µS) using MATH SET. As you are also sending the pauses between pulses the array size needs to be double the maximum number of pulses you will need at a time. If very long runs need an array bigger than available memory can do in one go, just repeat the BitStream command as many times as needed. n_transitions is the number of pulses and pauses to send from the array at that time. For different speeds prepare several arrays with different pulse widths. As the arrays will be very big you may run out of memory if there are too many. If the low speed arrays are only used briefly for acceleration / deceleration they can be shorter. This assumes you send a direction command to the driver hardware which generates the phases. PIO is another option. I guess then you could also generates the phases in the Pico. . Thanks Phil ![]() I did look at BITSTREAM some time ago but I need to generate up to 500K pulses/sec indefinitely. I guess PIO could be made to work if it's possible to somehow give it a 64bit count. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4943 |
Hi Phill, Phenix, Allie, By reading the user manual of the SHERLINE controller, it appears to be a smart unit, where you just input your desired CNC destination on the keypad, and it makes sure you get there. The only way to connect it to a computer is when you put it in SLAVE mode, and control it with STEP and DIRECTION. Then it behaves more or less like a stepper H-bridge. The SHERLINE does not support an encoder (unless I am mistaken) but it can work with end-stops. BITSTREAM may be a way to generate STEP and DIRECTION signals. But understanding Allie's configuration, these should be generated from the CMM2. I am unsure at the moment if Quadrature encoders are usefull. The STEPPER motors that come with the SHERLINE do not support them. They rely on the (micro-) steps of the stepper motor. If that is also the target application the CMM2 can do it all by itself. Generate steps, detect end stops. And then using the SHERLINE controller as a power stage to drive the stepper motor. That is in CMM2 operating mode. Disconnect the cable, and you are in SHERLINE controller mode, and you can key in commands for each axis. Complication could (does not have to be, but could) be to share the end-stop switches (or optical detectors). I can imagine wiring to the SHERLINE to be per SHERLINE specification, and a parallel (opto coupler isolated) end stop signal to the CMM2. Those are my 5 ct... Volhout P.S. END STOPS are called LIMIT SWITCH in the SHERLINE documentation. Edited 2025-05-27 23:21 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2482 |
If very long runs need an array bigger than available memory can do in one go, just repeat the BitStream command as many times as needed. Though there will be brief gaps as you restart the BitStream does that matter? At 1000 steps/mm an array of 10000 will give 5mm at a time. The same array can be used over and over. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4943 |
Does CMM2 support BITSTREAM ? Volhout . PicomiteVGA PETSCII ROBOTS |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1245 |
At 1000 steps/mm an array of 10000 will give 5mm at a time. The same array can be used over and over. Actually, probably wouldn't matter, in my use-case. I am not wanting to drive stepper motors. Many modern servo drives (amplifiers) take step and direction signals to increment/decrement a command position. They then drive the servo-motor/encoder to that command position. We have inertia, friction, etc., which always creates some amount of phase-lag and so I highly doubt that we would see a glitch during motion. I would never use this type of drive because I prefer the direct analog (+10V to -10V) command but it would be nice to have the feature for those who use those drives. @Volhout I don't understand the need for the CMM2, I would read encoders and output step/dir on the PicoMite. I'm not great at interpreting what others are attempting to achieve but I get the impression that allie is wanting to drive the axes with the Sherline, digitize the motion path of each axis (encoders) and then play-back the motions simultaneously from MMBasic. But I'm probably way off the mark ![]() |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |