Reading ECU RPM signal

Im working on a digital instrument cluster project . and im working on a vehicle with no can bus , However the ecu generates a signal as the atatchement ! im using the realdash platform . how ever i see fluctuations in rpm needle . i will attche the code it could be much appriciable if some one could see what mistake i did in my coding.

// 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);
}

thank you

I recon you would be better of using an interrupt driven counting routine to prevent any part of the sketch from holding up the counting.
That said, one must look for parts of the code where that could happen, and i recon that it is happening when sending the data. Not at first, but at some point the TX-buffer fills up. Every time you call SendCANFrameToSerial() you send 16 bytes. at 115200 that means about 11.5 bytes per ms (1 start bit, 1 stop bit, no parity bit and 8 data bits) And that function is called every pass through loop(). So you call it more often than the data can be transmitted as far as i can tell. So i figure that if you reduce the amount of transmissions at most once every 10 or 20 ms you will probably already get better results, but changing the counting to an interrupt driven function will get you better accuracy than polling (what you are doing now)

if you reduce the amount of transmissions at most once every 10 or 20 ms

does it mean to reduce the baud rate ?

No not the baud rate, just call

SendCANFramesToSerial();

periodically from loop, actually why don't you just change loop() into

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

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

You should only send an RPM value if you have calculated a new one correctly, have counted for half a second and done the multiplication.

The baud-rate obviously needs to remain the same.

I first thought it was just the buffer overflow, but now i see that you do the calculation and transmission in the wrong moment. (it got so much clearer after removing comments commented out parts and empty white lines... )

Huge thanks ! its worked ! appriciate your support !

Hello, how are you? I have a car with no can bus too. Can you provide the complete arduino Sketch? Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.