analogRead alternative (Part2)

Part 1, 2

Starting from the presentation of the parametric version of an alternate analogRead function, here is a lean version of the whole code. The header section of the code

/* Sampling parameters */
uint32_t _interval = 200; /* Interval between two consecutive ADC reading cycles */
uint32_t _lastTime;

Next comes the ‘setup’ routine

void setup(void)
{
	/* Initialize the ADC */
	InitADC(0);
	/* Console */
	Serial.begin(115200);
	/* Set the strating time */
	_lastTime = 0;
}

It contains the initialization parts of the ADC, console and timer. This section followed by the ‘loop’ routine

void loop(void)
{
	uint32_t _now = millis();
	/* Check elapsed time. This method handles millis overflow properly */
	if ((_now - _lastTime) >= _interval) {
		_lastTime = _now;  
		Serial.print(_now / 1000.0, 1);
		Serial.print(';');
		Serial.print(ADCRead());
		Serial.println();
	}
}

Every time the millis() is equal or more than the interval time, the loop routine prints the time (in seconds) and the raw ADC counts. And here are the two ADC related functions for acquiring analog signals in the fastest possible mode. Keep in mind that under these conditions, the output of the AnalogRead function ranges from 0 to 256 (@ 5 V)

/* Initilalize analog read in fast mode and low resolution */
uint8_t InitADC(uint8_t channel)
{
	/* Reset register contents */
	ADCSRA = 0;
	ADCSRB = 0; 
	ADMUX = 0;
	/* Set voltage reference */
	ADMUX |= (1 << REFS0); /* DEFAULT VCC, 5 V */
	/* left align ADC value to 8 bits from ADCH register */
	ADMUX |= (1 << ADLAR);
	/* Set channel */ 
	ADMUX |= channel;
	/* Set pre-scaler */
	ADCSRA |= (1 << ADPS1);
	/* Enable ADC */
	ADCSRA |= (1 << ADEN);
	/* Start first conversion */
	ADCSRA |= (1 << ADSC); 
	/* Wait for conversion */
	while (ADCSRA & (1 << ADSC));
}


/* Simple analog to digital conversion */
uint16_t ADCRead(void)
{
	/* Start conversion */
	ADCSRA |= (1 << ADSC); 
	/* Wait for conversion */
	while (ADCSRA & (1 << ADSC));
	/* Returned ADC value */
	return(ADCH);
}

Ultimately, if you really want to stick to the original analogRead format, here is the ‘advanced” ADCRead function:

/* Simple analog to digital conversion with analog channel parameter */
uint16_t ADCRead(uint8_t channel)
{
	/* Clear any lower 4 bits from the ADMUX register */
	ADMUX &= ~(0x0F)
	/* Set channel */
	ADMUX |= channel;
	/* Start conversion */
	ADCSRA |= (1 << ADSC); 
	/* Wait for conversion */
	while (ADCSRA & (1 << ADSC));
	/* Returned ADC value */
	return(ADCH);
}

 

Leave a Reply

You must be logged in to post a comment.