DPRG.c

IR obstacle detector for PIC12F629 and IR Remote Control Receiver RPM7138 (by Tsvetelin Velkov).



#include <system.h>

//======================================
// Setting Configuration and ID Bits
//======================================
#pragma DATA    0x2007, _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT
#pragma DATA    0x2000, 0x0C, 0x0E, 0x0C, 0x00 
#pragma DATA    0x03FF, 0x3444  // modify this value to be the same as on your pic controller
#pragma CLOCK_FREQ 4000000

char    count,pulse,mils,stot,sec,ratio;

//======================================
//Interrupt Routine
//======================================
void interrupt(void)
{
    mils++;                     // counts miliseconds
    tmr0 = 131;                 // set TMR0 
    clear_wdt();                // clear WDT -> don't forget to do that ;->>
    clear_bit(intcon,T0IF);     // clear interrupt flag
}

//=======================================
//Internal Oscilator Calibration Routine
//=======================================
inline void init(void)
{
    asm
    {
        bsf _status,RP0
        call 0x3FF
        movwf _osccal
        bcf _status,RP0
    }
}

//=======================================
//IR Right Checking Routine
//=======================================
char IRRCheck(void)
{
    char WAIT,prob;
    prob = 0;

    asm
    {
            MOVLW   23
            MOVWF   _WAIT
        loop1:
            BSF _gpio,2
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            BCF _gpio,2
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            BTFSS   _gpio, 1    // Look for a detection
            INCF    _prob,F
            NOP
            NOP
            DECFSZ  _WAIT,F
            GOTO    loop1
    }

    asm
    {
            MOVLW   23
            MOVWF   _WAIT
        loop2:
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DECFSZ  _WAIT,F
            GOTO    loop2
    }

    return prob;
}

//=======================================
//IR Left Checking Routine
//=======================================
char IRLCheck(void)
{
    char WAIT,prob;
    prob = 0;

    //high modulated signal for 300us
    //modulation is on 38KHz
    asm
    {
            MOVLW   23
            MOVWF   _WAIT
        loop1:
            BSF _gpio,0
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            BCF _gpio,0
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            BTFSS   _gpio, 1    // Look for a detection
            INCF    _prob, F
            NOP
            NOP
            DECFSZ  _WAIT,F
            GOTO    loop1
    }

    // low signal for 300us 
    asm
    {
            MOVLW   23
            MOVWF   _WAIT
        loop2:
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DECFSZ  _WAIT,F
            GOTO    loop2
    }

    return prob;
}

//=======================================
// Check for noises routine
//=======================================
char NLCheck(void)
{
    char WAIT,prob;
    prob = 0;

    //==================================
    //just count 46 times x 26us = 600us
    //and watch GP1, this have to detect the noise level
    asm
    {
            MOVLW   46
            MOVWF   _WAIT
        loop1:
            BCF _gpio, 0
            BCF _gpio, 2
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            BTFSS   _gpio, 1    // Look for a detection
            INCF    _prob, F
            NOP
            NOP
            DECFSZ  _WAIT,F
            GOTO    loop1
    }

    return prob;
}

//=====================================================
// Detect a obstacle on Right also detect the noise
//=====================================================
char RCheck(void)
{
    char detect,noise,i;

    for(i=0;i<10;i++)
    {
        noise += NLCheck();
        noise /= 2;
    }

    for(i=0;i<10;i++)
    {
        detect += IRRCheck();
        detect /= 2;
    }

    if(detect > noise)
    {
        detect -= noise;
    }
    else
    {
        detect = 0;
    }

    return detect;
}

//===============================================
// Detect a obstacle on Left 
//===============================================
char LCheck(void)
{
    char detect,noise,i;
    //detect noise
    //10x600us = 6ms !
    for(i=0;i<10;i++)
    {
        noise += NLCheck();
        noise /= 2;
    }
    //detect obstacle
    //10x600us = 6ms !
    for(i=0;i<10;i++)
    {
        detect += IRLCheck();
        detect /= 2;
    }
    // if detect > noise -> we have obstacle
    if(detect > noise)
    {
        detect -= noise;
    }
    else
    {
        detect = 0;
    }

    return detect;
}

//=======================================
//Main Routine
//=======================================
void main()
{
    option_reg  = 00000010b;    //set prescaler to 1:8 this means 125000 pulses per second and weak pull-up enable
    trisio      = 11001010b;    //set GP1,GP3 as input ,others output
    cmcon       = 00000111b;    //set GP0,GP1,GP2 as a digital IO 
    init();                     //Calibration  
    tmr0 = 131;                 //1000000/8=125000/125=1000 ili 1ms
    intcon = 0xA0;              //enable GIE & TMR0 interrupt

    count   = 0;
    pulse   = 0;
    mils    = 0;                //this counts miliseconds
    stot    = 0;                //this counts hundreds of miliseconds
    sec     = 0;                //this counts seconds 
    ratio   = 0;                //modify here to adjust the detection to the noise ratio

    while(1)
    {
        if(mils > 99)
        {
            mils = 0;
            stot++;
        }

        if(stot > 9)
        {
            stot = 0;
            sec++;
        }

        pulse = gpio;
        if(((pulse & 0x08) == 0x08) || (sec > 2))
        {
            //===================
            // Checking on right
            count = RCheck();
            if(count > ratio)
            {
                set_bit(gpio,GP4);      // if there is a obstacle on right -> thurn the right led on
            }
            else
            {
                clear_bit(gpio,GP4);
            }

            //===================
            // Checking on left
            count = LCheck();
            if(count > ratio)
            {
                set_bit(gpio,GP5);      // if there is a obstacle on left -> thurn the left led on
            }
            else
            {
                clear_bit(gpio,GP5);
            }

            //============================
            // it should check every 3 sec
            sec = 0;
        }
    }
}



http://www.sourceboost.com/home.html

Copyright © 2002-2006 SourceBoost Technologies