Ctimer0Cap0 for external fan counting - help

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Ctimer0Cap0 for external fan counting - help

跳至解决方案
1,904 次查看
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 项奖励
回复
1 解答
1,839 次查看
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 项奖励
回复
7 回复数
1,896 次查看
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 项奖励
回复
1,890 次查看
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 项奖励
回复
1,883 次查看
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 项奖励
回复
1,856 次查看
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 项奖励
回复
1,852 次查看
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 项奖励
回复
1,843 次查看
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 项奖励
回复
1,840 次查看
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 项奖励
回复