View previous topic :: View next topic |
Author |
Message |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
Infrared Measuring with PIC16F877A |
Posted: Wed Mar 21, 2012 3:28 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Mar 21, 2012 4:31 am |
|
|
You didn't tell about any problem with the measurement. |
|
![](templates/subSilver/images/spacer.gif) |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
|
Posted: Wed Mar 21, 2012 8:40 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Wed Mar 21, 2012 11:36 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
|
Posted: Wed Mar 21, 2012 2:58 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 21, 2012 3:10 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
|
Posted: Thu Mar 22, 2012 12:08 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Thu Mar 22, 2012 12:19 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
|
Posted: Thu Mar 22, 2012 2:23 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu Mar 22, 2012 5:31 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu Mar 22, 2012 5:35 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Jampe
Joined: 09 Mar 2012 Posts: 27
|
|
Posted: Thu Mar 22, 2012 7:23 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu Mar 22, 2012 8:19 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|