Ctimer0Cap0 for external fan counting - help

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ctimer0Cap0 for external fan counting - help

Jump to solution
597 Views
amithrao
Contributor II

Board LPCS5506 dev kit

I'm using 4 wire fan, Power, ground, TACH, and PWM. 

 

For PWM I'm using Ctimer2 Mat 3 in PWM mode.. Timer clock is 16MHz, PWM period is 1KHz, Duty cycled at 20%. 

That's working as expected. 

 

I Intend to use Ctimer0 in Capture Mode on channel 0 to count the fan rotations, and measure the RPM. What's the best way to do this, I have implemented it but it's behaving rather weirdly.

 

I've configured ctimer0 at 1KHz to count the fan signals (2 rising and 2 falling make a rotation) 

const ctimer_config_t CTIMER0_FAN_TACH_config = {

  .mode = kCTIMER_TimerMode,

  .input = kCTIMER_Capture_0,

  .prescale = 15999

};

static void CTIMER0_FAN_TACH_init(void) {

  /* CTIMER0 peripheral initialization */

  CTIMER_Init(CTIMER0_FAN_TACH_PERIPHERAL, &CTIMER0_FAN_TACH_config);

  /* capture channel 0 of CTIMER0 peripheral initialization */

  CTIMER_SetupCapture(CTIMER0_FAN_TACH_PERIPHERAL, CTIMER0_FAN_TACH_CAPTURE_0_CHANNEL, kCTIMER_Capture_BothEdge, true);

  CTIMER_RegisterCallBack(CTIMER0_FAN_TACH_PERIPHERAL, CTIMER0_FAN_TACH_callback, kCTIMER_SingleCallback);

  /* Start the timer */

  CTIMER_StartTimer(CTIMER0_FAN_TACH_PERIPHERAL);

}

 I'm getting interrupts randomly, and they stop abruptly. 
I get interrupts even without the fan connected. What am I missing ?

0 Kudos
1 Solution
532 Views
amithrao
Contributor II

It was a hardware issue ! the signal on the tach pin wasn't pulled up.. adding a pull up resistor there to 3.3V solved the issue! 
Thanks for your inputs  

View solution in original post

0 Kudos
7 Replies
589 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Can you share the motor type for example, DC, BLDC, PMSM,SR or stepper?

BTW, you use capture function of CTimer, can you tell us what the capturing signal is? is it from encoder or whatever so that the signal can represents the motor position or motor position change?

 

BR

XiangJun Rong

0 Kudos
583 Views
amithrao
Contributor II

https://products.sanyodenki.com/info/sanace/en/technical_material/dcsensor.html

9GX3612P3K001

 

TACH Pulse out is the signal type.. 

For setting up the capture, what should the timer clock be ? I set it up the same as the BOARD_BootClock

at 16MHz and adjusted the prescaler to be 16000 s.t the timer freq is 1 KHz. Lmk if this is incorrect 

 

 

0 Kudos
576 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

As you know that there are two methods to measure the motor speed. One is to measure the signal number in a fixed time, the method adapts to high speed motor, for your application, you can connect the tach sensor signal to the capture pin of CTimer, the CTimer will count the tach sensor signal as tick, you can have the MRT or whatever timer to generate an interrupt in a fixed cycle time, in the ISR, you can read the CTimer counter to know that how many signal are generated, in this way, you can get the speed of motor, you can compute the speed with the formula:

counter number/fixed cycle time

 

Another method is the one you are using, you use the CTimer capture function, for your case, the CTimer counts the 1KHZ tick, when a capture event happens, an interrupt is triggered, in the ISR, you can compute the difference between two consecutive events and compute the speed with the formula:

1/[reading difference*(tick cycle)]

BTW, the signal connected to CTimer capture pin can function as either tick or capturing signal depending your configuration.

 

Hope it can help you

BR

XiangJun Rong

 

0 Kudos
549 Views
amithrao
Contributor II

Thanks for the response.. Yes I'm using the second method, where the TACH signal is connected to the capture pin (not sure if it has to be a particular channel).. But as you can see, the initialization code above is how I've set it up.. 

 

void fan_tach_isr(uint32_t flags)
{
	static int8_t count = 1;
	uint8_t tc_read_count = 4; //4 poles for the fan = 1 rotation
	uint32_t tc = CTIMER_GetTimerCountValue(g_ctx.fanCtrlHandle.tach_ctimer_handle);

	if(++count > tc_read_count)
	{
		//uint32_t tc = CTIMER_GetTimerCountValue(g_ctx.fanCtrlHandle.tach_ctimer_handle);
		g_ctx.fanCtrlHandle.rpm = (60000/tc);
		CTIMER_Reset(g_ctx.fanCtrlHandle.tach_ctimer_handle);
		LOG_DEBUG("ISR count = %d, TC = %ld RPM = %ld", count, tc, g_ctx.fanCtrlHandle.rpm);
		count = 1;
	}
}

 

where tach_timer_handle is 

CTIMER0_FAN_TACH_PERIPHERAL

The interrupts are firing only when I connect and disconnect, and they're weird.. as in the TC field in the handle keeps increasing even when the fan is disconnected - (this may be expected? )

and the interrupts don't fire when the fan is running after a few rounds.. not sure what's going on here! any ideas ?

 

Btw, I'm using Ctimer2 to control the PWM pin on the same fan.. The config for that looks like this: 

amithrao_0-1674590073303.png

and the corresponding Tach pin to ctimer0, and the config looks like this: 

amithrao_1-1674590208228.png

 

Does it look okay ? or am I missing something ?

 

0 Kudos
545 Views
amithrao
Contributor II

Thanks for the response.. Yes I'm using the second method, where the TACH signal is connected to the capture pin (not sure if it has to be a particular channel).. But as you can see, the initialization code above is how I've set it up.. 

 

void fan_tach_isr(uint32_t flags)
{
	static int8_t count = 1;
	uint8_t tc_read_count = 4; //4 poles for the fan = 1 rotation
	uint32_t tc = CTIMER_GetTimerCountValue(g_ctx.fanCtrlHandle.tach_ctimer_handle);

	if(++count > tc_read_count)
	{
		//uint32_t tc = CTIMER_GetTimerCountValue(g_ctx.fanCtrlHandle.tach_ctimer_handle);
		g_ctx.fanCtrlHandle.rpm = (60000/tc);
		CTIMER_Reset(g_ctx.fanCtrlHandle.tach_ctimer_handle);
		LOG_DEBUG("ISR count = %d, TC = %ld RPM = %ld", count, tc, g_ctx.fanCtrlHandle.rpm);
		count = 1;
	}
}

 

where tach_timer_handle is 

CTIMER0_FAN_TACH_PERIPHERAL

The interrupts are firing only when I connect and disconnect, and they're weird.. as in the TC field in the handle keeps increasing even when the fan is disconnected - (this may be expected? )

and the interrupts don't fire when the fan is running after a few rounds.. not sure what's going on here! any ideas ?

0 Kudos
536 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Can you estimate the TACH signal  frequency when the motor is running?

I suppose that the TACH signal  frequency is too high, the capture frequency is too high for the MCU to handle. The maximum ISR frequency is 1MHz I suppose for the lpc550x.

For your case, pls delete the line in the ISR:

LOG_DEBUG("ISR count = %d, TC = %ld RPM = %ld", count, tc, g_ctx.fanCtrlHandle.rpm);

Because the line requires long time, instead, you can save the tc to an array, in the debug, you can check the data in the array.

Can you use the method one? you can have the CTimer to count the edge of the capture signal if the TACH signal  frequency is very high, pls have a try.

BR

XiangJun Rong

 

 

 

0 Kudos
533 Views
amithrao
Contributor II

It was a hardware issue ! the signal on the tach pin wasn't pulled up.. adding a pull up resistor there to 3.3V solved the issue! 
Thanks for your inputs  

0 Kudos