Jump to content
SAU Community

Recommended Posts

I've read a lot of contradicting information about the format of the RPM signal from the R33 ECU etc. I'm looking to build an Arduino project and I need to know the electronic format of the signal from pin #7 on the ECU.

Is it a rising/falling 5/12V square signal?

To complicate things further I'm using the standard ECU and also an RB20 Nistuned ECU (I also have a Z32 one handy). All work fine with the tacho so I'm hoping they all output in an identical fashion.

If anyone can assist that'd be fantastic - or even if you can point me in the direction of someone who will know for sure.

Link to comment
https://www.sau.com.au/forums/topic/448228-r33-s2-gts-t-rpm-signal/
Share on other sites

I'd strongly suggest you put a scope on it and double check - if memory serves there is a pullup resistor in the body harness to 12V. At the very least the R34 workshop manual shows the tacho pulse on the cluster side as being upwards of 10V and I'd imagine the R33 would be similar. The trigger edge varying depending on if it is a DE or DET but if you are just trying to get an RPM reading that won't matter. You may also find the signal isn't quite as clean as you'd expect - on older Nissans it isn't but I haven't scoped an R33 before so your mileage may vary.

Cheers, I had a dig through the service manual and the RB25DET output is shown as a rising edge 5V signal so I'll give it a shot. The signal seems to have a 25ms gap at 1k rpm and a 9ms gap between rises at 2.5k rpm so I'm not sure how well the arduino will pick it up at that speed but we'll see...

Yeah it won't be a problem. Setup your interrupt to store time between interrupts in microseconds and keep your ISR short and you won't have any issues even north of 10,000rpm. The best way to learn is by experimenting (imo) but if you get stuck with the code let me know.

If you get some working code post it up =D

I was looking at something similair a while a go to create a vct controller, but a much easier solution came along in my case so I never bothered.

Edited by nicr4wks

Since a few of you want to see some code I knocked up a basic version of my existing code. I'll test it tomorrow to confirm it works before posting it.

Daniel - Do you want to have a crack at the code before I post mine? I don't mind either way.

Nah go for it! The RPM signal is just a minor part of my project so I have plenty to keep me busy. If it's different to my approach I'll try it anyway and compare methods :)

Finally got around to testing this. Note that I tested on an MCU that's much faster than an Arduino (still waiting on my Uno - I'll test on it once it turns up) but the attached code should compile ok. When run it'll send the current RPM via the serial port at 4Hz but you can update as fast or slow as you want. The code should be fairly self explanatory but obviously you wouldn't use delay in a real program but it'll show the concept. It also has some basic noise rejection in place where pulses shorter than the specified minPulse value are ignored, it's surprisingly effective. Here's a pic showing the output from the code. Worth mentioning there is a bit more to my test hardware than just a straight connection to the MCU so your mileage may vary.

 
#define pinRPM 3 // Define the tacho input pin
#define minPulse 2000 // Reject any pulses shorter than this value in uS. 2000uS = 10,000rpm on a 6 cylinder
#define noPulses 3 // Number of tacho pulses per engine revolution. 3PPR for a six-cylinder 4 stroke.
 
volatile unsigned long rpmTime = 0; // Length of time in microseconds between interrupts
volatile unsigned long rpmLastTime = 0; // Value of micros at previous interrupt
int RPM = 0;
 
void setup()
{
  pinMode(pinRPM, INPUT); // Set pinRPM as an input
  attachInterrupt(pinRPM, rpm_count, RISING); // Enable ISR rpm_count on pinRPM on a rising edge
  Serial.begin(115000);
}
 
void loop()
{
  noInterrupts(); // Disable interrupts whilst doing calcs
  
  if (micros() - rpmLastTime > 500000L){RPM = 0;} // If it has been more than half a second between interrupts then assume engine has stopped
  
  else
  {
    RPM = 60000000L / rpmTime / noPulses;
  }
 
  Serial.print("Current RPM: ");
  Serial.println(RPM);
  interrupts();
  delay(250);
}
 
void rpm_count(){
  if ((micros() - rpmLastTime) < minPulse) {return;} // If the time between interrupts is less than the minimum pulse time then reject it as noise and return  
  rpmTime = micros() - rpmLastTime;
  rpmLastTime = micros();
}

My Uno clone arrived yesterday so I figured I'd bench test this on the Uno for completeness. Due to a misunderstanding on my part as to how Uno interrupt pins are mapped you'll need to change the pinRPM definition in the posted code to either 0 or 1 to use pin 2 or 3 for input respectively. You may also want to change the signed rpm integer variable to unsigned (unsigned int RPM) as that will allow up to a theoretical 65,535 rpm vs 32,767 rpm. Aside from that the code works as intended; bench tested to 60,000rpm on a square wave input (with minPulse adjusted appropriately) with the Uno at 16Mhz. At 9,000rpm using a 1% duty cycle signal I get a jitter of 20rpm which I'd say is down to my basic test rig. Should suffice methinks :yes:

EDIT: I forgot to mention that the previous tests were on a running RB30 - which is why I didn't rev it too hard ;)

Edited by XR Pilot

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×
×
  • Create New...