ADC Programming Registers

My goal is to create a personal ADC converter function through Arduino. My goal is to use a potentiometer and have a continuously stream of analog read to print in the serial port. I'm fairly new with register programming so my question is can i just add the ADC function in main or do i have to make a separate .h file?

My project consist of using ADC and keep getting a input value from A0 continuously.

My goal is to register program ADC rather than using the built in adc function.
// DATA Acquistion

void ACD_init(){
ADMUX = (1<<REFS0);
ADCSRA |= (1 << ADEN) | (1 << ADSC)| (1 << ADATE);
ADCSRB = 0x00;
}

uint16_t adc_read(uint8_t ch)
{
// select the corresponding channel 0~7
// ANDing with ’7′ will always keep the value
// of ‘ch’ between 0 and 7
//ch &= 0b00000111; // AND operation with 7
// ADMUX = (ADMUX & 0xF8)|ch; // clears the bottom 3 bits before ORing

// start single convertion
// write ’1′ to ADSC
ADCSRA |= (1<<ADSC);

// wait for conversion to complete
// ADSC becomes ’0′ again
// till then, run loop continuously
while(ADCSRA & (1<<ADSC));
ADC = (ADCL |(ADCH << 8));

return (ADC);
}

void setup() {
Serial.begin(9600);

}

void loop() {

int sensorValue = adc_read(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(1); // delay in between reads for stability

}

I tried with a ponentialmeter and built in anologread and it works. But with mines, it just outputs 1023 the whole time. I have ponentialmeter hooked up to ground 5v and A0. Any help is greatly appreciated. Thank you

.

My goal is to use a potentiometer and have a continuously stream of analog read to print in the serial port.

This does not sound like a well thought out goal. The ADC returns a value based on how long it takes the (constant or varying) input to charge a capacitor. That is a discrete event, not a continuity. You then want to sent the value to the serial port. That is a discrete event, not a continuity.

The time it takes to output the text to the serial port, at the stupidly slow speed you are using, is orders of magnitude longer than the time you are trying to save by not using the standard analogRead() function.

So, I really have to wonder what you are REALLY trying to accomplish.

@OP

The following mistakes are found in your program, and these are corrected; the program is tested and found working.

1. You have not initialized the ADC by calling the function ACD_init() from the Setup().

2. Auto-triggering Mode should be OFF.; ADSC (ADC Start Control) should be OFF initially.

3. Data type of sensorValue variable should be unsigned int (uint16_t).

4. Sampling time is too fast -- 1 ms. Does environmental variable change so fast?

5. The Sketch should have the following organizational hierarchy (though not strictly needed).
Global Space
Setup Function Space
Loop Function Space
User Function Space

6. The corrected Program.

void setup()
{
  Serial.begin(9600);
  ACD_init();
}

void loop()
{
  uint16_t sensorValue = adc_read(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1000);        // delay in between reads for stability
}

void ACD_init()
{
  ADMUX = (1 << REFS0); //default Ch-0; Vref = 5V
  ADCSRA |= (1 << ADEN) | (0 << ADSC) | (0 << ADATE); //auto-trigger OFF
  ADCSRB = 0x00;
}

uint16_t adc_read(uint8_t ch)
{
  // select the corresponding channel 0~7
  // ANDing with '7′ will always keep the value
  // of 'ch' between 0 and 7
  //ch &= 0b00000111;  // AND operation with 7
  // ADMUX = (ADMUX & 0xF8)|ch; // clears the bottom 3 bits before ORing

  // start single convertion
  // write '1′ to ADSC
  ADCSRA |= (1 << ADSC);

  // wait for conversion to complete
  // ADSC becomes '0′ again
  // till then, run loop continuously
  while (ADCSRA & (1 << ADSC));
  ADC = (ADCL | (ADCH << 8));
  return (ADC);
}
1 Like

PaulS:
The ADC returns a value based on how long it takes the (constant or varying) input to charge a capacitor.

That would be a dual-slope converter, not a successive approximation converter, which uses a DAC and a comparator.

AWOL:
That would be a dual-slope converter, not a successive approximation converter, which uses a DAC and a comparator.

And I was a CAD for not recognizing the difference.

GolamMostafa has already mentioned your problems with ADSC and ADATE. Here's another:

What value do you think the ADC Prescaler is set to? The ADC clock needs to be within a certain range for optimum accuracy. Is your clock within that range?

Also, use code tags!

Jiggy-Ninja:
GolamMostafa has already mentioned your problems with ADSC and ADATE. Here's another:

What value do you think the ADC Prescaler is set to? The ADC clock needs to be within a certain range for optimum accuracy. Is your clock within that range?

Also, use code tags!

@OP

For your information, the optimum ADC's Conversion Clock (clkADC) frequency is 125 kHz. The source frequency (clkSYS) is 16 MHz. You need to divide clkSYS with a suitable prescaler with the help of ADPS[2:0] bits of ADCSRA Register. The default value is ADPS[2:0 = 0, 0, 0] that divides the clkSYS by 2 factor, and it gives clkADC = 8 MHz -- too HIGH. So, please add appropriate values to the ADCSRA Register for clkADC = 125 kHz. (ADPS[2:0] = 000(1/2); 001(1/2); 010(1/4); 011(1/8); 100(1/16); 101(1/32); 110(1/64); 111(1/128))

Thanks to @Jiggy-Ninja with K+ for the fantastic catch.