[PIC] I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

Status
Not open for further replies.

nblrehman

Newbie level 2
Joined
May 10, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
26
Hello..
this is my very first thread...
I am a student.. I am stuck on this project of mine..
I am using PIC16F877A with 20MHz crystal.. and HC-SR04 sensor..

there is something wrong with my code.. When I set the range from 1 to 2 cm.. the program works perfect.. but as soon as I increase the range to 3 or greater than that... the LED ie, RC0 remains set.

the program is shown below... PLEASE HELP....
btw.. it is created on MPLABX using XC8 compiler..
the project file is attached...!!





Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#define _XTAL_FREQ 20000000
__PROG_CONFIG(1,0x3f32);
 
/*
 * 
 */
int main(int argc, char** argv) {
 
 int width;
 int range;
 int time;
 TRISB=0x04;
 TRISC=0x00;
 Loop:
 PORTB=0x00;
 width=0;
 time=0;
 range=0;
 RB1=1;    //send pulse with a 20us width
 __delay_us(20);
 PORTB=0x00;
 while (RB2==0)  //wait until an echo is received
 {
 }
 while (RB2==1) //calculate the width of the echo received
 {
 __delay_us(10);
 width++;
 }
 range=(width*10)/58; //calculate range
 if (range<2)      //if range less than 100m turn on LED
 {
 RC0=1;
 __delay_ms(500);
 }
 else
 {PORTC=0x00;
 __delay_ms(100);}
 goto Loop;
 
    return (EXIT_SUCCESS);
}

 

Attachments

  • ULTRAS_WITHOUT TIMER.7z
    38.5 KB · Views: 58
Last edited:

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

hello,

i didn't check all your code, but , some remarks :

maxi width counter value is 32767
(better is to use unsigned int to avoid negative value! if over 32767)
witch is 3276710/5880=> 55 meters !

In reality, maximum possible will be <4 meters 4000 mm
5,88µSec/ milimeter
=> 4000 * 5,88=> 23520 µSec maxi
if resolution is 10µS => your width counter will get 2352 maxi
poor resolution
2352 will give 2352/58=40,55 decimeter !

so, don't use delay10µS in the loop
with a loop in C langage , accuracy is not enough.



or try to calibrate the loop for 1µS duration or a multiple like 5,8µS !!
Code:
 while (RB2==1) //calculate the width of the echo received
 {
  Nop();;
  Nop();
 width++;
 }

check asm result to calculate the duration of the loop..
if duration is 1µS you will get 23520 µS / 58 => 405 cm
or if you can adjuts loop duration to 5,8µS by adding some NOP() =0.25µS
you have direct value in mm width=4055

the best is to use Timer counter
at 20Mhz , 1 cycle is 4/20=0.25µS
and your resolution will better than 1 mm

BTW, how do check the result ? no display ?

Nota: you can not measure below 2 or 3cm !!!


if you want also to correct the measure by the ambiant temperature
check **broken link removed**
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

hey..!!
THANx.. I check the result by led installed at RC0...
the problem I keep getting is that it sense any object below aprox 2 cm and the LED turns on..
but if wont sense any object above 2... like if I change the range to 3 .. it wont detect it and the LED stays ON..

btw... one NOP() is equal to how many microseconds...
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

btw... one NOP() is equal to how many microseconds...

I seem to remember reading a microchip note somewhere that this is not necessarily the case....
just thought I'd mention it.
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

hello


NOP is a void instruction wich do nothing, except to grab some processor time
1 NOP = 1 cycle ... with Q=20Mhz 1 cycle =4/20=> 0,25 µS

Nota: you can not measure below 2 or 3cm !!!
with ultrasonic sensor you always have a dead zone of measurment..
try to display your raw resulting measure (width) on a LCD or on USART -> Max232-> terminal PC
so you can check if the measure is valid, before transfor to physical easure in mm or cm (or inches ?)

You test with one led is to poor.
Code:
if (range<2)      //if range less than 100m turn on LED
what unit ?
and your never will measure over 4 meters .
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

No - the point I made was that 1 NOP does not always equal 1 cycle on pic chips.
Do not use NOP's for accurate timing.
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

hello,

No - the point I made was that 1 NOP does not always equal 1 cycle on pic chips.

Could you explain why 1 Nop is not allways 1 cycle when using in asm directive with THIS CHIP ?

I know that a time loop made with a serie of NOP can be disturb when an event/interrupt occurs,
but the subjet of delay whis using a serie of Nop operation is WITHOUT interrupt....
It's evident that timer are made for that function ....
except if the MCU has no other job to do...


 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

yes paul - it's a head scratcher... I believe the original source may have been thinking of this from the original microchip timing data
(remember that timing and counting are different things - many people use nop's for counting or delaying - that isnt the same thing as timing):

quote:
All instructions are executed in one single instruction cycle, unless a conditional test is true or the
program counter is changed as a result of an instruction. In these cases, the execution takes two
instruction cycles with the second cycle executed as an NOP. One instruction cycle consists of
four oscillator periods. Thus, for an oscillator frequency of 4 MHz, the normal instruction execution
time is 1 ms. If a conditional test is true or the program counter is changed as a result of an
instruction, the instruction execution time is 2 ms.

-----
I believe there was a reference to this and nops also being affected in certain cases but so far I cant locate the source - I'll post it if I can find it.
 

Re: I DONT KNOW WHERE I AM WRONG .. USING PIC16F877a and HC-SR04.. XTAL_FREQ = 20MHz>

Here is an example of delay of 500µS exactly ( without active interruption GIE=0)
it uses NOP as intermediate delay calibrated from FOSC =16Mhz so 1 cycle => 0.25µS
BTW; i made a mistake in POST #5 at 20Mhz Cycle is 4/20=0,2µS not 0,25µS
NOP is a basis instruction of the MCU, and can never change !
Only the final counting can be affect by Branch or not Branch with Instruction Test
as inside this example .. the main part of delay is made by 16 NOP instruction inside a loop


Code:
N1=100;  // initialise once the variable , to be reconized by compiler
 // tempo de 500,0µS
 // formula :   = 0,25+0,25 +(N1*(16*0,25+0,5+0,25))-0,25+(4*0,25)
 //               Load counter    N1 Loops  times ( 16 Nop + Decrement Counter + Branch loop) - Branch (skiped )+ final adjust by 4 nop.

 asm
 {	
	MOVLW 105 ;
	MOVWF _N1;   // 8 bit counter
 ici:	
	nop ;   //1
	nop ;
	nop ;
	nop ;
	nop ;
	nop ;
	nop ;
	nop ;
	nop ;
	nop ; //10
	nop ;
	nop ;
	nop ;
	nop ;
	nop ;
	nop ; //16
	decfsz _N1 ,F ;   //decr counter, skip over next instruction if equal to zero  
	bra ici   ;
	nop;
	nop;
	nop;
	nop;  // add 4x0.25=1µS to round tempo pile poil to 500µS
 }
  asm nop ;  // external nop final used as Break point to measure exact cycles and times . ...gives 500.0µS



the formula gives
elapsed Time= '= 0,25+0,25 +(105*(16*0,25+0,5+0,25))-0,25+(4*0,25)

test by decfsz takes 2 cycles
and branch to loop occurs 104 times , because skiped after last decreasing of counter =>to zero
4 nop are added to get exactly 500µS instead of 499µS.

For me , the main difference between Timing and Delay , is
we use Timer (Hardware + software) to generate an event after a given delay (amount of elementary cycles),
without blocking the MCU JOB
and pure Delay ,by software, use 100% the MCU ...
but it doesn't change that a NOP is 1 cycle delay...

for an oscillator frequency of 4 MHz, the normal instruction execution time is 1 µs.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…