• AVR Freaks

AnsweredHot!Difference between capture and compare modes with examples

Page: << < ..678910.. > >> Showing page 10 of 13
Author
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 17:09:48 (permalink) ☄ Helpfulby eagle1 2018/07/25 18:15:05
+1 (1)
Hi
PStechPaul
According to the second link, the pulse times are 1.125 mSec and 2.25 mSec. And there is also a carrier frequency of 30-56 kHz, which needs to be considered and processed.

Its only necessary handle the carrier if a simple photodiode or phototransistor is used on the receive side.
But there are specialized IR receivers that deal with the carrier detection and output the de-modulated signal.
 
Bear in mind that a common hand-held remote is not a very precise device, timmings will vary widely with temperature and battery status, so the decoding in the receive side must accept wide variations.
By the documentation I've found, the more common strategy is to decode the "1" and "0" based on the low/high duration ratio of 1/1, or 50% duty cycle, for "0" and 2/1, or 30% duty cycle, for "1".
 
I've found several solutions out there based on a simple free running timer and IOC to detects the transitions.
 
EDIT: Typos
post edited by JorgeF - 2018/07/25 18:09:54

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 22:07:54 (permalink)
0
I'm working with this code, which is not working I assume:
uint32_t capture_VS1838b(void)
{
    uint16_t capture_period;
    uint32_t ir_code;int8_t i;
    TRISCbits.RC2=1; // CCP1 at port C as input
    T1CON=0x80; // timer1 16-bits
    CCP1CON=0x05;INTCON=0x00; // Capture settings & disable all interrupts
    T1CONbits.TMR1ON=1; // turn on timer1
    capture_period = get_period();
    if (capture_period < 13800 && capture_period > 13200) // measuring 9ms+4.5ms=13.5ms
    {
        for (i=0;i<32;i++)
        {
            capture_period = get_period();
            if (capture_period < 12800 && capture_period > 1150) // check if pulse is 0
                BIT_CLEAR(ir_code,(31-i));
            else if(capture_period < 2300 && capture_period > 2200) // check if pulse is 1
                BIT_SET(ir_code,(31-i));
        }
    }
        return ir_code;
}

uint16_t get_period(void)
{
    uint16_t data1,data2;
    while(!PIR1bits.CCP1IF); // wait for capture input signal
    PIR1bits.CCP1IF=0; // clear the capture flag bit
    data1 = CCPR1; // copy the 1st data of capture data register
    while(!PIR1bits.CCP1IF); // wait for another capture input signal
    PIR1bits.CCP1IF=0; // clear the capture flag bit
    data2 = CCPR1; // copy the 2nd data of capture data register
    return data2 - data1;
}

 
This one in the main application:
void main(void) {
    DISABLE_INT_AN_4MHZ;
    i2c_init();
    i2c_start();
    LCD_Init();
    
    uint8_t val_arr[20];
    uint32_t capture_val;
    while(1){
        capture_val = capture_VS1838b();
        sprintf(val_arr,"%x",capture_val);
        LCD_string("remote code:");
        move_cursor(2,0);
        LCD_string("0x");
        move_cursor(2,2);
        LCD_string(val_arr);
        __delay_ms(500);
        sendCMD(clear_display);
    }
}

 
"capture_VS1838b();" should return 32-bits value, but I get 16-bits reading on the LCD!
 
post edited by eagle1 - 2018/07/25 22:17:40
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 22:12:50 (permalink)
+1 (1)
The problem could be in
BIT_CLEAR
and
BIT_SET
but you did not show the code for them.



This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 22:19:56 (permalink)
0
#define BIT_SET(d,b) (d|=(1<<b))
#define BIT_CLEAR(d,b) (d&=~(1<<b))

 
Tested them in CodeBlocks, and it's working, I don't know if they have some unpredictable actions time sensitive code.
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 22:27:29 (permalink) ☄ Helpfulby eagle1 2018/07/25 22:42:03
+2 (2)
eagle1
Tested them in CodeBlocks, and it's working,

That tells you nothing, because Codeblocks is not XC8 and has different sized default variable sizes.
Try
#define BIT_SET(d,b) (d|=(1U<<b))
#define BIT_CLEAR(d,b) (d&=~(1U<<b))
 
Note, doing a shift by a variable amount is a pretty inefficient thing to do in a PIC, so this code should work, but in a pretty inefficient way.
Once you get this working, you could investigate just setting or clearing a single fixed bit in your scratch variable, then shifting the whole variable one bit left or right every time around the loop.
That is the sort of thing a PIC can do very efficiently.
 
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 23:20:47 (permalink) ☄ Helpfulby eagle1 2018/07/26 00:24:48
+1 (1)
Try 1UL instead of 1U or 1, since it is shifted up to 31 bits.
 
Edit: Replace
for (i=0;i<32;i++)
BIT_CLEAR(ir_code,(31-i));
BIT_SET(ir_code,(31-i));

with
for (i=31;i>=0;i--)
BIT_CLEAR(ir_code,i);
BIT_SET(ir_code,i);

to avoid the subtraction.
post edited by 1and0 - 2018/07/25 23:25:20
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 23:24:40 (permalink)
+1 (1)
1and0
Try 1UL instead of 1U or 1, since it is shifted up to 31 bits.

+1
That's what I intended. :)
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/25 23:35:00 (permalink)
+1 (1)
In capture_VS1838b() ir_code should be initialized to a known value. Also, in that for() loop the if/else-if should only be if/else instead.
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 00:23:25 (permalink)
0
qɥb 
Note, doing a shift by a variable amount is a pretty inefficient thing to do in a PIC, so this code should work, but in a pretty inefficient way.

Hmm how could I know that something isn't efficient? I think one way is to break it into assembly.
 
 

Once you get this working, you could investigate just setting or clearing a single fixed bit in your scratch variable, then shifting the whole variable one bit left or right every time around the loop.
That is the sort of thing a PIC can do very efficiently.

 
You mean like this one:
uint32_t send_data(uint32_t data)
{
   uint8_t i,data_cpy,shifter=0x80000000;

   for (i = 0; i < 32; i++)
   {
       if (data & 0x80000000)
       {
           printf("1");
           data_cpy |= shifter;
       }
       else
       {
           printf("0");
           data_cpy &= ~shifter;
       }

       data <<= 1;
       shifter >>=1;
   }
   printf("\n");
    return data_cpy;
}

This function convert from HEX to binary.
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 00:27:08 (permalink)
0
1and0
Try 1UL instead of 1U or 1, since it is shifted up to 31 bits.
 
Edit: Replace
for (i=0;i<32;i++)
BIT_CLEAR(ir_code,(31-i));
BIT_SET(ir_code,(31-i));

with
for (i=31;i>=0;i--)
BIT_CLEAR(ir_code,i);
BIT_SET(ir_code,i);

to avoid the subtraction.




I copied these macros from this website:
http://ccspicc.blogspot.com/2016/07/nec-protocol-ir-remote-control-decoder-pic16f877a-ccs-pic-c.html?m=1
 
He's really good and did it with digital input and delays. And I'm struggling with the more precise CCP LOL that's funny :)
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 00:30:37 (permalink)
+2 (2)
eagle1
I'm working with this code, which is not working I assume:

        sprintf(val_arr,"%x",capture_val);

"capture_VS1838b();" should return 32-bits value, but I get 16-bits reading on the LCD!

Try "%lx".
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 00:40:07 (permalink)
+1 (1)
eagle1
Hmm how could I know that something isn't efficient? I think one way is to break it into assembly.

By familiar yourself with the PIC architecture and instruction set, and what they can do.
 

You mean like this one:
uint32_t send_data(uint32_t data)
{
   uint8_t i,data_cpy,shifter=0x80000000;

   for (i = 0; i < 32; i++)
   {
       if (data & 0x80000000)
       {
           printf("1");
           data_cpy |= shifter;
       }
       else
       {
           printf("0");
           data_cpy &= ~shifter;
       }

       data <<= 1;
       shifter >>=1;
   }
   printf("\n");
    return data_cpy;
}

This function convert from HEX to binary.

That is an efficient inefficient way to copy data to data_cpy, when it is simply
data_cpy = data;

provided you correct the type to uint32_t.
 
post edited by 1and0 - 2018/07/26 00:49:27
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 00:55:35 (permalink)
0
eagle1
This function convert from HEX to binary.

Look up the ultoa() function.
 
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 01:06:29 (permalink)
0
1and0
 
That is an efficient inefficient way to copy data to data_cpy, when it is simply
data_cpy = data;

provided you correct the type to uint32_t.

Yeah, but it also print the HEX value into binary, it's one of the functions I worked out when I started learning C.
1and0
Access is Denied
  • Total Posts : 9314
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 02:03:34 (permalink)
+1 (1)
eagle1
Yeah, but it also print the HEX value into binary, it's one of the functions I worked out when I started learning C.

Here:
    ultoa(str, val, 2); // convert to binary string
    if (strlen(str) == 32)
        printf("%s\n", str);
    else
        printf("%0*d%s\n", (int)(32-strlen(str)), 0, str); // prepend 0s

eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 03:34:37 (permalink)
0
How about this one:
int main(void) {
uint32_t buffer,code=0xff0b0025;
uint8_t i;

for (i=0;i<32;i++)
{
    if (code & (1<<i))
        buffer |= (1<<i);
    else
        buffer &= ~(1<<i);

}
printf("0x%.8x",buffer);
    return 0;
}

 
Is it better than:
#define BIT_SET(d,b) (d|=(1<<b))
#define BIT_CLEAR(d,b) (d&=~(1<<b))

eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 03:36:49 (permalink)
0
1and0
 
Here:
    ultoa(str, val, 2); // convert to binary string
    if (strlen(str) == 32)
        printf("%s\n", str);
    else
        printf("%0*d%s\n", (int)(32-strlen(str)), 0, str); // prepend 0s


Can I benefit from this into my "capture_VS1838b()" function?
 
 
I don't know what I'm missing!
I learned that the VS1838b works as pulling the pin low for incoming signal, so I changed the capture mode to capturing the falling edge. But still I get 0!
 
Now how about the function procedure, would it get the preceding bits after I test the NEC 13.5ms protocol?
uint32_t capture_VS1838b(void)
{
    uint16_t capture_period;
    uint32_t ir_code;uint8_t i;
    TRISCbits.RC2=1; // CCP1 at port C as input
    T1CON=0x80; // timer1 16-bits
    CCP1CON=0x04; // Capture settings every falling edge
    T1CONbits.TMR1ON=1; // turn on timer1
    capture_period = get_period();
    if (capture_period > 14000 && capture_period < 13200) // measuring 9ms+4.5ms=13.5ms
    {
        for (i=0;i<32;i++)
        {
            capture_period = get_period();
            if (capture_period < 1400 && capture_period > 1200) // check if pulse is 0 for 1.25ms
            ir_code |= (1<<i);
            else if(capture_period < 2300 && capture_period > 2200) // check if pulse is 1 for 2.25ms
            ir_code &= ~(1<<i);

        }
    }
        return ir_code;
}

 
Procedure:
1. Turn on the timer.
2. Start the test with "capture_period = get_period();", to test the 13.5ms protocol.
3. If yes then enter the loop of recording the 32 bits.
4. Again, call the function for each coming bit.
5. If the bit has a width of 1.25ms, then it's a 0. Otherwise, if it's 2.25ms then it's a 1.
 
But I don't get results!
post edited by eagle1 - 2018/07/26 03:45:28
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 19:36:12 (permalink)
0
I want to change the method of measuring the widths of the bits with; e.g. IOC and external ints and then maybe I may understand how to apply the capture mode.
 
I read this in a website:
PORTB is only used for the interrupt-on-change feature. Polling of PORTB is not recommended while using the interrupt-on-change feature.

 
Does that mean, that IOC only works by enabling interrupts and not only checking the flag bit; like, timers and CCP modules?
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 19:47:04 (permalink)
+2 (2)
No.
It means you should not have code regularly reading PORTB while you have IOC active.
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/26 22:52:27 (permalink)
0
qɥb
No.
It means you should not have code regularly reading PORTB while you have IOC active.

I'm trying to test IOC, what should I do exactly? Is it necessary to enable "RBIE" to get interrupt on change for PORTB pins 4-7? Or it works without enabling the interrupt bit?
 
I've done some work on the enabling/disabling interrupts and other configurations for my config.h file.
#define ENABLE_INT_IOC (INTCON=0xC8,INTCON2=0x00,INTCON3=0x00) // INTCONbits.RBIF
#define ENABLE_PIN_INT0_RISING (INTCON=0xD0,INTCON2=0x40,INTCON3=0x00) // INTCONbits.INT0IF
#define ENABLE_PIN_INT1_RISING (INTCON=0xC0,INTCON2=0x20,INTCON3=0x08) // INTCON3bits.INT1IF
#define ENABLE_PIN_INT2_RISING (INTCON=0xC0,INTCON2=0x10,INTCON3=0x10) // INTCON3bits.INT2IF
#define ENABLE_PIN_INT0_FALLING (INTCON=0xC0,INTCON2=0x00,INTCON3=0x00) // INTCONbits.INT0IF
#define ENABLE_PIN_INT1_FALLING (INTCON=0xC0,INTCON2=0x00,INTCON3=0x08) // INTCON3bits.INT1IF
#define ENABLE_PIN_INT2_FALLING (INTCON=0xC0,INTCON2=0x00,INTCON3=0x10) // INTCON3bits.INT2IF
#define DISABLE_INT (INTCON=0x00,INTCON2=0x00,INTCON3=0x00) // Disable all interrupts
#define AN_ENABLE (ADCON0=0x01,ADCON1=0x0f,CMCON=0x07) // ADCON0 choose CH & ADCON1 set of pins DIG/AN
#define AN_DISABLE (ADCON0=0x00,ADCON1=0x0f,CMCON=0x07) // Disable ADC
#define INTOSC_4MHz (OSCCON=0x66) // internal osc 4MHz
#define INTOSC_8MHz (OSCCON=0x76) // internal osc 8MHz

 
I'm trying to test both interrupts on PORTB by I don't know why it's not working! It's probably my first experience with PIC interrupts.
 
Here's my complete code set:
1. Main code:
void main(void) {
    INTOSC_4MHz;
    AN_DISABLE;
    ENABLE_PIN_INT0_RISING;
    TRISBbits.RB0=1;
    TRISDbits.RD2=0;
    while(1){
        EXT_INT0_RISING();
    }
}

 
2. Interrupts.c
 
void EXT_INT0_RISING(void)
{
    LATDbits.LATD2=0;
}

 
void interrupt INT_LOW(void)
{
    while(!INTCONbits.RBIF)
    {
        INTCONbits.RBIF=0;
        LATDbits.LATD2=1;
    }

    while(!INTCONbits.INT0F)
    {
        INTCONbits.RBIF=0;
        LATDbits.LATD2=1;
    }
}

 
3. Configuration bits for INT0:
#define ENABLE_PIN_INT0_RISING (INTCON=0xD0,INTCON2=0x40,INTCON3=0x00) // INTCONbits.INT0IF

 
What I'm missing here?
Page: << < ..678910.. > >> Showing page 10 of 13
Jump to:
© 2019 APG vNext Commercial Version 4.5