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 float getMinCrankingRpm() const;
91
92 /**
93 * This method is invoked once per engine cycle right after we calculate new RPM value
94 */
95 void onNewEngineCycle();
96 uint32_t getRevolutionCounterM(void) const;
97 void setRpmValue(float value);
98 /**
99 * The same as setRpmValue() but without state change.
100 * We need this to be public because of calling rpmState->assignRpmValue() from rpmShaftPositionCallback()
101 */
102 void assignRpmValue(float value);
103 uint32_t getRevolutionCounterSinceStart(void) const;
104 /**
105 * RPM rate of change between current RPM and RPM measured during previous engine cycle
106 * see also SC_RPM_ACCEL
107 */
108 float getRpmAcceleration() const;
109
110 // Get elapsed time since the engine transitioned to the running state.
111 float getSecondsSinceEngineStart(efitick_t nowNt) const;
112
113 /**
114 * this is RPM on previous engine cycle.
115 */
117
118 /**
119 * This is a performance optimization: let's pre-calculate this each time RPM changes
120 * NaN while engine is not spinning
121 */
123
125 return oneDegreeUs;
126 }
127
129
130 // RPM rate of change, in RPM per second
131 float rpmRate = 0;
132
133protected:
134 // Print sensor info - current RPM state
135 void showInfo(const char* sensorName) const override;
136
137private:
138 /**
139 * At this point this value is same exact value as in private m_value variable
140 * At this point all this is performance optimization?
141 * Open question is when do we need it for performance reasons.
142 */
143 float cachedRpmValue = 0;
144
145 /**
146 * The slowest RPM encountered during cranking, used for interpolating ignition advance
147 */
148 float minCrankingRpm = 0;
149
150 /**
151 * This counter is incremented with each revolution of one of the shafts. Could be
152 * crankshaft could be camshaft.
153 */
155 /**
156 * Same as the above, but since the engine started spinning
157 */
159
161
162 /**
163 * True if the engine is spinning (regardless of its state), i.e. if shaft position changes.
164 * Needed by spinning-up logic.
165 */
166 bool isSpinning = false;
167
169};
170
171void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex, efitick_t edgeTimestamp);
172
173void tdcMarkCallback(
174 uint32_t trgEventIndex, efitick_t edgeTimestamp);
175
177
178#define getRevolutionCounter() (engine->rpmCalculator.getRevolutionCounterM())
179
180/**
181 * @return tick time of scheduled action
182 */
183efitick_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
float getMinCrankingRpm() 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.