Go Down

Topic: Controlling an ILX511 Linear CCD Sensor (Read 28146 times) previous topic - next topic

Bumpasticka77

I'm attempting to control a linear CCD sensor using an Arduino Uno.  The sensor is a Sony ILX511.  The datasheet can be found here: (http://www.oceanoptics.com/technical/detectorsonyILX511.pdf).  The sensor requires a clock pulse and a gate pulse.  If I understand correctly from the datasheet, the gate pulse is HIGH (5V) while the clock pulse creates square waves to tell the sensor to shift along the pixels in the array. When the gate pulse goes from HIGH to LOW and back to HIGH it tells the sensor to restart.  I've finally come out with code that will create the proper pulses, with clock pulses having a 50% duty cycle.  I've tested the pulses by plotting in Labview and watching LEDs light up.  There is no maximum time in between clock pulses, so I've tried running the code at slow paces and at fast paces and still come out with the same problem.  The problem is that the sensor does not shift pixels in the array, and instead it remains on the first pixel.  I'm able to see this because output voltages only change when I shine light on the first pixel.

So, has anyone had any experience with running a CCD sensor with the arduino?  I don't see why it wouldn't be possible because the datasheet states that there are no maximum times in between clock pulses.  I've wired up the sensor exactly how the datasheet shows on page 10.  Any advice would be great.

I also suspected that voltage output by the arduino might be the case, so I tried with a 9V battery connected to the arduino and still the same problem.

Here is my code:

Code: [Select]
int CLKPin = 3;
int ROGPin = 5;
float pulsetimer = 0;
float counter = 0;


void setup() {
  DDRD = B00101000;  //Pins 3 and 5 as outputs
  Serial.begin(115200);
}

void loop() {
  pulsetimer = pulsetimer + 1;
  counter = counter + 1;
  Pulses();
  pulseRead();
  delay(15);
}

void pulseRead() {
  static float timer; //currently not used
  long PhotoRead;
  timer = (timer + 1); //currently not used
  PhotoRead = analogRead(0);
  //Serial.print("YELLOW = ");
  Serial.println(PhotoRead);
  //Serial.print(",");
  //Serial.print("RED = ");
  //Serial.print(redRead);
  //Serial.print(",");
  //Serial.print("Time = ");
  //Serial.print(timer);
  //Serial.print(",");
  //Serial.print("Pulsetimer = ");
  //Serial.println(pulsetimer);
  //Serial.print(",");
  //Serial.print("Counter = ");
  //Serial.print(counter);
  //Serial.print(",");
  //Serial.flush();
}

void Pulses() {
  int CLKState;
  CLKState = digitalRead(CLKPin);
  if(pulsetimer <= 30) {
    PORTD = B00001000;  //ROG - Low, CLK - High
    counter = 0;
  }
  else if(pulsetimer > 30 && pulsetimer < 35) {
    PORTD = B00101000; //ROG - High, CLK - High
    counter = 0;
  }
  else if(pulsetimer >= 35 && pulsetimer <= 12563) {
    if(counter == 3) { //Change CLK state every 3 iterations
      if(CLKState == HIGH) { //If CLK = HIGH set to low
                             //and vice versa
        PORTD = B00100000; //ROG - High, CLK - Low
        counter = 0;
      }
      else {
        PORTD = B00101000; //ROG - High, CLK - High
        counter = 0;
      }
    }
  }
  else if (pulsetimer > 12563 && pulsetimer < 12568) {
    PORTD = B00101000; //ROG - High, CLK - High
  }
  else if(pulsetimer == 12568) {
  pulsetimer = 0; //Restart
  PORTD = B00101000; //ROG - High, CLK - High
  counter = -1;
        }
    }

ralphnev

what have you set to the SHSW pin ? grd or vcc ?

I'm starting down a project using a uPD3799 & Due,
similar except 5000 pixels & i want to run at 1Msps .. 

AWOL

#2
Dec 11, 2012, 01:54 pm Last Edit: Dec 11, 2012, 01:57 pm by AWOL Reason: 1
Code: [Select]
float pulsetimer = 0;
Are you figuring on having fractional pulses?

Code: [Select]
CLKState = digitalRead(CLKPin);
You've made it an output, yet you're reading it.

Bumpasticka77

Thanks for the replies.

ralphnev,
I'm using the SHSW mode (set to grd).  It gives a smoother plot of data points compared to not using it, which outputs waves of different amplitudes.  Although, if I actually got the sensor to change pixels, not using the SHSW mode may be useful in distinguishing what pixel gave what reading because the output gives a constant voltage when clock pulses are LOW and then outputs the reading of the next pixel in line when the clock pulse is HIGH.  This way, you can see the shifting from pixel to pixel.  Keep me posted on your progress.

AWOL,
Right now, I'm not using fractional pulses.  Would I gain anything from this other than not having to count to as high as 12568?
Also, digitalReading an output pin will still return the state it is in. 

HazardsMind

Why isn't the CLKPin set in the setup() as pinMode(CLKPin, INPUT) or pinMode(CLKPin, OUTPUT)?

My GitHub:
https://github.com/AndrewMascolo?tab=repositories

AWOL

Quote
Also, digitalReading an output pin will still return the state it is in.

But you wrote the state it is in!

HazardsMind

#6
Dec 11, 2012, 06:38 pm Last Edit: Dec 11, 2012, 06:41 pm by HazardsMind Reason: 1
This is not the FULL code is it?
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

HazardsMind

Quote
DDRD = B00101000;  //Pins 3 and 5 as outputs

Nevermind my previous post
Quote
Why isn't the CLKPin set in the setup() as pinMode(CLKPin, INPUT) or pinMode(CLKPin, OUTPUT)?


I didn't know "B00101000" was possible to do with arduino.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Bumpasticka77

I appreciate ya'll checking my code

AWOL,
I realize that I'm writing what state it is in.  The point of reading it is to check the state and set it to the opposite state.  If it's high, set to low.  If it's low, set to high.

HazardsMind,
And yes this is the full code.  I tried keeping it simple since I'm reading and writing so often, and it is imperative that the clock pulses remain consistent.

I'm looking for advice on generating square wave pulses with a constant frequency and duty cycle, and reading the outputs of a sensor in between the pulses.  Or suggestions if anyone has interfaced a CCD sensor with arduino.

Riva

Did you get anywhere with your project?
I have started to mess about with an ILX511 but found it started to get warm at one end when grounding pin 4 to do S/H mode so stuck with pin 4 to VCC. What circuit did you use for S/H mode?
Below is some code I just wrote to test (for non S/H mode) but have not tried plotting it's results yet to know if it works.
As the UNO does not have enough memory to read the entire CCD I sample every other pixel and right shift the result 2 places to fit result into a byte.

Code: [Select]
#define CLK 5
#define ROG 11
#define LED 13
#define CLKSPEED 50

#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

byte sampleArray[1044];
unsigned long sampleTime;

void setup() {
  Serial.begin(115200);
  #if FASTADC
    // set prescale to 16
    sbi(ADCSRA,ADPS2) ;
    cbi(ADCSRA,ADPS1) ;
    cbi(ADCSRA,ADPS0) ;
  #endif
 
  pinMode(ROG,OUTPUT);
  digitalWrite(ROG,HIGH);
  pinMode(CLK,OUTPUT);
  digitalWrite(CLK,LOW);
  pinMode(LED,OUTPUT);
  delay(1000);
}

void loop() {
  digitalWrite(LED,HIGH);
  digitalWrite(CLK,HIGH);
  delayMicroseconds(500);
  digitalWrite(ROG,LOW);
  delayMicroseconds(1000);
  digitalWrite(ROG,HIGH);
  delayMicroseconds(500);
  for( int x = 0; x < 2088; x++){
    digitalWrite(CLK,LOW);
   
    sampleTime = micros();
    while ((sampleTime + CLKSPEED) > micros()){
    }
    digitalWrite(CLK,HIGH);
   
    sampleTime = micros();
    if (x & 1) {
      int y = analogRead(A0);
      sampleArray[x >> 1] = y >> 2;
    }
    while ((sampleTime + CLKSPEED) > micros()){
    }
  }
  digitalWrite(CLK,LOW);
  digitalWrite(LED,LOW);
  delay(100);
 
}
Don't PM me for help as I will ignore it.

Bumpasticka77

Hi Riva,

I never got past being able to read only the first pixel.  I even checked the logic with an analyzer and still didn't get an entire array of pixel data.  The circuit I was using was the one directly from the datasheet for the sensor.  I used an arduino with the sensor and collected data with an external data acquisition device I had lying around at work using Labview.  Were you actually able to receive data from the whole array of pixels?  If so, what did your circuit look like?  Were the CLK and ROG pins on the sensor connected directly to the arduino, or did you have additional circuitry in between?  I might have to come back to this project now haha.

Riva

No luck yet reading the entire pixel data. Like you I only seem to have the first pixel as the level raises/lowers when I cover only one end of the array.
I'm not even reading the dummy pixels or the optical black before the first actual pixel so suspect I'm not close yet.
After the array heating up I discovered a poor ground was to fault and though I may have fried the CCD but trying a new CCD gave the same results.
I still have a few ideas to try but am beginning to wonder if the arduino UNO & MEGA are maybe to slow at clocking & reading the device. The datasheet does not give upper limits on most signal timings but there is a large difference between something like 3000ns and 20us that is as fast as I can analogue sample the data using arduino.
I will let you know if I manage to get it working.
Don't PM me for help as I will ignore it.

Riva

In my tweaks & tests today I noticed that even if I disconnect ROG & CLK lines from the arduino I still get the same (first pixel) waveform as with them connected so they seem to have no effect.
Maybe CLK is not running quick enough though I cannot go much faster as it takes 24uS to analogue sample and store a pixel and with CLK running at 64uS PP I only have 8uS overhead when sampling.
Don't PM me for help as I will ignore it.

Riva

Hi Bumpasticka,

I laid out the hardware again as the old board was a bodge and also used a faster transistor for amplifying Vout and I am starting to get something now. The CCD is very sensitive to light so after applying an electrical tape mask and working in a dim room I managed to get an output.
First is covering the entire CCD with my finger and as expected the trace is flat but I am getting the dummy pixels before and maybe after (harder to see) the effective pixels.
The second picture is with my finger hovering over the middle of the CCD. It's not as good as expected as I think the setup is in need of a lens to focus light and mask off stray ambient light.
Don't PM me for help as I will ignore it.

dmzz

Hi guys,

perhaps you have a huge progress already on interfacing  ILX511 with Arduino.
Could you please post some complete wiring scheme and sample code for basic reading from the sensor. 
I'm complete nub, so will be thankful for any details here or on the WIKI.

Go Up