rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
rpm_calculator.h
Go to the documentation of this file.
1/**
2 * @file rpm_calculator.h
3 * @brief Shaft position sensor(s) decoder header
4 *
5 * @date Jan 1, 2013
6 * @author Andrey Belomutskiy, (c) 2012-2020
7 */
8
9#pragma once
10
11#include "scheduler.h"
12#include "stored_value_sensor.h"
13#include <rusefi/timer.h>
14#include "rpm_calculator_api.h"
15#include "trigger_decoder.h"
16
17#define MAX_ALLOWED_RPM 30000
18
19typedef enum {
20 /**
21 * The engine is not spinning, RPM=0
22 */
24 /**
25 * The engine is spinning up (reliable RPM is not detected yet).
26 * In this state, rpmValue is >= 0 (can be zero).
27 */
29 /**
30 * The engine is cranking (0 < RPM < cranking.rpm)
31 */
33 /**
34 * The engine is running (RPM >= cranking.rpm)
35 */
38
39/**
40 * Most consumers should access value via Sensor framework by SensorType::Rpm key
41 */
43public:
45
46 operation_mode_e getOperationMode() const override;
47
48 void onSlowCallback();
49
50 /**
51 * Returns true if the engine is not spinning (RPM==0)
52 */
53 bool isStopped() const override;
54 /**
55 * Returns true if the engine is spinning up
56 */
57 bool isSpinningUp() const;
58 /**
59 * Returns true if the engine is cranking OR spinning up
60 */
61 bool isCranking() const override;
62 /**
63 * Returns true if the engine is running and not cranking
64 */
65 bool isRunning() const;
66
67 bool checkIfSpinning(efitick_t nowNt) const;
68
69 /**
70 * This accessor is used in unit-tests.
71 */
73
74 /**
75 * Should be called on every trigger event when the engine is just starting to spin up.
76 */
77 void setSpinningUp(efitick_t nowNt );
78 /**
79 * Called if the synchronization is lost due to a trigger timeout.
80 */
81 void setStopSpinning();
82
83 /**
84 * Just a quick getter for rpmValue
85 * Should be same exact value as Sensor::get(SensorType::Rpm).Value just quicker.
86 * Open question if we have any cases where this opimization is needed.
87 */
88 float getCachedRpm() const;
89 /**
90 * This method is invoked once per engine cycle right after we calculate new RPM value
91 */
92 void onNewEngineCycle();
93 uint32_t getRevolutionCounterM(void) const;
94 void setRpmValue(float value);
95 /**
96 * The same as setRpmValue() but without state change.
97 * We need this to be public because of calling rpmState->assignRpmValue() from rpmShaftPositionCallback()
98 */
99 void assignRpmValue(float value);
100 uint32_t getRevolutionCounterSinceStart(void) const;
101 /**
102 * RPM rate of change between current RPM and RPM measured during previous engine cycle
103 * see also SC_RPM_ACCEL
104 */
105 float getRpmAcceleration() const;
106
107 // Get elapsed time since the engine transitioned to the running state.
108 float getSecondsSinceEngineStart(efitick_t nowNt) const;
109
110 /**
111 * this is RPM on previous engine cycle.
112 */
114
115 /**
116 * This is a performance optimization: let's pre-calculate this each time RPM changes
117 * NaN while engine is not spinning
118 */
120
122 return oneDegreeUs;
123 }
124
126
127 // RPM rate of change, in RPM per second
128 float rpmRate = 0;
129
130protected:
131 // Print sensor info - current RPM state
132 void showInfo(const char* sensorName) const override;
133
134private:
135 /**
136 * At this point this value is same exact value as in private m_value variable
137 * At this point all this is performance optimization?
138 * Open question is when do we need it for performance reasons.
139 */
140 float cachedRpmValue = 0;
141
142 /**
143 * This counter is incremented with each revolution of one of the shafts. Could be
144 * crankshaft could be camshaft.
145 */
147 /**
148 * Same as the above, but since the engine started spinning
149 */
151
153
154 /**
155 * True if the engine is spinning (regardless of its state), i.e. if shaft position changes.
156 * Needed by spinning-up logic.
157 */
158 bool isSpinning = false;
159
161};
162
163void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex, efitick_t edgeTimestamp);
164
165void tdcMarkCallback(
166 uint32_t trgEventIndex, efitick_t edgeTimestamp);
167
169
170#define getRevolutionCounter() (engine->rpmCalculator.getRevolutionCounterM())
171
172/**
173 * @return tick time of scheduled action
174 */
175efitick_t scheduleByAngle(scheduling_s *timer, efitick_t nowNt, angle_t angle, action_s const& action);
float getSecondsSinceEngineStart(efitick_t nowNt) const
bool isSpinningUp() const
bool isStopped() const override
floatus_t oneDegreeUs
float getRpmAcceleration() const
uint32_t getRevolutionCounterM(void) const
bool checkIfSpinning(efitick_t nowNt) const
void showInfo(const char *sensorName) const override
void setRpmValue(float value)
void setSpinningUp(efitick_t nowNt)
spinning_state_e state
bool isRunning() const
float getCachedRpm() const
uint32_t revolutionCounterSinceBoot
bool isCranking() const override
uint32_t getRevolutionCounterSinceStart(void) const
uint32_t revolutionCounterSinceStart
spinning_state_e getState() const
void assignRpmValue(float value)
operation_mode_e getOperationMode() const override
floatus_t getOneDegreeUs() override
Base class for sensors that compute a value on one thread, and want to make it available to consumers...
efitick_t scheduleByAngle(scheduling_s *timer, efitick_t nowNt, angle_t angle, action_s const &action)
void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex, efitick_t edgeTimestamp)
Shaft position callback used by RPM calculation logic.
operation_mode_e lookupOperationMode()
void tdcMarkCallback(uint32_t trgEventIndex, efitick_t edgeTimestamp)
spinning_state_e
@ RUNNING
@ SPINNING_UP
@ CRANKING
@ STOPPED
operation_mode_e
float angle_t
trigger_event_e
Base class for a sensor that has its value asynchronously set, then later retrieved by a consumer.