Go Down

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

mdma

This might be a silly question, but do you have to use a transistor to amplify the Vout? Is it possible to just connect directly to an analogue input? I realize I'll lose resolution, but that's not so important here.

I have the ILX511 wired up to the arduino, with CLK and ROG connected to digital outputs. I pulse ROG low for 5000us, then wait 1000us before alternating the clock - I've tried different frequences from 10us up to 10ms.  SHSW is held low so that I activate the internal S/H circuit.  I record the minimum and maximum values read, which are around 250-380.


Riva


This might be a silly question, but do you have to use a transistor to amplify the Vout? Is it possible to just connect directly to an analogue input? I realize I'll lose resolution, but that's not so important here.

I have never tried without a transistor on the output so cannot say.
Don't PM me for help as I will ignore it.

Bumpasticka77

So, since this was my first attempt at anything with electronics, I realized I was way over my head and needed to learn the basics.  Recently, I picked up coding again and came back to this project.  Using the Timer1 library, I got something that works, granted it will only control the ILX511 sensor.  You need an oscilloscope to view the output.

Code: [Select]
#include <TimerOne.h>
#define pwmRegister OCR1A

const int rog_pin = 4;
const int clock_pin = 9;
long period = 1;
long duty = 512;
unsigned long current = 0;
unsigned long previous = 0;
unsigned long difference = 0;

void setup() {
  pinMode(rog_pin, OUTPUT);
  pinMode(clock_pin, OUTPUT);
  Timer1.initialize(period);
  PORTB = B000010;
  PORTD = B00010000;
  Timer1.pwm(clock_pin, duty);
}

void loop() {
  current = micros();
  difference = current - previous;
  if(difference >= 2087) {
    Timer1.disablePwm(clock_pin);
    PORTB = B000010;
    delayMicroseconds(500);
    PORTD = B00000000;
    delayMicroseconds(500);
    PORTD = B00010000;
    delayMicroseconds(500);
    previous = micros();
    Timer1.pwm(clock_pin, duty);
  }
}


It works very well.  The long microsecond delays are to make it easier to view the end of the pixels on an oscilloscope.  As it is now, it will pulse the clock_pin at 1 Mhz.  The major problem with the code is that upon reinitializing pwm at the beginning of each read, the duty cycle is sometime distorted from 50% for the 1st pixel.  Also, the same goes for the last pulse when pwm is paused.  If anybody has ideas, that would be awesome.  I'll need to optimize that portion at some point...and then figure out how I'm going to store the pixel data at 500k - 1M hz  :smiley-eek-blue:

TeamAlpha

#18
Feb 27, 2015, 05:14 am Last Edit: Feb 27, 2015, 05:17 am by TeamAlpha
Bumpasticka,

Do you mind posting your schematic or pin wiring for the arduino with the sensor?  Also, did you use a transistor as suggested in the previous posts or did you just leave Vout un-amplified? 

Have you tried running this with other arduinos?  I believe the mega, for instance, prefers timer3 instead of timer1 because of the output pins. 

Thanks!

Riva

#19
Jun 14, 2015, 05:18 pm Last Edit: Jun 14, 2015, 05:24 pm by Riva Reason: Adding attachments
I also revisited this project as I was considering using a faster MCU but in the end found the voltage translation needed between 3.3V & 5V to much hassle so tweaked and tested my original Mega code to confirm it still worked okay.
You have to be aware the CCD is very sensitive and to reduce the light levels enough to do a finger test I have to put a piece of thin card on the CCD, my finder on this card and then another piece of cardboard to shade direct light from the ceiling light falling on my finger/CCD.

Attached is the Mega sketch, logic analyser capture of CLK/ROG output + test pin output used to determine time spent in different sections of the timer ISR.
Also attached are the outputs with my finger on the middle of the CCD and one with no finger. They were make with a simple sketch written in processing.
Don't PM me for help as I will ignore it.

Riva

#20
Jun 14, 2015, 05:26 pm Last Edit: Jun 14, 2015, 05:39 pm by Riva
Attached is the processing sketch used to read out the data from the ILX511 CCD running on the Arduino Mega.
Code: [Select]
boolean myDebug = false;

int sampleBufferSize = 2201;                                // The sample buffer
int[] sampleBuffer = new int[sampleBufferSize + 1];         // Samples
int sampleCount = 0;                                        // Sample position counter
int timeout = 0;                                            // Used for timeout counter while waiting for Serial data

import processing.serial.*;
Serial arduinoSerial;                                       // The serial port

void setup() {
  if (myDebug)
    println(Serial.list());                                 // List all the available serial ports
  else {
    //arduinoSerial = new Serial(this, Serial.list()[0], 230400);// Open the port you are using at the rate you want:
    arduinoSerial = new Serial(this, Serial.list()[0], 115200);// Open the port you are using at the rate you want:
    arduinoSerial.clear();                                  // Flush serial buffers
  }
  println("*******************************");
  println("* -= ILX511 Scanner v5 MEGA=- *");
  println("*******************************");
  if (!myDebug)
    delay(500);                                             // Delay some to allow scanner to reboot and start sending serial data

  if (myDebug) {                                            // Put some data in the buffer if debugging
    for (int x=0; x < sampleBufferSize; x++) {
      sampleBuffer[x] = x & 255;
    }
  }

  size((sampleBufferSize+10)/2, 300);                       // Display size just wider than sample buffer size
  frameRate(15);                                            // Reduce framerate to save CPU load
}

void serialEvent(Serial arduinoSerial) {
  if (millis() > timeout + 50) {                            // Timeout if no serial received for 50 milliseconds or more
    //print("Timeout ");
    //println(millis());
    sampleCount = 0;                                        // Timout so reset counter
  }
  sampleBuffer[sampleCount++] = arduinoSerial.read();       // Add value to buffer
  if (sampleCount > sampleBufferSize) {                     // End of buffer?
    print("Overflow ");
    println(millis());
    sampleCount = 0;                                        // zero it
  }
  timeout = millis();                                       // Get current time
}

void draw() {
  int y = 0;
  background(180);                                          // Clear to background colour
  doScale();                                                // Paint on the scale
  stroke(255, 255, 0);                                      // Set pen colour
  for (int x = 0; x < sampleBufferSize; x++) {              // Draw the buffer data
    if ((x % 2) == 0) {
      y = sampleBuffer[x] * 256;
    }
    else {
      y = y + sampleBuffer[x];
      //line((x/2)+5, sampleBuffer[x], (x/2)+5, 280);
      //point((x/2)+5, sampleBuffer[x]/2);
      point((x/2)+5, 280 - (y / 4));
    }
  }
}

void doScale() {
  stroke(0);
  line(0+5, 280, 0+5, 280 - 255);
  line(16+5, 280, 16+5, 280 - 255);
  line(1040+5, 280, 1040+5, 280 - 255);
  line(1043+5, 280, 1043+5, 280 - 255);
}

Don't PM me for help as I will ignore it.

Go Up