Interfacing Arduino with ADC0820

Hi all,

I'm trying to use an external ADC (ADC0820) with Arduino (Mega).

The schematics and the code (adapted by me, here below) I used are found here: http://davidallmon.com/pages/adc0820-spectrograph

But it doesn't work, what can be the problem?

Thanks

#include <util/delay_basic.h>

//debug
#define DBG 42
// ADC RD signal pin 17
#define RD 49
// ADC write signal pin 18
#define WR 48
// CCD Shift Gate pin 19
#define SH 47
// CCD Integration Clear Gate pin 20
#define ICG 51
// CCD Master clock pin 21
#define MCLK 50
// CCD and ADC clocks
#define CLOCK PORTL
// ADC data
#define ADATA PINC
uint8_t value;

void setup()
{
  // Initialize the clocks.
  DDRL |= (WR | SH | ICG | MCLK | RD | DBG);  // Set the clock lines to outputs
  CLOCK |= (RD | WR);        // Set the ADC wr line high.
  // Setup the ADC data port.
  DDRC = 0; // all C input
  // Enable the serial port.
  Serial.begin(115200);
  // Setup timer2 to generate a 470kHz frequency on MCLK - not used here
  TCCR2A =  + (0 << COM2A1) | (1 << COM2A0) | (1 << WGM21) | (0 << WGM20);
  TCCR2B = (0 << WGM22) | (1 << CS20);
  OCR2A = 16;
  TCNT2 = 1;
}

void readADC(void)
{    
    // ADC write.
    CLOCK &= ~WR;
    delayMicroseconds(1);
    CLOCK |= WR;
    // ADC convert.
    delayMicroseconds(2);
    // ADC read.
    CLOCK &= ~RD;
    delayMicroseconds(1);
    value = ADATA;
    CLOCK |= RD;
}

void sendData(void)
{
    Serial.print(value);
    Serial.print("\n");  
}

void loop()
{  
   readADC();
   sendData();          
   delay(300);    
}
DDRL |= (WR | SH | ICG | MCLK | RD | DBG);  // Set the clock lines to outputs

OR-ing together a bunch of Arduino pin numbers will NOT get you a useful bitmask. Use pinMode() instead of writing directly into the Data Direction Register. Use digitalWrite() to set output pins instead of writing to the PORT register. ONLY USE DIRECT REGISTER ACCESS IF YOU REALLY NEED THE SPEED OR NEED TO CHANGE MORE THAN ONE PIN IN THE SAME MICROSECOND.

Ok, thank you, now seems to work.
But actually I need the speed, I want to use a CCD too. This was only a test for the ADC.
Is there a solution? I don't understand why that code doesn't work for me.

Well...no it's still not working.
I cleared a bit the code I used, are there errors?

#define RD 21
#define WR 20
#define CLOCK PORTD
#define ADATA PINC
uint8_t buffer[1];

void setup() {
  pinMode(WR, OUTPUT);
  pinMode(RD, OUTPUT);
  PORTD = (1<<WR); //WR high
  PORTD = (1<<RD); //RD high
  DDRC = 0; // Setup the ADC data port.
  Serial.begin(115200);
}

void loop() {
  // ADC write.
CLOCK &= ~WR;
delayMicroseconds(1);
CLOCK |= WR;

// ADC convert.
delayMicroseconds(2);

// ADC read.
CLOCK &= ~RD;
delayMicroseconds(1);
buffer[0] = ADATA;
CLOCK |= RD;
Serial.print(buffer[0]);
delay(1000);
}

Thanks

  PORTD = (1<<WR); //WR high
  PORTD = (1<<RD); //RD high

That's a mistake if you want both bits set. When you write a PORT register you set all 8 bits. Setting the RD bit is also clearing all the other bits, including WR.

Also, port registers are only 8 bits wide. Shifting a 1 by 20 or 21 bits moves it completely out of the byte. TO MANIPULATE PINS USING DIRECT PORT MANIPULATION YOU NEED TO USE THE PORT NAME AND PIN MASK. YOU CAN"T DIRECTLY USE ARDUINO PIN NUMBER. Find a chart or diagram that maps maps Arduino pin numbers to port names in pin mask (or bit number you can use for shifting).

uint8_t buffer[1];

A one element array is pointless. Just use a scalar variable.