View Single Post
Old 10-24-2015, 09:59 PM   #11
ztan
Senior Member
 
Join Date: Jul 2013
Drives: Toyota 86
Location: Gold Coast, Australia
Posts: 311
Thanks: 44
Thanked 358 Times in 142 Posts
Mentioned: 60 Post(s)
Tagged: 0 Thread(s)
Having gotten my bricked ECU to talk on the bench again (but not 100% functional) using SHBoot, time to get back up developing.

The Evap sensor routine that I hooked polls the sensor at 60-80ms intervals - too slow to use to read frequency properly in the 50-150Hz range that the GM FlexFuel sensor uses - will convert to 0-5V output to make this work easier on the Evap A35-20 input.

Having a PLX DM6 gauge for wideband display, I decided to use an Arduino Nano ($3 on eBay) to do the following:

1. Read Hz signal from FlexFuel sensor

2. Output 0-5V signal to ECU. The Evap pin is pulled up to 5V without anything attached, so I have initially coded E0 to send 5V and E100 to send 0V

3. Output serial PLX iMFD packet to PLX daisy chain (using Fuel Level sender ID code as I could not find any device ID for a Flex Fuel sensor for the DM6). This needs to be the terminal device in the PLX chain and will display E% as "Fuel Level" on the gauge.

4. Flex fuel sensor can be calibrated using pure gasoline and E85 inputting the frequency reads into the E0 and E85 values in the code before sending to Arduino. The Continental 13577429 sensor that I have reads 55 Hz with gasoline and 131 Hz with E85. I also have a couple of Chinese made 13577379 eBay sensors which have linear output but calibrations are off (80 Hz with gasoline, 150Hz with E85) if anyone wants a cheap working sensor with calibration data, PM me.

Frequency read is based on FreqMeasure library at PJRC

Arduino code and Nano circuit diagram (it all works):
Code:
//Flex Fuel sensor code
//Input frequency on pin 8 - pulled up to 5V through 1.8K resistor
//V_out pin 3 - 0-5V output through 1.8K resistor with 10uf capacitor to ground
//PLX iMFD serial packet on Tx pin 0 through 3.3V TTL voltage divider (3.3K/6.8K)

#include <Arduino.h>
#include <FreqMeasure.h>

double sum = 0;
int count = 0;
int ethanol_int, V_out_int;
float freq, ethanol, V_out, E_scalar;
float E0 = 50; //calibration data for pure gasoline
float E85 = 135; //calibration data for E85
long P0, P1, Pdelta;
byte PLXpacket[7] {0x80, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40};

//PLX iMFD packet, sent every 100ms:
//0x80      Start byte
//0x00 0x11 Sensor device fuel level
//0x00      Sensor instance
//0x00 0x00 Sensor value (integer, unscaled)
//0x40      Stop byte

void setup()
{
  pinMode (3, OUTPUT);
  FreqMeasure.begin();
  Serial.begin(19200);
  P0 = millis();
  E_scalar = (E85 - E0) / 85;
}

void loop()
{
  if (FreqMeasure.available())
  {
    // average several readings together
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 30)
    {
      freq = FreqMeasure.countToFrequency(sum / count);
      sum = 0;
      count = 0;
    }
  }

  ethanol = (freq - E0) / E_scalar; //scale frequency to E% interpolating E0 and E85 values
  if (ethanol > 100)
  {
    ethanol = 100;
  }
  if (ethanol < 0)
  {
    ethanol = 0;
  }
  ethanol_int = (int)ethanol;

  V_out = 5 - (0.05 * ethanol);
  V_out = 51 * V_out; //scale to 255
  V_out_int = (int)V_out; //convert to integer for analogWrite

  analogWrite(3, V_out_int); //output V_out as PWM voltage on pin 3

  P1 = millis(); //send PLX packet on Tx pin every 100ms
  Pdelta = P1 - P0;
  if (Pdelta >= 100)
  {
    P0 = P1;
    PLXpacket[5] = ethanol_int; //set data byte in PLX packet to E%
    Serial.write(PLXpacket, 7);
  }
}
Attached Images
 

Last edited by ztan; 11-24-2015 at 04:48 AM.
ztan is offline   Reply With Quote
The Following 9 Users Say Thank You to ztan For This Useful Post:
504 (10-25-2015), Awstryker (10-26-2015), DAEMANO (10-24-2015), DustinS (10-26-2015), elBarto (10-25-2015), Guff (07-13-2016), solidONE (10-24-2015), Td-d (10-29-2015), thambu19 (11-11-2015)