Hi,
the CCD linear image sensor TCD1304 can be driven with a teensy 3.2.
There is a very detailed description on the TCD1304 at EsbenRossels page http://tcd1304.wordpress.com. His description is perfect, I have learned a lot there, thank you very much, Esben.
Here some remarks on creating teensy code driving the CCD.
1. Timing
The TCD1304 is driven by three pulses:
That’s hard, because buffer = analogRead(anlogPin); takes about 10 µs.
2. Speed up the ADC
In teensyduino there is ADC.h to be included. (https://github.com/pedvide/ADC).
Create an object with
and with the folllwing lines
the voltage can be read in half the time:
That's faster, but not fast enough. Fortunately the settings for the adc object in the 5 lines above have also an influence on the time for analogRead(), so with those settings it takes only 3,5 µs.
It is faster than buffer = adc->analogRead(analogPin, ADC_0); because here it is decided which ADC to take (ADC_0 or ADC_1) only within the function, every time it is called. It’s better to choose the ADC once and call then a function specialized for the desired ADC to read all pixels.
This can be made in setup() with
I have copied a function from ADC.cpp and ADC_Module.cpp and specialized it for ADC_0.
Now it is fast enough:
3. Timing pulses
At the beginning we need two pulses: fM and another one triggering the ADC.
The pulses for fM and ADCtrigger are made with PWM outputs.
On teensy 3.2 there are 3 timers for PWM:
It must be set the
frequency, the lower the resolution the higher the possible frequency.
e.g. 5 bits up to 1,5 MHz, 4 bits up to 3 MHz. (with f_CPU = 96 MHz)
To get a square wave the dutycycle must be half of 2^resolution (16 for 5 bits, 8 for 4 bits).
For details: https://www.pjrc.com/teensy/td_pulse.html
the CCD linear image sensor TCD1304 can be driven with a teensy 3.2.
There is a very detailed description on the TCD1304 at EsbenRossels page http://tcd1304.wordpress.com. His description is perfect, I have learned a lot there, thank you very much, Esben.
Here some remarks on creating teensy code driving the CCD.
1. Timing
The TCD1304 is driven by three pulses:
fM – the master clock, must run at 0.8-4 MHz
SH – the shift gate
ICG – the integration clear gate
The sensor has 3694 pixels, related to the light received by a pixel, it is charged up and the resulting voltage can be read at the output OS. It takes 4 fM cycles to readout that voltage of one pixel. So the readout frequency is 0.2 ... 1 MHz and the ADC must read the voltage in 1 ... 5 µs. SH – the shift gate
ICG – the integration clear gate
That’s hard, because buffer = analogRead(anlogPin); takes about 10 µs.
2. Speed up the ADC
In teensyduino there is ADC.h to be included. (https://github.com/pedvide/ADC).
Create an object with
Code:
ADC *adc = new ADC(); // adc object
Code:
adc->setReference(ADC_REFERENCE::REF_3V3, ADC_0);
adc->setAveraging(1); // set number of averages
adc->setResolution(12); // set bits of resolution
adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED);
Code:
buffer[i] = adc->adc0->analogRead(analogPin); // takes 5,4 µs
buffer[i] = adc->analogRead(analogPin, ADC_0); // takes 4,9 µs .
Code:
buffer[i] = analogRead(analogPin); // takes 3,5 µs
This can be made in setup() with
Code:
adc->adc0->singleMode();
Code:
uint16_t analogReadFastADC0(uint8_t pin){
uint16_t result;
adc->adc0->startReadFast(pin); // start single read (with adc->adc0->singleMode(); in setup() )
while(adc->adc0->isConverting()) {} // wait for the ADC to finish
// __disable_irq();
result = (uint16_t)ADC0_RA;
// __enable_irq();
return result;
}
Code:
buffer[i] = analogReadFastADC0(analogPin); // takes 2,2 us
3. Timing pulses
At the beginning we need two pulses: fM and another one triggering the ADC.
The pulses for fM and ADCtrigger are made with PWM outputs.
On teensy 3.2 there are 3 timers for PWM:
FTM0 can drive pins 5, 6, 9, 10, 20, 21, 22, 23
FTM1 can drive pins 3, 4
FTM2 can drive pins 25, 32
All pins of one timer have the same frequency, so three different frequencies are possible.FTM1 can drive pins 3, 4
FTM2 can drive pins 25, 32
It must be set the
resolution with analogWriteResolution(bits),
frequency with analogWriteFrequency(pin, frequency) and
dutycycle with analogWrite(pin, value).
Depending on the resolution we can choose different ranges of frequency with analogWriteFrequency(pin, frequency) and
dutycycle with analogWrite(pin, value).
frequency, the lower the resolution the higher the possible frequency.
e.g. 5 bits up to 1,5 MHz, 4 bits up to 3 MHz. (with f_CPU = 96 MHz)
To get a square wave the dutycycle must be half of 2^resolution (16 for 5 bits, 8 for 4 bits).
For details: https://www.pjrc.com/teensy/td_pulse.html