Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

after 10 seconds

Status
Not open for further replies.

mrfunkyjay

New Member
Hi all,

I have a source code as my project and would like to modify it.

The project is getting pulse from Receiver Module of RC and process it then giving output to LEDs. For those who were posting in my thread knew this.

Now I wish to do some kind of modification.

I have a forever loop, checking the pulse from 1st and 2nd channel of RC Receiver module and now I wish to have a system where after 10s there is no pulse greater than 1.6ms and less than 1.4ms, led will blink, let's say this simulates four blinking LEDs when stopping (for a while) in the middle of the road (real cars).

At the moment I have a subroutine called vStandby, this is used to turn off the blinker (left or right leds), turn on four LEDs, two of them sourced by PIC output pin high and two of them by CCP1 register, using PWM. In short, this standby subroutine executed everytime my remote control is positioned at the center (both steering and throttle).

I cannot get the idea of making 10s counter that counts up to 10s when it is more than 10s, it should execute the four blinker LEDs subroutine.

Anyone care to give an Idea?? I am using 20Mhz OSC and PIC18F4520. MPLAB C18 Compiler and PICkit2.

Thanks!

Best regards,

Kelvin
 
You can use an extarnal timer1 (32.768Khz), have it interrupt on overflow to give you a 1 second counter. You just need to keep count of the seconds, and use that to decide if the led must be on or off. Many MC datasheets have some sample code to create a realtime clock.
 
hi,
This should give you an idea regarding delays.

I cannot get the idea of making 10s counter that counts up to 10s when it is more than 10s, it should execute the four blinker LEDs subroutine.

Anyone care to give an Idea?? I am using 20Mhz OSC and PIC18F4520. MPLAB C18 Compiler and PICkit2.



I know its assembler code, requires to be translated into C18.
 
A while ago I converted the servo reading code to work on interrupts.

It's a little more complicated than the code you are working with but gives you the advantage that the measurement of the servo pulses is done automatically.

For this code to work the pulses must be on B4 through B7 as it uses the interrupt on change feature of these pins.

Code:
#define ServoPin PORTBbits.RB4
#define ServoTris TRISBbits.TRISB4
#define ServoBit 4

int ServoPos;

void low_isr();                    

#pragma code low_vector=0x18    //setup the ISR vector
void low_interrupt (){
  _asm GOTO low_isr _endasm    //jump to interrupt handler
}
#pragma code

#pragma interruptlow low_isr   //the ISR
void low_isr(){
static unsigned char PortState;
    if((PortState^PORTB)&(1<<ServoBit)){
        if(PORTB&(1<<ServoBit)){
            TMR1L=0;
            TMR1H=0;
            T1CONbits.TMR1ON=1;
        }else{
            T1CONbits.TMR1ON=0;         //stop timer 1
            ServoPos=TMR1H*256+TMR1L;   //16 bit timer value       
        }
    }
    PortState=PORTB;
    INTCONbits.RBIF=0;
}
#pragma code

//and in main I did,

    T1CON=0;
    ServoTris=1;
    INTCONbits.RBIE=1;
    INTCONbits.GIE=1;

Once the interrupts are enabled the pulse length will magically appear in ServoPos.

To read a second pulse, repeat the bit in the if((PortState^PO... with a new set of port definitions. You can still use Timer 1 for the other pulse.

If you are sure of the 20mS timing of your RC then you could add a time variable to the ISR as well.

Mike.
 
Much of the extra code size is due the C startup routine generically call C0. In the case of the C18 compiler it is called C018. It does variable initialization and a few other things, it gets the system ready to run user code. It is overhead that you have with a C program regardless of size. I think you will find that all (maybe most) compilers have a similar routine.
 
Was there something wrong with the method I proposed in the OP's other thread (grin)?

Seriously, well done Mike...

Nothing wrong with your method whatsoever. I wrote it to use the IOC because, due to a PM, I knew the OP wanted the CCP module for PWM.

Mike.
 
Just out of interest, how large is that code you wrote when compiled Pommie? I only know asm, and could not believe how big the sample C and Basic programs that I tried when compiled.

Regards,

After adding some initialisation code and a couple more variables it uses 0x17f (367) instructions. Pretty compact. The code expands (explodes?) a fair bit when you start including library functions.

This was the actual code compiled,
Code:
#include <p18f1320.h> 

#pragma config WDT = OFF, LVP = OFF, OSC = INTIO2

#define ServoPin PORTBbits.RB4
#define ServoTris TRISBbits.TRISB4
#define ServoBit 4

void low_isr();                    

int isrServoPos;

#pragma code low_vector=0x18                //setup the ISR vector
void low_interrupt (){
  _asm GOTO low_isr _endasm                 //jump to interrupt handler
}
#pragma code

#pragma interruptlow low_isr                //the actual ISR
void low_isr(){
static unsigned char PortState;             //to remember previous state
    if((PortState^PORTB)&(1<<ServoBit)){    //has the servo pin changed?
        if(PORTB&(1<<ServoBit)){            //is it the start of a pulse
            TMR1L=0;
            TMR1H=0;                        //yes, so start timer
            T1CONbits.TMR1ON=1;
        }else{                              //must be end of pulse
            T1CONbits.TMR1ON=0;             //so, stop timer 1
            isrServoPos=TMR1H*256+TMR1L;    //Store 16 bit timer value
        }
    }
    PortState=PORTB;                        //keep copy of previous state
    INTCONbits.RBIF=0;                      //clear interrupt flag
}
#pragma code

void main(void){
int ServoPos;
    OSCCON=0x70;                            //8MHz please
    ADCON1=0x7f;                            //no ADC
    INTCON2bits.NOT_RBPU=0;                 //WPU on
    T1CON=0;                                //init timer 1
    ServoTris=1;                            //servo pin set to input
    INTCONbits.RBIE=1;                      //port B change interrupt enabled
    INTCONbits.GIE=1;                       //Global interrupts enabled

    while(1){
        if(isrServoPos!=ServoPos)
            ServoPos=isrServoPos;

    }
}

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top