Multiple ADC Channels working at the same time

18 views
Skip to first unread message

bhaumikbhatt

unread,
Nov 1, 2010, 2:53:46 AM11/1/10
to openuniboard
Hi everyone!

I did the STIP - E program at Thinklabs and i am working on my project
MIDI drumkit.

I want to interface 8 external sensors (piezo's).
I successfully interfaced and 1 piezo and got satisfactory outputs
from it.

Can someone provide me with the code for reading all 8 channels at the
same time.
I searched the internet and found a code which uses the array method..
The result i obtained is giving the same conversion result in both
channels!

This is my code's example using 2 channels.. Or is it the hardware's
fault?

//---------main file----------
#include<avr/io.h>
#include<util/delay.h>
#include"LCD_mega128.h"
#include"serial.h"
#include"midi.h"
#include"adc.h"

#define PIEZOTHRESHOLD 90

unsigned static int adcValue[8]; //Array

void Port_Init(void)
{
DDRC = 0xFF; // Make port C as output port
PORTC = 0xFF; // Initial condition of LED OFF.

DDRD = 0X3F; // Make port D as input port 1st and 2nd switch //0011
1111
PORTD = 0xFF; // PULL UP THE RESISTORS.

DDRE = 0X3F; // Make port E as input port 3rd and 4th switch //0011
1111
PORTE = 0xFF; // PULL UP THE RESISTORS.
}

int main(void)
{
Port_Init();
UART_Init(MYUBRR);
lcd_init();
ADC_Init(); // enabled without free running mode

while(1)
{
adcValue[0] = ADC_read(0);

lcd_gotoxy1(1);
lcd_string("CUR0");
lcd_gotoxy2(1);
lcd_showvalue(adcValue[0]);

if(adcValue[0] >= PIEZOTHRESHOLD)
{
lcd_gotoxy1(6);
lcd_char('B');
lcd_gotoxy2(5);
lcd_showvalue(adcValue[0]);

noteOn(Bass_Drum1, 0, adcValue[0]);

PORTC = 0xFE;
}

adcValue[1] = ADC_read(1);

lcd_gotoxy1(9);
lcd_string("CUR1");
lcd_gotoxy2(9);
lcd_showvalue(adcValue[1]);

if(adcValue[1] >= PIEZOTHRESHOLD)
{
lcd_gotoxy1(14);
lcd_char('C');
lcd_gotoxy2(13);
lcd_showvalue(adcValue[1]);

noteOn(Crash_Cymbal1, 1, adcValue[1]);

PORTC = 0xFD;
}

}
}

//------------adc.h file--------

#ifndef _adc_h
#define _adc_h

#define ADC_START_CONVERSION ADCSRA |= (1<<ADSC)

unsigned static int ADC_temp, ADCr, i;

void ADC_Init(void)
{
ADMUX = 0xE0; //8 bit left-shift, channel1 default
ADCSRA = 0x87; //Only ADEN and Prescaler 128, ADIF will be set after
conversion completes
}

int ADC_read(int ADC_CHAN)
{
ADMUX |= (ADC_CHAN); // select channels 0-7

ADC_START_CONVERSION; // do single conversion

// wait for conversion done, ADIF flag active
while(!(ADCSRA & 0x10));

// do the ADC conversion 8 times for better accuracy
for(i=0;i<8;i++)
{
ADCSRA |= (1<<ADSC); // do single conversion

while(!(ADCSRA &0x10)); // wait for conversion done, ADIF flag active

ADC_temp = ADCH; // read out ADCH register

ADCr += ADC_temp; // accumulate result (8 samples) for later
averaging
}

ADCr = ADCr >> 3; // average the 8 samples

return ADCr;
}

#endif

//---end

sumit kumar

unread,
Nov 3, 2010, 6:26:19 AM11/3/10
to openun...@googlegroups.com
hey bhaumik where do u live..if u r near around delhi...then plz contact me...i did also my training from thinklab.and i am also trying to do project using avr microcontroller on embedded sysytem..if u are iterested then plz make contact with me so that we both can help each other....


Hardik Shah

unread,
Nov 3, 2010, 9:16:52 PM11/3/10
to openun...@googlegroups.com
Hi,
 There is a mistake in your program, first you will need to mask off all the channel bits in ADMUX register and than load the new channel selection bits.
ADMUX &= 0xE0;
ADMUX |= ADC_CHAN;
 
The conversion rate of adc is in usec so you can store the results of all the adc and process it accordingly. 


 

Bhaumik Bhatt

unread,
Nov 3, 2010, 2:57:02 PM11/3/10
to openun...@googlegroups.com
hey no.. i stay in mumbai .. tell me about ur project.. ill help in any way i can..

Bhaumik Bhatt

unread,
Nov 4, 2010, 10:28:19 AM11/4/10
to openun...@googlegroups.com
Thanks! i did that too.. Got some help from AVRFreaks here: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=99676

So, i did this, but not 0xE0: 

ADMUX &= 0xF8; // clear existing selection 

Also, my values from different channels affect each other!
I experimented with the internal sensors.. increased the threshold to 150 (since, decimal value of the origin on x-axis is 130 approx.) and gave sufficient light to the LDR (approx. value 20). 

Now, i increased the value on channel0 (LDR) by keeping my thumb on it.. It also increased the value on channel 1 and triggered the MIDI messages/LED's on both..

But when the value on channel 1 was increased, it did affect the channel 0 value but did not trigger the MIDI message or LED since it could not reach a higher value than 45! 

So, basically my values on different channels affect each other.. What should i do? I am going to make 8 drumpads with piezos in them

Bhaumik Bhatt

unread,
Nov 4, 2010, 11:45:39 AM11/4/10
to openun...@googlegroups.com
WOOHOOO!! It's working now! Yeah \m/... I removed the part where it calculates the average of 8 ADC samples "for better accuracy"

bhaumikbhatt

unread,
Nov 4, 2010, 11:36:55 AM11/4/10
to openuniboard
Thanks! i did that too.. Got some help from AVRFreaks here:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=99676

So, i did this, but not 0xE0:

ADMUX &= 0xF8; // clear existing selection

Also, my values from different channels affect each other.. This
problem persists!
I experimented with the internal sensors.. increased the threshold to
150 (since, decimal value of the origin on x-axis is 130 approx.) and
gave sufficient light to the LDR (approx. value 20).

Now, i increased the value on channel0 (LDR) by keeping my thumb on
it.. It also increased the value on channel 1 and triggered the MIDI
messages/LED's on both..

But when the value on channel 1 was increased, it did affect the
channel 0 value but did not trigger the MIDI message or LED since it
could not reach a higher value than 45!

So, basically my values on different channels affect each other.. What
should i do? I am going to make 8 drumpads with piezos in them.

On Nov 4, 6:16 am, Hardik Shah <imhardiks...@gmail.com> wrote:
> Hi,
>  There is a mistake in your program, first you will need to mask off all the
> channel bits in ADMUX register and than load the new channel selection bits.
> ADMUX &= 0xE0;
> ADMUX |= ADC_CHAN;
>
> The conversion rate of adc is in usec so you can store the results of all
> the adc and process it accordingly.
>
> On Mon, Nov 1, 2010 at 12:23 PM, bhaumikbhatt
> <bhaumikbhatt.nm...@gmail.com>wrote:

Hardik Shah

unread,
Nov 5, 2010, 10:54:06 AM11/5/10
to openun...@googlegroups.com
hey, if you are using atmega128 than you need to mask ADMUX with 0xE0 and than OR with channel bits,
 
congrats.
Reply all
Reply to author
Forward
0 new messages