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

Thread: TCD1304 with teensy 3.2

  1. #1
    Junior Member
    Join Date
    Apr 2018
    Posts
    7

    TCD1304 with teensy 3.2

    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:
    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.
    Thats hard, because buffer[I] = 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
    and with the folllwing lines
    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);
    the voltage can be read in half the time:
    Code:
     
    buffer[i] = adc->adc0->analogRead(analogPin); // takes 5,4 s
    buffer[i] = adc->analogRead(analogPin, ADC_0); // takes 4,9 s .
    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.
    Code:
     
    buffer[i] = analogRead(analogPin); // takes 3,5 s
    It is faster than [I]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. Its 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
    Code:
    adc->adc0->singleMode();
    I have copied a function from ADC.cpp and ADC_Module.cpp and specialized it for ADC_0.
    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;
    }
    Now it is fast enough:
    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.
    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, 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
    Attached Files Attached Files

  2. #2
    Junior Member
    Join Date
    Aug 2018
    Posts
    3
    Hi,
    thanks for your guide. I am trying to replicate it, but I have issues at the moment: can you please help me a little bit?
    I have TCD1304DG, not AP. Is this critical?
    I have tested the TCD1304neg.ino on a Teensy 3.6 and a Teensy 3.2. With or without the suggested components (resistor 150ohm, 2200ohm, transistor).
    I get basically all the pixels value around 3600. If i cover a portion of the sensor, all the pixels still stay around 3600. If I cover the whole TCD1304, the pixels are all around 6-700, but this does not always happen.
    Any hints?
    Regards,
    Davide

  3. #3
    Junior Member
    Join Date
    Apr 2018
    Posts
    7
    Quote Originally Posted by madaeon View Post
    Hi,
    thanks for your guide. I am trying to replicate it, but I have issues at the moment: can you please help me a little bit?
    I have TCD1304DG, not AP. Is this critical?
    I have tested the TCD1304neg.ino on a Teensy 3.6 and a Teensy 3.2. With or without the suggested components (resistor 150ohm, 2200ohm, transistor).
    I get basically all the pixels value around 3600. If i cover a portion of the sensor, all the pixels still stay around 3600. If I cover the whole TCD1304, the pixels are all around 6-700, but this does not always happen.
    Any hints?
    Regards,
    Davide
    Hi Davide,
    thanks for your interest.
    I don't know if it is critical with DG or AP, and don't believe.
    The reaction of your TCD seems to be the wrong way. Have a look at https://tcd1304.wordpress.com/tcd1304-pcb/ .
    The three pulses controlling the CCD are negated on the pcb and my software is made that way. Did you build in a 7404?
    best regards
    Reiner

  4. #4
    Junior Member
    Join Date
    Aug 2018
    Posts
    3
    Hi,
    thanks for your reply. I used the "2nd SMD-version" of the PCB from https://hackaday.io/project/9829-linear-ccd-module, it has an HC04 as inverter; the only difference is that I used a 2N5401 as transistor.
    I wrote a small windows program that show a graph of the values printed on the serial.
    I tested both 3v and the usb 5v as +V on the circuit. No differences.
    For pin connections I used:
    int fMPin = 3; // Mclk out 3 FTM1
    int SHPin = 14; //
    int ADCtrc = 6; // ADCtriggerClock out 6 FTM0, only internal use
    int ICGPin = 15; //
    int analogPin = A3; // Pin 17
    Must I connect something to pin 6 ?
    Now I read more or less 1040 on all the pixels, no matter if there is light/dark/ a black strip in the middle. What am I missing?
    Thank you very much!!
    Click image for larger version. 

Name:	20180808_123733.jpg 
Views:	85 
Size:	73.1 KB 
ID:	14377Click image for larger version. 

Name:	20180808_123539.jpg 
Views:	166 
Size:	84.6 KB 
ID:	14378

  5. #5
    Junior Member
    Join Date
    Apr 2018
    Posts
    7
    Hi Davide,
    I don't rally know if the transistor fits but I think it's not critical.
    The transistors emitter should be connected to 3,3V (with 2,2k) not 5V, because the ADC can only work upto 3,3V.
    Your connections are correct. Pin 6 must not be connected.
    I've added to diagrams from an oscilloscope, the blue line is pin 17 the analog pin, red line ICG.
    1. with much light on all pixels:Click image for larger version. 

Name:	AnalogoutMuchlight.jpg 
Views:	68 
Size:	76.0 KB 
ID:	14379
    2. with low light:Click image for larger version. 

Name:	AnalogoutLowlight.jpg 
Views:	60 
Size:	75.5 KB 
ID:	14380
    As you can see in the second picture there are some pixels at the beginning and at theend of the ICG frame, which are at 3,3 V, that are the dummy pixels 0..31 and 32..45 at the end.
    In the first picture there is so much light on the CCD, that also those pixels are at the low voltage - too much light. All pixels read about 1400.
    I hope it can help, feel free to ask again, if not.

    Reiner

  6. #6
    Junior Member
    Join Date
    Aug 2018
    Posts
    3
    Click image for larger version. 

Name:	001.jpg 
Views:	87 
Size:	148.3 KB 
ID:	14387Click image for larger version. 

Name:	002.jpg 
Views:	75 
Size:	79.1 KB 
ID:	14388

    It now works! Even if some things make me think: The TCD is REALLY sensible to he ambient light. I wanted to check the precision of detection cut-out slits in black cardboard. But at int_t integration time of 20000 the sensor was probably saturated, all pixels around 1700. I put the cut-out slits over the TCD, put 2 couples of (polarizer film sheet + another polarizer film at 90 blocking all the light), and a white paper sheet to diffuse the ambient light, and it works (see pictures) if the room is quite dark. Instead of the slits, each cut-out is a "round" valley, if I increment int_t time to 50000 it is better, a little bit. Is this normal? My goal would be to detect the position of a red laser (about 3mw) pointed at the TCD. I was able to measure its position, but ambient light sensisitvity is scaring me a little, if the sensor will operate in a dark room ok, but what if there is some more light? or it is operated outdoor? Is up to some degree solvable via firmware or electronically?
    Thanks!

  7. #7
    Junior Member
    Join Date
    Apr 2018
    Posts
    7
    Hi Davide,
    fine it works.
    Yes, it's very sensible.
    I don't believe there is a lot to do by firmware or electronics, if there is too much light the CCD is saturated,
    then you can only shorten t_int, probably down to 10 microseconds ( by sending 't' to teensy)
    May be a filter can help?
    Reiner

  8. #8
    Junior Member
    Join Date
    Aug 2015
    Posts
    7
    Hi everyone,

    i'm also trying to replicate it on a breadboard but i cannot manage to get any signal on OS pin. I've checked the clock signals with a logic analyzer and all seem to be good. All values i'm reading are at 3600.
    Is it possible i got a faulty sensor?
    @Madaeon: what did you change to get it running?

    BRs,
    Sem

  9. #9
    Junior Member
    Join Date
    Aug 2015
    Posts
    7
    Clock Signals (fM,SH,ICG) Click image for larger version. 

Name:	Bildschirmfoto 2019-12-26 um 19.08.20.png 
Views:	7 
Size:	99.3 KB 
ID:	18547
    Output (SH,OS) Click image for larger version. 

Name:	Bildschirmfoto 2019-12-26 um 17.13.52.jpg 
Views:	13 
Size:	50.0 KB 
ID:	18546

    Any Idea why i cannot read any values?
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Bildschirmfoto 2019-12-26 um 17.05.08.png 
Views:	7 
Size:	53.4 KB 
ID:	18545  
    Last edited by SamMoo; 12-26-2019 at 05:09 PM.

  10. #10
    Junior Member
    Join Date
    Aug 2015
    Posts
    7
    Is anyone willing to help me here?

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,973
    Quote Originally Posted by SamMoo View Post
    Is anyone willing to help me here?
    Most assuredly @SamMoo … problem is it would have someone with the hardware at hand like the prior two posters on this year+ old thread.

    > Or enough details / context /specifics to inspire and entice someone to understand the problem enough to get toward a solution.

    Perhaps in reviewing the prior post details and presenting your own the missing piece will become apparent.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,973
    For instance - until I clicked link above I might have assumed not getting OS signal related to some 'Operation System' when it seems to be the Ouput Signal :: tcd1304.wordpress.com/tcd1304-specifications/

    First date I see on the BLOG is Jan then March 2017 with regard to a single resolved Bug :: tcd1304.wordpress.com/bugs/

  13. #13
    Junior Member
    Join Date
    Dec 2017
    Posts
    2
    You are showing four signals, but the CCD takes only three.

    I'm looking at the 3rd figure in your post, and assuming your four signals are (from the top)
    MCLK (looks ok, I can't read the frequency)
    SH (polarity is reversed and the delay from the falling edge of ICG is not long enough)
    ICG (looks ok)
    4th unknown, not sent to the CCD

    Also I cannot see the frequency (or period) of ICG vs SH. The periods must obey this relation ICGperiod = nSHperiod, and ICGperiod > 7,4 ms (assuming MCLK = 2,0 MHz) and SH > 10 s

    As reim suggest, try with very low values for the SHperiod. The chip is quite sensitive. In a normally lit room I see saturation with an SHperiod of app. 100-200 s

  14. #14
    Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    83
    Hi Reim

    Could you include a listing, or a diagram, to show how you connected the TCD1304 to the Teensy?

    Thank you
    M Nelson

  15. #15
    Junior Member
    Join Date
    Apr 2018
    Posts
    7
    Hi M Nelson
    there is a list of connections in the file TCD1304neg.ino.

    Reiner

  16. #16
    Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    83
    Thank you, I found that. Is there any reason you chose TX3, RX3 rather than, Tx2,RX2 or TX1,RX1?

    The pairs on the side of the Teensy are a little more convenient for routing a pcb.
    Last edited by DrM; 01-31-2020 at 03:16 PM.

  17. #17
    Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    83
    BTW, the bandwidth of the Teensy 3.2 ADC input, seems a bit tight for this. Do you see any issues with that? What do you think of doing it with the 4.0?

  18. #18
    Junior Member
    Join Date
    Apr 2018
    Posts
    7
    Quote Originally Posted by DrM View Post
    BTW, the bandwidth of the Teensy 3.2 ADC input, seems a bit tight for this. Do you see any issues with that? What do you think of doing it with the 4.0?
    I don't know 4.0 good enough. In my description above i told a lot an the speed of the ADC.

  19. #19
    Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    83
    One more question, I think. Are you using the logic inverter with your code? Would there be any issue in wiring the digital pins from the Teensy directly to the TCD 1304?

    Thank you

  20. #20
    Member
    Join Date
    Apr 2018
    Location
    Eastern Time, USA
    Posts
    83
    I saw a note above somewhere asking if the transistor is important. The answer is yes. Alternatively an opamp with a sufficient slew rate should be good. Given the sensor performance, it can be a simple non-inverting unit gain configuration.

Posting Permissions

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