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.

[SOLVED] ADC value subtraction problem

Status
Not open for further replies.

vibodha

Newbie level 6
Newbie level 6
Joined
Jun 3, 2013
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,365
In my program, I measure the Maximum and minimum digital value form a LDR input. Then display Max, Min and the difference of Max and min this.

But it shows a wrong answer for the difference.
example
Max = 722 and Min = 400; Difference = 326 (displayed value) but the correct one is 322
Please help me

use 16F887

the cord segment is



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
unsigned int Min_ADC_Value,value,Max_ADC_Value,ADC_Value,DOP;
///////////////////////////////////////////////// Finding Min and max
Max_ADC_Value =  ADC_Get_Sample(0);
Min_ADC_Value =  ADC_Get_Sample(0);
while(j<145)
{
     j++  ;
     ADC_Value=ADC_Get_Sample(0);
      if (Max_ADC_Value<ADC_Value)
      {
          Max_ADC_Value=ADC_Value;
         }
         else
             if(Min_ADC_Value>ADC_Value)
              {
                Min_ADC_Value=ADC_Value;
                }
delay_ms(500); 
}
////////////////////////////////////////////////////
DOP=Max_ADC_Value- Min_ADC_Value; // this value converted to char and display with Max_ADC_Value and Min_ADC_Value on LCD

 
Last edited by a moderator:

Re: ADC value substraction problem

The code seems correct to me. Are you sure about the conversion from number to char ? You can start fixing Max and Min (instead of reading actual values) and see what happens.
 

Re: ADC value substraction problem

You must replace the row #8 at code above for the one presented bellow:


Code C - [expand]
1
ADC_Value=Min_ADC_Value;





+++
 

Re: ADC value substraction problem

You must replace the row #8 at code above for the one presented bellow:


Code C - [expand]
1
ADC_Value=Min_ADC_Value;





+++
But in this case the while loop will be useless since the ADC_Value (and then its min and max) will never be refreshed
 

Re: ADC value substraction problem

Tnx for reply albbg ,
Yes conversion to char is correct... manually I put values for Min and Max without reading from ADC. in this case its working fine . i.e no errors at conversion . but when I read form ADC and do the calculation, it gets wrong. :-(

- - - Updated - - -

You must replace the row #8 at code above for the one presented bellow:


Code C - [expand]
1
ADC_Value=Min_ADC_Value;





+++



Tnxx for reply andre_teprom ,
But this is not the case I think..
 

It's not clear to me if you also printed the two values Max and Min toghether with DOP, so you can be absolutely sure about the value of all the three variables, or if you know your input data so you only printed DOP and checked it based on your knowledge about the input signal. What about it (I mean waveform and frequency) ?
Are there any other ADC_Get_Sample(0) calls in you code ?
 

Dear albbg,


I send these data for USART every time and then I have to plot DOP with time. Yes as you say calculation can be done at the PC end and plot. but what the hell is going inside the pic ??

this is the only place I use ADC
 

It could be you read the ADC before the conversion has finished. I see you used a delay of 500 ms in the loop: it should be OK. I think you coul try to put a delay also between the first two ADC reading.
I don't think the problem is in the difference operation, but in the read values.
I didn't understand: on LCD screen you printed max, min and DOP or only DOP ?
 

I print all the values on LCD

Can this happen??
It could be you read the ADC before the conversion has finished.
I think the pointer goes to next instruction after completing the ADC conversion.
I put the Delay_ms(500) to give enough response time to LDR
 

Just to debug, send all these values ( DOP / Max_ADC_Value / Min_ADC_Value ) to UART just before calculate subtraction.
It is not clear the time elapsed between acquisition and sending to debug.


+++
 

hello,

Don't use read ADC to define min and max initial values.


Code:
Max_ADC_Value = 0;
Min_ADC_Value = 1023;
while(j<145)
{
     j++  ;
     ADC_Value=ADC_Get_Sample(0);
      if (ADC_Value>Max_ADC_Value)
      {
          Max_ADC_Value=ADC_Value;
         }
         else
             if(ADC_Value<Min_ADC_Value)
              {
                Min_ADC_Value=ADC_Value;
                }
delay_ms(500); 
}
 

Show the ADCONx settings.

hello..

ANSEL and ANSELH are in PIC 16F887
Code:
 ANSEL  = 1;              // Configure AN0 pin as analog
  ANSELH = 0;                 //Configure other AN pins as digital I/O

- - - Updated - - -

hello,

Don't use read ADC to define min and max initial values.


Code:
Max_ADC_Value = 0;
Min_ADC_Value = 1023;
while(j<145)
{
     j++  ;
     ADC_Value=ADC_Get_Sample(0);
      if (ADC_Value>Max_ADC_Value)
      {
          Max_ADC_Value=ADC_Value;
         }
         else
             if(ADC_Value<Min_ADC_Value)
              {
                Min_ADC_Value=ADC_Value;
                }
delay_ms(500); 
}

I changed the modification, but same problem... :(
 

Just a stupid test to see if LCD is printing correctly: exchange the sequence in which the variables are sent to the LCD, i.e. if now you sent to LCD Max, Min and DOP, try sending DOP, Max and Min and see what happen.
I mean if you use an instruction equivalent to print("%d %d%d",Max,Min,DOP) try doing print("%d %d%d",DOP,Max,Min)
 

Where is ADC initialze ? like .... ADC_Init();
This following code works perfect.. on 16F877

result on terminal
Code:
16F877 Test Min Max 
Init LCD
Test Min Max ADC
ADC Max= .  961
ADC Min= .  573
Delta  =    388


Code:
........
 j=0;
  ADC_Init();
  Max_ADC_Value = 0;
  Min_ADC_Value = 1023;
  while(j<30)
  {
     j++  ;
     ADC_Value=ADC_Get_Sample(0);
     //WordToStr(ADC_Value,CRam1);
     //Echo();  // on Terminal 
      if (ADC_Value>Max_ADC_Value)
      {
          Max_ADC_Value=ADC_Value;
         }
         else
             if(ADC_Value<Min_ADC_Value)
              {
                Min_ADC_Value=ADC_Value;
                }
  Led_Verte_D0 =!Led_Verte_D0 ;              
  delay_ms(50); 
  }
  Lcd_Cmd(_LCD_FIRST_ROW );
  strcpy(CRam1,"ADC Max= ....  ");
  WordToStr(Max_ADC_Value,CRam1+10);
  Echo();
  
   Lcd_Cmd(_LCD_SECOND_ROW );
   strcpy(CRam1,"ADC Min= ....  ");
  WordToStr(Min_ADC_Value,CRam1+10);
  Lcd_Out_CP(CRam1);
  Echo();
  
  delay_ms(2500); 
  Lcd_Cmd(_LCD_FIRST_ROW );
  strcpy(CRam1,"Delta  =  ....  ");
  DOP=Max_ADC_Value- Min_ADC_Value;
  WordToStr(DOP,CRam1+10);
  Lcd_Out_CP(CRam1);
  Echo();
     
 do
 {} 
 while (1);
 

Just a stupid test to see if LCD is printing correctly: exchange the sequence in which the variables are sent to the LCD, i.e. if now you sent to LCD Max, Min and DOP, try sending DOP, Max and Min and see what happen.
I mean if you use an instruction equivalent to print("%d %d%d",Max,Min,DOP) try doing print("%d %d%d",DOP,Max,Min)

Where is ADC initialze ? like .... ADC_Init();
This following code works perfect.. on 16F877

result on terminal
Code:
16F877 Test Min Max 
Init LCD
Test Min Max ADC
ADC Max= .  961
ADC Min= .  573
Delta  =    388


Code:
........
 j=0;
  ADC_Init();
  Max_ADC_Value = 0;
  Min_ADC_Value = 1023;
  while(j<30)
  {
     j++  ;
     ADC_Value=ADC_Get_Sample(0);
     //WordToStr(ADC_Value,CRam1);
     //Echo();  // on Terminal 
      if (ADC_Value>Max_ADC_Value)
      {
          Max_ADC_Value=ADC_Value;
         }
         else
             if(ADC_Value<Min_ADC_Value)
              {
                Min_ADC_Value=ADC_Value;
                }
  Led_Verte_D0 =!Led_Verte_D0 ;              
  delay_ms(50); 
  }
  Lcd_Cmd(_LCD_FIRST_ROW );
  strcpy(CRam1,"ADC Max= ....  ");
  WordToStr(Max_ADC_Value,CRam1+10);
  Echo();
  
   Lcd_Cmd(_LCD_SECOND_ROW );
   strcpy(CRam1,"ADC Min= ....  ");
  WordToStr(Min_ADC_Value,CRam1+10);
  Lcd_Out_CP(CRam1);
  Echo();
  
  delay_ms(2500); 
  Lcd_Cmd(_LCD_FIRST_ROW );
  strcpy(CRam1,"Delta  =  ....  ");
  DOP=Max_ADC_Value- Min_ADC_Value;
  WordToStr(DOP,CRam1+10);
  Lcd_Out_CP(CRam1);
  Echo();
     
 do
 {} 
 while (1);

Use ADC_Read(0) instead of ADC_Get_Sample(0) and see.

Just to debug, send all these values ( DOP / Max_ADC_Value / Min_ADC_Value ) to UART just before calculate subtraction.
It is not clear the time elapsed between acquisition and sending to debug.


+++





Hy brothers, Finally I found the error. I have done very stupid mistake when displaying the values.:twisted::twisted:.. Thank you very much for spending your time for the problem...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top