You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.6 KiB
157 lines
5.6 KiB
/**
|
|
* \file
|
|
* \brief Tachometer Module
|
|
* \author Erich Styger, erich.styger@hslu.ch
|
|
* \license SPDX-License-Identifier: BSD-3-Clause
|
|
* Module to calculate the speed based on the quadrature counter.
|
|
*/
|
|
|
|
#include "platform.h" /* interface to the platform */
|
|
#if PL_CONFIG_USE_TACHO
|
|
#include "Tacho.h" /* our own interface */
|
|
#include "QuadCounter.h"
|
|
#if PL_CONFIG_USE_SHELL
|
|
#include "McuShell.h"
|
|
#endif
|
|
#include "McuUtility.h"
|
|
#include "McuRTOS.h"
|
|
#include "McuCriticalSection.h"
|
|
|
|
#define TACHO_SAMPLE_PERIOD_MS (5)
|
|
/*!< speed sample period in ms. Make sure that speed is sampled at the given rate. */
|
|
#define NOF_HISTORY (16U+1U)
|
|
/*!< number of samples for speed calculation (>0):the more, the better, but the slower. */
|
|
|
|
static volatile QuadCounter_QuadCntrType TACHO_LeftPosHistory[NOF_HISTORY], TACHO_RightPosHistory[NOF_HISTORY];
|
|
/*!< for better accuracy, we calculate the speed over some samples */
|
|
static volatile uint8_t TACHO_PosHistory_Index = 0;
|
|
/*!< position index in history */
|
|
|
|
static int32_t TACHO_currLeftSpeed = 0, TACHO_currRightSpeed = 0;
|
|
/*!< position index in history */
|
|
|
|
int32_t TACHO_GetSpeed(bool isLeft) {
|
|
if (isLeft) {
|
|
return TACHO_currLeftSpeed;
|
|
} else {
|
|
return TACHO_currRightSpeed;
|
|
}
|
|
}
|
|
|
|
void TACHO_CalcSpeed(void) {
|
|
/* we calculate the speed as follow:
|
|
1000
|
|
steps/sec = delta * -----------------
|
|
samplePeriod (ms)
|
|
As this function may be called very frequently, it is important to make it as efficient as possible!
|
|
*/
|
|
int32_t deltaLeft, deltaRight, newLeft, newRight, oldLeft, oldRight;
|
|
int32_t speedLeft, speedRight;
|
|
bool negLeft, negRight;
|
|
McuCriticalSection_CriticalVariable()
|
|
|
|
McuCriticalSection_EnterCritical();
|
|
oldLeft = (int32_t)TACHO_LeftPosHistory[TACHO_PosHistory_Index]; /* oldest left entry */
|
|
oldRight = (int32_t)TACHO_RightPosHistory[TACHO_PosHistory_Index]; /* oldest right entry */
|
|
if (TACHO_PosHistory_Index==0) { /* get newest entry */
|
|
newLeft = (int32_t)TACHO_LeftPosHistory[NOF_HISTORY-1];
|
|
newRight = (int32_t)TACHO_RightPosHistory[NOF_HISTORY-1];
|
|
} else {
|
|
newLeft = (int32_t)TACHO_LeftPosHistory[TACHO_PosHistory_Index-1];
|
|
newRight = (int32_t)TACHO_RightPosHistory[TACHO_PosHistory_Index-1];
|
|
}
|
|
McuCriticalSection_ExitCritical();
|
|
deltaLeft = oldLeft-newLeft; /* delta of oldest position and most recent one */
|
|
/* use unsigned arithmetic */
|
|
if (deltaLeft < 0) {
|
|
deltaLeft = -deltaLeft;
|
|
negLeft = TRUE;
|
|
} else {
|
|
negLeft = FALSE;
|
|
}
|
|
deltaRight = oldRight-newRight; /* delta of oldest position and most recent one */
|
|
/* use unsigned arithmetic */
|
|
if (deltaRight < 0) {
|
|
deltaRight = -deltaRight;
|
|
negRight = TRUE;
|
|
} else {
|
|
negRight = FALSE;
|
|
}
|
|
/* calculate speed. this is based on the delta and the time (number of samples or entries in the history table) */
|
|
speedLeft = (int32_t)(deltaLeft*1000U/(TACHO_SAMPLE_PERIOD_MS*(NOF_HISTORY-1)));
|
|
if (negLeft) {
|
|
speedLeft = -speedLeft;
|
|
}
|
|
speedRight = (int32_t)(deltaRight*1000U/(TACHO_SAMPLE_PERIOD_MS*(NOF_HISTORY-1)));
|
|
if (negRight) {
|
|
speedRight = -speedRight;
|
|
}
|
|
TACHO_currLeftSpeed = -speedLeft; /* store current speed in global variable */
|
|
TACHO_currRightSpeed = -speedRight; /* store current speed in global variable */
|
|
}
|
|
|
|
void TACHO_Sample(void) {
|
|
/* calling it from a timer interrupt every portTICK_PERIOD_MS */
|
|
static int cnt = 0;
|
|
/* get called from the RTOS tick counter. Divide the frequency. */
|
|
cnt += portTICK_PERIOD_MS;
|
|
if (cnt < TACHO_SAMPLE_PERIOD_MS) { /* sample only every TACHO_SAMPLE_PERIOD_MS */
|
|
return;
|
|
}
|
|
cnt = 0; /* reset counter */
|
|
|
|
TACHO_LeftPosHistory[TACHO_PosHistory_Index] = QuadCounter_GetPosLeft();
|
|
TACHO_RightPosHistory[TACHO_PosHistory_Index] = QuadCounter_GetPosRight();
|
|
TACHO_PosHistory_Index++;
|
|
if (TACHO_PosHistory_Index >= NOF_HISTORY) {
|
|
TACHO_PosHistory_Index = 0;
|
|
}
|
|
}
|
|
|
|
#if PL_CONFIG_USE_SHELL
|
|
/*!
|
|
* \brief Prints the system low power status
|
|
* \param io I/O channel to use for printing status
|
|
*/
|
|
static void TACHO_PrintStatus(const McuShell_StdIOType *io) {
|
|
McuShell_SendStatusStr((unsigned char*)"Tacho", (unsigned char*)"Tachometer status\r\n", io->stdOut);
|
|
McuShell_SendStatusStr((unsigned char*)" L speed", (unsigned char*)"", io->stdOut);
|
|
McuShell_SendNum32s(TACHO_GetSpeed(TRUE), io->stdOut);
|
|
McuShell_SendStr((unsigned char*)" steps/sec\r\n", io->stdOut);
|
|
McuShell_SendStatusStr((unsigned char*)" R speed", (unsigned char*)"", io->stdOut);
|
|
McuShell_SendNum32s(TACHO_GetSpeed(FALSE), io->stdOut);
|
|
McuShell_SendStr((unsigned char*)" steps/sec\r\n", io->stdOut);
|
|
}
|
|
|
|
/*!
|
|
* \brief Prints the help text to the console
|
|
* \param io I/O channel to be used
|
|
*/
|
|
static void TACHO_PrintHelp(const McuShell_StdIOType *io) {
|
|
McuShell_SendHelpStr((unsigned char*)"tacho", (unsigned char*)"Group of tacho commands\r\n", io->stdOut);
|
|
McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Shows tacho help or status\r\n", io->stdOut);
|
|
}
|
|
|
|
uint8_t TACHO_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) {
|
|
if (McuUtility_strcmp((char*)cmd, (char*)McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, (char*)"tacho help")==0) {
|
|
TACHO_PrintHelp(io);
|
|
*handled = TRUE;
|
|
} else if (McuUtility_strcmp((char*)cmd, (char*)McuShell_CMD_STATUS)==0 || McuUtility_strcmp((char*)cmd, (char*)"tacho status")==0) {
|
|
TACHO_PrintStatus(io);
|
|
*handled = TRUE;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
#endif /* PL_CONFIG_USE_SHELL */
|
|
|
|
void TACHO_Deinit(void) {
|
|
}
|
|
|
|
void TACHO_Init(void) {
|
|
TACHO_currLeftSpeed = 0;
|
|
TACHO_currRightSpeed = 0;
|
|
TACHO_PosHistory_Index = 0;
|
|
}
|
|
|
|
#endif /* PL_HAS_MOTOR_TACHO */
|
|
|
|
|