Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Stability of microsecond pulses

  1. #1
    Junior Member
    Join Date
    Apr 2016
    Posts
    4

    Stability of microsecond pulses

    I'm trying to generate short single pulses using a Teensy 3.2 and I think I'm running into some limits on timing precision, or at least my (simplistic) knowledge level of same.

    The test code, which is adapted from the sample code for IntervalTimer and some posts to the forum here, generates a short pulse, waits a while, and then repeats. The ultimate application will generate half a dozen or so pulses of different widths in response to external input; here, I'm just testing the speed and stability limits.

    As you can see from the attached scope capture, there are two issues. First, the nominally 1 microsecond pulse is substantially longer, maybe 1.7 microseconds or so. That's not a big deal as long as the offset is consistent (i.e. if I request a 300 ns pulse to actually get 1 microsecond). Of greater concern is the occasional pulse which is nearly double in length. I haven't quantified this, but it happens roughly one pulse out of 20 or 30. It's a problem for the final application (which is controlling a capacitive-discharge spot welder for very fine wire); if I accidentally get a pulse that's twice as long as requested, there's a real risk of getting a spark discharge which would damage the device I'm trying to weld to.

    1 microsecond is the shortest pulse I'd need and I don't care about jitter (the pulses would be separated by several seconds); any thoughts or suggestions for improving the consistency would be greatly appreciated.

    Code:
    IntervalTimer myTimer;
    
    const int pulse_pin = 3;
    
    void setup() {
      pinMode(pulse_pin, OUTPUT);
      SCB_SHPR3 = 0x20200000;  // Systick = priority 32 (defaults to zero)
    }
    
    FASTRUN void pulse() {
      digitalWriteFast(pulse_pin, LOW);
      myTimer.end();
    }
    
    void loop() {
    
      myTimer.priority(0);
    
      digitalWriteFast(pulse_pin,HIGH);
      myTimer.begin(pulse, 1);  
      myTimer.priority(0);
    
      delay(10);
    }
    Click image for larger version. 

Name:	20180606-0003.png 
Views:	10 
Size:	52.0 KB 
ID:	13981
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20180606-0001.png 
Views:	5 
Size:	44.0 KB 
ID:	13980  

  2. #2
    Junior Member
    Join Date
    Apr 2016
    Posts
    4
    And, following up to myself, I found a solution. So, in case it's useful for someone else...

    Don't use IntervalTimer, use Timer1 (or Timer3) in PWM mode. Works very well with a jitter of maybe 10 ns (and my cheap little scope only has 50 MHz bandwidth, so some of that is probably instrument limits). By setting the Timer1 period to 2048, each "increment" of PWM corresponds to 1 microsecond of pulse width. By changing the period to 256, I got some reasonably clean 125 ns pulses (with visible rise & fall times, but again scope limits....).

    Code:
    #include <TimerOne.h>
    
    const int pulse_pin = 3;
    
    void setup() {
      pinMode(pulse_pin, OUTPUT);
      SCB_SHPR3 = 0x20200000;  // Systick = priority 32 (defaults to zero)
      Timer1.initialize(2048);
      noInterrupts();
    }
    
    void loop() {
    
      Timer1.pwm(pulse_pin, 1);
      Timer1.start();
      delayMicroseconds(10);
      Timer1.disablePwm(pulse_pin);
      digitalWriteFast(pulse_pin,LOW);
      Timer1.stop();
    
      delay(10);
    }
    Click image for larger version. 

Name:	20180606-0009.png 
Views:	10 
Size:	55.0 KB 
ID:	13983Click image for larger version. 

Name:	20180606-0010.png 
Views:	11 
Size:	54.5 KB 
ID:	13984

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •