Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me fix errors of an ADC code

Status
Not open for further replies.

justinjohney

Member level 1
Joined
Jun 11, 2012
Messages
33
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,584
Code:
#include <avr/io.h> 
#include <avr/interrupt.h>
#include <util/delay.h>

int adc_result=0;
int ch=0;

int main (void) 
{ 
//set portC as input and enable the pull up resistor 
DDRC=0x00;
PORTC=0xFF;

//set up port D 0-5  as output& C 6,7 as input
DDRD=0x3F;

// Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz 
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);


// Set ADC to Free-Running Mode 
ADCSRB &=~((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0)) ;  
  
// Enable ADC 
ADCSRA |= (1 << ADEN);  
// Enable ADC Interrupt
//ADCSRA |= (1 << ADIE);  
   
// Enable Global Interrupts 
 //sei();  


  
   
// Loop Forever 
 	while(1)

 		{ 
		// Set ADC reference to AREF
		// Left adjust ADC result to allow easy 10 bit reading
		//select adc channel 1
		ADMUX=0x00;

			for(ch=0;ch<3;ch++)
			 {
		    	// Start A2D Conversions 
			   ADCSRA |= (1 << ADSC);
		
			   //Read the adc result
			   adc_result=ADCW;
		       	_delay_ms(10);
			
				if(adc_result>970)
				{
					if(ch==0)
					{
						PORTD1=1;
						_delay_ms(50);

							if(adc_result>970)
								{
									PORTB4=1;
								}
					}

					else if(ch==1)
					{

						PORTD2=1;
						_delay_ms(50);
							if(adc_result>970)
								{
									PORTB4=1;
								}
					}
					else(ch==2)
					{
						PORTD2=1;
						_delay_ms(50);
							if(adc_result>970)
								{
									PORTB4=1;
								}


				}
				ADMUX++;
			}

	}
	 
}
im using avr studio 4 avr gcc compiler
atmega168
 

Re: adc code shows error

What AVR model are you working with?

AVR Studio 4, GCC compiler
Code:
What do you expect to happen?

actually i want to convert three analog signal into digtal simultaneously(with max speed) and compare it with threashold and if any one it is greater than the threashold then a led must glow corresponding to that signal.Moreover if the condition stable for a particular time then there must be get an o/p on a port pin at a particular pin.
Code:

What problem(s) are you encountering?


build error,i know the code is not completed



i think now you got it. can you help me?[/code]
 

code shows error in avr studio

the following code shows error in avr studio, avr gcc compiler.




Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#include <avr/io.h>
#include <stdio.h>  
#include <avr/interrupt.h>
#include <util/delay.h>
 
//system clock @16MHz
#define F_CPU 16000000 
 
 
//Global variable 
int adc_result[2]={0,0,0};
uint8_t ch=0;
 
 
/* PORT INIT */
void port_init (void) 
{
//set portB.1 as output
DDRB |=(1<<PB1);
PORTB&=~(1<<PB1);
 
//set portC0,1,2, as input and enable the pull up resistor 
DDRC &=~(1<<PC0)|~(1<<PC1)|~(1<<PC2);
PORTC |=(1<<PC0)|(1<<PC1)|(1<<PC2);
 
//set up port D 0-2  as output& D6,7 as input with pull up resistor 
DDRD &=~(1<<PC0)|~(1<<PC1)|~(1<<PC2);
DDRD &=~(1<<PD6)|~(1<<PD7);
PORTD |=(1<<PD6)|(1<<PD6);
 
}
 
 
void init_adc(void)
{
// Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz 
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
 
 
// Set ADC to Free-Running Mode 
//ADCSRB &=~((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0)) ; 
 
//select adc channel 0
//ADMUX=ch; 
 
// Enable ADC Interrupt
ADCSRA |= (1 << ADIE);  
 
// Enable ADC
ADCSRA |= (1 << ADEN);  
 
 
// Enable Global Interrupts 
sei();
 
//Start first conversion 
ADCSRA |= (1<<ADSC);
}
 
 
 
/* Interrupt service routines */ 
 
ISR(ADC_vect)
{
 
//delay  for discarding first conversion result
//_delay_ms(10);
//Read the adc result
    switch(ch)
    {
        case 0:
            {
            
            adc_result[0]=ADCW;
            
            if(adc_result[0]>862)
                {
 
                    do
                    {
                    PORTD|=(1<<PD0);//glow the led corresponding to signal 1
                    //Start next  conversion with same channel
                    _delay_ms(3);
                    ADCSRA |= (1<<ADSC);
                    adc_result[0]=ADCW;
                        if(adc_result[0]>887)
                        {
                            do
                            {
                            ADCSRA |= (1<<ADSC);
                            adc_result[0]=ADCW;
                            PORTB|=(1<<PB0);//  o/p drive if the state at adc0 exist for a particular time      
                            }while (adc_result[0]<970)
                        }   
                    }while(adc_result[0]<862)
 
                }
 
            else if (adc_result[0]<754)
                {
                PORTD|=(1<<PD3);//glow the led corresponding to UV indication
                }
            else
                {
                    if(ch<3)
                    {
 
                        ch++;
                        ADMUX=ch;
                    }
                    else
                    {
                        ch=0;
                        ADMUX=ch;
                    }
                }
            break;
            }
 
        case 1:
            {
            adc_result[1]=ADCW;
        
            if(adc_result[1]>862)
                {
 
                    do
                    {
                    PORTD|=(1<<PD1);//glow the led corresponding to signal 2
                    //Start next  conversion with same channel
                    _delay_ms(3);
                    ADCSRA |= (1<<ADSC);
                    adc_result[0]=ADCW;
                        if(adc_result[0]>887)
                        {
                            do
                            {
                            ADCSRA |= (1<<ADSC);
                            adc_result[0]=ADCW;
                            PORTB|=(1<<PB0);//  o/p drive if the state at adc1 exist for a particular time      
                            }while (adc_result[1]<862)
                        }
                    }while(adc_result[1]<862)
 
                }
            else if(adc_result[1]<754)
                {
                PORTD|=(1<<PD3);//glow the led corresponding to UV indication
                }
            else
                {
                    if(ch<2)
                    {
                        ch++;
                        ADMUX=ch;
                    }
                    else
                    {
                        ch=0;
                        ADMUX=ch;
                    }
                }
            break;
            }
 
        case 2:
            {
            adc_result[2]=ADCW;
            //Start next  conversion 
            ADCSRA |= (1<<ADSC);
            if(adc_result[2]>862)
                {
 
                    do
                    {
                    PORTD|=(1<<PD2);//glow the led corresponding to signal 3
                    //Start next  conversion with same channel
                    _delay_ms(3);
                    ADCSRA |= (1<<ADSC);
                    adc_result[0]=ADCW;
                    if(adc_result[2]>887)
                        {
                            do
                            {
                            ADCSRA |= (1<<ADSC);
                            adc_result[0]=ADCW;
                            PORTB|=(1<<PB0);//  o/p drive if the state at adc2 exist for a particular time      
                            }while (adc_result[2]<862)
                        }
                    }while(adc_result[2]<862)
 
                }
            else if(adc_result[2]<754)
                {
                PORTD|=(1<<PD3);//glow the led corresponding to UV indication
                }
            else
                {
                    if(ch<3)
                    {
                        ch++;
                        ADMUX=ch;
                    }
                    else
                    {
                        ch=0;
                        ADMUX=ch;
                    }
                }
            break;
            }
    }
}
 
 
void main() 
{ 
 
    port_init();
 
    
 
// Loop Forever 
    while(1)
 
        { 
        ADMUX=ch; 
        init_adc();
        
        }           
}

 

Re: code shows error in avr studio

What kind of error?

Code:
int adc_result[2]={0,0,0};
You can 't declare an array of two integers and assign three values

- - - Updated - - -

I don't think that code like the following can work
Code:
DDRC &= ~(1 << PC0) | ~(1 << PC1) | ~(1 << PC2);

This is basically

Code:
DDRC = DDRC & (0b11111110 | 0b11111101 | 0b11111011);

But 
(0b11111110 | 0b11111101 | 0b11111011) = 0b11111111 so the above will not have any result

What would make sense is
DDRC &=  ~( (1 << PC0) | (1 << PC1) | (1 << PC2) );

The same goes for DDRD
 

Re: adc code shows error

this is applied in a ATmega2560, and this for unit conversions in this case the upper channels are enabled, if you please do it as self CONVERTION or via IRQ, you can manipulate it within the scope of the IRQ


Code:
TEM4 = Select_chanel (13);



Code:
[INDENT]extern int CHANEL_ADC;

void set_Adac (void)
  {

PRR0 |= (1<<PRADC);                               // power down module adc
PRR0 &= ~(1<<PRADC);                              // power up module adc
ADCSRA |= ((1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0)); // Set ADC prescaler speed 
ADMUX  |=  (1<<REFS0) | (0<<REFS1);               // Set ADC referencia
ADCSRB &=  (0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);      
DIDR0 |= ((1<<ADC7D) | (1<<ADC6D) | (1<<ADC5D) | (1<<ADC4D) | (1<<ADC3D) | (1<<ADC2D) | (1<<ADC1D)| (1<<ADC0D)); // Habilitacion de canal
DIDR2 |=  ((0<<ADC15D) | (0<<ADC14D) | (0<<ADC13D) | (0<<ADC12D) | (0<<ADC11D) | (0<<ADC10D) | (0<<ADC9D) | (0<<ADC8D)); // Habilitacion de canal
// ADCSRA |= (1<<ADATE); // AUTO TRIGER
// ADCSRA &= ~(1<<ADIE); // Enable ADC Interrupt
ADCSRA |= (1<<ADEN);    // Enable ADC
// ADCSRA |= (1<<ADSC);  // Start A2D Conversions
}

int Select_chanel (char chanel)
{ 
   
	ADMUX  &= 0x11100000 ;
	if (chanel <= 7)
	{
    	    ADCSRB &= ~(1<<MUX5);
	    ADMUX |=  chanel;
	}
	if (chanel >= 8)
	{
	    ADMUX  |= chanel - 8 ;
	    ADCSRB |= (1<<MUX5);
	}
	
	ADCSRA |= (1<<ADIF);
	ADCSRA |= (1<<ADSC);  // Start A2D Conversions
    while (!(ADCSRA & (1<<ADIF)));

	
     uint16_t ADC_rslt = (ADCL);
     ADC_rslt += (ADCH << 8);      // for all 10 bits 
     return ADC_rslt;
}[/INDENT]
 

Re: adc code shows error

The do - while loops are missing semi colons. this is basically what you need to build.

do {

} while ( condition );
 

Re: adc code shows error

how can i make my system clock into 16MHz in atnega168?
 

Re: adc code shows error

code shows error again
avr studio 4
avr gcc compiler



Code:
#include <avr/io.h> 
#include <stdio.h>  
#include <avr/interrupt.h> 
#include <util/delay.h> 

//system clock @1MHz 
#define F_CPU 1000000 


//Global variable 
int adc_result[3]={0,0,0};//for storing the adc out put 
uint8_t ch=0; 


/* PORT INIT */ 
void port_init (void) 
{ 
//set portB.1 as output drive for relay 
DDRB |=(1<<PB1); 
PORTB&=~(1<<PB1); 

//set portC0-4 as input and enable the pull up resistor 
DDRC &=~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));// ADC i/p R,B,Y & Gnd, neutral 
PORTC |=((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)); 

//set up port D 0-3  as output 
DDRD &=~((1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3));//o/p led for R,B,Y and GLP 
} 


void init_adc(void) 
{ 
// Set ADC prescaler to 8 - 125KHz sample rate @ 1MHz 
ADCSRA |= ((1 << ADPS1) | (1 << ADPS0)); 

// Enable ADC Interrupt 
ADCSRA |= (1 << ADIE);  

// Enable ADC 
ADCSRA |= (1 << ADEN);  

// Enable Global Interrupts 
sei(); 

ADCSRA |= (1<<ADSC); 

} 




/* Interrupt service routine for Analog comparator*/ 
ISR(ANA_COMP) 
{ 

} 





/* Interrupt service routines */ 

ISR(ADC_vect) 
{ 

//delay  for discarding first conversion result 
//_delay_ms(10); 
//Read the adc result 
   switch(ch) 
   { 
      case 0: 
         { 
                
         adc_result[0]=ADCW; 
          
         if(adc_result[0]>823) //checking for vge >265V 
            { 

               do 
               { 
               PORTD|=(1<<PD0);//glow the led corresponding to signal 1 
               _delay_ms(3); 
               //Start next  conversion with same channel 
               ADCSRA |= (1<<ADSC); 
               //wait for coversion to be completed 
               while (!(ADCSRA & (1<<ADIF))); 
               adc_result[0]=ADCW; 
                  if(adc_result[0]>837) //checking for vge >270V 
                  { 
                     do 
                     { 
                     ADCSRA |= (1<<ADSC); 
                     //wait for coversion to be completed 
                     while (!(ADCSRA & (1<<ADIF))); 
                     adc_result[0]=ADCW; 
                     PORTB|=(1<<PB1);//  o/p drive ON if the state at adc0 exist for a particular time       
                     }while (adc_result[0]<823);//do until the vge reduced to 265V 
                  }    
               }while(adc_result[0]>823); 
               PORTD&=~(1<<PD0);//off the led corresponding to signal 1 
               PORTB&=~(1<<PB1);// o/p drive off for ON the relay 

            } 

         else if (adc_result[0]<713)//checking for vge <230V
            { 
               do 
               { 

                  PORTD|=(1<<PD3);//glow the led corresponding to UV indication 
                  ADCSRA |= (1<<ADSC); 
                  //wait for coversion to be completed 
                  while (!(ADCSRA & (1<<ADIF))); 
                  adc_result[0]=ADCW; 
               }while(adc_result[0]<713);//do until vge >230V 
               PORTD&=~(1<<PD3);//off the led corresponding to UV indication 
            } 
         else 
            { 
               if(ch<3) 
               { 

                  ch++;//change adc channel 
                  ADMUX=ch; 
               }    
            } 
         break; 
         } 

      case 1: 
         { 
         adc_result[1]=ADCW; 
       
         if(adc_result[1]>823)//checking for vge >265V 
            { 

               do 
               { 
               PORTD|=(1<<PD1);//glow the led corresponding to signal 2 
               //Start next  conversion with same channel 
               _delay_ms(3); 
               ADCSRA |= (1<<ADSC); 
               //wait for coversion to be completed 
               while (!(ADCSRA & (1<<ADIF))); 
               adc_result[0]=ADCW; 
                  if(adc_result[0]>837) //checking for vge >270V 
                  { 
                     do 
                     { 
                     ADCSRA |= (1<<ADSC); 
                     //wait for coversion to be completed 
                     while (!(ADCSRA & (1<<ADIF))); 
                     adc_result[0]=ADCW; 
                     PORTB|=(1<<PB1);//  o/p drive if the state at adc1 exist for a particular time       
                     }while (adc_result[1]>862); 
                  } 
               }while(adc_result[1]>823); 
               PORTD|=(1<<PD1);//off the led corresponding to signal 2 
               PORTB&=~(1<<PB1);// o/p drive off for ON the relay 
            } 
         else if(adc_result[1]<713)//checking for vge <230V 
            { 
               do    
                  { 

                  PORTD|=(1<<PD3);//glow the led corresponding to UV indication 
                  ADCSRA |= (1<<ADSC); 
                  //wait for coversion to be completed 
                  while (!(ADCSRA & (1<<ADIF))); 
                  adc_result[0]=ADCW; 
                  }while(adc_result[0]<713);//do until vge >230V 
                  PORTD&=~(1<<PD3);//off the led corresponding to UV indication 
            } 
         else 
            { 
               if(ch<3) 
               { 
                  ch++; 
                  ADMUX=ch; 
               } 
            } 
         break; 
         } 

      case 2: 
         { 
         adc_result[2]=ADCW; 
         //Start next  conversion 
         ADCSRA |= (1<<ADSC); 
         if(adc_result[2]>862)//checking for vge >265V 
            { 

               do 
               { 
               PORTD|=(1<<PD2);//glow the led corresponding to signal 3 
               //Start next  conversion with same channel 
               _delay_ms(3); 
               ADCSRA |= (1<<ADSC); 
               //wait for coversion to be completed 
               while (!(ADCSRA & (1<<ADIF))); 
               adc_result[0]=ADCW; 
               if(adc_result[2]>837) //checking for vge >270V 
                  { 
                     do 
                     { 
                     ADCSRA |= (1<<ADSC); 
                     //wait for coversion to be completed 
                     while (!(ADCSRA & (1<<ADIF))); 
                     adc_result[0]=ADCW; 
                     PORTB|=(1<<PB1);//  o/p drive if the state at adc2 exist for a particular time       
                     }while (adc_result[2]<862); 
                  } 
               }while(adc_result[2]<862); 
               PORTD|=(1<<PD2);//glow the led corresponding to signal 3 
               PORTB&=~(1<<PB1);// o/p drive off for ON the relay 

            } 
         else if(adc_result[2]<713)//checking for vge <230V 
            { 
               do    
                  { 

                  PORTD|=(1<<PD3);//glow the led corresponding to UV indication 
                  ADCSRA |= (1<<ADSC); 
                  //wait for coversion to be completed 
                  while (!(ADCSRA & (1<<ADIF))); 
                  adc_result[0]=ADCW; 
                  }while(adc_result[0]<713); 
                  PORTD&=~(1<<PD3);//off the led corresponding to UV indication 
            } 
         else 
            { 
               if(ch<3) 
               { 
                  ch++; 
                  ADMUX=ch; 
               }    
            } 
         break; 
         } 


// GLP 
      case 3: 
         { 
            adc_result[3]=ADCW; 
            ADMUX=0x04;//select adc 4 
            //Start next  conversion 
            ADCSRA |= (1<<ADSC); 
            //wait for coversion to be completed 
            while (!(ADCSRA & (1<<ADIF))); 
            adc_result[4]=ADCW; 
               if((adc_result[3]-adc_result[4])>31) 
               { 
                  PORTD|=(1<<PD3);//ON the led corresponding to GLP indication 
                  do 
                  { 
                     ADMUX=0x03;//select adc 3 
                     //Start next  conversion 
                     ADCSRA |= (1<<ADSC); 
                     //wait for coversion to be completed 
                     while (!(ADCSRA & (1<<ADIF))); 
                     adc_result[3]=ADCW; 
                     ADMUX=0x04;//select adc 4 
                     //Start next  conversion 
                     ADCSRA |= (1<<ADSC); 
                     //wait for coversion to be completed 
                     while (!(ADCSRA & (1<<ADIF))); 
                     adc_result[4]=ADCW; 
                        if((adc_result[3]-adc_result[4])>38)
                        { 
                           PORTB|=(1<<PB1);// o/p drive 
                        } 

                  }while((adc_result[3]-adc_result[4])>31); 

                  PORTD&=~(1<<PD3);//OFF the led corresponding to GLP indication 
                  PORTB&=~(1<<PB1);// off the  o/p drive 
               }    

         } 

  



} 


int main(void) 
{ 
    
    
   port_init(); 
   //discarding the first adc result 
   ADCSRA |= (1<<ADSC); 
   //wait for coversion to be completed 
   while (!(ADCSRA & (1<<ADIF))); 
   ADMUX=ch; 

// Loop Forever 
    while(1) 

       { 
      init_adc(); 
      }          
}
 
Last edited:

Re: adc code shows error

looking at your code there are some oddities that do not understand.

for example in the code main () {} put in a loop while (), init adac, this does not make much sense, once you tell the ADC that resolves their just right through the interruption is not necessary that put inside the loop, the while loop should be empty.
Another detailed discussion, is that the service interruptions ADC put some time delays that exceed the timing of the ADC. I think you should do this out of the ADC service, perhaps with a timer loop checking the results on the response time to pretend, so you would have two elements in the program running freely

and on the other hand you say that the compiler gives or indicates errors, why not also posts the error to see what or what is the response you get from the compiler
 

Re: adc code shows error

Hello!

Some remarks: (including a summary of what has been said above)
- Please provide a full description of your errors (compiler's error code, error string, error line number, etc...)
- Don't change subject. After your first error report, you write suddenly "how can i make my system clock into
16MHz in atnega168?", and we don't know if the first problem has been solved or not...
- Looking at your code, you use a lot of hard-coded values. For example the number 823 happens 5 times.
what happens if the value is wrong? You correct it. But you have to correct it at 5 places. Why not defining it
like this : #define ADCVAL_265 823, and then use ADCVAL_265 in your code instead of 823. If the value is
wrong, you can correct it only once in the define statement.
- Looking at your code again, you have a huge ISR function with a switch on the channel number. But for all your
channel cases, you do the same processing. For example you write:

Code:
switch(ch) {
case [COLOR="#FF0000"]0:[/COLOR]
adc_result[[COLOR="#FF0000"]0[/COLOR]]=ADCW; 
....

case [COLOR="#FF0000"]1[/COLOR]:
adc_result[[COLOR="#FF0000"]1[/COLOR]]=ADCW; 
....

case [COLOR="#FF0000"]2[/COLOR]:
adc_result[[COLOR="#FF0000"]2[/COLOR]]=ADCW; 
....

case [COLOR="#FF0000"]3[/COLOR]:
adc_result[[COLOR="#FF0000"]3[/COLOR]]=ADCW;
....
}

This can be factorized as :
Code:
adc_result[ch] = ADCW;
switch(ch) {
case 0:
... code specific to case 0
case 1:
...code specific to case 1
case 2:
...code specific to case 2
case 3:
...code specific to case 3
}

Then this part is very recurrent:

Code:
             ADCSRA |= (1<<ADSC); 
               //wait for coversion to be completed 
               while (!(ADCSRA & (1<<ADIF))); 
               adc_result[0]=ADCW;

I think you could factorize even further and end up in a half-page efficient code.

- Last, but no least, you may consider to say "hello", "please", "thank you" to people who reply, etc...

Dora.
 

Re: adc code shows error

thanx Mr. doraemon

here is my new code. can u predict its behaviour




Code:
#include <avr/io.h>
#include <stdio.h>  
#include <avr/interrupt.h>
#include <util/delay.h>

//#define F_CPU 1000000 //system clock @1MHz

//Global variable 
int adc_result[5]={0,0,0,0,0};//for storing the adc out put
uint8_t ch=0;
uint8_t y=0;
uint8_t i=0;
int k=0;

/* PORT INIT */
void port_init (void) 
{
DDRB |=(1<<PB1);//set portB.1 as output drive for relay
PORTB&=~(1<<PB1);//initially set 0 as o/p drive
DDRB |=(1<<PB0);//error occur

//set portC0-4 as i/p with pull up resistor 
DDRC &=~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));// ADC i/p R,B,Y & Gnd, neutral
PORTC |=((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));

//set up port D 0-4  as output
DDRD &=~((1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4));//o/p led for R,B,Y and GLP
}

void init_adc(void)
{
ADCSRA |= ((1 << ADPS1) | (1 << ADPS0));// Set ADC prescaler to 8 - 125KHz sample rate @ 1MHz 
ADCSRA |= (1 << ADEN);  // Enable ADC
ADCSRA |= (1 << ADIE); // Enable ADC Interrupt
ADCSRA |= (1<<ADSC);//start conversion
while (!(ADCSRA & (1<<ADIF)));//wait for coversion to be completed

}

void init_glp(void)
{
	i=ch;
	ADMUX=ch;
	init_adc();
	adc_result[i]=ADCW;
}



int main(void) 
{ 
	i=ch;
	port_init();
	ADMUX=ch;
	init_adc();
	ADCSRA |= (1<<ADSC);//discarding the first adc result
	
// Loop Forever 
 	while(1)
 		{ 
			ch=0;
			init_adc();
			if(ch<3)
			{
				for(ch=0;ch<3;ch++)
					{	
						ADMUX=ch;
						init_adc();
						adc_result[i]=ADCW;
						if (adc_result[i]>795)//checking for 265V
						{
							PORTD=y;//OV indication led on
							_delay_ms(1);
							init_adc();
							adc_result[i]=ADCW;
								if(adc_result[i]>810)//checking for 270V
								{
									do
									{
										PORTB|=(1<<PB1); //  o/p drive ON
										init_adc();
										_delay_ms(1);
										adc_result[i]=ADCW;
									}while(adc_result[i]>795);
									PORTD=0x00;//off the OV indicator led 
									PORTB&=~(1<<PB1);// o/p drive off 
								}
						}
						else if(adc_result[i]<690)//checking for 230V
							{
								do
								{
									PORTD|=(1<<PD3);// on the led corresponding to UV indication
									init_adc();
									adc_result[i]=ADCW;
								}while(adc_result[i]<690);//checking for 230V
							}
						y++;
					}
					y=0;
				}	
			else if((2<ch)&&(ch<5))
			{
				ch=3;
				init_glp();
				ch++;
				init_glp();
				k=(adc_result[4]-adc_result[3]);
				if(k>30)//checking for 230V
				{
					PORTD|=(1<<PD4);//ON the led corresponding to GLP indication
					_delay_ms(1);
					ch=3;
					init_glp();
					ch++;
					init_glp();
					k=(adc_result[4]-adc_result[3]);
					if(k>45)//checking for 15V difference
					{
						do
						{
							PORTB|=(1<<PB1); //  o/p drive ON
							ch=3;
							init_glp();
							ch++;
							init_glp();
							k=(adc_result[4]-adc_result[3]);
						}while(k>30);//checking for 15V difference
						PORTB&=~(1<<PB1);// o/p drive off 
						PORTD&=~(1<<PD4);//OFF the led corresponding to GLP indication
					}
				
				}
			}
			else
			{
				PORTB|=(1<<PB0);
			}
		}
}
 

Re: adc code shows error

Hello!

Some other remarks:

- Usually you initialize ADC at the beginning of the program and never touch it again (except if you have to
change ADC sampling characteristics). In your program you repeatedly calls it in a loop, which makes absolutely
no sense. For example, you call port_init only once, which is the right thing to do. Why do you repeatedly
call the ADC initialization?
- Apparently your initialization actually makes a conversation. An initialization should only initialize. I would
keep the 3 first lines of the init and use the two last lines in a function like this:
Code:
uint16 Convert(void) {
	ADCSRA |= (1<<ADSC);//start conversion
	while (!(ADCSRA & (1<<ADIF)));//wait for coversion to be completed
	return ADCW;
}
NB: I don't know AVR, so it may not be uint16 but another type. Adjust to the right type.
- I don't know anything about AVR, but apparently you setup interrupts (line 3 of your init_adc function). But
you don't define an interrupt routine.
- I don't understand this part:

Code:
		if(ch<3) {
			for(ch=0;ch<3;ch++) {
Usually you don't iterate on a variable you have just tested. Maybe it works, but you may end up making
action that you don't want in this part of the program.

Could you explain in plain english what you are planning to do?
I understand that you are measuring a voltage and that you want to take actions according to he voltage
but I don't see clearly what it should do. But looking at the redundancies, I'm almost sure that the core can
be done in a readable way with a smaller code.

Could you accurately and in plain english describe what you want to do?

Dora.
 

Re: adc code shows error

Mr. doraemon ,
i have 5 ac signal which must be contineously checked , The first 3 signal need to be checked for undervoltage and over voltage. if a signal above a threshold1 then an OV indicator must glow. if the OV indicator glow,Again we checked that signal with a threshold2 which is higher than threashold1. if that is true i need an out put in PB1 until the voltage reduces below threashold1.
if the signal is not greater than threshold1, then it must test fo.r under voltage threahold3.if our signal under than threshold3 then UV indicator glow and again it checked for threshold 4 (Remember, threshold4<threshold 3)and if that is true then i need a o/p at PB1.
if our signal not in the range of above 2 situation then the channel must change and check these condition for other 2 signals.
if all is correct then i want to compare my 4th and 5th signal each other and if the difference b/w that two signal > threshold 5 and an indication will glow and check again for threshold 6 and if it is greater than threshold 6 then i want an o/p at PB1 until the diference go under threashold7.

all these process repeated .
my updated code is here:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
fine F_CPU 1000000UL //system clock @1MHz
 
 
#include <avr/io.h>
#include <stdio.h>  
#include <avr/interrupt.h>
#include <util/delay.h>
 
 
//Global variable 
uint16_t adc_result[5]={0,0,0,0,0};//for storing the adc out put
uint8_t ch=0;
uint8_t y=0;
uint8_t i=0;
int k=0;
 
/* PORT INIT */
void port_init (void) 
{
DDRB |=(1<<PB1);//set portB.1 as output drive for relay
PORTB&=~(1<<PB1);//initially set 0 as o/p drive
DDRB |=(1<<PB0);//error occur pin
 
//set portC0-4 as i/p with pull up resistor 
DDRC &=~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));// ADC i/p R,B,Y & Gnd, neutral
PORTC |=((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));
 
//set up port D 0-4  as output
DDRD &=~((1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4));//o/p led for OV,UV and GLP
}
 
void init_adc(void)
{
    ADCSRA |= ((1 << ADPS1) | (1 << ADPS0));// Set ADC prescaler to 8 - 125KHz sample rate @ 1MHz 
    ADCSRA |= (1 << ADEN);  // Enable ADC
}
 
void read_adc(void)
{
    _delay_ms(1);
    ADCSRA |= (1<<ADSC);//start conversion 
    while ((ADCSRA & (1<<ADSC)));//wait for coversion to be completed 
    adc_result[i]=ADCW; 
}
 
void init_glp(void)
{
    i=ch;
    ADMUX=ch;
    read_adc();
    adc_result[i]=ADCW;
}
void glp(void)
{
    init_glp();
    ch++;
    init_glp();
    k=(adc_result[4]-adc_result[3]);
}
 
 
 
int main(void) 
{ 
    i=ch;
    port_init();
    ADMUX=ch;
    init_adc();
    read_adc();
    
// Loop Forever 
    while(1)
        { 
            ch=0;
            if(ch<3)
            {
                for(ch=0;ch<3;ch++)
                    {
                        ADMUX=ch;
                        read_adc();
                        if (adc_result[i]>792)//checking for 255V
                        {
                            PORTD|=(1<<PD0);//OV indication led on
                            _delay_ms(1);
                            read_adc();
                                while(adc_result[i]>823)//checking for 265V
                                {
                                    do
                                    {
                                        PORTB|=(1<<PB1); //  o/p drive ON
                                        read_adc();
                                    
                                    }while(adc_result[i]>792);//Should be in the state off until voltage reaches under 255V 
                                    PORTD=0x00;//off the OV indicator led 
                                    PORTB&=~(1<<PB1);// o/p drive off 
                                }
                        }
                        else if(adc_result[i]<621)//checking for 200V
                        {
                            
                                    PORTD|=(1<<PD3);// on the led corresponding to UV indication
                                    read_adc();
                                    while(adc_result[i]<495)// checking for 160V
                                    {
                                        do
                                        {
                                            PORTB|=(1<<PB1); //  o/p drive ON
                                            read_adc();
                                        }while(adc_result[i]<543);  _delay_ms(1);
                                        PORTB&=~(1<<PB1);// o/p drive off 
                                    }
                                PORTD&=~(1<<PD3);//Off the UV indicator
                        }
                        i++;
                    }
                    ch++;
            }
            
//GLP SECTION
                
            else if((2<ch)&&(ch<5))
            {
                {
                    ch=3;
                    glp();
                    if(k>22)//checking for 7V
                    {
                        PORTD|=(1<<PD4);//ON the led corresponding to GLP indication
                        _delay_ms(1);
                        ch=3;
                        glp();
                        if(k>22)//checking for 9V difference
                        {
                            do
                            {
                                PORTB|=(1<<PB1); //  o/p drive ON
                                ch=3;
                                glp();
                            }while(k>3);//Should be in the state off until voltage reaches under 7V 
                            PORTB&=~(1<<PB1);// o/p drive off 
                            PORTD&=~(1<<PD4);//OFF the led corresponding to GLP indication
                        }
                    }
                }
                ch=0;
            }
            else
            {
                PORTB|=(1<<PB0);
            }
        }
}

 
Last edited by a moderator:

Re: adc code shows error

Hello!

So now that you have your spcecs written, you should proceed to implementation,
but I would recommand a more functional approach.

1. You have thresholds, but they don't appear in your code. The first thing is
to define them:
#define THRES_255V 792
#define THRES_265V 823
#define THRES_200V 621
#define THRES_160V 495
#define THRES_7V 22
etc...
And don't write the values again in your code.
Now you can notice that if you write:
Code:
if(adc_result[something] > THRES_255V) {
	...
}
Then you don't even have to comment the code because THRES_255V says everything.

2. Now according to your specs, you have 5 AC signals that you need to measure
continuously. I think it should be like this:

Code:
[some initializations]
while(1) {
	read_all_adc_values();
	[do the processing here but don't read the 5 values again until the
	current signal evaluation is finished]
}

3. There are inconsistencies in your program. Example:
Code:
		ch=0;
		if(ch<3) {
Do you think there is any chance that your if is not entered? Remove the if statement,
it's useless (I mean, don't remove the statements in the if, remove the if line only
and of cours the closing bracket. And also remove the else part completely, including
statements in "else {" because these statements will never be reached.

4. There is a logical issue in your code. You say:
"if a signal above a threshold1 then an OV indicator must glow. if the OV indicator
glow,Again we checked that signal with a threshold2 which is higher than threashold1.
if that is true i need an out put in PB1 until the voltage reduces below threashold1."
Now let's assume your signal rises over threshold1 and stays there (i.e. does not
go over threshold 2), then you will block your program and you will not read other
signals until this condition is true.
Conclusion: you shouldn't do like this. You should do as I wrote above, read the 5
signals, process, read 5 signals, process, etc...
This way the program will be kept very simple.

Dora.
 
Re: adc code shows error

thank you Mr. Dora, your advice help me a lot.
I just updated the code



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# define F_CPU 1000000UL //system clock @1MHz
#define THRES_255V  792
#define THRES_265V  823
#define THRES_200V  621
#define THRES_160V  495
#define THRES_175V  543
#define THRES_9V    28
#define THRES_7V    22
 
 
#include <avr/io.h>
#include <stdio.h>  
#include <avr/interrupt.h>
#include <util/delay.h>
 
 
//Global variable 
uint16_t adc_result[5]={0,0,0,0,0};//for storing the adc out put
uint8_t ch=0;
uint8_t y=0;
uint8_t i=0;
int k=0;
 
/* PORT INIT */
void port_init (void) 
{
DDRB |=(1<<PB1);//set portB.1 as output drive for relay
PORTB&=~(1<<PB1);//initially set 0 as o/p drive
DDRB |=(1<<PB0);//error occur pin
 
//set portC0-4 as i/p with pull up resistor 
DDRC &=~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));// ADC i/p R,B,Y & Gnd, neutral
PORTC |=((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4));
 
//set up port D 0-4  as output
DDRD &=~((1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4));//o/p led for OV,UV and GLP
}
 
void init_adc(void)
{
    ADCSRA |= ((1 << ADPS1) | (1 << ADPS0));// Set ADC prescaler to 8 - 125KHz sample rate @ 1MHz 
    ADCSRA |= (1 << ADEN);  // Enable ADC
}
 
void read_adc(void)
{
    i=ch;
    _delay_ms(1);
    ADCSRA |= (1<<ADSC);//start conversion 
    while ((ADCSRA & (1<<ADSC)));//wait for coversion to be completed 
    adc_result[i]=ADCW; 
}
 
void init_glp(void)
{
    ADMUX=ch;
    read_adc();
}
void glp(void)
{
    init_glp();
    ch++;
    init_glp();
    k=(adc_result[4]-adc_result[3]);
}
 
 
 
int main(void) 
{
    i=0;
    i=ch;
    port_init();
    ADMUX=ch;
    init_adc();
    read_adc();
    
// Loop Forever 
    while(1)
        { 
 
            PORTD&=~(1<<PD0);//OV indication led off
 
            if(ch<3)
            {
                for(ch=0;ch<3;ch++)
                    {
                        ADMUX=ch;
                        read_adc();
                        if (adc_result[i]>THRES_255V)//checking for 255V
                        {
                            PORTD|=(1<<PD0);//OV indication led on
                            _delay_ms(1);
                            read_adc();
                                while(adc_result[i]>THRES_265V)//checking for 265V
                                {
                                    do
                                    {
                                        PORTB|=(1<<PB1); //  o/p drive ON
                                        read_adc();
                                    
                                    }while(adc_result[i]>THRES_255V);//Should be in the state off until voltage reaches under 255V 
                                    PORTD=0x00;//off the OV indicator led 
                                    PORTB&=~(1<<PB1);// o/p drive off 
                                }
                        }
                        else if(adc_result[i]<THRES_200V)//checking for 200V
                        {
                            
                                    PORTD|=(1<<PD3);// on the led corresponding to UV indication
                                    read_adc();
                                    while(adc_result[i]<THRES_160V)// checking for 160V
                                    {
                                        do
                                        {
                                            PORTB|=(1<<PB1); //  o/p drive ON
                                            read_adc();
                                        }while(adc_result[i]<THRES_175V);
                                        PORTB&=~(1<<PB1);// o/p drive off 
                                    }
                                PORTD&=~(1<<PD3);//Off the UV indicator
                        }
                    }
                ch++;
            }
            
//GLP SECTION
                
            else if((2<ch)&&(ch<5))
            {
                {   
                    ch=3;
                    glp();
                    if(k>THRES_7V)
                    {
                        PORTD|=(1<<PD4);//ON the led corresponding to GLP indication
                        _delay_ms(1);
                        ch=3;
                        glp();
                        if(k>THRES_9V)
                        {
                            do
                            {
                                PORTB|=(1<<PB1); //  o/p drive ON
                                ch=3;
                                glp();
                            }while(k>THRES_7V); 
                            PORTB&=~(1<<PB1);// o/p drive off 
                            PORTD&=~(1<<PD4);//OFF the led corresponding to GLP indication
                        }
                    }
                    else
                    {
                        PORTD&=~(1<<PD4);//off the led corresponding to GLP indication
                    }
 
                }
                ch=0;
            }
            else
            {
                PORTB|=(1<<PB0);// Error in microcontroller programming
                ch=0;
            }
        }
}

 
Last edited:

Re: adc code shows error

Hello!

Are you reading what I write?
I told you that for each loop, you should read the ADC ONCE for ALL THE CHANNELS and then do the
processing. If you permanently do local loops with read_adc in the whole software, then you cannot
write a meaningful program. You will for sure be locked at some place. So for the last time:


Code:
 	while(1) { 
 	 	read_your_5_ADC_values_at_once();  // Might sound redundant, but: READ THE ADC ONCE PER LOOP ONLY!!!!!
 				// At that point, your add_values array should be filled with 5 new values.
	 	do_your_processing_here_and_dont_touch_the_ADC_here();
 	}

Beside this, you should look at your code first from the highest level:

Code:
	if(ch < 3) { // This will be valid for channels 0, 1, 2
	}
	//GLP SECTION
	else if((2 < ch) && (ch < 5)) { // This will be valid for channels 3, 4
	}
	else { // As you have only 5 channels (0 to 4), what is the meaning of this one?
	}

Now one programming hint: in a program, if you have too many indent levels, you are doing something wrong.
Your mileage may vary, but for instance in my case, I don't remember having written programs with more
than, say, 3~4 indent levels. You have 7, this is way too much. At least for the complexity of what you want
to do. One may disagree, but I think that if one function takes more than one page (i.e. if you cannot view it
in a single screen), then you have to split it. Most of the screens are about 1000 ~ 1200 pixels high now.
This gives you about 50 lines, depending on the font.

And you should avoid to pile up the while / do while as you do.
Example:
Code:
	while(adc_result[i] > THRES_265V) { //checking for 265V
		do {
			PORTB |= (1 << PB1); //  o/p drive ON
			read_adc();
		}
		while(adc_result[i] > THRES_255V); //Should be in the state off until voltage reaches under 255V
		PORTD = 0x00; //off the OV indicator led
		PORTB &= ~(1 << PB1); // o/p drive off
	}
I really don't understand what this does.

Dora.
 

Re: adc code shows error

How can i program my code to atmega 168 using universal microcontroller kit?which memmory is used for that?eeprom or flash?
 

Re: adc code shows error

Hello!

How can i program my code to atmega 168 using universal microcontroller kit?which memmory is used for that?eeprom or flash?

Before replying this question, did you solve your other software problems? Dos your software work now?

Dora.
 

Re: adc code shows error

ya Mr.Dora
thank you for your help
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top