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

ADC with PIC16F887 for Sonar Detector

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



Joined: 23 Oct 2011
Posts: 3

View user's profile Send private message

ADC with PIC16F887 for Sonar Detector
PostPosted: Sun Oct 23, 2011 10:39 pm     Reply with quote

Hi everyone,
I am a total n00b when it comes to microcontrollers so this might sound like a dumb question but I have no clue what I am doing wrong. I need to have an ADC program to detect a analog voltage change in a sonar detector. here is my code of what I have thus far:
Code:
#include <16f887.h>
#DEVICE ADC=8
#FUSES NOWDT      //No Watch Dog Timer
#FUSES EC_IO         //20MHz oscillator
#FUSES PUT        //Power Up Timer
#FUSES NOPROTECT  //Code not protected from reading
#FUSES NODEBUG    //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD      //No EE protection
#use delay (clock=20000000)
#use rs232(baud=38400, xmit=PIN_C6, stream=PC)

   long value;
   int done;
void main ()
{

   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(sAN1 | VSS_VDD);
   


      while(TRUE){
   set_adc_channel(1); //AN1 AKA PIN 3
   delay_us(16); //required delay
   
   value=read_adc();
   
   printf("value=%lu \n \r", value);
   done=ADC_done(); //sets a HIGH to PIN C0 when ADC completes
   output_bit( PIN_C0, done);
   
         if(value>200){
            output_high(PIN_B0);
         
            }//AKA PIN
            else{
            output_high(PIN_B2);
            }
         
   
      }
   
   }


The LEDs come on once I run the program and never turn off (PIN_C0 I understand why it never changes).

When connected to Putty, the output of value is just a series of changing numbers from 0-255 (which i understand is all ones in a 8 bit string) and I can't seem to stop this stream of info to get a good reading. So i am very stumped and some help and insight into my n00by ways would be highly appreciated.

Thanx!
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Mon Oct 24, 2011 2:46 am     Reply with quote

Seriously, I doubt if you can read a sonar detector with an ADC, though it will depend on what hardware processing you have before the signal gets to the PIC.

Problem is speed.
Normally a sonar 'pulse', is a small burst of a signal at the best working frequency of your transducer. Typically something like 40KHz. This is transmitted, and then a few moments later, at a time interval dependant on the distance to the target, the first reflection is received, as a pulse of waveform, with a much reduced amplitude than the transmitted signal.
Now the receive circuitry, normally has a 'blocker' circuit, that turns off the receive amplifier, while the pulse is being sent (otherwise the amplitude can overload this), and then an amplifier, and a filter to block frequencies outside the required range, which _may_ in some cases be followed by an integrator to give an amplitude 'envelope' for the signal, or may just return the signal.
Now, you don't say whether this is an 'airborne' sonar system, or a water one. The timings change between these (speed of sound in air is about 330m/Sec, while in water about 1480m/sec - remember round trip takes twice as long though).
If your system actually returns the sonar 'pulse', rather than the envelope, you have a problem using the ADC. You need to ignore signals below some threshold level, and detect the pulse at some signal level you have decided meets the sensitivity requirement. Now, sampling theory tells us that to even basically resolve a signal, we must sample at least twice per cycle, so at 40KHz (say), the ADC will need to be sampling at 80000 times per second. Even at this rate, you can easily miss the peak of the signal by a large amount, and a higher rate is really needed. Now the ADC on the 16F887, is electrically seen as a 10pF capacitor inside the PIC, in series with about 9KR of resistance, and another 5pF at the pin of the chip. How fast the voltage on the internal capacitor will charge, will depend on the output impedance of your 'detector'. How low is this?. Then the signal must be applied for long enough for the capacitor to charge, and the reading taken, which takes another eleven cycles of the ADC clock (625KHz in your case). Add all this together, and a single conversion takes about 1/44000th second 'best case' (this only if your signal source meets the source impedance requirements of the ADC....). Too slow to reliably see a pulse.....

In your case, the timings are even worse. You don't need to reselect the ADC channel every time round the loop. Extra time. The printf will take about 3mSec - a pulse will be gone in far less than this time. Then 'of course' pin C0 goes high. The ADC has _always_ completed a conversion when it returns a value, so adc_done, will always be true. This value is only of use if you are running the ADC asynchronous to the code.

Normally, the signal will be amplified, the envelope generated, and this fed into a comparator, rather than an ADC, to give a response in a very few uSec, when the envelope reaches the level required. The level may well be auto adjusted, by changing the voltage fed to the comparator, so that the system can adjust it's sensitivity up for longer range objects.

If your sensor returns an envelope, then you may be able to use the ADC. However you will need to sit in a fast loop, _just_ reading the ADC (no printing), and only print when you see a significant pulse.

Best Wishes
MexiCub125



Joined: 23 Oct 2011
Posts: 3

View user's profile Send private message

PostPosted: Mon Oct 24, 2011 11:44 am     Reply with quote

Well, I have been testing with a power supply thus far so that I can get a understanding of the ADC on this PIC but that seems to not be working.

As for the sensor, the pin's definition that I would like to use is as followed:
Pin 3 - This pin outputs analog voltage with a scaling factor of
(Vcc/1024) per cm. A supply of 5V yields ~4.9mV/cm. Hardware limits the maximum reported range on this output
to ~700 cm at 5V The output is buffered and corresponds to the most recent range data.

So from what my TA has been harping on is that the ADC would be the best bet for this type of sensor.

This sensor will be used in air on top of a rotating servo.
Ttelmah



Joined: 11 Mar 2010
Posts: 19339

View user's profile Send private message

PostPosted: Mon Oct 24, 2011 2:53 pm     Reply with quote

OK.
So what you have is more than a sonar sensor, but an assembly of some sort giving a voltage output. This will be OK with the ADC, but you need to check some more things. Ideally post a link to the data sheet of the module. You need at the very least to know the output impedance of the unit, and the nature of the response - is it a stable voltage, while a target is at a fixed distance.

Best Wishes
Ali_P



Joined: 18 Oct 2011
Posts: 7
Location: Pakistan

View user's profile Send private message ICQ Number

PostPosted: Tue Oct 25, 2011 10:38 am     Reply with quote

Hi, this sample prog and the sensor may help you. I made it a while ago. I'll provide a link for the sensor here.

http://www.sparkfun.com/products/639

Its a cool ultrsonic sensor having 3 outputs, I think PWM/RS232/Analogue.
The last option is useful to you. it works great. I displayed the output on the lcd, you can display it whereever You want.

Here is the listing.
Note that the adc is in 10 bit mode.

Code:

#include <16F877A.h>
#device *=16 ADC=10 //10 bit adc
#include <STDLIB.H>
#include <math.h>
#fuses HS,NOWDT,PROTECT,PUT
#use delay(clock=20000000)
#include <lcd.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


/*simple program to read adc ch7 for analogue value from the utrasonic module and display the result on the lcd, the input uses a smooting average filter to reduce errors (average of 10 values)*/

void main(void)

{

 float value1,sum1,a[10];
 int out1;
 setup_port_a( ALL_ANALOG );
 setup_adc( ADC_CLOCK_INTERNAL );

   while(1)

  {

   lcd_init();
             delay_ms(100);

 while(TRUE)

    {

     lcd_gotoxy(2,1);
        printf(lcd_putc," SONAR ");
           delay_ms(2000);
              lcd_gotoxy(2,1);
                 printf(lcd_putc,"                    ");
                   delay_ms(1000);



 While (1)

   {

     for (out1=0;out1<10;out1++)  //10 value input

        {

     set_adc_channel( 7 );
      delay_us(20);
        value1 = Read_ADC();
          a[out1]=((value1*5)/1023);  // voltage conversion

         }

     for (out1=0;out1<10;out1++)
        sum1+=a[out1];  // summing
           sum1=sum1/out1; // averaging
             sum1=(sum1*100); // reqiured distance for the sensor module
                 lcd_gotoxy(1,1);
                     delay_ms(1);
                         printf(lcd_putc,"DIST: %1.0f ''  ",sum1);
                            delay_ms(200);
     
         sum1=0; // clearing value for next input

      }
     }
    }
   }

Hope this helps. Regards
_________________
Ali
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