Here I have created this circiut for building CCD spectrometer. I am using TCD1304AP CCD and Ardiuno Mega. I have written this below code.
<
C:
#include <util/delay.h>
#ifdef ARDUINO_AVR_MEGA2560
#define LAMP 0x20
#define SH 0x40
#define ICG 0x80
#define MCLK 0x10
#else
#define LAMP 0x01
#define SH 0x02
#define ICG 0x04
#define MCLK 0x08
#endif
#define CLOCK PORTB
#define MIN_SIGNAL 10
uint16_t buffer[800];
uint16_t avg = 0;
char cmdBuffer[16];
int cmdIndex;
int exposureTime = 20;
void setup() {
// Initialize the clocks.
DDRB |= (LAMP | SH | ICG | MCLK); // Set the clock lines to outputs
CLOCK |= ICG; // Set the integration clear gate high.
// Enable the serial port.
Serial.begin(115200);
// Setup timer2 to generate a 380.614kHz frequency on D11
TCCR2A = +(0 << COM2A1) | (1 << COM2A0) | (1 << WGM21) | (0 << WGM20);
TCCR2B = (0 << WGM22) | (1 << CS20);
OCR2A = 20;
TCNT2 = 1;
// Set the ADC clock to sysclk/32
ADCSRA &= ~((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0));
ADCSRA |= (1 << ADPS2) | (1 << ADPS0);
}
void readCCD(void) {
int x;
uint16_t result;
CLOCK &= ~ICG;
_delay_loop_1(12);
CLOCK |= SH;
delayMicroseconds(5);
CLOCK &= ~SH;
delayMicroseconds(15);
CLOCK |= ICG;
delayMicroseconds(1);
for (x = 0; x < 800; x++) {
CLOCK |= SH;
if (x == 0) {
result = (uint16_t)(1023 - analogRead(A0));
if (result > MIN_SIGNAL) {
avg = result - MIN_SIGNAL;
} else {
avg = result;
}
} else {
result = (uint16_t)(1023 - analogRead(A0));
}
CLOCK &= ~SH;
if (result < avg) {
result = 0;
} else {
result -= avg;
}
buffer[x] = result;
delayMicroseconds(20);
}
}
void sendData(void) {
int x;
for (x = 0; x < 800; ++x) {
Serial.println(buffer[x]);
}
}
void loop() {
while (Serial.available()) {
cmdBuffer[cmdIndex++] = Serial.read();
}
if (cmdBuffer[0] == 'r') {
sendData();
} else if (cmdBuffer[0] == 'l') {
CLOCK &= ~LAMP;
} else if (cmdBuffer[0] == 'L') {
CLOCK |= LAMP;
} else if (cmdBuffer[0] == 'e') {
exposureTime = atoi((char *)&cmdBuffer[1]);
if (exposureTime > 1000) exposureTime = 1000;
else if (exposureTime < 0) exposureTime = 0;
Serial.println(exposureTime);
}
memset(cmdBuffer, 0 , sizeof(cmdBuffer));
cmdIndex = 0;
readCCD();
delay(exposureTime);
}