If any one know Flowcode 3 and C-pic programming then i need your help

i have written a flowcode3 program to control an ultrasonic sensor SRF05 but i have some problems with using timers and some other calculations

Am starting AT LAST!!! to understand what is going on with the motion sensor2 example

so if am using an 8MHz xtal crystal and a prescaler of 1/8

and system division by four>>>how do we do that???i dont know!!can someone tell me??>>

then each instruct cycle time will equal 2 micro seconds

then assuming that speed of sound 338m/sec=.338 mm/micro seconds

.338usx2us=.676mm>>>/2>>>.338mm range

i will use tmr1 and the sensor am using after triggering it for at least 10 micro seconds

sends a high echo pulse for 35 milli seconds period then it will lower its

triggering the pulse without returning an

echo pulse so for that i will need an interrupt to see how many times

Timer1 has overflowed"counted">> because the sensor

will have lowered its echo line after more than one timer1 overflow>>>is that right??because

my timer1 period=1048560 micro seconds=1048,560 milli seconds>>but if i use a lower prescaler lets say like

1/1 then the timer1 period will equal 131070 micros seconds=131.070 milli seconds which is more than enough

"almost three times" for the sensor to send a high pulse for an echo and to lower it because it will have lowered its

echo long time before that,then i will have to stop timer1 and write a C-code to

get timer1"16-bit"value which is made of two parts TMR1H and TMR1L>>with whatever prescaleri use>>> so

i have to get these two parts the high and the low part of Timer1 and combine them together

to find the distance travelled like this Distance = ( Capture_TMR1H << 8 ) + Capture_TMR1L

then i will have a distance value measured in mm's



i will not use an interrupt timer1 overflow any way>>is that needed?? >> and i will have to combine what to get distance ????

i dont know???does this method needs an interrupt Timer1 overflow???i think if i use a timer overflow interrupt it will never be > 1???is that right???


I have included a program that i just wrote in flow code using timer1 but it still missing how to get the low and high parts

of timer1????????


I really don’t know if this

I really don’t know if this is going to help you at all (and I’m away this weekend, so don’t get upset, if I don’t answer until sunday evening CET).

I don’t know Flowcode and to be honest, I haven’t heard about it before, but I know PIC C and have used the SRF05, so maybe my I can help you.

I used the SRF05 together with a PIC33FJ128MC802 chip.For measuring distance, I use timer3. I have set up timer 3 with an interrupt and a gate. The gate feature is enabling the timer to measure, how long time the gate pin is high and fire an interrupt when it goes low. The echo pin of the SRF05 is wired to the gate pin and the time the echo pin is high is proportional with the distance (see SRF05 spec sheet). So, it is all just a matter of setting the PING pin high, wait 10usec, setting the PING pin low and in the interrupt routine, read the timer value, which is the distance.

I don’t know if your PIC has the gate pin feature. What PIC chip are you using?

My test code is here. It doesn’t do much, since it is a cut’n’paste from a larger program:

#include <p33FJ128MC802.h>
#include <timer.h>

_FOSCSEL(FNOSC_FRC & IESO_OFF);

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_HS);

#define PING _RB10
#define PINGbit 0b0000010000000000
#define ECHO _RB11
#define ECHObit 0b0000100000000000

unsigned int volatile distance = 0;
int volatile pinging = 0;

void cpu_setup(void)
{
//Setup oscillator
//===============
//Fosc = FinM/(N1N2)
//Fin = 20Mhz
//Fosc = 2024/(32)
PLLFBD=22;
CLKDIVbits.PLLPRE=1;
CLKDIVbits.PLLPOST=0;
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);

while(OSCCONbits.COSC != 0x03);
while(OSCCONbits.LOCK != 0x01);

//Setup ports
//===========
AD1PCFGL = 0xffff;
TRISA = 0; //All pins output
TRISB = 0; //All pins output
_TRISB11 = 1; //B11 input
PORTA = 0; //All pins low
PORTB = 0; //All pins low

//Set timer3 gate
//===============
_T3CKR=11; //RP11 is the ECHO pin

}

//Delay a number of uS using timer2
void delayus(unsigned int delayTime)
{
WriteTimer2(0);
OpenTimer2(T2_ON & T2_PS_1_256 & T2_32BIT_MODE_OFF & T2_SOURCE_INT & T2_GATE_OFF & T2_IDLE_CON, 0xFFFF);
while(ReadTimer2() < (delayTime/6.4)) { }
CloseTimer2();
}

//Delay a number of mS using timer2
void delayms(unsigned int delayTime)
{
WriteTimer2(0);
OpenTimer2(T2_ON & T2_PS_1_256 & T2_32BIT_MODE_OFF & T2_SOURCE_INT & T2_GATE_OFF & T2_IDLE_CON, 0xFFFF);
while(ReadTimer2() < (delayTime/0.0064)) { }
CloseTimer2();
}

//ECHO timer interrupt
void attribute((interrupt, auto_psv)) _T3Interrupt(void)
{
distance = ReadTimer3();
pinging = 0;
WriteTimer3(0);
//Clear interrupt
_T3IF=0;
}
//Send ping
void ping(void)
{
if (pinging)
return;
pinging = 1;
PING = 1;

//Use timer3 in gated mode to measure time of echo
WriteTimer3(0);
ConfigIntTimer3(T3_INT_PRIOR_2 & T3_INT_ON);
OpenTimer3(T3_ON & T3_PS_1_64 & T3_SOURCE_INT & T3_GATE_ON & T3_IDLE_CON, 0xFFFF);

//Use timer2 to measure 10us ping
delayus(10);
PING = 0;
}

int main(void)
{
int x;

cpu_setup();
ping();
while(1) {
distance = 0;
ping();
while (pinging) { }

//Wait 50 ms to let echo die out

delayms(50);

//Here we can use distance


}
while(1);
}

hi

thanks for your help …

am using pic16f877 and i want to use timer1 with SRF05 …flowcode3 is a flowchart programming for pic’s and can use C-codes.

but i think you should know this before looking through the code generated.

Flowcode variables are given the prefix FCV_ in C code. It is this C code that is compiled to give you your working program.

Flowcode V3 does not currently have direct access to registers onboard the chip without using C code.

You would insert writes from your variables into the timer registers whenever you need to initialise the timer with a preset variable.

You would insert reads to your variables whenever you need to know the current timer count value.

this is the C-code generated by flwocode3…it seems that i am missing somethimg in using timer1 or something else??




#define MX_PIC

//Defines for microcontroller
#define P16F877
#define MX_EE
#define MX_EE_SIZE 256
#define MX_SPI
#define MX_SPI_C
#define MX_SPI_SDI 4
#define MX_SPI_SDO 5
#define MX_SPI_SCK 3
#define MX_UART
#define MX_UART_C
#define MX_UART_TX 6
#define MX_UART_RX 7
#define MX_I2C
#define MX_MI2C
#define MX_I2C_C
#define MX_I2C_SDA 4
#define MX_I2C_SCL 3
#define MX_PWM
#define MX_PWM_CNT 2
#define MX_PWM_TRIS1 trisc
#define MX_PWM_1 2
#define MX_PWM_TRIS2 trisc
#define MX_PWM_2 1

//Functions
#include <system.h>
#pragma CLOCK_FREQ 8000000

//Configuration data
#pragma DATA 0x2007, 0x3ffa

//Internal functions
#include “C:\Program Files\Matrix Multimedia\Flowcode V3\FCD\internals.h”

//Macro function declarations


//Variable declarations
char FCV_ECHO_LOOP;
short FCV_DISTANCE;
char FCV_ECHO;
char FCV_TMR1H;
char FCV_TMR1L;



//Supplementary defines


//Macro implementations

//Supplementary implementations


void main()
{

//Initialisation
adcon1 = 0x07;


//Interrupt initialisation code
option_reg = 0xC0;


//Loop
//Loop: While 1
while( 1 )
{
//Delay
//Delay: 250 ms
delay_ms(250);


//C Code
//C Code:

tmr1h = 0x00; //Initialise the timer value to 0
tmr1l = 0x00; //Initialise the timer value to 0



//Output
//Output: 0xff -> C4
trisc = trisc & 0xef;
if (0xff)
portc = (portc & 0xef) | 0x10;
else
portc = portc & 0xef;


//C Code
//C Code:
delay_us(10);



//Output
//Output: 0 -> C4
trisc = trisc & 0xef;
if (0)
portc = (portc & 0xef) | 0x10;
else
portc = portc & 0xef;


//Input
//Input: C5 -> Echo
trisc = trisc | 0x20;
FCV_ECHO = ((portc & 0x20) == 0x20);


//Decision
//Decision: Echo?
if( FCV_ECHO )
{
//C Code
//C Code:

t1con = 0x3B; //Enable timer1 with 1:8 prescaler



//Loop
//Loop: While Echo
while(1)
{
if (( FCV_ECHO ) == 0) break;
}


//C Code
//C Code:

t1con.0=0;
FCV_TMR1L=tmr1l;
FCV_TMR1H=tmr1h;




//Calculation
//Calculation:
// Distance = ( ( TMR1H << 8 ) + TMR1L )
FCV_DISTANCE = ( ( FCV_TMR1H << 8 ) + FCV_TMR1L ) ;


}


//Delay
//Delay: 250 ms
delay_ms(250);


}


mainendloop: goto mainendloop;
}

void interrupt(void)
{

}

I have never used the

I have never used the 16f877, but a quick look at the datasheet reveals that it does not have the gated timer mode that I use with the dsPIC. Your code looks like it ought to work. I have some questions, though:

1. Won’t “if (0xff)” always be true? Also, you have an if(0) laterthat always evaluates to false.

2. You set t1con = 0x3B. 0x3B = 111011, which, according to datasheet is:
TMR1ON=1
TMR1CS = 1
T1SYNC=0
T1OSCEN=1
T1CKPS=11

I notice that you have TMR1CS = 1 => External clock. Do you have an external clock in your setup? (Not the main crystal on OSC1/2, but a separate timer oscillator on T1OSI/T1OSO). If you don’t, you need to set TMR1CS=0 or else the timer doesn’t run. Also, I’m not sure that you need T1OSCEN=1 when using the interal timer, but I’m not sure on this.

**hi **

thank you very much for your help JKA you wont believe how long i have been struggling with SRF05 i knew that my problem is in uisng timer1 as it should be…i am using 8mhz crystal on pins OSC1/2 so i think i have to change TMR1CS=0,i

 

but i didnt get what you mentioned about the if statments " Won’t “if (0xff)” always be true? Also, you have an if(0) laterthat always evaluates to false" may be i didnt understand how ultrasonic sensor works???

this is my procedure…

1. Turn Sensor Pwr Hi
Delay for 100ms

2.C-code Containing

tmr1h=FCV_CAPTUREH; load pic tmr1h,tmr1l in flowcode
tmr1l=FCV_CAPTUREL;

3. Output 1 to the INIT pin
delay_us(10);or 20 micro seconds

4. C Icon contain g,initialize timer1 to zero

tmr1h = 0x00;
tmr1l = 0x00;

5. Wait for ECHO pin to go high

6. t1con = 0x31; Start timer counting with 1 : 8 prescalar

7.Keep counting while ECHO pin is high (LOOP)

8. if ECHO pin becomes LOW>>>>>C Icon containg

t1con.0 = 0; //Stop Timer1 Counting
FCV_CAPTUREH = tmr1h;get tmr1h value
FCV_CAPTUREL = tmr1l;get tmr1l value

9.Distance = ( ( CaptureH << 8 ) + CaptureL )/58, calculate distance in cm >>(distance is an integer)

10. Output a 0 to the INIT pin

11.delay 100 Milli seconds

12.Repeat again

In C, 0 is the same as false

In C, 0 is the same as false and everything else is true, if you use it in if and while statements. So, if(0xff) or if(255) in decimal is always true. Likewise, if(0) is always false.

The question is, what are you trying to do here:

trisc = trisc & 0xef;
if (0xff)
portc = (portc & 0xef) | 0x10; <-- This is always executed, becuase 0xff is always true
else
portc = portc & 0xef;

 

and here:

 

trisc = trisc & 0xef;
if (0)
portc = (portc & 0xef) | 0x10;
else
portc = portc & 0xef; <-- This is always executed, becuase 0 is always false

 

I don’t know, if it has any effect on your program, though

 

Your method for reading the SRF05 seems ok

hi

tahnks again for your help and support …

my inquiry is when i trigger the sensor lets say pin C2 to the SRF05 the sensor will send an echo pulse to pic pin lets say C3 the sensor will send(raise) its echo line so that an input 5v will always be sent to the pin C3 ,at thisinstance i will start a timer to measure time so i need a statement that will instruct the pic to start a timer as soon as the echo pin goes high (C5 is 5v) and to keep measuring time untill the echo pin goes low by either detecting something or after 30 milli seconds if nothing is detected so then i will have to stop the timer and get that value and do the calculations,so my question is what is the suitable instruction to start the timer and stop it is it if ECHO start timer and how to stop the timer do i use while ECHO keep looping is that right or is there another way to do it

 

This is where the gated mode

This is where the gated mode of the dsPIC is nice to have, because it takes care of it all automagically. :slight_smile:

You could take a look at the CCP module (Capture/Compare/PWM) http://ww1.microchip.com/downloads/en/DeviceDoc/31014a.pdf. This is all a theoretical thing, that I havent given much thought, but:

Connect the ECHO pin of SRF05 to CCP1 (or CCP2 if you prefer that). In CCP1CON set CCP1Mode to "Capture every rising edge".

Create an interrupt routine for the CCP1 capture, a global variable called "measured" and another one called "done"

When you wish to measure the distance, do:

Initialize measured and done to 0
Reset and enable timer1
Pull the trigger pin of SRF05 high and low to send a ping.
while(!done); //Loops until done is true (=not 0)
//Now measured holds the time of the ping

In the interrupt routine you have:
if (measured == 0) {
measured = timer1 value
Configure CCP1CON to "Capture every falling edge"
} else {
measured = timer1 value - measured.
done = 1
}

Does this make sense?

What I try to say is, you setup the capture module to trigger an interrupt when the CCP1 pin goes high. This is when the SRF05 starts to measure the distance. In the interrupt routine we note the time this happens (because time has passed from the reset and enable of timer 1 and until the echo pin goes high). Then we reconfigure the capture module to trigger the interrupt when CCP1 goes low. This is when the SRF05 receives the echo. The time that the CCP1 pin was high (= the time of the echo to arrive) is the difference between these two timer1 values.

You might want to read the datasheet on the CCP module and interrupts. You can find them on http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010242

Good luck :slight_smile:

hi

THANK you very much for your help jka ,actually pic 16f877 has two CCP modes tha can be used but i need these two pins for "DC pwm motor controlling"

thanks for your help and thank you again.i willl tell you waht happens with me later on …actually its 2 am in the morning here in jordan and am trying to get the sensor to function as it should…

There is always too few CCP

There is always too few CCP modules :).

Glad I could help you. Good luck.