//This is the firmware developed by David Allmon @ http://davidallmon.com/pages/adc0820-spectrograph
I built this circuit on a proto breadboard (David H Haffner Sr,) and tested it and it works beautifully @ my website on Hackaday are the full project details and PCB gerber files + schematics so please take a look :) //
// Debug point pin 16
// ADC RD signal pin 17
// ADC write signal pin 18
// CCD Shift Gate pin 19
// CCD Integration Clear Gate pin 20
// CCD Master clock pin 21
// CCD and ADC clocks
// ADC data
uint8_t buffer[3694]; char cmdBuffer[16]; int cmdIndex; int exposureTime = 10;
void setup() {
// Initialize the clocks. DDRD |= (WR | SH | ICG | MCLK | RD | DBG); // Set the clock lines to outputs CLOCK |= ICG; // Set the integration clear gate high. CLOCK |= (RD | WR); // Set the ADC wr line high.
// Setup the ADC data port. DDRC = 0; // Enable the serial port. Serial.begin(115200);
// Setup timer2 to generate a 470kHz frequency on pin 21 TCCR2A = + (0 << COM2A1) | (1 << COM2A0) | (1 << WGM21) | (0 << WGM20); TCCR2B = (0 << WGM22) | (1 << CS20); OCR2A = 16; TCNT2 = 1;
}
void readCCD(void) {
int x; uint8_t dummy;
// Clear the CCD shift register and // dump the electrons into it. CLOCK |= DBG; CLOCK &= ~ICG; _delay_loop_1(12); CLOCK |= SH; delayMicroseconds(5); CLOCK &= ~SH; delayMicroseconds(10); CLOCK |= ICG; delayMicroseconds(1);
for (x = 0; x < 3694; x++) { // Shift out one pixel and // digitize it. CLOCK |= SH;
// ADC write. CLOCK &= ~WR; delayMicroseconds(1); CLOCK |= WR;
// ADC convert. delayMicroseconds(2);
// ADC read. CLOCK &= ~RD; delayMicroseconds(1); buffer[x] = ADATA; CLOCK |= RD;
// Eat up a few cycles for timing. asm("nop"); asm("nop"); asm("nop"); asm("nop");
CLOCK &= ~SH; delayMicroseconds(4); } CLOCK &= ~DBG;
}
void sendData(void) {
int x;
for (x = 30; x < 3678; ++x) { Serial.print(x - 30); Serial.print(","); Serial.print(buffer[x]); Serial.print("\n"); }
}
int cmdRecvd = 0;
void loop() {
int x; char ch;
if (cmdRecvd) { if (cmdBuffer[0] == 'r') { sendData(); } else if (cmdBuffer[0] == 'e') { sscanf(cmdBuffer+1,"%d", &exposureTime); if (exposureTime > 1000) exposureTime = 1000; } memset(cmdBuffer, 0, sizeof(cmdBuffer)); cmdIndex = 0; cmdRecvd = 0; } delay(exposureTime); readCCD(); if (Serial.available()) { ch = Serial.read(); if (ch == 0x0a) { cmdBuffer[cmdIndex++] = '\0'; cmdRecvd = 1; } else { cmdBuffer[cmdIndex++] = ch; cmdRecvd = 0; } }
}