One shot timer : Multiple pins with unique intervals

Status
Not open for further replies.
This is my first post, although I have been programming Arduino for 10 years. I ported all my circuit boards over to Teensy about 3 years ago. I'm pretty comfortable with Teensyduino programming, but implementing good timer code can be a challenge for me.

BACKGROUND:

I currently use Teensy 3.6 to control color-separated LED exposures for film scanning. My imaging system uses a matrix of red, green, and blue LED's to backlight the film for image capture. The Teensy receives a short LVTTL pulse and immediately starts exposure for a specified interval. This is repeated for each subsequent frame for the duration of the film footage.

Occasionally, I need to reduce the intensity of one or more color channels to re-balance the color temperature to the film. This is easily accomplished by setting PWM for each channel. However, I get inconsistent exposures from one frame to the next when intervals are very short (i.e. 100 us). This is true even when I configure Teensy for faster timer frequencies. I am also limited to about 20Khz frequencies, or my power mosfet transistors go on strike. So it appears I need an alternative to PWM to accomplish this. One of my colleagues suggested I dispense with PWM and use different exposure times for each color channel to affect color balance.

Important Considerations:

1. Exposure for each frame should begin with the same latency after the trigger input signal is received.

2. It would be nice to have the exposure times accurate to 1 us or better, but this is not so important. What is critical is the duration time of each color channel must be virtually identical for each successive exposure. This ensures the color balance and density of each consecutive image will be consistent to the human eye.

My existing pin assignments are based on Teensy 3.6, but I intend to port over to Teensy 4.x, which appears to have universal hardware interrupt capability on all pins, with no pin being more efficient than another in this respect.

This code is simplified and contains no real-world volatile variables. I'm just looking for a strategy. For triggering, I've been using AttachInterrupt() so far, as I started this project on Arduino 10 years ago. The TeensyTimerTool appears to be a superior alternative, so the sample code below is based on this library.

Code:
#define	PIN_EXPOSURE_INTERRUPT	3
#define PIN_EXPOSURE_ENABLE	24
#define	PIN_RED_ENABLE	        2
#define	PIN_GREEN_ENABLE	14
#define	PIN_BLUE_ENABLE	        7

#include "TeensyTimerTool.h"
using namespace TeensyTimerTool;

OneShotTimer	t1;
	

void setup()
{
	//Hardware Interrupt Pin
	pinMode(PIN_EXPOSURE_INTERRUPT,INPUT);

	//Exposure Enable Pin - must be TTL high to ignite LED's
	pinMode(PIN_EXPOSURE_ENABLE,OUTPUT);
        
        //Individual Color Channel Enable Pins
	pinMode(PIN_RED_ENABLE,OUTPUT);
	pinMode(PIN_GREEN_ENABLE,OUTPUT);
	pinMode(PIN_BLUE_ENABLE,OUTPUT);

	//Initialize with LED's disbled;
	digitalWrite(PIN_EXPOSURE_ENABLE, LOW);	
	//Enable all color channel so they are ready to expose
	digitalWrite(PIN_RED_ENABLE,HIGH);		
	digitalWrite(PIN_GREEN_ENABLE,HIGH);	
	digitalWrite(PIN_BLUE_ENABLE,HIGH);
	
	//Initiazlize OneShotTimer
	t1.begin(ExposeRGB);
}

void loop()
{
	t1.trigger(0);	//No Delay Desired To Start Function

	//Wait 500us and Trigger Again
	delayMicroseconds(500);
}

//The timer function imagines a total exposure time of 100us, with red = 90us, green = 95us, and blue = 100us.  All color channels ignite simultaneously.

void ExposeRGB()
{
	//All color channels Are already enabled, so start exposure
	digitalWriteFast(PIN_EXPOSURE_ENABLE,HIGH);

	//Wait 90us and disable RED, as it gets only 90us exposure
	delayMicroseconds(90);
	digitalWriteFast(PIN_RED_ENABLE,LOW);

	//Wait another 5us, and disable GREEN channel, so it gets 95us exposure time
	delayMicroseconds(5);
	digitalWriteFast(PIN_GREEN_ENABLE,LOW);

	//Finally, wait 10us and then disable exposure, so blue will have received 100us of exposure time.
	digitalWriteFast(PIN_EXPOSURE_ENABLE,LOW);

	//Now re-enable all color channels for the next exposure.
	digitalWriteFast(PIN_RED_ENABLE,HIGH);		
	digitalWriteFast(PIN_GREEN_ENABLE,HIGH);	
	digitalWriteFast(PIN_BLUE_ENABLE,HIGH);	


}

A few questions:

1. Is this a good code strategy to achieve my goals without writing directly to registers?

2. If I use Teensy 4.0, do you recommend any specific pins for the INTERRUPT pin, or the four output pins?

3. Should I disable interrupts at the beginning of my timer function for improved delay function, and re-enable them at the end, or is this done automatically?

4. Should I specify any specific timer available in Teensy 4.0 when setting up the OneShotTimer object that is best for my application?

5. How might I modify my code to get the most consistent sequential exposure times, possibly to less than 1us?

Thanks, and I appreciate some guru advice.
 
Status
Not open for further replies.
Back
Top