* Update tachometer.cpp Initial implementation of E30 M3 Tach output solution #907, unit_test plus debugging next * tacho unit tests First successfull unit test for tachometer * RAM adjustment so it would link * refactoring tacho, broken! * starting to make some progress...still fails after a few seconds * Rework with SW PWM * Update after code review * unit_test update * First working unit_test * Update .gitignore * Update engine_controller.cpp * Update engine_controller.cpp * Update tachometer.h * Update test_tacho.cpp Co-authored-by: rusefi <rusefi@users.noreply.github.com>
This commit is contained in:
parent
b015ec5944
commit
ea4cfa9046
|
@ -12,31 +12,69 @@
|
||||||
|
|
||||||
#include "tachometer.h"
|
#include "tachometer.h"
|
||||||
#include "trigger_central.h"
|
#include "trigger_central.h"
|
||||||
|
#include "pwm_generator.h"
|
||||||
|
|
||||||
EXTERN_ENGINE;
|
EXTERN_ENGINE;
|
||||||
|
|
||||||
static scheduling_s tachTurnSignalOff;
|
static SimplePwm tachControl("tach");
|
||||||
|
static float tachFreq;
|
||||||
|
static float duty;
|
||||||
|
|
||||||
static void turnTachPinLow(void *) {
|
#if EFI_UNIT_TEST
|
||||||
enginePins.tachOut.setLow();
|
float getTachFreq(void) {
|
||||||
|
return tachFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getTachDuty(void) {
|
||||||
|
return duty;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void tachSignalCallback(trigger_event_e ckpSignalType,
|
static void tachSignalCallback(trigger_event_e ckpSignalType,
|
||||||
uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
uint32_t index, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
UNUSED(ckpSignalType);
|
// only process at index configured to avoid too much cpu time for index 0?
|
||||||
if (index != (uint32_t)engineConfiguration->tachPulseTriggerIndex) {
|
if (index != (uint32_t)CONFIG(tachPulseTriggerIndex)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enginePins.tachOut.setHigh();
|
|
||||||
float durationMs;
|
#if EFI_UNIT_TEST
|
||||||
if (engineConfiguration->tachPulseDurationAsDutyCycle) {
|
printf("tachSignalCallback(%d %d)\n", ckpSignalType, index);
|
||||||
// todo: implement tachPulseDurationAsDutyCycle
|
printf("Current RPM: %d\n",GET_RPM());
|
||||||
durationMs = engineConfiguration->tachPulseDuractionMs;
|
UNUSED(edgeTimestamp);
|
||||||
} else {
|
#else
|
||||||
durationMs = engineConfiguration->tachPulseDuractionMs;
|
UNUSED(ckpSignalType);
|
||||||
|
UNUSED(edgeTimestamp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// How many tach pulse periods do we have?
|
||||||
|
int periods = CONFIG(tachPulsePerRev);
|
||||||
|
|
||||||
|
if(periods == 0){
|
||||||
|
warning(CUSTOM_ERR_6709,"Check Tachometer Pulse per Rev!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
engine->executor.scheduleForLater(&tachTurnSignalOff, (int)MS2US(durationMs), &turnTachPinLow);
|
|
||||||
|
// What is the angle per tach output period?
|
||||||
|
float cycleTimeMs = 60000.0 / GET_RPM();
|
||||||
|
float periodTimeMs = cycleTimeMs / periods;
|
||||||
|
tachFreq = 1000.0 / periodTimeMs;
|
||||||
|
|
||||||
|
if (CONFIG(tachPulseDurationAsDutyCycle)) {
|
||||||
|
// Simple case - duty explicitly set
|
||||||
|
duty = CONFIG(tachPulseDuractionMs);
|
||||||
|
} else {
|
||||||
|
// Constant high-time mode - compute the correct duty cycle
|
||||||
|
duty = CONFIG(tachPulseDuractionMs) / periodTimeMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case Freq is under 1Hz, we stop pwm to avoid warnings!
|
||||||
|
if (tachFreq < 1.0) {
|
||||||
|
tachFreq = NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
tachControl.setSimplePwmDutyCycle(duty);
|
||||||
|
tachControl.setFrequency(tachFreq);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initTachometer(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
void initTachometer(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
|
@ -44,11 +82,14 @@ void initTachometer(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enginePins.tachOut.initPin("Tachometer", CONFIG(tachOutputPin), &CONFIG(tachOutputPinMode));
|
startSimplePwmExt(&tachControl,
|
||||||
|
"Tachometer",
|
||||||
|
&engine->executor,
|
||||||
|
CONFIG(tachOutputPin),
|
||||||
|
&enginePins.tachOut,
|
||||||
|
NAN, 0.1, (pwm_gen_callback*)applyPinState);
|
||||||
|
|
||||||
#if EFI_SHAFT_POSITION_INPUT
|
#if EFI_SHAFT_POSITION_INPUT
|
||||||
addTriggerEventListener(tachSignalCallback, "tach", engine);
|
addTriggerEventListener(tachSignalCallback, "tach", engine);
|
||||||
#endif /* EFI_SHAFT_POSITION_INPUT */
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "engine_test_helper.h"
|
||||||
|
|
||||||
|
extern WarningCodeState unitTestWarningCodeState;
|
||||||
|
extern float getTachFreq(void);
|
||||||
|
extern float getTachDuty(void);
|
||||||
|
|
||||||
|
TEST(tachometer, testPulsePerRev) {
|
||||||
|
// This engine has a tach pin set - we need that
|
||||||
|
WITH_ENGINE_TEST_HELPER(BMW_E34);
|
||||||
|
|
||||||
|
// We don't actually care about ign/inj at all, just tach
|
||||||
|
engineConfiguration->isInjectionEnabled = false;
|
||||||
|
engineConfiguration->isIgnitionEnabled = false;
|
||||||
|
|
||||||
|
// Configure tach pulse count
|
||||||
|
// 5 PPR, 25% duty
|
||||||
|
engineConfiguration->tachPulsePerRev = 4;
|
||||||
|
engineConfiguration->tachPulseDuractionMs = 0.5f;
|
||||||
|
engineConfiguration->tachPulseDurationAsDutyCycle = true;
|
||||||
|
engineConfiguration->tachPulseTriggerIndex = 0;
|
||||||
|
|
||||||
|
// Set predictable trigger settings
|
||||||
|
engineConfiguration->trigger.customTotalToothCount = 8;
|
||||||
|
engineConfiguration->trigger.customSkippedToothCount = 0;
|
||||||
|
engineConfiguration->useOnlyRisingEdgeForTrigger = false;
|
||||||
|
engineConfiguration->ambiguousOperationMode = FOUR_STROKE_CAM_SENSOR;
|
||||||
|
eth.applyTriggerWaveform();
|
||||||
|
|
||||||
|
// get the engine running - 6 revolutions
|
||||||
|
eth.fireTriggerEvents(48);
|
||||||
|
|
||||||
|
// ensure engine speed and position
|
||||||
|
ASSERT_EQ(1500, GET_RPM()) << "RPM";
|
||||||
|
ASSERT_EQ(15, engine->triggerCentral.triggerState.getCurrentIndex()) << "index #1";
|
||||||
|
ASSERT_EQ(engine->triggerCentral.triggerState.shaft_is_synchronized, true);
|
||||||
|
ASSERT_EQ(100,getTachFreq());
|
||||||
|
ASSERT_EQ(0.5,getTachDuty());
|
||||||
|
std::cerr << "Tach Freq: " << getTachFreq() << "\n" << std::endl;
|
||||||
|
std::cerr << "Tach Duty: " << getTachDuty() << "\n" << std::endl;
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ TESTS_SRC_CPP = \
|
||||||
tests/test_pid_auto.cpp \
|
tests/test_pid_auto.cpp \
|
||||||
tests/test_pid.cpp \
|
tests/test_pid.cpp \
|
||||||
tests/test_accel_enrichment.cpp \
|
tests/test_accel_enrichment.cpp \
|
||||||
|
tests/test_tacho.cpp \
|
||||||
tests/test_gpiochip.cpp \
|
tests/test_gpiochip.cpp \
|
||||||
tests/test_multispark.cpp \
|
tests/test_multispark.cpp \
|
||||||
tests/sensor/basic_sensor.cpp \
|
tests/sensor/basic_sensor.cpp \
|
||||||
|
|
Loading…
Reference in New Issue