• AVR Freaks

AnsweredHot!Difference between capture and compare modes with examples

Page: << < ..111213 > Showing page 11 of 13
Author
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 23:01:42 (permalink) ☄ Helpfulby eagle1 2018/07/26 23:55:01
+2 (2)
This is my personal opinion.
Defining macros like that is a TERRIBLE idea.
It hides what is really happening, and obliterates the INTCON register every time you use it.
You are also enabling interrupts before you have finished your initialisation code. I strongly recommend you do not set GIE until all of your initialisation has been done.
 
Do not put while() statements inside an interrupt service like that.
You should always code an interrupt service to do the minimum possible, and get out as soon as possible. Do NOT wait inside the interrupt service. Use an if(), not a while().
You have made the same mistake with RBIF that everyone does the first time you try to use it.
You MUST do a read of PORTB just before you clear RBIF. This is not optional.
The datasheet does spell this out, but everyone misunderstands it.
 
Your ISR code handling INTF is clearing the wrong flag, RBIF instead of INTF.
 
 
 
 
 
post edited by qɥb - 2018/07/26 23:14:58

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/27 00:25:39 (permalink)
0
qɥb
This is my personal opinion.
Defining macros like that is a TERRIBLE idea.
It hides what is really happening, and obliterates the INTCON register every time you use it.
You are also enabling interrupts before you have finished your initialisation code. I strongly recommend you do not set

1. Which ones are good and which ones need to change?
 2. Do you mean I should avoid applying definitions for internal modules configurations?
3. Or you mean I should remove all those definitions, and put all needed configuration bits in the main source file one by one; like this:
    TRISBbits.RB0=1;
    TRISDbits.RD2=0;
    INTCONbits.GIE=1;
    INTCONbits.PEIE=1;
    INTCONbits.INT0IE=1;

 
 
But I think definitions like:
#define AN_DISABLE (ADCON0=0x00,ADCON1=0x0f,CMCON=0x07)

Is good because it takes care of all necessary setting/clearing bits to disable ADC
The other one:
#define AN_ENABLE (ADCON0=0x01,ADCON1=0x0f,CMCON=0x07)

Enables the ADC.
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/27 00:59:28 (permalink)
0
What I'm doing now:
 
I set up this code:
void main(void) {
    INTOSC_4MHz;
    AN_DISABLE;
    TRISBbits.RB0=1;
    TRISDbits.RD2=0;
    INTCONbits.GIE=1;
    INTCONbits.PEIE=1;
    INTCONbits.INT0IE=1;
    INTCON2bits.INTEDG0=1;
    while(1){
        EXT_INT0_RISING(); // keeps LATD2 low all the time
                                       // When I pull LATB0 HIGH LATD2 should go HIGH
    }
}

 
The interrupt code:
void EXT_INT0_RISING(void)
{
    LATDbits.LATD2=0;
}

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

    if(INTCONbits.INT0F)
    {
        INTCONbits.INT0IF=0;
        LATDbits.LATD2=1;
    }
}

 
The hardware setup:
1. I connected 10k resistor to LATB0/INT0, to pull the pin to GND.
2. A button to LATB0/INT0 going to 5V. Like the one on the right:

 
What happens, when I press the button, LATD2 goes HIGH/LOW so fast with low brightness. I thought the LED should be HIGH as long as I'm pressing the button. 
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/27 03:56:57 (permalink)
+2 (2)
eagle1
The hardware setup:
1. I connected 10k resistor to LATB0/INT0, to pull the pin to GND.
2. A button to LATB0/INT0 going to 5V. Like the one on the right:
 
What happens, when I press the button, LATD2 goes HIGH/LOW so fast with low brightness. I thought the LED should be HIGH as long as I'm pressing the button. 

That shows your misunderstanding of interrupts. Normally, execution after exiting the interrupt continues with execution of code in your main loop.  Try connecting the button to an IOC pin and see what happens with your posted code.
 
Edit: A button has bounces too. Read http://www.ganssle.com/debouncing.htm
post edited by 1and0 - 2018/07/27 04:06:27
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/27 07:07:05 (permalink)
0
1and0
 
That shows your misunderstanding of interrupts. Normally, execution after exiting the interrupt continues with execution of code in your main loop.  Try connecting the button to an IOC pin and see what happens with your posted code.
Edit: A button has bounces too. Read http://www.ganssle.com/debouncing.htm

Yeah, I think polling a pin for receiving IR signal won't work because of the bouncing.
After the last post, the external interrupts worked, but I again changed the method to normal pin polling.
 
uint32_t PIN_POLLING_VS1838b(void)
{
    while (PORTBbits.RB2)
    TMR1_period1 = TMR1;
    while (PORTBbits.RB2)
    TMR1_period2 = TMR1;
    pulse_width = TMR1_period2 - TMR1_period1;
    if (pulse_width < 14000 && pulse_width > 13000)
    {
        for (c=0;c<32;c++)
        {
            while (PORTBbits.RB2)
            TMR1_period1 = TMR1;
            while (PORTBbits.RB2)
            TMR1_period2 = TMR1;
            pulse_width = TMR1_period2 - TMR1_period1; 
            if (pulse_width < 1300 && pulse_width > 1100)
                ir_code_INT &= ~(1<<c);
            else
                ir_code_INT |= (1<<c);
        } 
    } 
    return ir_code_INT;
}

But didn't work, that proves the method applied in this link:
http://ccspicc.blogspot.com/2016/07/nec-protocol-ir-remote-control-decoder-pic16f877a-ccs-pic-c.html?m=1 
 
Is really good, he's using delays with counts. I'm lost now for all the ways I thought about, capture, external interrupts, interrupts on change and finally polling a pin :) It isn't that easy for me, I need more time to solve it.
jack@kksound
code tags!
  • Total Posts : 3198
  • Reward points : 0
  • Joined: 2014/05/14 10:03:19
  • Location: 0
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/27 07:56:28 (permalink)
0
You still have ignored this bit of information:
You have made the same mistake with RBIF that everyone does the first time you try to use it.
You MUST do a read of PORTB just before you clear RBIF. This is not optional.
The datasheet does spell this out, but everyone misunderstands it.

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/27 08:02:32 (permalink) ☄ Helpfulby eagle1 2018/07/27 21:30:19
+2 (2)
eagle1
 
Yeah, I think polling a pin for receiving IR signal won't work because of the bouncing.

IR signal should not have bounces.
 

But didn't work, that proves the method applied in this link:
http://ccspicc.blogspot.com/2016/07/nec-protocol-ir-remote-control-decoder-pic16f877a-ccs-pic-c.html?m=1 
 
Is really good, he's using delays with counts. I'm lost now for all the ways I thought about, capture, external interrupts, interrupts on change and finally polling a pin :) It isn't that easy for me, I need more time to solve it.

That only proves you do not understand how everything works together. Take a step back and try to understand how things work, then use what you know to implement a solution for it.
 
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/27 08:03:20 (permalink) ☄ Helpfulby eagle1 2018/07/27 21:30:40
+1 (1)
jack@kksound
You still have ignored this bit of information:

That is why I suggest him to connect the button to an IOC pin and see.
jack@kksound
code tags!
  • Total Posts : 3198
  • Reward points : 0
  • Joined: 2014/05/14 10:03:19
  • Location: 0
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/27 08:10:54 (permalink)
+1 (1)
I suspect that will only result in more confusion. sad: sad
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/27 08:22:04 (permalink)
+1 (1)
jack@kksound
I suspect that will only result in more confusion. sad: sad

Yeah, like why the LED stays high when the button is released. ;)
 
PStechPaul
Super Member
  • Total Posts : 2299
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: online
Re: I want to know the difference between capture and compare modes with examples 2018/07/27 15:06:51 (permalink)
+2 (2)
I would suggest taking a break from trying to decode the IR R/C signal, and going back to a set of simple tutorials, such as those by Gooligum.
 
https://www.gooligum.com.au/PIC-tutorials
 
Once you feel that you fully understand each one, try porting it to your PIC of choice, using the datasheet to provide the information for requisite changes in the code. Here is one for $10 that includes interrupts and CCP for enhanced mid-range devices:
 
https://www.gooligum.com..../enhanced-PIC-tutorial

 
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/28 07:53:13 (permalink)
0
Quick question:
Is there anything wrong with this code:
uint32_t PIN_POLLING_VS1838b(uint16_t *arr)
{
    TMR1=0;
    while ((!PORTBbits.RB2) && (TMR1 < 10000)); // test 9ms low 9182
 if ((TMR1 > 10000) || (TMR1 < 9000))
  return 1;
 TMR1 = 0;
    while ((PORTBbits.RB2) && (TMR1 < 5000)); // test 4.5ms high ~4480 
 if ((TMR1 > 4600) || (TMR1 < 4300))
  return 2; 
    TMR1 = 0; 
//////////////////////////////////////////////////////////////////////////////// 
 for(i=0;i<32;i++){ // 2.25ms & 1.25ms test
 TMR1 = 0;
    while ((!PORTBbits.RB2) && (TMR1 < 800));
    TMR1 = 0;
    while ((PORTBbits.RB2) && (TMR1 < 2000));
    //arr[i]=TMR1;
    if((TMR1 < 700) && (TMR1 > 400))
        ir_code_INT &= ~(1<<i);
    else if((TMR1 < 2000) && (TMR1 > 1000))
        ir_code_INT |= (1<<i); 
    }
//////////////////////////////////////////////////////////////////////////////// 
    return ir_code_INT;//
}

PStechPaul
Super Member
  • Total Posts : 2299
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: online
Re: I want to know the difference between capture and compare modes with examples 2018/07/28 22:44:02 (permalink) ☄ Helpfulby eagle1 2018/07/28 23:39:32
+1 (1)
I don't know how you are calling this function. ir_code_INT is apparently defined outside the function, but it also returns that value. This seems very awkward. I assume you call this function and expect it to return a "1" when RB2 has been low for 9 mSec (although the NEC spec has the signal high). Then you call it again and it returns "2" when RB2 has been high for 4.5 mSec (reverse of spec).  Then apparently you call it again hoping to decode the 32 bits of the address and data, but it is unclear how it gets to that section without missing some pulses.
 
This seems like a very wrong way to attempt what you want. You may be trying to simplify the process because you don't understand the CPP capture methods, but it is just confusing things, IMHO. Maybe others will have better luck figuring out your code and determining if it can work. And there is no "escape" from the 32 count loop if a pulse is missing.

 
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/29 00:05:44 (permalink)
0
PStechPaul
I don't know how you are calling this function.
I'm calling it from main:
 
void main(void) {
    INTOSC_4MHz;
    AN_DISABLE;     
    i2c_init();
    i2c_start();
    LCD_Init();
    TRISBbits.RB2=1;
    INTCONbits.GIE=0;
    INTCONbits.PEIE=0;
    INTCON2bits.RBPU=1; // disable PORTB pullup resistors
    T1CON=0x80; // timer1 16-bits
    T1CONbits.TMR1ON=1; // turn on timer1
    while(1){
        
        while (PORTBbits.RB2);
        capture_val = PIN_POLLING_VS1838b();
        sprintf(val_arr,"%lx",capture_val);
        LCD_string("remote code:");
        move_cursor(2,0);
        LCD_string(val_arr);
        __delay_ms(500);
        sendCMD(clear_display);
    } 
}

 
ir_code_INT is apparently defined outside the function, but it also returns that value. This seems very awkward. I assume you call this function and expect it to return a "1" when RB2 has been low for 9 mSec (although the NEC spec has the signal high). Then you call it again and it returns "2" when RB2 has been high for 4.5 mSec (reverse of spec).
1."ir_code_INT" is defined in "interrupts.h" but main has another 32-bit variable for returned function.
2. The function should return "1" if it didn't match the 9ms count:
if ((TMR1 > 10000) || (TMR1 < 9000))

I tested "TIMER1" in this location and returned 9182. Which is in this range. And the same for 4.5ms.
3. NEC actually sends HIGH 9ms burst, but the VS1838b pulls the pin low, as you explained to me in an earlier post. And leave the pin HIGH, if it's a "SPACE" bit. Because VS1838b's out pin is idle HIGH and active LOW.
 
 

Then apparently you call it again hoping to decode the 32 bits of the address and data, but it is unclear how it gets to that section without missing some pulses.
Yes, I got a reading and got an array[32] to read all the 32-bits periods with TIMER1, but the PROBLEM is that all the buttons give the same code; like, 0xffffff00. I was so happy that I figured out how to measure each bit, but not yet :)
 
This seems like a very wrong way to attempt what you want. You may be trying to simplify the process because you don't understand the CPP capture methods, but it is just confusing things, IMHO. Maybe others will have better luck figuring out your code and determining if it can work. 

I'm not applying CCP capture now, I'm working with simple pin polling and timer1 measuring.
 
And there is no "escape" from the 32 count loop if a pulse is missing.
You're right about this part, I should put this condition like 9ms and 4.5ms, maybe this is the cause of the problem.
 
Also as an extra information, I recorded each bit data/space width and I displayed all of the 32 data and 32 spaces periods on the LCD for debugging. So there were periods out of range at first, but after I got all the periods correctly. But of course now there's a PROBLEM which I couldn't figure out for all yesterday until now I don't know why all the buttons are the same code! 
post edited by eagle1 - 2018/07/29 00:07:57
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/29 02:05:56 (permalink)
0
I've put the conditions inside the 32 loops but the same problem:
uint32_t PIN_POLLING_VS1838b(uint16_t *arr1,uint16_t *arr2)
{
    TMR1=0;
    while ((!PORTBbits.RB2) && (TMR1 < 10000)); // test 9ms low 9182
 if ((TMR1 > 10000) || (TMR1 < 9000))
  return 1;
 TMR1 = 0;
    while ((PORTBbits.RB2) && (TMR1 < 5000)); // test 4.5ms high ~4480
 if ((TMR1 > 4600) || (TMR1 < 4300))
  return 2;
    TMR1 = 0;

 for(i=0;i<32;i++){ // test 650 for "0" 1680 for "1"
 TMR1 = 0;
    while ((!PORTBbits.RB2) && (TMR1 < 800));
    if ((TMR1 > 800) || (TMR1 < 300))
  return 3;
    TMR1 = 0;
    while ((PORTBbits.RB2) && (TMR1 < 2000));
    if ((TMR1 > 2000) || (TMR1 < 400))
        return 4;
    if((TMR1 < 700) && (TMR1 > 400))
        ir_code_INT &= ~(1<<i);
    else if((TMR1 < 2000) && (TMR1 > 1000))
        ir_code_INT |= (1<<i);
    }
    return ir_code_INT;
}

PStechPaul
Super Member
  • Total Posts : 2299
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: online
Re: I want to know the difference between capture and compare modes with examples 2018/07/29 02:37:57 (permalink) ☄ Helpfulby eagle1 2018/07/29 02:42:35
+2 (2)
This is "pulse distance coding", where the time between rising pulse edges determines whether it is a "0" (1.125 mSec), or "1" (2.25 mSec). So your loop should only look for a change from high to low (with the inverted output), and reset the timer count at that point, after checking the pulse distance to be within, say, 1000 and 1500 (for zero), or 2000 to 2500 (for one). The loop should break and return an error code if the timer exceeds 3000. I am assuming a timer frequency of 1 MHz, or 1 uSec per count.
 
Something like:

   uint32_t ir_code_INT = 0; // Don't need to define this except within function
// At this point the 9 mSec low and 4.5 mSec high should have been detected, and first pulse (low)

  for(i=0;i<32;i++) { // 2.125ms & 1.125ms test

    TMR1 = 0; // Start timing to next pulse
    while ( (!PORTBbits.RB2) && (TMR1 < 65000) ); //wait for end of pulse (rising edge)

    while ( (PORTBbits.RB2) && (TMR1 < 65000) ); //wait for start of pulse (falling edge)
    if(TMR1 >= 65000)  // Timeout

      return 0;  //Error code

    else if ((TMR1 > 1000) && (TMR1 < 1500))

      ir_code_INT &= ~(1<<i); // 0 detected

    else if((TMR1 > 2000) && (TMR1 < 3000))
      ir_code_INT |= (1<<i); // 1 detected
    else

      return 0; // Error code
    }
  return ir_code_INT;



 
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/29 02:41:27 (permalink)
0
OK, I think I solved part of the problem:
I have to change:
        ir_code_INT &= ~(1<<i);
        ir_code_INT |= (1<<i);

 
 
To:
        ir_code_INT &= ~(1<<(31 -i));
        ir_code_INT |= (1<<(31 -i));

 
Now, I'm getting different readings :)
But they are not consistent in length even with the hex specifier "%lx".
sprintf(val_arr,"%lx",capture_val);

The readings don't come in the same length!
 
Edit:
Comparing the readings with the ones I have by a proved Arduino library, they are the same which is phenomenal but only left problem is the length of the readings is not consistent, it varies, sometimes it's 6 hex digits, sometimes 4 and 8.
post edited by eagle1 - 2018/07/29 02:47:42
PStechPaul
Super Member
  • Total Posts : 2299
  • Reward points : 0
  • Joined: 2006/06/27 16:11:32
  • Location: Cockeysville, MD, USA
  • Status: online
Re: I want to know the difference between capture and compare modes with examples 2018/07/29 02:54:26 (permalink)
+2 (2)
The coding is LSB first. So I think the way you had it was OK.

 
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/29 03:21:38 (permalink)
0
PStechPaul
The coding is LSB first. So I think the way you had it was OK.

Which one? the first or the second one? In my last post.
 
Actually the first one didn't work, because the programmer on this website:
http://ccspicc.blogspot.com/2016/07/nec-protocol-ir-remote-control-decoder-pic16f877a-ccs-pic-c.html 
 
Which is also the source I copied my code based on that code, is doing this method, which is starting from the MSB.
 
Also, I thought about that at first but didn't think about it this morning, but I'm glad I did it anyway :)
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/29 07:16:20 (permalink) ☄ Helpfulby eagle1 2018/07/29 07:54:27
+2 (2)
eagle1
OK, I think I solved part of the problem:
I have to change:
        ir_code_INT &= ~(1<<i);
        ir_code_INT |= (1<<i);

To:
        ir_code_INT &= ~(1<<(31 -i));
        ir_code_INT |= (1<<(31 -i));


Hint: My Post #186.
 

Now, I'm getting different readings :)
But they are not consistent in length even with the hex specifier "%lx".
sprintf(val_arr,"%lx",capture_val);

The readings don't come in the same length!
 
Edit:
Comparing the readings with the ones I have by a proved Arduino library, they are the same which is phenomenal but only left problem is the length of the readings is not consistent, it varies, sometimes it's 6 hex digits, sometimes 4 and 8.

Hint: My Post #188 regarding if/else.  Your code tests TMR1 ranges of 400-2000, 400-700, and 1000-2000, but _not_ 700-1000. The other issue might be %lx does not display leading zeros.
Page: << < ..111213 > Showing page 11 of 13
Jump to:
© 2019 APG vNext Commercial Version 4.5