18F452 RB port interrupts slow/inconsistent?

Thread Starter

pizzaice

Joined Jan 10, 2008
8
Hi guys,
I am currently trying to do a couple of improvements to my solenoid system (thread)and hence used two optical sensor to sense their position and therefore the time delay between the driver signal and the actual movement of the solenoid.

On my PIC 18f452 I used two interrupt-configured B ports, RB5 and RB6 to sense a high or low status and then calculate the delay in crankshaft degrees. This then feeds back into my main interrupt routine that opens and closes these valves at the actual timing minus the delay.

For some reason though the delay calculation does not work. When I output the values of the calculated delay onto my display I get values fluctuationg between 30 and 500. It should only really be thirty or max 100.

Any ideas what could be wrong with my idea?It seems like the RB5 and RB6 ports are too slow for the use with interrupts that fast. But then, as read in other threads in this forum they should take the same time as the external interrupts INT0, INT1 and INT2 (which are all taken by the way;)..).

The code looks like this (sorry... its long and a bit messy sometimes)
Rich (BB code):
//**************************************************************************************************
//HIGH PRIORITY INTERRUPT HANDLER
//Description: Performs high priority interrupt actions
//**************************************************************************************************
#pragma code
#pragma interrupt InterruptHandlerHigh

void InterruptHandlerHigh()
{
	// Handle high priority interrupts.
	//Determine interrupt source


	//**********************************************************************************************
	//Intake/Exhaust response sensor
	//**********************************************************************************************
	if(INTCONbits.RBIF)
	{
		
	// Intake
	
			if(PORTBbits.RB6 == 0) // Solenoid has moved in ie. valve opened
			{
				if(IntOpenSensDelay==0)
				{
					IntOpenSensDelay==30;
				}
				else
				{
					IntOpenSensDelay=engineRotationDegs-INTOPENCAD-adjustAdvanceInt;	// example: 370-365=5
				}
				
			}
			else if(PORTBbits.RB6 == 1)					// Solenoid has moved out ie. valve closed
			{
				if(IntCloseSensDelay==0)
				{
					IntCloseSensDelay=30;
				}
				else
				{
					IntCloseSensDelay=engineRotationDegs-INTCLOSECAD-adjustWidthInt;  // example: 550-540=10
				}
			}
	
	// Exhaust
	
		//If optical switch has been triggered on
			if(PORTBbits.RB5 == 0) //Solenoid has moved out of lightbeam
			{
				if(ExhOpenSensDelay==0)
				{
					ExhOpenSensDelay=30;
				}
				else
				{
					ExhOpenSensDelay=engineRotationDegs-EXHOPENCAD-adjustAdvanceExh;
				}
			}
			else if(PORTBbits.RB5 == 1)	
			{
				if(ExhCloseSensDelay==0)
				{
					ExhCloseSensDelay=30;
				}
				else
				{
					ExhCloseSensDelay=engineRotationDegs-EXHCLOSECAD-adjustWidthExh;
				}
			}
		//Clear interrupt flag
		INTCONbits.RBIF	= 0;
	}
	
	//**********************************************************************************************
	//TDC Sensor
	//**********************************************************************************************
	if(INTCON3bits.INT1IF)
	{
		//To synchronise the EVVT system with the engine, the TDC sensor on the shaft encoder is 
		//required to be triggered in order to confirm the engine position
		if(systemSyncToEng == 0)
		{
			engineStroke = 1;
			//System is now synchronised
			systemSyncToEng = 1;
		}

		if(systemSyncToEng)
		{
			//Reset sync according to TDC sensor after every engine cycle
			if(engineRotationDegs > 700)
			{
				engineRotationDegs = -1;
				engineStroke = 1;
			}
		}
	
		//Clear interrupt flag
		INTCON3bits.INT1IF = 0;
	}
	
	//**********************************************************************************************
	//Shaft encoder
	//**********************************************************************************************
	if(INTCONbits.INT0IF)
	{
		//The core interrupt, handling the critical intake and exhaust valve open/ close signals
		if(systemSyncToEng)
		{
			//Encoder increments since last RPM calculation
			encoderRPM++;

			//******************************************************************************
			//The EVVT system counts the engine rotation over one engine cycle
			//i.e. 0 to 719 degs
			//******************************************************************************
			engineRotationDegs++;

			//************************
			//Intake Valve Open/ Close
			//************************
			//Output signal to trigger intake valve open
			if(engineRotationDegs == (INTOPENCAD-IntOpenSensDelay-adjustAdvanceInt))
			{
				PORTBbits.RB4 = 1;
			}

			//Output signal to trigger intake valve close
			if(engineRotationDegs == (INTCLOSECAD-IntCloseSensDelay-adjustWidthInt))
			{
				PORTBbits.RB4 = 0;
			}

			//*************************
			//Exhaust Valve Open/ Close
			//*************************
			//Output signal to trigger exhaust valve open
			if(engineRotationDegs == (EXHOPENCAD-ExhOpenSensDelay-adjustAdvanceExh))
			{
				PORTBbits.RB3 = 1;
			}

			//Output signal to trigger exhaust valve close
			if(engineRotationDegs == (EXHCLOSECAD-ExhCloseSensDelay-adjustWidthExh))
			{
				PORTBbits.RB3 = 0;
			}

			//******************
			//Display Eng Stroke
			//******************
			//Stroke 1
			if(engineRotationDegs == 0)
			{
				engineStroke = 1;
			}
			//Stroke 2
			else if(engineRotationDegs == 180)
			{
				engineStroke = 2;
			}
			//Stroke 3
			else if(engineRotationDegs == 360)
			{
				engineStroke = 3;
			}
			//Stroke 4
			else if(engineRotationDegs == 540)
			{
				engineStroke = 4;
			}

			//**************
			//Display Update
			//**************
			// if(page == 0x05)
			// 			{
			// 				//Update display of CAD (Crank Angle Degs)
			// 				DisplayLCD(LCD_COM,	LCD_POS05);
			// 				if(engineRotationDegs > 359)
			// 				{
			// 					BinToBCD16Bit(engineRotationDegs - 360);
			// 				}
			// 				else
			// 				{
			// 					BinToBCD16Bit(engineRotationDegs);
			// 				}
			// 				DisplayLCD(LCD_TXT,	hundreds);
			// 				DisplayLCD(LCD_TXT,	tens);
			// 				DisplayLCD(LCD_TXT,	ones);
			// 
			// 				//Update stroke
			// 				DisplayLCD(LCD_COM,	LCD_POS48);
			// 				BinToBCD8Bit(engineStroke);
			// 				DisplayLCD(LCD_TXT,	ones);
			// 			}
		}

		//Clear interrupt flag
		INTCONbits.INT0IF = 0;
	}
 

nanovate

Joined May 7, 2007
666
Looking at your interrupt handler I see that you have writes to the LCD. This could be the problem. You want your interrupt service routine to be as fast as possible. Can you just have your interrupt set some flags then write to the LCD later?
 

Thread Starter

pizzaice

Joined Jan 10, 2008
8
thank you for the reply, nanovate

if you have a look again in the code these LCD writes are commented out. do you have any other idea why the RB port interrupts could be slower than the other external ones?

cheers,
chris
 

nanovate

Joined May 7, 2007
666
Could this be the problem?

Rich (BB code):
if(IntOpenSensDelay==0)
{
   IntOpenSensDelay==30;
}
else
{
   IntOpenSensDelay=engineRotationDegs-INTOPENCAD-adjustAdvanceInt;   // example: 370-365=5
}
You have a "==" instead of a "=".
 

Thread Starter

pizzaice

Joined Jan 10, 2008
8
Thanks, that could be the problem. I corrected it just now but the interrupts still have really slow response. So you guys think it has to do with my programming rather than a general rule that RB interrupts are slower than external ones?

Cheers,
Chris
 

nanovate

Joined May 7, 2007
666
The Pin Change Interrupts on RBn should have a response time very close the other external interrupts. How have you configured the priority bits on your all your interrupts?
 
Top