How to fire TTL sequences with Arduino (kHz range)?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to fire TTL sequences with Arduino (kHz range)?

Andreas Karampatzakis-2
Dear all,

I am trying to use my Arduino Uno to modulate a laser via TTL. I need to create on/off pulse trains of periods as fast as 1 microsecond (500 ns ON / 500 ns OFF). 

I have set up the Arduino as per the wiki (thanks for publishing this), however, I am not able to achieve accurate pulsing. 

My currect approach is this:

core.setProperty("Arduino-Switch", "State", "4"); //This sets output to pin = 10
int w = 1; //This should be the pulse width - in this case 1ms
for (i=0; i<3000; i++) { //fire a train of 3000 pulses
    core.setProperty("Arduino-Shutter", "OnOff", 0);
    Thread.sleep(w); // sleep
    core.setProperty("Arduino-Shutter", "OnOff", 1);
    Thread.sleep(w); // sleep
}

but when checking with an oscillope, the timing is totally off, probably due to the time it takes for the setProperty command and the loop to execute.

Is there a way to create the sequence of pulses with the desired timing and upload it to Arduino to be executed from there without using sleep command?

Thank you

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to fire TTL sequences with Arduino (kHz range)?

Austin
The timing is off because the windows OS + serial communication isn’t fast or reliable enough to achieve this speed.

I’d accomplish this by writing a subroutine into the arduino code where you

        - take the shutter “on” command that’s already in the code, and use that to turn on an autonomous loop in the arduino
        - inside the loop for the arduino (use a while) make sure NOT to use “digital write” sa this has too much state checking and isn’t reliably quick
        - do NOT use a wait or delay function in the arduino code, instead use a micros() call, and a while, so that any microcontroller delays will be fixed on the next pulse.

        so something like this (syntax is only an example here)


        unsigned long lastTime=0;
        while(shutter == 1)
                {
                while (micros() < lastTime) {}
                //put your state here as well as direct TTL calls
                lastTime = micros() +500;
                }

Austin

               

> On Feb 19, 2017, at 11:57 PM, Andreas Karampatzakis <[hidden email]> wrote:
>
> Dear all,
>
> I am trying to use my Arduino Uno to modulate a laser via TTL. I need to create on/off pulse trains of periods as fast as 1 microsecond (500 ns ON / 500 ns OFF).
>
> I have set up the Arduino as per the wiki (thanks for publishing this), however, I am not able to achieve accurate pulsing.
>
> My currect approach is this:
>
> core.setProperty("Arduino-Switch", "State", "4"); //This sets output to pin = 10
> int w = 1; //This should be the pulse width - in this case 1ms
> for (i=0; i<3000; i++) { //fire a train of 3000 pulses
>     core.setProperty("Arduino-Shutter", "OnOff", 0);
>     Thread.sleep(w); // sleep
>     core.setProperty("Arduino-Shutter", "OnOff", 1);
>     Thread.sleep(w); // sleep
> }
>
> but when checking with an oscillope, the timing is totally off, probably due to the time it takes for the setProperty command and the loop to execute.
>
> Is there a way to create the sequence of pulses with the desired timing and upload it to Arduino to be executed from there without using sleep command?
>
> Thank you
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot_______________________________________________
> micro-manager-general mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/micro-manager-general


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to fire TTL sequences with Arduino (kHz range)?

MarshallC
Austin wrote
The timing is off because the windows OS + serial communication isn’t fast or reliable enough to achieve this speed.

I’d accomplish this by writing a subroutine into the arduino code where you

        - take the shutter “on” command that’s already in the code, and use that to turn on an autonomous loop in the arduino
        - inside the loop for the arduino (use a while) make sure NOT to use “digital write” sa this has too much state checking and isn’t reliably quick
        - do NOT use a wait or delay function in the arduino code, instead use a micros() call, and a while, so that any microcontroller delays will be fixed on the next pulse.

        so something like this (syntax is only an example here)


        unsigned long lastTime=0;
        while(shutter == 1)
                {
                while (micros() < lastTime) {}
                //put your state here as well as direct TTL calls
                lastTime = micros() +500;
                }

Austin
Austin makes some really good points with the overhead of wait, digital write, and serial comms.  I would add that in any loop construct the timing will still not be totally accurate.  If your application critically relies on timing accuracy and you have to use an arduino you should write in a timer overflow interrupt, rather than a loop.  You can add this to the uManager arduino source, then enable/disable and set the timer reset with serial commands.  Here's a good link:
https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers
As far as determining the frequency that comes from the arduino clock and any dividers, which you'll have to look into.  Note that an interrupt vector (the block of code to be executed on each call) should be kept as short as possible because while it's going nothing else can happen (except a higher priority interrupt).

Marshall
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to fire TTL sequences with Arduino (kHz range)?

Nico Stuurman-2
In reply to this post by Andreas Karampatzakis-2
Hi Andreas


On 2/19/2017 11:57 PM, Andreas Karampatzakis wrote:
>
> I am trying to use my Arduino Uno to modulate a laser via TTL. I need
> to create on/off pulse trains of periods as fast as 1 microsecond (500
> ns ON / 500 ns OFF).

As you discovered, doing this using the computer interface to the
Arduino is way too slow.  Last time I checked, USB sends messages only
at a 4kHz rate, so the sending and receiving of a message will easily
take a few ms (plus, the controller needs to interpret the message and
respond to it using un-optimized code running on a 16MHz processor).

There is is some code hidden away in the Arduino Micro-Manager project
that may be useful.  It uses so called "Timed output mode". I forgot the
details (it was commented out since it was rarely used and not
documented), but you could uncomment the code in the Arduino-switch part
of the adaptor code and see what happens.

Alternatively, you could create your 1MZ digital signal using anything
else (signal generator or another Arduino), and combine them with the
Arduino output using a logical AND gate.

Best,

Nico




------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to fire TTL sequences with Arduino (kHz range)?

Philip Nicovich
To further Austin's point, don't use digitalWrite() on the Arduino if you need fast timing.  You should set the register directly if you can.  

There's more on port registers here:


In there you'll see that you need to configure the register for input or output using the DRDX then write directly to the register using PORTX (X = B, C, or D, depending on which set of pins you want).  You need to set the entire register at once with an 8-bit binary string.  This is simple for a set of pins changing at once and can get a little complex if you're trying to use multiple pins on a register for different things.  Better to move other functions to other registers if you can.

The benefit is quite large in speed.  You can get 1 MHz rep rates with such a setup.  The issue, though, is control over duty cycle at that speed.  It looks like it takes 2 clock cycles to flip a pin with PORTX, but it's going to take more than that to cycle through a loop.  Introducing a timer is going to make the max speed reduce quite a bit, but some clever work with interrupts may do the job (as suggested by Marshall). 

Looks like there's a faster digitalWrite() function that uses fewer clock cycles here:


Might be worth checking out!

Thanks,
Rusty

On Mon, Feb 20, 2017 at 12:31 PM, Nico Stuurman <[hidden email]> wrote:
Hi Andreas


On 2/19/2017 11:57 PM, Andreas Karampatzakis wrote:
>
> I am trying to use my Arduino Uno to modulate a laser via TTL. I need
> to create on/off pulse trains of periods as fast as 1 microsecond (500
> ns ON / 500 ns OFF).

As you discovered, doing this using the computer interface to the
Arduino is way too slow.  Last time I checked, USB sends messages only
at a 4kHz rate, so the sending and receiving of a message will easily
take a few ms (plus, the controller needs to interpret the message and
respond to it using un-optimized code running on a 16MHz processor).

There is is some code hidden away in the Arduino Micro-Manager project
that may be useful.  It uses so called "Timed output mode". I forgot the
details (it was commented out since it was rarely used and not
documented), but you could uncomment the code in the Arduino-switch part
of the adaptor code and see what happens.

Alternatively, you could create your 1MZ digital signal using anything
else (signal generator or another Arduino), and combine them with the
Arduino output using a logical AND gate.

Best,

Nico




------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general



--

Philip R Nicovich

Research Fellow,  ARC Centre of Excellence in Advanced Molecular Imaging

 

THE UNIVERSITY OF NEW SOUTH WALES

UNSW  SYDNEY  NSW  2052  AUSTRALIA

T: +61 (0)4 9909 2177

E: [hidden email]


CRICOS Provider No. 00098G


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
micro-manager-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/micro-manager-general
Loading...