Friday, 28 September 2012

Boat Instruments on the Way

The instruments on Dragon III are aging, like the boat which will be 33 this year. The senders seem pretty reliable, but some of the gauges are a little sticky and the connections a little dubious. Besides that, there never was a tachometer there, just an opportunity to guess at engine speed from the sound. Today I did a little investigating in the line of getting the temperature gauge to read again. Along the way I cleared out some spider webs and figured out several things.

The water temperature and oil pressure senders are just variable resistors, changing with temperature or pressure. They are each wired as the bottom leg of a voltage divider, grounding through the engine. Both result in around 2 to 3 volt signals that could go directly to an A/D converter.

The temperature sender is about 100 ohms at ambient and drops its resistance with increasing temperature.

The pressure sender is about 89 ohms at zero pressure and... I need to check my notes.

The negative side of the coil is easily available to provide about a 200 volt AC signal that could drive a tachometer. With help from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1262397180 I came up with this circuit to produce countable pulses.



I hooked up a breadboarded version this afternoon and could see a rapidly flashing LED when the engine was idling. Visible flashing probably means under about 25 Hz. The Atomic 4 will fire on all four cylinders once every two revolutions (4 stroke) so 2 firings per rev. 25/2*60 = 750 rpm or less, which is certainly in the ball park. So I soldered it up on a little chunk of perfboard for some further tests.

In the mean time, I started from the Arduino demo code for interrupts and wrote a tach sketch to count rising pulses on pin 2 and convert them to RPM once a second, with a window for some damping. I tested the code with a push button (hence the debounce check) and by counting from pin 13 and both produce sensible results.


int pin = 13;
volatile int state = LOW;
volatile long last = 0;
volatile long kount[] = {0,0,0,0,0,0};
volatile long per = 1000;
volatile long sper = 0;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, count, RISING);
  Serial.begin(9600);
}

void loop()
{
  long rpm = 0;
  digitalWrite(pin, 1);
  delay(2);
  digitalWrite(pin, 0);
  delay(2);
  if(millis()-sper >= per){
    sper = millis();
    rpm = kount[0]*30+kount[1]*15+kount[2]*8+kount[3]*4+kount[4]*2+kount[5];
    rpm = rpm * 2 / 4;  // two rotations per power stroke for each of four cylinders
    Serial.println();
    Serial.println(rpm);
    kount[5]=kount[4];
    kount[4]=kount[3];
    kount[3]=kount[2];
    kount[2]=kount[1];
    kount[1]=kount[0];
    kount[0]=0;
  }
}

void count()
{
  // 4 cyl engine at 12000 rpm = 4*12000/60/2 = 400 Hz or 2.5 ms
  if(millis()-last >= 2){  // cancel HF noise by waiting
    state = !state;
    last = millis();
    kount[0]++;
    Serial.print(".");
  }
}