# Jitter in TTL generated by Aurdino UNO

**URL:** <https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828>\
**Category:** 3rd Party Boards\
**Created:** [February 2, 2015, 1:25pm UTC](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828 "2015-02-02T13:25:25Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![nickgammon](https://avatars.discourse-cdn.com/v4/letter/n/45deac/32.png) [@nickgammon](https://forum.arduino.cc/u/nickgammon)\
**Post date:** [October 7, 2015, 12:49am UTC](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828/21 "2015-10-07T00:49:08Z")

</div>

Any objection to using:

```cpp
noInterrupts ();

```

?

---

<div class="post-metadata">

**Author:** ![krupski](https://avatars.discourse-cdn.com/v4/letter/k/c4cdca/32.png) [@krupski](https://forum.arduino.cc/u/krupski)\
**Post date:** [October 7, 2015, 4:33am UTC](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828/22 "2015-10-07T04:33:55Z")

</div>

> ddemunshi:  
> Hi,
> 
> I am currently building a device which requires manipulating several TTL pulses, which in turn controls other devices.
> 
> I test the ideas, I initially tried to generate a TTL sequence with Aurdino Uno. I wrote a very simple code which I am copying below.
> 
> However, when I see the signal on an oscilloscope, I see that the TTL is jittering, which means the rising and/or falling edges of two respective TTL pulses are moving with respect to each other, by about,t 8 -10 microseconds. This will effect the response of my device.

You are seeing the results of interrupts running in the background. Try this:

```arduino
cli (); // disable interrupts
void loop (void)
{
      digitalWrite(ledPin, HIGH);
      delayMicroseconds(500);
      digitalWrite(ledPin, LOW);
      delayMicroseconds(500);
}

```

I know you are in an endless loop, but if you were not (say you were generating only 10 pulses, then doing something else, then do this:

```arduino
cli (); // turn off interrupts
// generate your pulses
// now we're done
sei (); // turn interrupts back on

```

Hope this helps.

---

<div class="post-metadata">

**Author:** ![krupski](https://avatars.discourse-cdn.com/v4/letter/k/c4cdca/32.png) [@krupski](https://forum.arduino.cc/u/krupski)\
**Post date:** [October 7, 2015, 4:46am UTC](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828/23 "2015-10-07T04:46:28Z")

</div>

> ddemunshi:  
> 2% is actually not very god enough for photonics research. Also the final goal is to move down to hundreds of KHz region of frequency and hence I am wondering if Uno is good enough for that.
> 
> CPU clock on Uno as far as I understand is 16 MHz so at 1KHz, I am quite far away from the CPU clock frequency. But I think the timer is required for stabilizing the waveform, atleast that is what has to be done on labview based systems.
> 
> I do not care about the value of software solution since this will be a driving part of a device. However, if you can provide some example of what you mean by "careful coding" it will be immensely helpful.
> 
> thanks

The code below is an IR remote control generator, but it uses techniques that you also need (if I understand you correctly).

One important part of the code is the timer driven interrupt which is used to make accurate pulses to turn the IR LED on and off at exactly the right rate, duty cycle and pulse width. You will see how the timer is setup to accomplish this.

The timer control registers will vary from part to part (for example, TIMSK vs TIMSK0 or TCCR0A vs TCCR1A), but the idea is the same.

And, despite the fact that this code uses "int main (void)" rather than "setup" and "loop" means nothing. It's still "Arduino" code.

Hope this helps...

```arduino
///////////////////////////////////////////////////////////////////////////////
//
//  Infrared Remote Control for SONY DSLR A-700 Digital Camera
//  Copyright (c) 2015 Roger A. Krupski <rakrupski@verizon.net>
//
//  Last update: 06 October 2015
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////

#define F_CPU 8000000UL // 8.00 mhz external crystal

#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/pgmspace.h>
#include <util/delay.h> // for _delay_xs

// ATtiny25/45 fuse settings (in Makefile):
// L-fuse: 0xFF (external crystal)
// H-fuse: 0xDF (SPI enabled, BOD disabled)
// E-fuse: 0xFF (self program enabled)

#define IO_PORT PORTB // (port write)
#define IO_PIN PINB  // (port read)
#define IO_DDR DDRB  // (port ddr)
#define IR_BIT PB0    // 2N4401 base drive for IR LED (thru 330 ohm resistor)
#define MODE PB1      // mode select: select shutter0 or shutter1 (has external 10K pullup)
#define BUTTON PB2    // send IR code (red button - active low - external 10K pullup)
#define KHZ 40        // IR carrier freq

volatile uint8_t state = 0; // led on/off state
volatile uint8_t onoff = 0; // bit polarity
volatile uint8_t count = 0; // led pulse counter

// Sony camera shutter release code 0x00B4B8F (focus and shoot)
// (header + 20 bits)
static const uint8_t shutter1[] PROGMEM = {
    // header
    0x60, 0x18,
    // command
    0x30, 0x18, 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, // B
    0x18, 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, // 4
    0x30, 0x18, 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, // B
    0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // 8
    0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, // F
    // end of command
    0x00,
};

// Sony camera shutter release code 0x00ECB8F (focus, wait 2 sec, then shoot)
// (header + 20 bits)
static const uint8_t shutter2[] PROGMEM = {
    // header
    0x60, 0x18,
    // command
    0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x18, 0x18, // E
    0x30, 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, // C
    0x30, 0x18, 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, // B
    0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // 8
    0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, // F
    // end of command
    0x00,
};

void send_cmd (const uint8_t *cmd, uint8_t rpt, uint8_t dly)
{
    uint8_t idx;

    IO_DDR |= _BV (IR_BIT); // set IR drive pin as an output

    while (rpt--) {
        idx = 0; // reset index
        state = 0; // insure state starts correctly

        do { // each one is a pulse count at carrier freq
            while (count); // wait until ISR is done sending pulses
            count = pgm_read_byte (cmd + idx++); // set next pulse count
            onoff = (idx % 2); // set which side is high
        } while (count); // until we hit 0 (end of command)

        _delay_ms (dly); // delay between commands
    }

    IO_DDR &= ~_BV (IR_BIT); // set IR drive pin back to an input
}

ISR (TIMER0_COMPA_vect)
{
    if (count) { // if a count was pushed in...
        state ? IO_PORT &= ~_BV (IR_BIT) : onoff ? IO_PORT |= _BV (IR_BIT) : IO_PORT &= ~_BV (IR_BIT);
        count -= state; // decrement count (on times only)
        state ? state = 0 : state = 1; // if led was on set it off, else set it on
    }
}

ISR (INT0_vect) // INT0 handler - we arrive here when the button is pressed
{
    GIMSK = (0x00 & ~_BV (INT0)); // disable hardware INT0
    cli ();  // disable any further interrupts
}

int main (void)
{
    uint8_t deb;

    cli ();  // disable interrupts while setting stuff

    IO_PORT = 0x00;
    IO_PORT |= _BV (BUTTON); // button pin high = pullup
    IO_DDR  = 0x00; // all pins inputs (for now)
    ADCSRA = 0x00; // turn off ADC

    // set timer 0 (8 bit) to CTC mode, carrier freq. this times the IR pulses.
    TCCR0A = (0x00 | _BV (WGM01)); // mode 2 (CTC) OCR0A = top
    TCCR0B = (0x00 | _BV (CS00)); // F_CPU/1 = 8000000
    OCR0A  = ((F_CPU / 2000 / KHZ) - 1); // divider for IR carrier freq
    TIMSK  = (0x00 | _BV (OCIE0A)); // enable interrupt on OCR0A match

    MCUCR  = (0x00 & ~(_BV (ISC01) | _BV (ISC00))); // set hardware INT0 active on low LEVEL

    sei ();  // setup done, enable interrupts

    while (1) {

        set_sleep_mode (SLEEP_MODE_PWR_DOWN); // set CPU to go into power down mode
        sleep_enable ();  // enable CPU to be powered down
        sleep_bod_disable ();  // turn off brown-out detector
        GIMSK = (0x00 | _BV (INT0)); // enable INT0 active low
        sei ();  // enable interrupts so cpu can recognize pushbutton INT0
        sleep_cpu ();  // power down cpu (all clocks stopped)

        /////////////// asleep - awaiting pushbutton INT0 ///////////////

        sleep_disable ();  // turn off sleep mode
        sei ();  // enable interrupts because they were disabled upon waking up

        // send "shutter1" or "shutter2" depending in the state of pin 6 (PB2)
        (IO_PIN & _BV (MODE)) ? send_cmd (shutter1, 3, 24) : send_cmd (shutter2, 3, 24);  // send code

        // wait for button to be released (prevent repeats if button held down).
        deb = 100; // init debounce
        while (deb--) {
            _delay_us (100); // tiny delay
            if (! (IO_PIN & _BV (BUTTON))) { // if button is pressed...
                deb = 100; // ...keep checking
            }
        } // now button confirmed released for 10000 usec (10 msec)
    }
}
// end of sony_ir.cpp

```

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 4:58pm UTC](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828/24 "2021-05-06T16:58:34Z")

</div>

Closed on May 6, 2021, 4:58pm UTC



[Previous page](https://forum.arduino.cc/t/jitter-in-ttl-generated-by-aurdino-uno/286828.md?page=1)
