measuring da distance!

Markd77

Joined Sep 7, 2009
2,806
I decided to use the ADC for listening to the echo as I cant use pin RC2 for CCP capture mode since its going to be use for multiplexing...dont want to use 2 PORTS for multiplexing so as not to complicate my software!

Attached is the receiver amplifier im going to use, i also attached the schematic in the original post 1 as i need to ask a question: as you can see i have encircled the 33k value of the receiver...

i would like to know if i should keep this or remove it since i am going to use the receiver amplifier attached??

Also im using the chip UA741CN for the op-amp so im not too sure what to do with pin 1 (offset null1) and pin 2 (offset null2) im ok with the other pins.

please allow me to ask one more thing, in the sensor attachement i will like to know if the number 1 and 2 represent what? i mean which one is positive and which is negative between 1 and 2

I am building the whole circuit on breadboard now...

kindly regards, Eric
IMHO there is not much point using the ADC with that circuit, you may as well use a normal pin because the voltage will rise to high level and stay there like in post #17
Unless you have a +/- 9V supply available for the 741 I recommend putting pin 1 and pin 2 in the bin along with the other pins and get an op amp that will work with a 0-5V supply, like the LM358. A rail to rail one might be better but the LM358 will probably be OK.
You would also need something to protect the PIC if you used the 741 with a split supply. A 5.1V zener would probably do it.
I don't think it makes much difference between 1 and 2 on the sensor and receiver, however if there is a black wire and a red wire or a + and a - on them then connect black or - to ground to be safe.
You can scrap the 33k resistor, the 3k9 in the circuit does the same thing.
 
Last edited:

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
IMHO there is not much point using the ADC with that circuit, you may as well use a normal pin because the voltage will rise to high level and stay there like in post #17
That's a very good news!! Please explain the algorithm to be used for using a normal pin for the receiver? Then I will use normal pin RC7 for for the receiver!

Unless you have a +/- 9V supply available for the 741 I recommend putting pin 1 and pin 2 in the bin along with the other pins and get an op amp that will work with a 0-5V supply, like the LM358. A rail to rail one might be better but the LM358 will probably be OK. You would also need something to protect the PIC if you used the 741 with a split supply. A 5.1V zener would probably do it.
I will use an op amp that work with 0-5V as suggested! Hopefully will get the LM358... my bad I didn't check the power for the 741 but any op amp working with 0-5 V will do right? (In case I can't get the LM358)

I don't think it makes much difference between 1 and 2 on the sensor and receiver, however if there is a black wire and a red wire or a + and a - on them then connect black or - to ground to be safe.
There's a black sign on each sensor...so I will just ground it for the receiver, But as for the transmiter that schematic...guess the negative side will be connected to the positive side of the diode, right?

You can scrap the 33k resistor, the 3k9 in the circuit does the same thing.
Thanks I will scrap it then!

Thanks a millions...

Regards, Eric
 

Markd77

Joined Sep 7, 2009
2,806
That's a very good news!! Please explain the algorithm to be used for using a normal pin for the receiver? Then I will use normal pin RC7 for for the receiver!

I will use an op amp that work with 0-5V as suggested! Hopefully will get the LM358... my bad I didn't check the power for the 741 but any op amp working with 0-5 V will do right? (In case I can't get the LM358)

There's a black sign on each sensor...so I will just ground it for the receiver, But as for the transmitter that schematic...guess the negative side will be connected to the positive side of the diode, right?
The algorithm:

{Set RC7 to output low}
Start timer
Send pulses
Wait for oscillations to die down
{Set RC7 to input}
Wait for the pin to go high
Read timer
Calculate distance

Look for a single supply op amp that can work reasonably near the power supply. The LM358 (and the LM324) are cheap, easily available (at least over here) and work from roughly ground to Vcc-1.5V, ie 3.5V, which is enough to be seen as high and low by the PIC.
Sensor wires configuration sounds good.

You might run into problems if the output from the receiver amplifier stays high from the initial pulses. To get rid of that, put a 1k resistor between the amplifier and the PIC pin and add the steps in brackets into the algorithm to pull the output down.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
circuit has been built on breadboard with LM358...
i will add that 1k resistor...thanks!


But in the above algorithm, shouldn't RC7 (receiver pin) set as input and RA2 (transmitter pin) set as output? i'm asking coz in the first brace, it written set RC7 as output low...

Also when you say: 'wait for the pin to go high', i assume you talking about pin RC7 (receiver) and also i think pin RC7 should be initializa with 0, so how is that pin RC7 going to be set high...since its a normal pin...


there' quite a few thing happening here...im thinking of using timer0 for the multiplexing...so i guess i should use timer1 for wave duration, right?

well still thinking but i got to get started...

ima post small piece of code!

regards
 

Markd77

Joined Sep 7, 2009
2,806
circuit has been built on breadboard with LM358...
i will add that 1k resistor...thanks!


But in the above algorithm, shouldn't RC7 (receiver pin) set as input and RA2 (transmitter pin) set as output? i'm asking coz in the first brace, it written set RC7 as output low...

Also when you say: 'wait for the pin to go high', i assume you talking about pin RC7 (receiver) and also i think pin RC7 should be initializa with 0, so how is that pin RC7 going to be set high...since its a normal pin...


there' quite a few thing happening here...im thinking of using timer0 for the multiplexing...so i guess i should use timer1 for wave duration, right?

well still thinking but i got to get started...

ima post small piece of code!

regards
Have a look at the graph of the output in post #17. That will happen when you receive the reflected pulse which is good. It will also happen when the receiver picks up the pulse directly when it is sent which is bad, because it won't drop down to a logic low fast enough to then receive the reflected pulse.
Setting the receiver pin RC7 to an output at logic low with the resistor will drain the charge on the capacitor from the unwanted direct pulse. The same pin then needs to become an input and when the reflected pulse comes it will set the input pin to logic high, at which point you read the timer.
Sometimes I'm not too good at explaining things, but hopefully this is clearer.

Timer1 sounds like a good idea if you aren't using it for anything else. Just set the prescaler so that at the maximum distance you want to measure it wont overflow.
 

Markd77

Joined Sep 7, 2009
2,806
I mentioned it in passing before, the bottom horizontal on the schematic for the receiver should be connected to ground, the symbol is missing from the schematic, but it's not going to work without it.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I mentioned it in passing before, the bottom horizontal on the schematic for the receiver should be connected to ground, the symbol is missing from the schematic, but it's not going to work without it.
Ok! I been building my circuit based on receiver amplifier that I post in post #38 and this exactly what you redrew for testing...

But in post #38 receiver amplifier, that line you are talking about is grounded! Please lemme know if I'm wrong while reading you you wrote in the post before this one!
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Have a look at the graph of the output in post #17. That will happen when you receive the reflected pulse which is good. It will also happen when the receiver picks up the pulse directly when it is sent which is bad, because it won't drop down to a logic low fast enough to then receive the reflected pulse.
Setting the receiver pin RC7 to an output at logic low with the resistor will drain the charge on the capacitor from the unwanted direct pulse. The same pin then needs to become an input and when the reflected pulse comes it will set the input pin to logic high, at which point you read the timer.
Sometimes I'm not too good at explaining things, but hopefully this is clearer.

Timer1 sounds like a good idea if you aren't using it for anything else. Just set the prescaler so that at the maximum distance you want to measure it wont overflow.
This is well explained!!! Thanks I understood...
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
please check my burst routine and tell me if it makes sense!!

pulse = RA2
cycles = register to store number of cycles
burst = routine
delay_pls = register for delay

i didnt use a delay routine coz i needed to get an accurate 25us (12us+13us)! most importantly please tell me if this routine will still hold when cycles = 0

im still working on other part of the code

kindly regards,
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
I haven't checked it with the stopwatch in simulator, it looks about right but there are a couple of issues.
It will always run at least one cycle because the test for cycles is at the end.
If you move it to "here" then, because you are using decfsz, it will do (cycles-1) cycles (or 256 cycles for 0) so you need to adjust for that.

For short delays I often use these instead of loops:
call 4cy = 4 cycles (the label 4cy can be put before any return statement)
goto $+1 = 2 cycles ($+1 just means the next instruction)
nop = 1 cycle
 
Last edited:

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I haven't checked it with the stopwatch in simulator, it looks about right but there are a couple of issues.
It will always run at least one cycle because the test for cycles is at the end.
If you move it to "here" then, because you are using decfsz, it will do (cycles-1) cycles (or 256 cycles for 0) so you need to adjust for that.

For short delays I often use these instead of loops:
call 4cy = 4 cycles (the label 4cy can be put before any return statement)
goto $+1 = 2 cycles ($+1 just means the next instruction)
nop = 1 cycle

Thanks! i dont know yet how to simulate code...#very bad# can you please simulate it or edit the way you think it must be!?

regards
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I think I still have a few issues that i assume to be the last ones...

Is my timer1 setting ok for this kind of work? as i would like to measure a maximum range of approximately 200cm, well any minimum range would be fine...

In my attachement, as you can see, im a bit stuck at writing down that equation, that i believe to be the correct on, into assembly...well, i can break it into piece but im actually stuck on writing the mupliply and divide operator...any help please!!

And how to deal with out of range distances (overrange and underrange)???

Kindly regards,
 

Attachments

Last edited:

Markd77

Joined Sep 7, 2009
2,806
Here's how I would do it:
It's set for 13 cycles and clear for 12.
Rich (BB code):
    movlw 5
    movwf cycles
    incf cycles, F        ;add one so Zero bit can be used instead of Carry bit

loopcycles
    decf cycles, F
    btfsc STATUS, Z
    goto endcycles
    bsf pulse
    call delay4cy
    call delay4cy
    call delay4cy
    bcf pulse
    call delay4cy
    goto$+1                ;2 cycles
    goto loopcycles
endcycles
Just put a label delay4cy before any return statement in any subroutine.

eg.

Rich (BB code):
....
....
delay4cy
   return
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Here's how I would do it:
It's set for 13 cycles and clear for 12.
Rich (BB code):
    movlw 5
    movwf cycles
    incf cycles, F        ;add one so Zero bit can be used instead of Carry bit
 
loopcycles
    decf cycles, F
    btfsc STATUS, Z
    goto endcycles
    bsf pulse
    call delay4cy
    call delay4cy
    call delay4cy
    bcf pulse
    call delay4cy
    goto$+1                ;2 cycles
    goto loopcycles
endcycles
Just put a label delay4cy before any return statement in any subroutine.

eg.

Rich (BB code):
....
....
delay4cy
   return

i just realized the power of goto $+1!

does that mean that goto $+2 will move to 2 instructions ahead and goto$-1 will move to 1 instruction back??

do you also mean that delay4cy must be added before all the routine in the code??

also call delay4cy = 4 cycles, does that mean that (call =2 cycles) + (return = 2 cycles) now as delay4cy is on top of every return ==>> delay4cy makes 4 cycles??

i'll also try to edit my code

thanks
 

Markd77

Joined Sep 7, 2009
2,806
Yes, you got it, a lot of times you will see something like this:
Rich (BB code):
    btfsc ADCON, DONE
    goto $-1
to replace
Rich (BB code):
wait
    btfsc ADCON, DONE
    goto wait
with the delay4cy, just pick one return and put it there. The compiler won't let you put it twice. call takes 2 cycles, return also takes 2 cycles.

To test for overrun the easiest thing to do is disable the timer1 interrupt, then in the "listen" loop also test the timer1 interrupt flag and go to an abort value if it becomes set.

Interrupts should be disabled while you send the pulse, so the timing doesn't get messed up.

For underrun you probably need to experimentally find the lowest value returned by listen, add a few, and then compare the result of listen with that. If it's less you have underrun.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
i just want my reasonning checked up!

here's how i plan to compute the distance:

distance [cm] = ((s*t)/2)*100

where t is timer1 value [us];
s = 340 [m/s].

==>> distance [cm] = ((340*(t/1000000))/2)*100 = t*0.017

so all i have to do is multiply timer1 value by 0.017, di i make sense???

thanks mard77 for you last post...still have to read it again
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
i been checcking the distance code generator...

First, i think byte order MUST be set to big endian! am I correct??

now when you fill it like this:

i/o register name = TMR1 (16 bit timer value)
temporary register = temp

output = TMR10...TMR11

now im wondering which of 'TMR10, TMR11' corresponds to TMR1H and which corresponds to TMR1L?????

my common sense tells me that TMR10 = TMR1H and TMR11 = TMR1L....but im not sure at all.

And i will bunch all this peice of code in a routine...

regards,
 

Markd77

Joined Sep 7, 2009
2,806
Yes, the last 2 posts look correct. I've just run a couple of numbers through the generated code for x 0.017 and it works well for them.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I'm editing my 'distance' routine...
but now I'm wondering shouldn't I start the timer1 after sending the pulses, and more precisely right after the oscillations have died down???

coz in that algorithm...we starting timer before sending pulses!

regards,
 
Top