ADC0831

Hoping for some help. I am having no luck finding a method to interface with an ADC0831. I am new to the digital world and have some basic understanding. I believe I need to send a clock signal to the clk(pin7) not sure how to generate or at what frequency. Then I need to set the /cs pin (1) high to start then low to read. Next should be able to read the digital output from DO (pin 6) and finally set /cs back to high. I am struggling on how to send the clock signal and then read the digital output at the same clock rate. Any thoughts or help would be greatly appreciated.
Thanks,
Jimmy

Looks like an SPI interface.
You will connect to the Arduino's SCK (clock), Arduino's Slave Select (chip select), Arduino's MOSI (master Out, slave in) to data in, and MISO (Master In Slave Out) to the data out.

Look in the playground for SPI examples.

When you do an SPI transfer, you will take chip select low, command an SPI transfer which create a burst of clock pulses, while those occur the Arduino also toggles the data out line, and captures the data coming in from the device, and then you take chip select hi.

Thanks,

Here is what I have tried:

Connections:
Arduino - ADC0831
pin 13 - pin 7 (CLK)
pin 12 - pin 6 (DO)
pin 10 - pin 1 (CS)

#include "SPI.h"
int ss=10;

void setup()
{
Serial.begin(9600);
pinMode(ss, OUTPUT);
SPI.begin();
}

void loop()
{
byte value;
digitalWrite(ss, LOW);
value = SPI.transfer(0x00);
Serial.print("Value: ");
Serial.println(value,DEC);
digitalWrite(ss, HIGH);
delay(1000);
}

I have tried different voltage inputs to pin 2 on the 0831 (1.2V to 3.9V) and only get "value: 0" on the serial output.

Am I reading the value correctly? (spt.transfer line)
I could not find anything in the reference specifically for reading the data.
I also could not find anything for the ADC0831 supporting SPI. (Is this necessary?)
Thanks,
Jimmy

I didn't realize you could still buy this part! This was a cool chip in its day.

I'm not sure the SPI library is right for this part. You start conversion by driving CS LOW. Then when CLK goes from HIGH to LOW, a zero is clocked out on DO. Then the next 8 CLK HIGH to LOW transitions clock the data out onto DO. Then you drive CS HIGH again to tristate the DO line.

I closed the data sheet, let me look at it again.

Something like this should work. This is untested and I'm not sure the delays are necessary but it's a relatively slow part. This should give you an idea about how to talk to it.

byte CS=HIGH;
byte CLK=HIGH;


byte ADCread() { // function to read ADC0831
  byte _byte = 0;

  digitalWrite(CS, LOW);
  digitalWrite(CLK, LOW);
  delayMicroseconds(1);
  digitalWrite(CLK,HIGH);
  if (!digitalRead(DO)) return _byte = false; // exit if no start bit

  for (int i=7; i>=0; i--) // else read next 8 bits
  {
    digitalWrite(CLK, LOW);
    delayMicroseconds(1);
    if (digitalRead(DO))
      _byte |= (1 << i);
    digitalWrite(CLK, HIGH);
    delayMicroseconds(1);
  }
  digitalWrite(CS, HIGH);

  return _byte;

Here is how I implemented it:

//byte CS=HIGH;
//byte CLK=HIGH;
int CS=8;
int CLK=6;
int DO=7;

void setup()
{
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DO, INPUT);
}

byte ADCread() { // function to read ADC0831
  byte _byte = 0;

  digitalWrite(CS, LOW);
  digitalWrite(CLK, LOW);
  delayMicroseconds(1);
  digitalWrite(CLK,HIGH);
  if (!digitalRead(DO)) return _byte = false; // exit if no start bit

  for (int i=7; i>=0; i--) // else read next 8 bits
  {
    digitalWrite(CLK, LOW);
    delayMicroseconds(1);
    if (digitalRead(DO))
      _byte |= (1 << i);
    digitalWrite(CLK, HIGH);
    delayMicroseconds(1);
  }
  digitalWrite(CS, HIGH);
  return _byte; 
}

void loop (){
  byte reading;
  reading = ADCread();
  Serial.print("Data:  ");
  Serial.println(reading,BIN);
  delay(1000);
}

I changed the first 2 lines. I assume you wanted CS and CLK to be the pins.

All I get is all 1s either 7 or 8 (1111111 or 11111111) and occasional 0's regardless of the input voltage.

Am I just completely lost on this?
Thanks,
Jimmy

You have to set CS and CLK HIGH before you call ADCread(). I didn't indicate that very well.

Sorry, that was all wrong. Replace ADCread() with this:

byte ADCread() { 
  byte _byte = 0;
  digitalWrite(CS, LOW);  
  digitalWrite(CLK, HIGH);
  delayMicroseconds(1);
  digitalWrite(CLK,LOW);
  delayMicroseconds(1);
  if (!digitalRead(DO)) return _byte = false; // exit if no start bit

  for (int i=7; i>=0; i--) // else read next 8 bits
  {
    digitalWrite(CLK, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK, low);
    delayMicroseconds(1);  
    if (digitalRead(DO))
      _byte |= (1 << i);
  }
  digitalWrite(CS, HIGH);

  return _byte; 
}

Hy everbody.

I have the same ADC device and I have the same problem. But now I solve it. I use the SPI comunication and boilá!!.

Here's my code:

#include <SPI.h>
int CS = 49;
int result;

void setup() {        
    pinMode(CS, OUTPUT);
            
    Serial.begin(9600);
    SPI.begin();
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV64);
    //SPI.setDataMode(SPI_MODE0);
    
    digitalWrite(CS, HIGH);
}
void loop() {
    int result;
    digitalWrite(CS, LOW);
    result = SPI.transfer(0x00);
    digitalWrite(CS, HIGH);
    Serial.println("Data: " + String(result));
    delay(1000);   
}

I try to improve it because sometimes i have more than one value for the same position of the potentiometer. If somebody have the solution i'll apreciate it.

I think sometimes the most significant bit escapes me because the difference beetwen two values for the same potentiometer's position is 2?. For examples I saw sometimes 184, sometimes 56.
Thaks for all.
PD: Sorry for my english.

Finally it works. Not with SPI library.
I've used the code of EmilyJane with two modifications.

  • This ADC module has not got a start bit to syncronize the read.
  • The delay i use is a 4us per CLK cycle => 250 Khz. We need to have present the max speed ADC0831 can support is 400 Khz and with a 2us per cycle time we have 500 Khz and maybe it can will generate problems.

And here the code:

#include <SPI.h>

int CS = 49;
int CLK = 52;
int DO = 50;

byte result;

void setup() {        
    pinMode(CS, OUTPUT);
    pinMode(CLK, OUTPUT);
    pinMode(DO, INPUT);
    
    digitalWrite(CS, HIGH);
    digitalWrite(CLK, LOW);
    
    Serial.begin(9600);
}

void loop() {
    result = ADCread();
    Serial.println("Data: " + String(result));
    delay(1000);   
}

byte ADCread() { 
    byte _byte = 0;
  
    digitalWrite(CS, LOW);  
    digitalWrite(CLK, HIGH);
    delayMicroseconds(2);
    digitalWrite(CLK,LOW);
    delayMicroseconds(2);

    for (int i=7; i>=0; i--) {
        digitalWrite(CLK, HIGH);
        delayMicroseconds(2);
        digitalWrite(CLK, LOW);
        delayMicroseconds(2);
    
        if (digitalRead(DO)){
            _byte |= (1 << i);   
        }
      }
      digitalWrite(CS, HIGH);

      return _byte; 
}

Thanks