Shop OBEX P1 Docs P2 Docs Learn Events
Implementing pulse setup/hold time monitoring device — Parallax Forums

Implementing pulse setup/hold time monitoring device

I need an instrument that can monitor two signals from a stepper motor controller.

Namely STEP and DIR.

For the STEP signal I want to monitor the step pulse length and time between pulses recording min and max.
For the DIR signal I want to record the minimum setup/hold time in relation to rising edge of the STEP pulse.

The STEP signal frequency is max 150 kHz and the minimum pulse length (both more or less
guaranteed by design because it is software generated) is 500 nsec.

Required accuracy is 2 usec.

I happen to have Parallax Propeller dev kit that I've never used so I figure out, maybe this is something that
could be relatively easily implemented on it.

Is this feasible?

Where should I start?

Pointers to 'closest similar' ready made project to get me started?

I've never programmed Propeller but have close to 40 years of experience in embedded stuff with
all the usual suspect CPUs working with assembler and C.

Any comments welcome.

cheers Kusti

Comments

  • iseriesiseries Posts: 1,492
    edited 2018-03-15 10:43
    While what you are asking for is simple enough, coding it is a different story.

    Here is some sample code that records how long a signal is high and low using some hardware counters.
    #include "simpletools.h"
    
    #define DIR 1
    #define STEP 2
    
    void doRecord(void *);
    
    long volatile Low;
    long volatile High;
    int *cog;
    
    
    int main()
    {
    
      cog = cog_run(&doRecord, 50);
      
     
      while(1)
      {
        print("Low: %d, High: %d", Low, High);
        pause(1000);    
      }  
    }
    
    void doRecord(void *par)
    {
      CTRA = 0x30000000 | STEP;  //Count when high
      CTRB = 0x20000000 | STEP;  //Count when low
      FRQA = 1;                  //Count by 1
      FRQB = 1;                  //Count by 1
      
      input(STEP);
      
      while (1)
      {
        while (get_state(STEP) == 0);  //Wait for pin to go low
        PHSA = 0;                      //Clear high counter
        while (PHSA == 0);             //Wait for counter to start
        PHSB = 0;                      //Clear low counter
        while (get_state(STEP) == 0);  //Wait for pin to go low
        Low = PHSA;                    //How many counts was that
        while (get_state(STEP) == 1);  //Wait for pin to go high
        High = PHSB;                   //How many counts was that
      }
    }
    

    To convert counter values to microseconds you need to divide by 80 as the processer is running at 80 Mhz.

    Here is a link to the hardware manual and also about counters.
    https://parallax.com/downloads/propeller-p8x32a-documentation

    Mike
  • Thanks!!

    Looks simple enough to get me started, I will dug out the dev kit tonight and see what happens ;)

    Funny, I was not expecting C, my mind set was spin and stuff though I had read about C on Propeller when bought the kit some years ago.


    cheers Kusti
  • Actually never picked up SPIN. Long time seasoned C coder.

    Love the propeller as it's straight forward and simple to program.

    STM on the other hand is a head banger.

    Mike
  • jmgjmg Posts: 15,173
    edited 2018-03-15 19:10
    nyholku wrote: »
    ..
    Namely STEP and DIR.

    For the STEP signal I want to monitor the step pulse length and time between pulses recording min and max.
    For the DIR signal I want to record the minimum setup/hold time in relation to rising edge of the STEP pulse.

    The STEP signal frequency is max 150 kHz and the minimum pulse length (both more or less
    guaranteed by design because it is software generated) is 500 nsec.

    Required accuracy is 2 usec.
    A 2us accuracy is going to give 0 on 500ns ?
    As above, gated counters can measure Hi or Lo times, to 12.5ns, but you may need care to capture a single pulse before the next one arrives.

    One easy sanity check there, would be to allocate one COG CTRA,CTRB pair, and have one Pulse-Width gated, and the other Edge counting.
    Reading both, without clearing either, will roughly indicate cases where multiple pulses were averaged.

    Roughly is because you cannot capture both values on the same sysclk, nearest possible capture is 50ns, so there can be small phase creep of the two.
    If you are ok with averages, you could measure many pulses in HLL.

    setup/hold time is not so simple... but timers can do LOGIC A & !B etc on two pins, so that can assist :
    STEP   ___/===\_______/===\_______/===\_______/===\_______/===\_______
    DIR   ________________________/======================\________________
              ^w          ^w          ^w
    DIR & !STEP   ________________/===\____/======\____/==\___________________
                          ^cT1        ^cT2 CTRA
    !DIR & !STEP _/======\____/==\___________________
                          ^cT3        ^cT4 CTRB
       
    

    Here you track STEP edge using wait and save gated timers (cT1,cT3 points), then when DIR has _/= since last save, wait for next STEP, and cT2-cT1 is th, and cT4-CT3 is tsu
  • Hi, thanks for input, I'm back on this project after a period of hiatus.

    I have some hurdles on the way but I will make a second thread on those.
  • Cluso99Cluso99 Posts: 18,069
    Some basics first.
    Most instructions (pasm) are 4 clocks so at 80MHz thats 50ns per instruction. However you can overclock the prop. Most of Parallax P1 boards have pluggable xtals and Parallax sell (currently?) 6.25MHz crystals. That would give you 100MHz or 40ns per instruction. The waitpxx instructions can get 1 clock resolution after setup.
    Then there are two counters that can be programmed in each cog.
    You biggest problem will be seeing the results on a monitor. Youll need to do some averaging.

    Start with something simple. Wait for the start of the step pulse, time the length, output it, wait a little for the output, and repeat.
  • ErNaErNa Posts: 1,752
    So, if I understand correctly, you want to determine the timing of an actual stepper controller with output signals "Step" and "Dir". There should be a reason to do this. Can you tell about that reason?
    Fakt is (not Fake), that for some reason step/direction signals exist, while it would be much better to only have quadrature signals to drive a stepper. But it is, as is is. The problem is: if there is a "dir" signal, it makes only sense to change dir of a stepper at low speed, that is, step pulses have low frequency. A good idea is the change direction in the middle of two step pulses. But in a control loop you might be forced to change direction very quickly (if for example the loop runs at 20kHz). So you create more decisions than you can execute. In this case: just do nothing, wait until you decision settles.

    So my advice: before you solve the problem to measure a problem, try to eliminate the underlying problem. You could e.g. easily take the output of the stepper controller, filter any glitch and create new step/dir signals to drive your motor driver.
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-10-06 22:01
    Most likely the DIR only has to be set prior to the STEP going active as it is probably latched on the rising edge of STEP (presuming active is high). So anything from >=0ns is probably fine. It may need to remain stable thru the STEP width although again its not likely. This does presume that the device has an electronic interface which is most likely these days.
    So for your testing, you could just use a simple program to wait for Step to go hi, read the time CNT, read the DIR pin, then wait for Step to go low, read CNT, sub the first CNT value from the new CNT value, and output the results to hub for another cog to process at its leisure, and go back to the start. You could add for the first wait to subtract its CNT from the previous CNT when STEP went low to give the time of the low part of Step. All this is easy in pasm.

    Here is a simple example (untested and not complete)
    con
      pinstep  = 3  ' the pin number for STEP
      pindir   = 4  ' the pin number for DIR
    
    pub start
    
    dat
                    org     0
    entry
    loop            waitpeq pinhi,stepmask                  ' wait for STEP to go hi
                    mov     timehi,cnt                      ' save the time
                    mov     direction,ina                   ' read all pins
                    and     direction,dirmask               ' extract DIR pin
                    wrlong  direction,ptrdir                ' save in hub
                    sub     timelo,timehi                   ' get the STEP low time (not valid first time)
                    wrlong  timelo,ptrsteplo                ' save in hub
    
                    waitpeq pinlo,stepmask                  ' wait for STEP to go lo
                    mov     timelo,cnt                      ' save the time
                    sub     timehi,timelo                   ' get the STEP high time
                    wrlong  timehi,ptrstephi                ' save in hub
                    jmp     #loop
    
    pinhi           long    1<<pinstep                      ' 
    pinlo           long    0<<pinstep                      ' will always be 0
    stepmask        long    1<<pinstep                      ' same as pinhi
    dirmask         long    1<<pindir
    direction       long    0
    timehi          long    0
    timelo          long    0
    
    ptrdir          long    @dirhub                         ' pointer to the location in hub for the DIR pin value
    ptrstephi       long    @stephi                         ' pointer to the location in hub for the STEP high time count (clocks)
    ptrsteplo       long    @steplo                         ' pointer to the location in hub for the STEP low time count (clocks)
    
    dat
                    org     0
    ' hub locations...
    dirhub          long    0
    stephi          long    0
    steplo          long    0
    
  • jmgjmg Posts: 15,173
    edited 2019-10-06 22:40
    Cluso99 wrote: »
    Most likely the DIR only has to be set prior to the STEP going active as it is probably latched on the rising edge of STEP (presuming active is high). So anything from >=0ns is probably fine. It may need to remain stable thru the STEP width although again its not likely...
    From the OP's initial wording, they needed DIR setup and hold (relative to Step _/=), so I think they suspect issues that may need trouble shooting.
    However, that is easy to add to your example loop, if they configure the CTRA, CTRB to be 2-pin gated from STEP, DIR, they can also be read and MIN values collected.
  • Surely what you are trying to do you would do with a scope or logic analyzer? The only reason you would do it with a Prop is because you want it to be a permanent instrument, a one-off or a production item itself. If you are lacking basic test equipment but you have a Prop then why not try SPLAT, it is a logic analyzer for the Prop that you can view on a serial terminal.

    Either way, Tachyon Forth itself can easily do what you want including the VGA display and even data-logging to an SD if there is some reason for that.
  • Hi, OP here ;) after some time getting back to this.

    My goal is a device that proves to me that the stepper motor controller firmware is functioning correctly.

    After each optimisation and release ;)

    So it needs to count the steps observing dir and output the motor position.

    It needs to monitor the STEP pulse length and time between pulses.

    It needs to monitor DIR signal in relation to the STEP signal.

    More specifically:

    STEP pulse needs to a have a minimum length and both the speed (inverse of
    time between pulses) and acceleration (inverse of change of time between pulses)
    have to be guarded agains some limit.

    The DIR signal must be guarded against being too close either after or before a step pulse.

    The DIR signal must be guarded against being too short.

    These are goals that are not easily accomplished with off the shelf measurement devices.

    I have not yet read through the responses for which I'm thankful.

    I just hurried to write this clarification and will now proceed to read your thought. Thanks!
  • jmgjmg Posts: 15,173
    nyholku wrote: »
    ....

    The STEP signal frequency is max 150 kHz and the minimum pulse length (both more or less guaranteed by design because it is software generated) is 500 nsec.
    Required accuracy is 2 usec.

    More specifically:

    STEP pulse needs to a have a minimum length and both the speed (inverse of
    time between pulses) and acceleration (inverse of change of time between pulses)
    have to be guarded agains some limit.

    The DIR signal must be guarded against being too close either after or before a step pulse.

    The DIR signal must be guarded against being too short.

    The simplest design is to sample and report each edge, but at 150kHz that gets to be a high reporting rate.
    Burst capture is possible, but the P1 has limited RAM.

    Since you know your targets, and are interested in limits, an alternative design would be to send Arm & Report signals, and have P1 collect the minimums.
    You then collect and report
    DIR_t1_min
    DIR_t0_min
    DIR_tsu_min
    DIR_th_min
    STEP_t1_min
    STEP_t0_min
    STEP_dt_max

    Even that will be tight, as you have only ~133 PASM opcodes time budget to capture and perform all those min/max tests.

    One COG could test STEP and another could test DIR & timer hardware can run gated to collect t1,t0.
    Possibly a 3rd cog can manage DIR_tsu_min, DIR_th_min, STEP_dt_max ?
    A 4th cog does the serial link arm/report.
  • @jmg Thanks, that is aligned with my thinking. I will muse some more.
Sign In or Register to comment.