Engine RPM (EngineParameterRapid)
Will this work?
Based on pulsin()
To the function, I need to convert the input frequency from the engine (one pulse per rpm) to 4 pulses per RPM to be able to use may one year old RPM gauge (gasoline and now I have a diesel engine).
As well shall the data be send through NMEA2k.
The input frequency should be average by 30 readings.
Here is the code:
// Demo: NMEA2000 library. Calculate Engine RPM
#include <NMEA2000.h>
#include <N2kMessages.h>
#include <NMEA2000_teensy.h>
#include <FreqMeasure.h>
float frequency;
byte EngineInstance = 0;
byte rpmGaugeOut = 6;
#define RapidDataUpdatePeriod 167
byte freqDivider = 4;
volatile float freqOut;
tNMEA2000_teensy NMEA2000;
// List here messages your device will transmit.
const unsigned long TransmitMessages[] PROGMEM = {127488L, 0};
// *****************************************************************************
void setup() {
// Set Product information
NMEA2000.SetProductInformation("000001001", // Manufacturer's Model serial code
101, // Manufacturer's product code
"Engine RPM", // Manufacturer's Model ID
"1.0.0.0 (2018-08-24)", // Manufacturer's Software version code
"1.0.0.0 (2018-08-24)" // Manufacturer's Model version
);
// Set device information
NMEA2000.SetDeviceInformation(000001001, // Unique number. Use e.g. Serial number.
140, // Device function=Engine. See codes on http://www.nmea.org/Assets/20120726%20nmea%202000%20class%20&%20function%20codes%20v%202.00.pdf
50, // Device class=Engine. See codes on http://www.nmea.org/Assets/20120726%20nmea%202000%20class%20&%20function%20codes%20v%202.00.pdf
2046 // Just choosen free from code list on http://www.nmea.org/Assets/20121020%20nmea%202000%20registration%20list.pdf
);
// Uncomment 2 rows below to see, what device will send to bus. Use e.g. OpenSkipper or Actisense NMEA Reader
//Serial.begin(115200);
NMEA2000.SetForwardStream(&Serial);
// If you want to use simple ascii monitor like Arduino Serial Monitor, uncomment next line
NMEA2000.SetForwardType(tNMEA2000::fwdt_Text); // Show in clear text. Comment for default Actisense format.
// If you also want to see all traffic on the bus use N2km_ListenAndNode instead of N2km_NodeOnly below
NMEA2000.SetMode(tNMEA2000::N2km_NodeOnly, 23);
// NMEA2000.SetDebugMode(tNMEA2000::dm_Actisense); // Uncomment this, so you can test code without CAN bus chips on Arduino Mega
NMEA2000.EnableForward(false); // Comment this, if you want to see bus traffic on your serial.
NMEA2000.ExtendTransmitMessages(TransmitMessages);
NMEA2000.Open();
}
// *****************************************************************************
void loop() {
NMEA2000.ParseMessages();
SendN2kRapidData();
FreqCount();
}
void FreqCount() {
FreqMeasure.begin();
double sum = 0;
int count = 0;
if (FreqMeasure.available()) {
// average several reading together
sum = sum + FreqMeasure.read();
count = count + 1;
if (count > 30) {
frequency = FreqMeasure.countToFrequency(sum / count);
freqOut = (frequency / freqDivider);
sum = 0;
count = 0;
}
}
}
void rpm() {
unsigned long highTime = ((1000000 / freqOut) / 2); // calculate the time of high level in microseconds
unsigned long currentTime = micros();
if (currentTime - (highTime * 2) <= currentTime) {
digitalWrite(rpmGaugeOut, HIGH);
}
else
digitalWrite(rpmGaugeOut, LOW);
}
void SendN2kRapidData() {
static unsigned long RapidDataUpdated = millis();
tN2kMsg N2kMsg;
if ( RapidDataUpdated + RapidDataUpdatePeriod < millis() ) {
RapidDataUpdated = millis();
int int_frequency = (int)frequency;
SetN2kEngineParamRapid(N2kMsg, EngineInstance, int_frequency, N2kDoubleNA, N2kDoubleNA); //SetN2kEngineParamRapid(N2kMsg, EngineInstance, frequency, EngineBoostPressure, EngineTiltTrim);
NMEA2000.SendMsg(N2kMsg);
}
}