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

Thread: Can I use Teensy 3.1 to interface / drive a linear CCD (TCD1304AP)

  1. #1
    Junior Member
    Join Date
    May 2015
    Posts
    1

    Can I use Teensy 3.1 to interface / drive a linear CCD (TCD1304AP)

    I heard the teensy 3.1 might be capable of driving the TCD1304AP (a linear CCD from Toshiba). I checked that it has a fast enough ADC. However, I still got to start 3 clock like signals at the same time to properly drive the camera.

    1st signal is 1MHz (up to 4MHz)
    2nd signal is 0.25MHz (1/4 of the main clock);
    - Data is coming out from the camera at this clock rate
    3rd signal has a maximum period of 20us.

    Do you think the teensy 3.1 can power up all these clock signals at the same time? Currently I have the stm32f401re. Though I can power up these clocks, but I can't get them to go at the same time. The stm doesn't have a fast enough ADC as well. Please advise.

    Attaching spec sheet of TCD1304AP:TCD1304DG.pdf

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,022
    Looking at the datasheet, I would say Teensy 3.1 might be able to do this. Maybe. But it'd require some pretty significant fiddling with the DMA controller to keep the ADC reading at that speed and generate the two clock waveforms. Or maybe you'd use the timers to generate the waveforms and trigger the DMA engine to read the ADC in sync? Or maybe create a 3rd waveform in sync, for the purpose of triggering the ADC at a different point in the middle of the SH clock cycle. Either way, it'll be tricky DMA-based design to sustain 250 ksamples/sec while generating those waveforms.

  3. #3
    Junior Member
    Join Date
    Jun 2015
    Posts
    2
    I was able to get the chip working with a Teensy 3.1. I didn't have much knowledge on the Arduino or Teensy chip so it's probably not an efficient method but it works. Let me know if you're still interested.

  4. #4
    Junior Member
    Join Date
    Apr 2013
    Posts
    4
    Quote Originally Posted by playsted View Post
    I was able to get the chip working with a Teensy 3.1. I didn't have much knowledge on the Arduino or Teensy chip so it's probably not an efficient method but it works. Let me know if you're still interested.
    Please share your code. I plan to build an spectrometer with this CCD.

  5. #5
    Junior Member
    Join Date
    Jun 2015
    Posts
    2
    Quote Originally Posted by frank View Post
    Please share your code. I plan to build an spectrometer with this CCD.
    Hi, this is only a semi functional version but is all I could find.

    I used to PWM at 1 MHZ for the main timing. I tried using multiple PWM but it never worked. Eventually I had to use empty loops and a oscilloscope to get timings better in some area. Realistically I think the Teensy may not be meant for this sort of thing but I'm sure someone more familiar with the chip could get it running well.

    Another issue is output of the data. I sent it over serial which is very slow and ended up interfering with the reading on the chip. I think the chip expects to be continuously read so stopping to send the data had some weird results.



    Code:
    #define MCpin 20
    #define ICGpin 10
    #define SHpin 12
    #include <ADC.h>
    
    volatile int runCode = 0;
    volatile bool inter = false;
    int aa;
    unsigned long t1;
    unsigned long t2;
    unsigned long dt;
    int bb;
    int loops = 0;
    #define BUFSIZE 3694
    uint8_t data_buffer[BUFSIZE];
    ADC *adc = new ADC(); // adc object
    volatile unsigned long ticks = 0;
    
    void setup()   {
      
      ARM_DEMCR |= ARM_DEMCR_TRCENA;
      ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
      memset(data_buffer,0,sizeof(data_buffer));
      pinMode(ICGpin, OUTPUT);
      digitalWriteFast(ICGpin, HIGH);
      pinMode(SHpin, OUTPUT);
      pinMode(MCpin, OUTPUT);
      pinMode(11, OUTPUT);
      digitalWriteFast(11, HIGH);
      pinMode(19, INPUT);
      attachInterrupt(19, isrService, RISING); // interrrupt 1 is data ready  
      Serial.begin(115200);
      //Serial.println("Starting");
      analogWriteResolution(5);
      analogWriteFrequency(MCpin, 1000000);
      analogWrite(MCpin, 16);
      adc->setAveraging(1);  
      adc->setResolution(8);
      adc->setConversionSpeed(ADC_VERY_HIGH_SPEED);
      adc->setSamplingSpeed(ADC_VERY_HIGH_SPEED);
      adc->startContinuous(A0, ADC_0);   
      adc->analogReadContinuous(ADC_0);
      digitalWriteFast(SHpin, LOW);
    
    }
    
    void loop()                     
    {
    
      //turn interrupts on, these will be used for syncronization of the signals  
      interrupts();
    
      // increment loops to allow us to make decisions based on how many reads have been performed
      loops += 1;
      //if (loops>20){digitalWriteFast(11, HIGH);}
      
      // ticks tracks the main PWM, should be at 1 MHZ
      ticks = 0;
      
      // wait for first PWM tick, the main interrupt based on the PWM increments the ticks value
      while (ticks < 1){};
      // cycle ICG low
      digitalWriteFast(ICGpin, LOW);
      
      // loop used for timing, checked wait time with oscilliscope, has weird jumps in wait time based on number of loops, must be optimized by the compiler?
      // not sure why I didn't use the tick counter for this timing, pretty sure tick counter was only reliable for longer waits
      // see sensor sheet for timing reasons, using the default here i think
      for (bb=0;bb<20 ;bb++){};
      digitalWriteFast(SHpin, HIGH);
      while (ticks < 6){};
      digitalWriteFast(SHpin, LOW); //for norm
      while (ticks < 10){};
      digitalWriteFast(ICGpin, HIGH);
      
      // turn off interrupts for the main loop where we read the analog signal
      // in order for loop to run uninterrupted, cycles through all data
      noInterrupts();
      for (aa=0;aa<923;aa++){
        digitalWriteFast(SHpin, HIGH);
        for (bb=0;bb<60;bb++){};
        data_buffer[2*aa] = adc->analogReadContinuous(ADC_0);
        for (bb=0;bb<60;bb++){};
        digitalWriteFast(SHpin, LOW);
        for (bb=0;bb<60;bb++){}; 
        data_buffer[2*aa+1] = adc->analogReadContinuous(ADC_0);
        for (bb=0;bb<60;bb++){};   
      }
    
      digitalWriteFast(SHpin, HIGH);
      for (aa=0;aa<923;aa++){
        digitalWriteFast(SHpin, HIGH);
        for (bb=0;bb<60;bb++){};
        data_buffer[923+2*aa] = adc->analogReadContinuous(ADC_0);
        for (bb=0;bb<60;bb++){};
        digitalWriteFast(SHpin, LOW);
        for (bb=0;bb<60;bb++){}; 
        data_buffer[923+2*aa+1] = adc->analogReadContinuous(ADC_0);
        for (bb=0;bb<60;bb++){};
      }
      
      //t2 = ARM_DWT_CYCCNT;
      interrupts();
      ticks = 0;
      while (ticks < 1){};
    //  digitalWriteFast(ICGpin, LOW);
      adc->analogReadContinuous(ADC_0);
      digitalWriteFast(SHpin, HIGH);
      while (ticks < 6){};
      digitalWriteFast(SHpin, LOW);
      
      // turn off interrupts so can send serial data uninterrupted
      // print out every reading, can change if we want to print every X  
      noInterrupts();
      if (loops > 0){
        for (aa=0;aa<3694;aa++){
          Serial.print(data_buffer[aa]);
          Serial.print(" ");
          data_buffer[aa] = 0;
        }
        Serial.println(" end");
        loops = 0;
        //delay(100);
      }
      interrupts();
      delay(3000);
    }
    
    
    
    void isrService()
    {
      ticks = ticks + 1;
    
    }

  6. #6
    Junior Member
    Join Date
    Apr 2013
    Posts
    4
    Quote Originally Posted by playsted View Post
    Hi, this is only a semi functional version but is all I could find.
    Thank you for sharing your code. I hope I find some time to test and improve it.

  7. #7
    Junior Member
    Join Date
    Jul 2016
    Posts
    1
    Hello everyone
    Would anyone know to indicate some code already available for reading the TCD1304 CCD using Teensy?
    Thank you.
    Ps: I saw something on this link [1], but the author himself says he does not have the correct reading speed.

    [1] https://github.com/superzerg/TCD1304AP_teensy2pp

  8. #8
    Do you think the teensy 3.1 can power up all these clock signals at the same time? Currently I have the stm32f401re. Though I can power up these clocks, but I can't get them to go at the same time. The stm doesn't have a fast enough ADC as well. Please advise.


    ibps clerk result 2017

  9. #9
    Junior Member
    Join Date
    Dec 2017
    Posts
    1
    I don't mean to be blunt, but if you can't get the stm32f401re to drive and read the TCD1304, you're doing it wrong.

    It's possible that the MCU isn't fast enough if you want the main loop to do everything, but that's exactly what I mean by doing it the wrong way. You should use the peripherals.

    I have a stable firmware including command-line interfaces for linux and mac, and a german guy wrote a windows GUI as well. I have documented it as well as I could here:
    https://tcd1304.wordpress.com

    I don't know the teensies, but if the 3.1 has enough peripherals and is as fast or faster than the stm32f103 "blue-pill" which can also drive and read the TCD1304 (another german ported my firmware to this chip, but hasn't yet published it, and I've confirmed it works), then it should just be a matter of utilizing the chip properly.

Posting Permissions

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