Varvtalsräkning på digital ingång - Förslag?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Varvtalsräkning på digital ingång - Förslag?

Inlägg av Rick81 »

Ja testa den. Smidigt med inbyggd funktion i stm32.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Varvtalsräkning på digital ingång - Förslag?

Inlägg av DanielM »

Jag har skrivit C kod från den där kinesen. Jag har inte testat detta. Men med tanke på att det fungerar för han, så lär det fungera för mig också.
Jag har bara gjort så den är något mer användarvänlig.

Ni får gärna testa och säga vad ni tycker om den?

Kod: Markera allt

/*
 * Use a timer and select combined channels -> Encoder Mode.
 * Then select our prescaler and the counter period
 * Then select Encoder Mode TI1 and TI2.
 * Leave the rest as default
 */
void Encoder_init(Encoder *encoder, TIM_HandleTypeDef *htim, uint16_t one_rotation_pulses, uint32_t check_every_ms) {
	encoder->htim = htim;
	encoder->one_rotation_pulses = one_rotation_pulses;
	encoder->check_every_ms = check_every_ms;
}

void count_encoder(Encoder *encoder) {
	if (HAL_GetTick() - encoder->tick > encoder->check_every_ms) {
		/* Control TIM for every check_every_ms */
		encoder->cnt2 = encoder->htim->Instance->CNT;

		/* Control the rotation count */
		if (__HAL_TIM_IS_TIM_COUNTING_DOWN(encoder->htim)) {
			encoder->dir = 1;
			/* __HAL_TIM_IS_TIM_COUNTING_DOWN Exception when the macro is wrong configured */
			if ((encoder->cnt2 > encoder->cnt1) && (encoder->cnt2 - encoder->cnt1 < 100))
				encoder->dir = 0;
		} else {
			encoder->dir = 0;
			/* __HAL_TIM_IS_TIM_COUNTING_DOWN Excepting when the macro gives error */
			if ((encoder->cnt1 > encoder->cnt2) && (encoder->cnt1 - encoder->cnt2 < 100))
				encoder->dir = 1;
		}

		if (encoder->dir) {
			/* Down Counting */
			if (encoder->cnt1 >= encoder->cnt2)
				encoder->diff = encoder->cnt1 - encoder->cnt2;
			else
				encoder->diff = (encoder->htim->Instance->ARR + encoder->cnt1) - encoder->cnt2;
		} else {
			/* Up Counting */
			if (encoder->cnt2 >= encoder->cnt1)
				encoder->diff = encoder->cnt2 - encoder->cnt1;
			else
				encoder->diff = (encoder->htim->Instance->ARR + encoder->cnt2) - encoder->cnt1;
		}

		if ((encoder->htim->Instance->SMCR & 0x03) == 0x03) {
			/* X4 Mode Countering increase with 4 Pulse */
			encoder->speed = encoder->diff * 60 / 4 / encoder->one_rotation_pulses; //RPM x 60
		} else {
			/* X4 Mode Countering increase with 2 Pulse */
			encoder->speed = encoder->diff * 60 / 2 / encoder->one_rotation_pulses; //RPM x 60
		}

		encoder->tick = HAL_GetTick();
		encoder->cnt1 = encoder->htim->Instance->CNT;
	}
}

float Encoder_getSpeed(Encoder *encoder){
	return encoder->dir == 1 ? (float) encoder->speed : -((float) encoder->speed);
}

Kod: Markera allt

#ifndef SRC_ENCODER_ENCODER_H_
#define SRC_ENCODER_ENCODER_H_

#include "main.h"

typedef struct{
	uint8_t dir;
	uint16_t cnt1, cnt2, diff, speed, one_rotation_pulses;
	uint32_t tick, check_every_ms;
	TIM_HandleTypeDef* htim;
}Encoder;

void Encoder_init(Encoder* encoder, TIM_HandleTypeDef* htim, uint16_t one_rotation_pulses);
void count_encoder(Encoder *encoder);
float Encoder_getSpeed(Encoder *encoder);

#endif /* SRC_ENCODER_ENCODER_H_ */
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Varvtalsräkning på digital ingång - Förslag?

Inlägg av DanielM »

Nu är koden testad och den fungerar! :tumupp:
Skriv svar