Help in reading rpm signal

Hello everyone,

Im working on a real dash project. however its a toyota corolla with 4efe engine with NO CAN BUS communication . my attempt is to digital read the ecu generated RPM signal and then to feed the data to read dash via serial com. I scoped the ecu RPM signal and figured out it had duty of 50% and has a frequency around 28 at idle . with some basic coding i was able to get the rpm respnsive to throtle . how ever the RPM needle fluctuctaes all times even at idle and sometimes get frozen and also sometimes it lagy . i will attach my code and the ecu scoped rpm signal at idle. appriciate your help and support

// input pin can be any digital input
unsigned long inputPin = 3;

boolean inputState = false;
boolean lastInputState = false;
unsigned long count = 0L;
unsigned long rpm = 0;

unsigned long previousCountMillis = millis();
const long countMillis = 500L;

void setInputState() {
  inputState = digitalRead(inputPin);
}

void setup() {
  pinMode(inputPin, INPUT);
  Serial.begin(115200);
}


void loop() {
  
 SendCANFramesToSerial();


rpm = count*60;
   
   
  // runs every time thru the loop
  setInputState();
  
  // count every transision HIGH<->LOW
  if (inputState != lastInputState) {
    count++;  
    lastInputState = inputState;
  }

  // ------- every half second, count is equal to Hz.---------------
  if (millis() - previousCountMillis >= countMillis) {
    previousCountMillis += countMillis;
    
    // show Hz on Serial too if available
    // Serial.print(count); 
    // Serial.println(" Hz");

  

    // reset to zero for the next half second's sample
    count = 0L;
    // Serial.print(rpm); 
    // Serial.println(" RPM");
    
  }
}


void SendCANFramesToSerial()
{
  byte buf[8];

  // build & send CAN frames to RealDash.
  // a CAN frame payload is always 8 bytes containing data in a manner
  // described by the RealDash custom channel description XML file
  // all multibyte values are handled as little endian by default.
  // endianess of the values can be specified in XML file if it is required to use big endian values

  // build 1st CAN frame, RPM, MAP, CLT, TPS (just example data)
  memcpy(buf, &rpm, 2);


  // write first CAN frame to serial
  SendCANFrameToSerial(3200, buf);

  
}


void SendCANFrameToSerial(unsigned long canFrameId, const byte* frameData)
{
  // the 4 byte identifier at the beginning of each CAN frame
  // this is required for RealDash to 'catch-up' on ongoing stream of CAN frames
  const byte serialBlockTag[4] = { 0x44, 0x33, 0x22, 0x11 };
  Serial.write(serialBlockTag, 4);

  // the CAN frame id number (as 32bit little endian value)
  Serial.write((const byte*)&canFrameId, 4);

  // CAN frame payload
  Serial.write(frameData, 8);
}

Iam not reving . it just fluctuates


Capture.PNG

Impossible to remotely help on this sort of custom projects. I believe there is something wrong in your code where you calculate the RPM. Either your Arduino is not fast enough so it skips calculations, or the idea of using that signal is not working in the first place.

Try to set a constant value to your RPM in Arduino code to verify that RPM is stable in RealDash. If it still fluctuates, make sure you are not getting RPM from multiple sources.

Hello thanks for the reply i was able to get the rpm working by seting the SendCANFramesToSerial(); after calculating the rpm value . how ever its responsive ! but there is a bit of lag . is there a way to improve my responses ?

void loop() {    
  setInputState();
  if (inputState != lastInputState) {
    count++;  
    lastInputState = inputState;
  }

  if (millis() - previousCountMillis >= countMillis) {
    previousCountMillis += countMillis;
    rpm = count*60;
    SendCANFramesToSerial();
    count = 0L;
  }
}

Your if statement produces 500ms delay on each RPM update, so it wont update any faster than twice a second.