Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Programming (http://www.chiefdelphi.com/forums/forumdisplay.php?f=51)
-   -   Reading interupt pin as Standard IO (http://www.chiefdelphi.com/forums/showthread.php?t=46578)

intellec7 15-04-2006 13:26

Reading interupt pin as Standard IO
 
I am trying to generate code that reads the pulswidth of a signal. I am avoiding use of Interupt pins 1 and 2 for later use. As my code is set up, I am trying to read the pulsewidth on pin 3. (BTW this is the Vex controller, I don't think it should make a difference though)
The code:
Code:

#define accel_x                rc_dig_int3

.......
  else if (INTCONbits.RBIF && INTCONbits.RBIE)  /* Ints 3-6 (RB4, RB5, RB6, or RB7) changed. */
  {
    int_byte = PORTB;          /* You must read or write to PORTB */
        if(accel_x){
                WriteTimer1( 0x00 );
                T1CONbits.TMR1ON = 1; // turn it on
        }
        else if (!accel_x){
                        T1CONbits.TMR1ON = 0; // turn it off
                        accel_xTilt= ReadTimer1();
                        WriteTimer1( 0x00 );
                }
       

    INTCONbits.RBIF = 0;    /*    and clear the interrupt flag        */
  }

I had a suspicion that maybe I am reading the pin incorrectly, so I set up:
Code:


void Process_Data_From_Local_IO(void){
if(accel_x){printf("ON\n");}
else if (!accel_x){printf("OFF\n");}
}

It works, but it seems that there is a lag. Forexample I hooked up a normal switch to the pin. On the terminal I get
0n
0n
....
I then press the switch
0n
0n
0n
....................... (Ons for about another second)
Off
Off

It is the same for the 0ff to On transition.
I thought maybe for some reason my ISR was consuming to much time, explaining the delay, and so I took all of my code out an left the default:
Code:

...
 else if (INTCONbits.RBIF && INTCONbits.RBIE)  /* Ints 3-6 (RB4, RB5, RB6, or RB7) changed. */
  {
    int_byte = PORTB;          /* You must read or write to PORTB */
    INTCONbits.RBIF = 0;    /*    and clear the interrupt flag        */
  }                                        /*    to clear the interrupt condition.  */

Thanks for anyhelp.

Mike 15-04-2006 15:11

Re: Reading interupt pin as Standard IO
 
The delay may be the USART waiting for the transmit buffer to clear of "On"s before the "Off"s are being sent. Try setting a pin high/low and reading that, it is a much faster response time.

Alan Anderson 15-04-2006 15:45

Re: Reading interupt pin as Standard IO
 
I second Mike's comment. I know the IFI loader's terminal window introduces a significant delay when there is continuous data coming in. Hyperterminal is much better.

I don't know how the Vex serial communication is implemented. It's likely that you're sending "on" and "off" messages faster than they can be transmitted, and that they're being buffered.

Greg Ross 15-04-2006 15:57

Re: Reading interupt pin as Standard IO
 
Quote:

Originally Posted by Alan Anderson
I second Mike's comment. I know the IFI loader's terminal window introduces a significant delay when there is continuous data coming in. Hyperterminal is much better.

I don't know how the Vex serial communication is implemented. It's likely that you're sending "on" and "off" messages faster than they can be transmitted, and that they're being buffered.

Exactly. Try printing the on/off messages only when the pin state changes.

intellec7 15-04-2006 21:10

Re: Reading interupt pin as Standard IO
 
Quote:

Originally Posted by GW (Greg) Ross
Exactly. Try printing the on/off messages only when the pin state changes.

Alright, I did that, and I am pretty sure that was the lag I was experiencing, so now I can poll the input and if it is different from the last input I print something to the screen.

Now I'm trying to do it with interrupts, and I have the code in the ISR as so:
Code:

        else if (INTCONbits.RBIF && INTCONbits.RBIE){  /* Ints 3-6 (RB4, RB5, RB6, or RB7) changed. */
                int_byte = PORTB;          /* You must read or write to PORTB */
                INTCONbits.RBIF = 0;    /*    and clear the interrupt flag */
                if(accel_x){
                        printf("High!n");
                }
                else if (accel_x ==0){
                        printf("LOW!n");
                }
        }

But I never get any output from the program, telling me that the interrupt is never... interrupting. Right?

[EDIT]-Stupid mistake... I never enabled interrupts by setting bit : INTCONbits.RBIE :-p

Alan Anderson 16-04-2006 08:32

Re: Reading interupt pin as Standard IO
 
As a general rule, using printf in an interrupt service routine is a Bad Idea. The serial communication library routines might handle it without causing issues...or they might not.

ISRs should be reserved for things which take approximately no time to perform. Make a comparison, set a flag, store a value, maybe compute a delta or a sum. But try not to start something which will require waiting for something else to happen.

intellec7 16-04-2006 20:42

Re: Reading interupt pin as Standard IO
 
Quote:

Originally Posted by Alan Anderson
As a general rule, using printf in an interrupt service routine is a Bad Idea. The serial communication library routines might handle it without causing issues...or they might not.

I was just doing that to see when the ISR was running.
My actual code is
Code:

        else if (INTCONbits.RBIF && INTCONbits.RBIE){  /* Ints 3-6 (RB4, RB5, RB6, or RB7) changed. */
                int_byte = PORTB;          /* You must read or write to PORTB */
                INTCONbits.RBIF = 0;    /*    and clear the interrupt flag */
               
                if(accel_x){
                        //Here it measures the Low time
                        T1CONbits.TMR1ON = 0; // turn it off
                        accel_xTiltC=ReadTimer1();
                        WriteTimer1( 0x00 );
                        T1CONbits.TMR1ON = 1; // turn it on
                        Status = 2;
                }
                else if (accel_x ==0){
                        //This time it measures the High time
                        T1CONbits.TMR1ON = 0; // turn it off
                        accel_xTilt= ReadTimer1(); //capture timer value
                        WriteTimer1( 0x00 );
                        T1CONbits.TMR1ON = 1; // turn it on
                        Status = 1;
                }
        }

accel_xTilt is an unsigned integer, and since Timer1 is configured as a 16 bit timer, that should be suffice to hold any timer value right? But from 6ms - 4 ms I get negative values! I thought maybe for some reason it was wrapping around and doing something funny, so when I made it a long I got all zero values.
Does anyone have code that does frequency/duty cycle measurement?

Alan Anderson 16-04-2006 21:59

Re: Reading interupt pin as Standard IO
 
Quote:

Originally Posted by intellec7
accel_xTilt is an unsigned integer, and since Timer1 is configured as a 16 bit timer, that should be suffice to hold any timer value right? But from 6ms - 4 ms I get negative values! I thought maybe for some reason it was wrapping around and doing something funny, so when I made it a long I got all zero values.

You probably had the right values in the accel_xTilt variable, but printf() has difficulty showing anything other than an int unless you cast things just right.

intellec7 16-04-2006 22:25

Re: Reading interupt pin as Standard IO
 
Quote:

Originally Posted by Alan Anderson
You probably had the right values in the accel_xTilt variable, but printf() has difficulty showing anything other than an int unless you cast things just right.

How did you know :-p. I had %d with an unsigned int... changed it to %u and voila. Thanks for your help.


All times are GMT -5. The time now is 03:18.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi