AVR multiple sensors interfacing

Your source for all things Atmel.

Moderator: phalanx

Post Reply
szak1592
Posts: 1
Joined: Mon Nov 24, 2014 1:41 am

AVR multiple sensors interfacing

Post by szak1592 » Mon Nov 24, 2014 1:52 am

I have interfaced a single sensor and the code works, but when I try to interface two sensors at the same time, the simulation does not work at all. Please check the code and the simulation schematic in proteus and let me know what is wrong in the code. Here is the schematic snapshot
https://drive.google.com/file/d/0B0yPkU ... sp=sharing


#define F_CPU 4000000UL
#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{
DDRC = 0xff;
DDRD = 0xff;
DDRA = 0x00;

ADMUX=0x00;
//ADMUX |= 1<<REFS0 | 1<<REFS1;
ADCSRA |= 1<<ADIE;
ADCSRA |= 1<<ADEN;

sei();

ADCSRA |= 1<<ADSC;

while (1);
return 0;
}
ISR(ADC_vect)
{

uint16_t adc_value;
uint16_t adc_value_2;
switch (ADMUX) {
case (0xC0):
// ADCSRA |= (1<<(ADSC));
// while ((ADCSRA &(1<<ADIF))==0);
adc_value=ADC;

if (adc_value<512)
{
PORTC = PORTC & 0b11111110;
}
else
{
PORTC = PORTC | 0b00000001;
}
//ADMUX = 0xE1;
break;



case (0xC1):
adc_value_2=ADC;

if (adc_value<512)
{
PORTC = PORTC & 0b11111101;
}
else
{
PORTC = PORTC | 0b00000010;
}
//ADMUX = 0xE1;
break;


default:
break; }

ADCSRA |= 1<<ADSC;


}

Valen
Support Volunteer
Posts: 1715
Joined: Wed Dec 22, 2010 2:05 am

Re: AVR multiple sensors interfacing

Post by Valen » Mon Nov 24, 2014 3:57 pm

In the first place, you never change the analog multiplexer register. ADMUX stays 0x00 (whatever that means for your anonymous AVR chip.) Not all AVR chips are created equal in terms of ADC features. Afaik, most cannot do multiple simultaneous measurements, and there are differences in differential measurements and available amplifier gain settings. So it's better if you name the specific chip model that you are using so we can check the appropriate datasheet for the details. Part of the ADMUX bits are the voltage reference selection. Which I suspect is selected as the external Aref pin (with internal reference disabled) when ADMUX is 0x00. In your schematic this seems to be floating, so the ADC sample you get can be anything it seems. Like using a rubber tape-measure.

Second, you never fully set the ADCSRA (Status and control) and SFIOR (special functionIO) register. The 3 least significant bits of ADCSRA determine the clock prescaler, and so ultimately the sample rate. You keep starting new conversions that take 25 ADC clockcycles to perform (x2 CPU clock divider from the prescaler), and whatever time you need to process them in the ISR. Nothing wrong with that though. But if you use free running mode it only needs 13 ADC clock periods to do a conversion. You may need to look at this (and the following) a bit and make a reasonable choice on samplerate/clock prescaler setting to get the best out of your applied signal. What is making those LDRs fluctuate in resistance? You never mentioned that as well. Troubleshooting starts with knowing what to expect.

Third, your ISR routine is relatively long considering the previous. It should only retrieve the last ADC result and store it in a global variable. Perhaps also the last multiplexer selection so you know what pin it comes from. And then switch to another multiplexer setting before starting the next sample conversion. Leave the GPIO pin toggling and switch statement code (which can be quite computationally expensive, if-statements are much faster) for the main loop to process based on the stored sample in the global variables.

Post Reply