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 CCS Technical Support

Ultrasonic distance measuring
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

Ultrasonic distance measuring
PostPosted: Mon Nov 07, 2011 2:39 pm     Reply with quote

Hi everyone
Let me start by saying that I'm a starter at pic programming yet I've made a mistake by choosing to build a robot for my school project (its a long story:))
I am using a 16f877 and 4mhz osc.
Here is my receiver

I connected my transmitter directly to pic (one pin to ground other to a port in pic).

My problem is when I use this code there is no output at pinb7. Therefore receiving end is always high and I can't get a reading in cm on the serial output screen. I know this is not a beginner project to do but any help would be great. Thanks

I tried many codes over weeks but this is the recent one;
(there was a while(true) there in my main function I must have deleted accidently in recent chances to my code).
Code:

#include <16F877.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=4000000)

#use rs232(baud=9600 , XMIT = PIN_C6)

#define Echo PIN_B1

long time;
int16 dist;
int16 k;
void transducer(void){           
      #pragma use fast_io(B)
      output_bit(PIN_B7, 1);
      delay_us(13);
      output_bit(PIN_B7, 0);
      delay_us(12);
      #pragma use standard_io(B)
}



void main()
{
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   
  set_tris_b(0x1f);
    while(true){
    for(k=0; k<8; k++)           
{
    transducer();
}
 
   while(!input(Echo))                     
{}

set_timer1(0);                           // setting timer zero

while(input(Echo))                       // Wait for high state of echo pin
{}

time=get_timer1();                       // Getting the time

dist=time/58 ;
printf("%lu cm \n\r", dist);
delay_ms(250);   
     
 }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 3:04 pm     Reply with quote

Quote:

My problem is when I use this code there is no output at pinb7.

void transducer(void){
#pragma use fast_io(B)
output_bit(PIN_B7, 1);
delay_us(13);
output_bit(PIN_B7, 0);
delay_us(12);
#pragma use standard_io(B)
}


void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);

set_tris_b(0x1f);

while(true){
for(k=0; k<8; k++)
{
transducer();
}


My advice is to make a simple program that only toggles Pin B7. Get rid
of the Timer1 setup line. Get rid of the #use fast_io lines and get rid of
the TRIS line. Let the compiler set the TRIS. Don't use output_bit().
Use output_high() and output_low().

Debug the program and the hardware until you can successfully toggle the pin.

Also, if you have an ICD or Pickit or anything programmer or debugger
connected to the board, it will be connected to pins B6 and B7. These
are not the best pins to use for external circuits, for that reason. It's
best to choose some other pins.
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 3:14 pm     Reply with quote

I'm using a simple JDM programmer I got from a friend so all my programming is done outside the board (btw I'm currently using a breadboard if thats somehow relevant)

When I first encountered output problems I did test for led blinker and it was running ok. Sorry I forgot to mention that.
I setup Pwm (Ccp1) once to get 40khz square wave(%50 duty cycle) and output was 2.6v ( I don't have an oscilloscope I'm planning on using the one at school )


(sorry if my english is a bit off)
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 7:09 pm     Reply with quote

I tried this code and got 2.2v output on multimeter. My first code persistent on not working though. any help would be great, thanks

Code:

output_high(pin_b2);
delay_us(12)
output_low(pin_b2);
delay_us(12);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 9:37 pm     Reply with quote

Since you don't have an oscilloscope, you should test low speed blinking
of an LED. Example:
Code:

#include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20M)

//==================================
void main()


while(1)
  {
   output_high(PIN_B0);   // Blink LED on pin B0
   delay_ms(500);
   output_low(PIN_B0);
   delay_ms(500);
  }




Try this test on various pins to make sure that they work.
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 4:03 am     Reply with quote

PCM programmer wrote:
Since you don't have an oscilloscope, you should test low speed blinking
of an LED. Example:
Code:

#include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20M)

//==================================
void main()


while(1)
  {
   output_high(PIN_B0);   // Blink LED on pin B0
   delay_ms(500);
   output_low(PIN_B0);
   delay_ms(500);
  }




Try this test on various pins to make sure that they work.


I tested this code it seems to be working as intended.What should try/test next? btw thanks for the help Im stuck at this this one for weeks
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 5:53 am     Reply with quote

Some comments:
You say the transducer is directly wired to B7. Have you any details of the TX transducer?. While some can be driven off a 5v output like this, many need a lot higher drive voltage. Devices like the Polaroid transducers for example need nearly 70v!.... Also, the transducers behave as resonant devices at their drive frequency, and could quite easily destroy a PIC output pin if connected without some protection. This may well be what has happened to your B7.
So, give some details of your transducer...

Now, also the transducer will have a very specific operating frequency - typically close to 40KHz. The timings of your code, won't be right unless your clock rate in the clock command, matches what your system is actually running at. So start with the test program, and verify that the LED flash interval really is _1 second_. If it is not, then your crystal is not 20MHz. this needs to be got 'right'.

Then, don't fiddle around using #pragma. This is not going to do anything worthwhile in your code. Pragma, is a command to force pre-processing code to be executed first. It does nothing in your code, and just makes the code look messy. Seriously, if you are using fast_io for speed, then select this, and leave it selected. Given the need for speed, use:

Code:

#use fast_io(b)
#inline
void transducer(void){           
      output_highPIN_B7); //This is faster than output_bit
      delay_us(13);
      output_low(PIN_B7);
      delay_us(12);
}

The compiler will probably make the routine 'inline' anyway, but force it, to be sure.

Then lay things out logically so you (and us), can see what
Code:

void main(void) {
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   
  set_tris_b(0x1f);
  do  {
    for (k=0; k<8; k++) {
       transducer(); //8 pulses on the transducer
    }
    while (input(Echo)==0) ; //You seem to be waiting for a low....
    time=get_timer1();                       // Getting the time

    dist=time/58 ;
    printf("%lu cm \n\r", dist);
    delay_ms(250);   
    } while(TRUE);
}

Now you are waiting after sending the pulse , 'while' the input is high. However according to your comments you want to wait _till_ the pin goes high....

There is though a potential problem. On most ultrasonic rangefinders the 'receive' input _will_ trigger while the pulse is being sent. You actually have to wait for the signal to drop, and then go high _again_. You may need to rethink what you are doing here....

Best Wishes


Last edited by Ttelmah on Tue Nov 08, 2011 7:44 am; edited 1 time in total
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 6:20 am     Reply with quote

Sorry I forgot the tranducer specs
here they are :

1.Model:TCT40-16R/T (Diameter 16mm)

2.Nominal frequency:40KHz

3.Emission sound pressure (at 10V):≥117dB

4.Reception sensitivity (at 40KHz):≥-65dB

5.Capacitance:2000PF ±30%

6.Maximum input voltage:60Vp-p

7.Operating temperature:-20℃--+70℃

8.Storage temperature:-40℃--+85℃

I did test the crystal time to time It seemed ok. and the original curcuit
(I got the receiver from) was based on 16f628 using 4mhz. so I assumed 4mhz is way to go to get timing right. also orginal code was in Picbasic I can post it if you want to. about my code part ; my goal was to send 40khz pulse and when receiver detect the echo signal( output should go low when pulse is detected). store that time and calculate the distance by dividing time with 58( 58 part is calculated from speed of sound , wave traveling same distance twice etc.) I did test for many codes over time but this one is from this forum I thought I should give it a try. I hope I explained myself. Thanks
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 7:30 am     Reply with quote

There are many ways to drive a 40kHz transmitter. Simply connecting it to an IO pin is not one of them. Rolling Eyes

Taka a look at http://www.ti.com/lit/an/slaa136a/slaa136a.pdf Its an application note from Ti. Its based on their MSP430 processor, which is their equivalent of the PIC. They generate the 40kHz in the processor and use simple circuitry to generate a decent drive voltage for the transducer. It also describes the timing and even gives code, which is useless to us. Confused

This is the sort of thing you need to build.

RF Developer
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 7:45 am     Reply with quote

My first curcuit was this ;
[img]



In my code I triggered the 4th in on 555 with
[/code]
output_high(pin_b7);
delay_us(250);
output_low(pin_b7);
[code]

after getting no reading from 555's output pin , first I assumed 555 was broken , and I switched it with another one but that didnt give out reading either so I decided to connect the TX diretly to pic( I've read it somewhere that it was posible , I dont know though.) Then I should re wire this Tx circuit? Im lost Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 8:23 am     Reply with quote

OK.
With those sensors, you probably can drive the TX from a PIC pin without damage, _but_ the range will be tiny. I'd guess possibly about 1foot max.
Driving from the 555, will be better, especially if you use a higher supply voltage for this chip.

Other choices:

Push-pull drive as suggested in the example from RF_Developer.

Drive from a PIC pin, with a transistor, and an inductor across the TX transducer (and a trap resistor). This way you can get a higher effective drive voltage from a 5v supply, by using the 'flyback' energy in the inductor. Something in the order of 1mH.

If you are running at 4MHz, then hopefully the LED flash example from PCM_Programmer, will actually flash at 5 second from start to start of the light pulse. Does it?.

Don't worry for now about the receive code. Just do a dead basic 40KHz pulse code, sending for rather longer, and see if you get the LED to light on the receive circuit.
It is the old 'get one part working first'.

Best Wishes
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 8:56 am     Reply with quote

I tried PCM_Programmer's code for led. It was on for half second and off for half second. considering delay_ms(500) it should be right?. I also tried my
555 circuit again pin3 is always 0v with my code ( the one that uses delay_us(250))

I currently have 330uH inductor would it work?

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 9:45 am     Reply with quote

RAzorex wrote:
I tried PCM_Programmer's code for led. It was on for half second and off for half second. considering delay_ms(500) it should be right?. I also tried my
555 circuit again pin3 is always 0v with my code ( the one that uses delay_us(250))

I currently have 330uH inductor would it work?

Thanks


No.
If you look at PCM_Programmers example, it is setup for a _20MHz_ oscillator. Clock=20M
and HS fuse
If this is running at the right speed, then your circuit _does not_ have a 4MHz oscillator.

Would you actually 'see' the pulse on pin3?.
You talk about using a multimeter, and if the oscillator is actually running 5* faster than you think, then the pulse would only be 50uSec. Most multimeters take perhaps 1/4 second to acquire a reading.....

Yes, but remember if using an inductor in flyback like this, the transistor that is driving it would need something like perhaps a 60V rating. Not a PIC output pin, or even a 555, and you _must_ have a trap resistor to limit just how large the voltage spike is, or you risk everything else in your circuit.

Best Wishes
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 10:23 am     Reply with quote

I will take another look at my setup to confirm my oscillator issue I will post the results. Btw






I tried this circuit once code was in mikroC ,it was very problematic also it was said to be very unstable for robot use so gave up on it. my question is the tx part of this circuit should give about 20v (with a pwm code 40khz %50 duty cyle) would you recommend this?
thanks

edit : I think resistor in image "3k3" should be 33k
RAzorex



Joined: 07 Nov 2011
Posts: 13

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 11:03 am     Reply with quote

I forgot to put HS to config earlier so when tested again (#use delay(clock=20M) with 4mhz on circuit led flashed about 4 second from start to start it seems a bit off still
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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