CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Infrared Measuring with PIC16F877A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

Infrared Measuring with PIC16F877A
PostPosted: Wed Mar 21, 2012 3:28 am     Reply with quote

Hello all ,
I've tried to measuring distance with GP2Y0A02YK0F and PIC16F877A.
The IR sensor connected to PIN_A1.

This is the code I tried to write :
Code:

#include <16F877A.h>                           // Preprocessor directive that selects the chip
#fuses HS,NOWDT,NOPROTECT,NOLVP                // Preprocessor directive that defines the chip fuses
#use delay(clock=20000000)                     // Preprocessor directive that specifies clock speed
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Preprocessor directive that includes RS232 libraries
void main() {
   unsigned int8 value;
   printf("Sampling:");                      // Printf function included in RS232 library
   setup_adc_ports(AN0_AN1_AN3 );
   setup_adc(ADC_CLOCK_INTERNAL);            // Built-in A/D setup function
   set_adc_channel(1);                       // Built-in A/D setup function

while(TRUE) {
         delay_ms(1000);                      // Built-in delay function
         value = read_adc();                 // Built-in A/D read function
         printf("value=%d\n",value);     
}
}


Can someone please help me?
Thanks ,
Jampe.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Mar 21, 2012 4:31 am     Reply with quote

You didn't tell about any problem with the measurement.
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Wed Mar 21, 2012 8:40 am     Reply with quote

I try to receive information from remote controller and the data is wrong.
I just wanted to know if my code should work.

Thanks,
Jampe.
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Mar 21, 2012 11:36 am     Reply with quote

give us a clue - what is "the data is wrong" - off by some factor, high all the time or just what ? What value are you getting from the read ??
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Wed Mar 21, 2012 2:58 pm     Reply with quote

I got data even without connecting the sensor.
Why is that?
How do I modify my code for a working code?

*to remain , the sensor is connected to pin A1 *

Thanks,
Jampe.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 21, 2012 3:10 pm     Reply with quote

Quote:
I got data even without connecting the sensor.

You're reading the A/D pin. If you have nothing connected, the PIC will
still read whatever random voltage is floating on the pin.

Quote:

the data is wrong.

value = read_adc();

printf("value=%d\n",value);

You are reading an unsigned 8-bit integer, because that is what the
read_adc() function returns in this case. But your printf statement
is not setup to print an unsigned 8-bit value.

Download the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Put it on your desktop. Whenever you get a result from a function
that doesn't seem correct, or if the compiler gives you an error message,
then look up the function in the manual and see how to use it. In the case
of printf, look up the correct format string for an unsigned 8-bit integer.
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 12:08 am     Reply with quote

PCM programmer , thank you for your answer.

I changed it to :

Code:
printf("value=%x\n",value);


Quote:

This device outputs the voltage corresponding to the
detection distance


For 80cm I receive data of "27" , is that logical?

I even tested something else :
my minimum measure is 20cm , my maximum is 150cm.
I defined that my resolution is 130/255=0.51 cm per bit.
Is this that correct attitude?

Thanks,
Jampe
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 12:19 am     Reply with quote

I printed the spec sheet you reference out, but for the life of me, can't remember just where I put it now. Anyway, the response was non-linear, so you will have to apply a correction factor to the data you get to convert to actual distance. It actually will measure less than 20 cm according to the data sheet, but seemed to me you got the same number at 10 as at 25 or something like that. Bottom line is you will have to correct the reading you get to get to actual distance. The correction curve is in the sheet you reference.
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 2:23 am     Reply with quote

gpsmikey , thank you for your reply.
I saw the graph and I took it in account but I checked for 80cm..
Does my code should work?
How can I convert the voltage that my sensor sends to cm?
Thanks,
Jampe.
temtronic



Joined: 01 Jul 2010
Posts: 9161
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 5:31 am     Reply with quote

Like Mikey, I downloaded the datasheet and saw the horrible, nonlinear output of the sensor that only uses about 1/2 of the PIC ADC range.
You have a few options to 'make it work'.
1) create a lookup table of distance vs. voltage.

2) create a formula that converts voltage into distance.

#1 is simple and easy to construct.#2 requires more time and effort, though Excel or Matlab could probably figure out the 'formula' quickly.#2 might need floating point, transcendental function, etc. which the PIC really wasn't designed for(but can do them!) so will be slow.

I'd choose #1 and see if it's good enough for your application.Either a table of values or even a lot of if rdg=xxx then dist=yyy statements will work. It will be the quickest to see how the sensor works with the PIC.

Since I don't have that sensor, I can't take the time to 'play' with it to cut basic code for you.I would stay with 8 bit resolution though, it's faster and easier to code.You might 'google' the sensor for code.It wouldn't be hard to translate another source into CCS C.
temtronic



Joined: 01 Jul 2010
Posts: 9161
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 5:35 am     Reply with quote

Like Mikey, I downloaded the datasheet and saw the horrible, nonlinear output of the sensor that only uses about 1/2 of the PIC ADC range.
You have a few options to 'make it work'.
1) create a lookup table of distance vs. voltage.

2) create a formula that converts voltage into distance.

#1 is simple and easy to construct.#2 requires more time and effort, though Excel or Matlab could probably figure out the 'formula' quickly.#2 might need floating point, transcendental function, etc. which the PIC really wasn't designed for(but can do them!) so will be slow.

I'd choose #1 and see if it's good enough for your application.Either a table of values or even a lot of if rdg=xxx then dist=yyy statements will work. It will be the quickest to see how the sensor works with the PIC.

Since I don't have that sensor, I can't take the time to 'play' with it to cut basic code for you.I would stay with 8 bit resolution though, it's faster and easier to code.You might 'google' the sensor for code.It wouldn't be hard to translate another source into CCS C.
Jampe



Joined: 09 Mar 2012
Posts: 27

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 7:23 am     Reply with quote

Thank you temtronic for your reply.
I found this website and I tried to translate them code :

Code:

//  Noah Stahl
//  5/25/2011
//  http://arduinomega.blogspot.com
//  Arduino Mega 2560
//This sketch is used to test the Sharp Long Range Infrared Sensor.
//The sensor output is attached to analog pin 15. Once the distance
//is calculated, it is printed out to the serial monitor.

#define sensorIR 15               //Must be an analog pin
float sensorValue, inches, cm;    //Must be of type float for pow()

void setup() {
  Serial.begin(9600);
}

void loop() {
  sensorValue = analogRead(sensorIR);
  inches = 4192.936 * pow(sensorValue,-0.935) - 3.937;
  //cm = 10650.08 * pow(sensorValue,-0.935) - 10;
  delay(100);
  Serial.print("Inches: ");
  Serial.println(inches);
}



to this pic code :

Code:

#include <16F877A.h>
#INCLUDE <math.h>                           // Preprocessor directive that selects the chip
#fuses HS,NOWDT,NOPROTECT,NOLVP                // Preprocessor directive that defines the chip fuses
#use delay(clock=20000000)                     // Preprocessor directive that specifies clock speed
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Preprocessor directive that includes RS232 libraries
void main() {
   float  value,value2;
   printf("Sampling:");                      // Printf function included in RS232 library
   setup_adc_ports(AN0_AN1_AN3 );
   setup_adc(ADC_CLOCK_INTERNAL);            // Built-in A/D setup function
   set_adc_channel(1);                       // Built-in A/D setup function

while(TRUE) {
         delay_ms(1000);                      // Built-in delay function
         value = read_adc();                 // Built-in A/D read function
         value2=10650.08*pow (value,-0.935) - 10;
         printf("value in cm=%f\n",value2);     
}
}


the result is for 80cm I receive :
Quote:
value in cm=703.95


I still not sure that I do everything well to define A1 as my analog input.. please inform me..

Thanks all ,
Jampe.
temtronic



Joined: 01 Jul 2010
Posts: 9161
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Mar 22, 2012 8:19 am     Reply with quote

It will help everyone if you should print out the raw ADC reading( 'value' ) as well as your 'distance'. That way you can compare your results with what the datasheet says.

Also read the PIC adc section of the datasheet.

Your line...
setup_adc(ADC_CLOCK_INTERNAL);

probably should NOT be _INTERNAL

You'll need to check the chart of processor speed vs. adc_clock speeds.

Also, you should always add 'errors' to the use_rs232(..) line.This will prevent the PIC from 'hanging' when data comes in.While you don't use now, it's 'standard' practice to always do this.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group