how to add snap interrupt at 1khz rate in tiny-g2 for accurate machine position capturing need urgent help

15 views
Skip to first unread message

shams iqbal

unread,
Jul 30, 2016, 5:36:40 PM7/30/16
to TinyG Development
i am working on tiny-g2 but its very difficult code to understand so i thought that its better to ask that how to add 1khz interrupt in tinyg-2 for accurate machine axis position capturing 
here my idea is very simple capture motor axis position generated by dda ( at 1 khz interrupt rate genrated by sys-tick-timer or timer/counter channel) and send these absolute machine coordinate to other mcu for servo motor control loop doing this way i can save alot off hardware/software resources of second mcu where that controller have digital commanded position instead of step pulses counting and will be able to perform pid control loop for position control of each axis same function i have implemented in grbl running on stm32f103 mcu but i am looking for multi-axis(4-6) control option i am hopeful that someone will help me 

Carl McGrath

unread,
Jul 31, 2016, 6:49:14 AM7/31/16
to TinyG Development
Have you tried changing the $si , status interval, to a value of 1ms?
That might generate too much load on tinyG2.

I assume you realize, from an accuracy perspective, that the position reported by tinyG2 is the result of tinyG2 doing step pulse counting, so any issues that might cause steps to not be fully executed by the steppers will not be reported.

Alden Hart

unread,
Jul 31, 2016, 7:43:31 AM7/31/16
to TinyG Development
Shams,

The code is organized using multiple interrupt levels and a main loop (no interrupt). The highest level interrupt is the step generation and step segment loader. The next lower is the acceleration computation to get ready for the next segment (prep). The main loop executes as a non-blocking run-to-completion cooperative multitasking kernel. USB and other IO are slotted into the other interrupt levels. I would suggest using the edge branch, and reading the header comments in stepper.h for more details. 

As to your question, depending on what you are trying to do there may be some options.

- If you just want position reporting the status reports support that. The minimum status interval is 100 ms, depending on your build. You could decrease the interval, but would probably flood the USB channel with data. This does not sound like what you are interested in, however.

- The systick timer does increment every MS. Typically this is used to set an event in the future and wait until the timer reached the appointed time (like motor timeouts, for example). Main loop functions read this value and execute when their time has arrived.

- The stepper segments (sequences of pulses) are queued to the stepper system roughly every 1 ms (1 Khz - actually a bit faster than that in most cases). This may be what you want. Check out the loader code in stepper.cpp. Be advised that the loader is time critical, and it should finish all its operations before the next step clock interrupt expires. This is not essential, but makes for smoother motion if that can be achieved.

- Part of the stepper system is a "feedback" counter that counts output pulses. See encoder.h/.cpp. This may be what you are looking for. The encoder feeds error terms back to the step generation routines in case there is an error between model space (work coordinate system) and the joint space (steps). If the math is working correctly (which it always does) the error term is less than 1 step. The system keeps track of these error terms and a bunch of other low-level data. These terms can be compiled in for reporting during development and debugging. See here  https://github.com/synthetos/g2/wiki/Diagnostics

The encoder module is designed to introduce position feedback into the system. In the Edge branch all it does is count the actual steps that are sent to the stepper drivers. Currently the correction mechanism is very slow. It "bleeds" corrections into the pulse stream slowly to maintain pulse coherence and thus surface finish. If you wanted to use the encoders for higher speed functions you may need to find a different way to do do the positional correction. Or maybe it will work with what's there. We have not tried this.

Alden



On Saturday, July 30, 2016 at 5:36:40 PM UTC-4, shams iqbal wrote:

shams iqbal

unread,
Jul 31, 2016, 3:27:32 PM7/31/16
to TinyG Development
hi
thank you for the help but you can read my question maybe i missed something in my question my question was how to generate interrupt @ 1000hz rate for capturing motor current position means it should be done in firmware not the gui side hope you got my question 
regards

Rob Giseburt

unread,
Jul 31, 2016, 4:07:44 PM7/31/16
to TinyG Development
Hi Shams,

Let me see if I understand the goals correctly. You would like to:

* Not use Step/Direction pins to communicate position to the drivers
* Use some communication channel (presumably I2C, SPI, etc) to tell another MCU (or one of many) what position it should have a motor at a given time.
* You feel that 1KHz is a reasonable relate at which to communicate this to the external MCUs.

Assuming all of that is true, then you don't need the DDA interrupt and timer to handle the step pins, only for timing of the loading.

Let me very briefly explain how our system works:
1) We ingest moves in the form of gcode, parse it, process it, and hand it to the Planner.
2) The Planner puts the move into the move queue, and then stitches the moves together so they will execute cleanly.

Separately, we have the interrupt/timer driven run loop which takes the moves off of the move queue and executes them.

We break the moves into up to three "sections": head (acceleration), body (cruise), and tail (deceleration). Not all moves will have all three sections.

Each section is broken into "segments" of time that are all the same velocity. Each segment is at minimum MIN_SEGMENT_MS milliseconds (currently 0.75) long.

The "exec" function generates the sections, which are then each prepped for the loader. The DDA/stepper timer interrupt then calls the loader when it's out of steps, and the loader prepares the structures for the DDA/stepper interrupt.

I believe what you describe would be either in the exec, sending whole segments (with a start velocity, end velocity, jerk value, and distance vector) to the external MCUs, or replacing the loader which would send constant-velocity segments with a distance vector at between 1-2KHz.

The difficulty will be ensuring coordinated motion. You will likely need some additional output pin that all the external drivers can sync the section/segment start/end times on.

-Rob
--
You received this message because you are subscribed to the Google Groups "TinyG Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to devTinyG+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

shams iqbal

unread,
Jul 31, 2016, 5:30:15 PM7/31/16
to TinyG Development
Hi Rob Giseburt, thanks for the valuable information 
  • yes you got my question i don't wanna use Step/Direction pins to communicate with drives 
  • yes i want to use SPI port (with dma ) for communication to drive for commanded position where each motor should be at that time 
  • well every closed loop position control servo motor runs typically at 1KHz rate very few professional system offers 2kHz position loop 
  • i do have  my own designed servo drives so i can add any communication interface with it for commanded position data
now as per these destination i need some more information 
"Each section is broken into "segments" of time that are all the same velocity. Each segment is at minimum MIN_SEGMENT_MS milliseconds (currently 0.75) long.

The "exec" function generates the sections, which are then each prepped for the loader. The DDA/stepper timer interrupt then calls the loader when it's out of steps, and the loader prepares the structures for the DDA/stepper interrupt.

I believe what you describe would be either in the exec, sending whole segments (with a start velocity, end velocity, jerk value, and distance vector) to the external MCUs, or replacing the loader which would send constant-velocity segments with a distance vector at between 1-2KHz."

                     here how each section is broken into "segment " ? if a section is 7.5 millisecond long then will it be broken  in to 10 segments (as segment is 0.75 millisecond long) or only three segments ? when DDA/stepper timer interrupt calls the loader little brief code wise /sequence wise ? how to read these segments and collect each axis commanded/target position as well velocity ? well i have first priority to eliminate DDA execution and reduce the cpu load the which is the most time consuming code in cpu if its not possible then i want to capture commanded position variables every 0.75/1 millisecond so where and which interpret i should do that 
thanks for helping me 

shams iqbal

unread,
Jul 31, 2016, 5:48:57 PM7/31/16
to TinyG Development

hi Alden ,
its been long time i am finding a way to talk with you and i am pleased to get interacted with you any how back to the topic regarding to my question 
i want to read encoder position but in timely fashion way here i am going to point out what are the intention to do so 
if i use tiny-g2 as it is basses then i have to count pulses/direction genrated by tiny-g2 to other mcu to recalculate target position of each axis (which is used for pid servo motor position controller ) and this needs hardware resources + huge software resources to get commanded position this is the exactly what have done in current setup to run my dc servo based cnc machine as many other peoples are doing i have done it and running my cnc machine without any problem if operated carefully 
                     now my current target is to run tiny-g2 which should support 10000mm/min max travel speed/axis so according to my calculation if minimum step size = 1u meter then 10000*1000 step=10000000 steps/minute and step frequency would be 10000000/60=166666 hz so i assume that 170khz step generation rate is good enough for most cnc machines and every professional cnc machine have 10000mm/min rapid feed rate to travel each axis thats way more most cnc machine mechanical support . at the moment if 2 step pulses are not captured/missed for each axis during encoder position loop calculation for 1000 hz rate(due system response delay) thats going to genrate 2um position error in each axis way in under tolerance of actual machined parts where mostaly tolerance are +-10um for precision machined parts i have pointed this thing to mention that when we increase step precision then three or 4 step pulses error is considered in required accuracy tolerance 
                     every professional cnc machine is operated 1000hz servo position control loop for each axis thats what i am trying to do in tiny-g2 i do have ardiuno due for testing now getting 32-bit integer position for each axis and sending that position via spi dma to other mcu will save other controller's hardware resources  where other controller will just capture encoder position and execute pid position control loop as per your point 
                                                                                                                         "Part of the stepper system is a "feedback" counter that counts output pulses. See encoder.h/.cpp. This may be what you are looking for. The encoder feeds error terms back to the step generation routines in case there is an error between model space (work coordinate system) and the joint space (steps). If the math is working correctly (which it always does) the error term is less than 1 step. The system keeps track of these error terms and a bunch of other low-level data. These terms can be compiled in for reporting during development and debugging. See here  https://github.com/synthetos/g2/wiki/Diagnostics " looks like this can be used but how often this is used in the current tiny-G2 system is there a defined interval rate for this function to be executed or this can be used by other hardware interrupt ?
note: i am going offload mcu by not to toggle  Step/Direction pins AND disabling step pulse reset interrupt 
                    you and your team have done a great job to building a nice six axis motion controller but i will say that the controller chip choice is very poor for this purpose look at the price of ardiuno due and stm32f4 discovery and fair comparison is 192kb sram vs 64kb ram , 84mhz vs 168mhz did you ever seen code execution delay running from on chip flash i don't think so number of timer counter available for motion control things here if i am forced to run tiny-g2 on ardiuno due i have no timer counter for quadrature encoder interface but on stm32f4 i have sufficient timers/counter to do so  i am working on avr chips since 2000 almost 16 years now and atmel products are the worst choice for this kind of application due to these are very sensitive to emi esd rfi noises and start behaving very ugly i think you may have not seen such problems but i do and i know that how to deal with these problem and many others don't know about these problems i am hopefull that you guys will workout to port tiny-g2 on stm32f4 family chips especially stm32f429 discovery boards where this beast have enough ram and horsepower to run tiny-g2 as standalone controller with nice huge graphics controller on chip which offloads the cpu  
here you guys have done another bad choice to not use kiel mdk and using open source things you guys have no idea that which code will took how much time to execute on chip i am eager to see a stm32f429 discovery port i tried to start work but tiny-g2 code is bit messy thing to learn it and to mess with it and port it on stm32f429 discovery 

shams iqbal

unread,
Jul 31, 2016, 6:00:06 PM7/31/16
to TinyG Development
Hi Alden,
              about diagnostic there is not detail that which function "https://github.com/synthetos/g2/wiki/Diagnostics" is used for what purpose can you plz define it i am not able to find any reference 
regards
Shams


On Sunday, July 31, 2016 at 4:43:31 PM UTC+5, Alden Hart wrote:

Rob Giseburt

unread,
Jul 31, 2016, 6:02:33 PM7/31/16
to devT...@googlegroups.com
The sections are broken into constant-velocity segments in the _exec_aline_{head,body,tail} functions. (https://github.com/synthetos/g2/blob/edge/TinyG2/plan_exec.cpp#L525-L641)

_exec_aline_segment() then prepares it for the loader (https://github.com/synthetos/g2/blob/edge/TinyG2/plan_exec.cpp#L663-L713) by calling st_prep_line (https://github.com/synthetos/g2/blob/edge/TinyG2/stepper.cpp#L1002-L1080) by filling out the st_pre structure. This has to complete before the currently running segment finishes.

_load_move (https://github.com/synthetos/g2/blob/edge/TinyG2/stepper.cpp#L796-L975) then takes the st_pre structure and fills out the st_run structure. This has to happen fast enough that it can happen in between steps without throwing the step timing off.

The the stepper DDA timer (https://github.com/synthetos/g2/blob/edge/TinyG2/stepper.cpp#L599-L652) repeatedly executes the contents of the st_run structure, and requests the next load when a segment is done.

Each section, which could be as short as 0.75ms but can be arbitrarily long (generally less than a minute), is broken into segments that are roughly 1ms long. The number of segments must be an integer number, and the distance traveled over all of them must be precise, so the length time of them is variable. All of the segment of a given section will take the same amount of time.

-Rob

Alden Hart

unread,
Jul 31, 2016, 6:18:02 PM7/31/16
to TinyG Development
The diagnostics report internal variable states related to the distance calculation and step calculations. They tell you how many steps are queued up for each segment (see Rob Giseburt's email for definition of segment). 

See config_app.cpp starting on line 704 - #ifdef __DIAGNOSTIC_PARAMETERS
The variables and structures referred to there are found in stepper.h

Most of the code that uses these values is in the following routines:
   Plan_exec.cpp function _exec_aline_segment()
   Stepper.cpp function st_prep_line()

See especially the  * NOTES ON STEP ERROR CORRECTION: in the comments in _exec_aline_segment(). This explains the use of these registers.

shams iqbal

unread,
Aug 1, 2016, 12:10:10 AM8/1/16
to TinyG Development
Hi Rob,
thanks for helping me out i have studied the code again but this time i have more clarification then the previous time i read the code here now i have few questions 
  • #define MIN_SEGMENT_USEC ((float)750) // minimum segment time (also minimum move time)
  • #define NOM_SEGMENT_USEC ((float)1500) // nominal segment time
  1. what is going to the impact of changing MIN_SEGMENT_USEC  ((float)750)  to MIN_SEGMENT_USEC  ((float)1000)
  2. what is going to the impact of changing NOM_SEGMENT_USEC  ((float)1500)  to NOM_SEGMENT_USEC  ((float)1000)
  3. does segment changing to 1000 will create any code execution conflict 
so this will generate segments needed to move a straight line e.g if a move is 2.8 sec long then it will generate 2800 segment if i am getting it right and further steps to be moved in segment are calculated for each motor in this section 

or (i=0; i<MOTORS; i++) {
mr.commanded_steps[i] = mr.position_steps[i]; // previous segment's position, delayed by 1 segment
mr.position_steps[i] = mr.target_steps[i]; // previous segment's target becomes position
mr.encoder_steps[i] = en_read_encoder(i); // get current encoder position (time aligns to commanded_steps)
mr.following_error[i] = mr.encoder_steps[i] - mr.commanded_steps[i];
}
 
here error are also calculated due to fractional steps between target position and commanded position if i am getting it right 
now after this step next phase it initialize dda step timer  here i don't need DDA function if i new that how many steps are to be generated for each segment for each motor at which velocity rate then how to disable DDA step pulse generation function while it does not impact other function like request to load next segment and add servo motor communication execution code instead of DDA step pulse generation 
 plz correct me if i am not able to understand correctly 
regards

joachi...@googlemail.com

unread,
Nov 17, 2016, 3:40:08 AM11/17/16
to TinyG Development
Hi Shams,

I justt read your post about your project of working with absolute machine axis positions within TiniG2. You mentioned, that you implemented this function in grbl.
I am trying to build a servo driven miniMill, playing with the fantastic work of Miguel Sanchez. (DC servo drive on Arduino https://github.com/misan/dcservo)
It is working quite well, but I am thinking about the problem, that I have a mcu working on step an direction, not knowing where the axis actually is located and how fast it is moving in which direktion. 
Your thought to send step and direction commands on the base of the actual axis-information is quite interesting to me - Would it be possible to have a look on your grbl - implementation?

At the same time it is of interest to me, which programm can work with this feedback - information?  

Thanks for some ideas

Greetings Joachim

joachi...@googlemail.com

unread,
Nov 19, 2016, 11:56:35 AM11/19/16
to TinyG Development
Hello Alden,

i am just thinking about building a milling machine using the cool dc servo solution of Miguel Sanchez (https://github.com/misan/dcservo)
I made some tests with encoders I got from an old inkprinter - it was working great. But thats only one axis ....

Now, I read your answer to Shams:

- Part of the stepper system is a "feedback" counter that counts output pulses. See encoder.h/.cpp. This may be what you are looking for. The encoder feeds error terms back to the step generation routines in case there is an error between model space (work coordinate system) and the joint space (steps). If the math is working correctly (which it always does) the error term is less than 1 step. The system keeps track of these error terms and a bunch of other low-level data. These terms can be compiled in for reporting during development and debugging. See here  https://github.com/synthetos/g2/wiki/Diagnostics

And i am curious, what would happen, if one would sent the actual step-counts from an encoder instead of counting output pulses?
could that be leading to a close loop stepper solution - or into a disaster?

Looking foreward hearing from you

sincerely 

joachim

shams iqbal

unread,
Nov 19, 2016, 4:45:05 PM11/19/16
to TinyG Development
Hello,
            well i have been doing this with arduino nano and atxmeg64 where arduino nano was doing as it should be and xmega was used to captured step/dir to run dc servo motors i have tested both grbl and tiny-g2 it works without any problem 
            further if you think that you will be able to run three servo motors in any mega series then just forget it ........  it will not give you performance needed to control servo motors and run a cnc mill i have used xmega and it uses hardware quadrature decoders while using event system and a timer/counter ........ here you will be trapped again that these timer/counters are 16-bit and it will give you 16-bit value as encoder position and for step/dir signal xmega up/down direction using event system wont works in real hardware its still wrong description in datasheet dont use and adc channel in xmega its way bad then mega series but there is a one good thing that xmega are less sensitive to ESD/EMI/RFI noise i dont know that do you either encountered with these noises 
            GRBL runing on arduino nano will consume almost +90% processing power while xmega give you double the processing power atmega328p i have not tested tingy/tiny-g2 processing power consumption so i have no idea how it works 
           
            well i have calculated all things and now it is possiable to run grbl on xmega while controlling three axis servo motors and one spindle control using pid @ 1Khz rate and soon i will be launching new controller with feedrate/rev Gcode setting options where it will be first to xmega series project which will support threading/tapping options  and almost a complete cnc controller sorry to say it will not be open source project but 
                           it will be a prove that in old days it was possiable to run cnc on 8-bit processors with almost all options like moderate cnc have where that had less than of 2 mips processing power and these days they are not able to run stepper motor control and all processing power is used even thats 16-mips grbl /32 mips tinyg /72 32-bit mips tinyg2 
                    
         reality is that no one wants to let you know that how to do it better way to control cnc machine i myself dont want to do so because it took me more than 16 years to reach at this point what i can do is to gave you clue which i have already given you 
         
         to see how it works 
         pid running at 1khz so minimum step which can be executed in one second is =1000
         in per/min steps will be =1000x60=60000
         now if one step =0.01 mm 
then 
         feed rate wold be =60000/100= 600mm/min
         and this is where most cnc works during finish cut i mean 600mm/min or even slower to get more surface finish 
         getting 10 micron accuracy is very difficult on diy cnc hardware we used cnc machine to build a cnc hardware and used linear rail baring slide with precision ball screws and then we will be able to see 5 micron accuracy 
            
        so at this speed you are one to one with stepper controller at lower speed you are also one to one its just like same as acting like stepper motor  .. at above speed you will get little bit degradation in machining and in most cases its like under 5% at most higher speed i did some test on higher speed for pcb milling with fine tracing of 8 mills width and did not noticed any visual defect 
               you can see that how these (tinyg/grbl) is running and you will find that they calculate 0.01mm cricle accuracy in general setting  thats the professional machine also does in real time and who needs more than this much .
               so i will say you its good approach to use servo motors instead of steppers motors where you will get good speed/load performance and wont fear to lose any step th
well about both control tinyg/grbl they are meant to control stepper motors you want to run servos then write your own motion planner thats what i ended up and going to do it in few days sad things the none of each party is interested to help me to modify there motion planner to make it compatible with cloosed loop servo motor control in that way it was possible to keep it open source 
          hope my info about servo performance will help you to go with more better way then using stepper motors 
regards
Shams 

joachi...@googlemail.com

unread,
Nov 20, 2016, 6:31:52 AM11/20/16
to TinyG Development
Hi Shams,

thanks for your answer, and your help. You encouraged me: 
because, you are right wehn you say: " who needs more than 0.01mm circle accuracy"

If that is possible - Great!

I don`t have your skills very likely not the talent and in any case no further 16 years to work on servocontroller....

Therefore, I am depending on such great work Migeual Sanchez, and the guys of TinyG,    Marlin, GRBL and Chillipeppr did. And advices like you just gave me one.

Thanks for the help, and a lot of success with your project

sincerely 

Joachim

           
Reply all
Reply to author
Forward
0 new messages