Off topic, but related.
With the Arduino Nano going in as a FlexFuel Sensor controller, there is space for much more to be added on. I decided to make a doubleclick TRAC control switch so I don't have to hold down the TRAC switch down for 3+ seconds to turn if off. Simple code and adds 2 resistors and an NPN transistor to the circuitry.
If you want it on by default, set initial button state to 4, which acts as a doubleclick a certain time (TRAC_initializeDelay) after power on.
Why not the full pedal dance? Mine is a street car and we in Australia can't use the speeds on road which people have issues with VSC activating brakes at, requiring the pedal dance to be used or sent over CANBUS like with OFT. Out of interest, can anyone share the CAN sequence needed for pedal dance active?
Code, schematic, and picture of controller box with FlexFuel sensor leads, TRAC switch leads, PLX serial interface.
Updated Arduino code:
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)
//TRAC double click code
//Input switch on pin 6 - pulled up to 5V through 3.3K resistor
//Output on pin 10 through NPN transistor to take VSC connection to ground
#include <Arduino.h>
#include <FreqMeasure.h>
//FlexFuel sensor
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
//PLX data
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
//TRAC switch double click
bool TRAC_buttonMonitor = HIGH;
int debounce = 20;
int doubleClick = 200;
int longClick = 3500;
int TRAC_initializeDelay = 5000;
int TRAC_buttonState = 0; //initialize to 0 for normal operation, 4 for on by default after delay
long TRAC_buttonCounter = 0;
void setup()
{
pinMode (3, OUTPUT);
pinMode (10, OUTPUT);
digitalWrite (10, LOW);
pinMode (6, INPUT);
FreqMeasure.begin();
Serial.begin(19200);
P0 = millis();
E_scalar = (E85 - E0) / 85;
}
void loop()
{
//Read FlexFuel sensor frequency
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;
}
}
//Convert frequency to E%
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;
//FlexFuel voltage output
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
//PLX data packet
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);
}
//TRAC switch doubleclick
TRAC_buttonMonitor = digitalRead(6);
switch (TRAC_buttonState)
{
case 0: //inactive
if (TRAC_buttonMonitor == LOW) // button pressed
{
digitalWrite (10, HIGH); //Transistor on
TRAC_buttonState = 1; //increment state
}
break;
case 1: //check for release
if (TRAC_buttonMonitor == HIGH) //if button released
{
TRAC_buttonCounter = millis(); //start counter
TRAC_buttonState = 2; //increment state
}
break;
case 2: //wait for doubleClick
if (TRAC_buttonMonitor == LOW && (millis() - TRAC_buttonCounter) > debounce && (millis() - TRAC_buttonCounter) < doubleClick) //second click registered
{
TRAC_buttonState = 3; //increment state
}
else if ((millis() - TRAC_buttonCounter) > doubleClick)
{
digitalWrite (10, LOW); //Transistor off
TRAC_buttonState = 0; //reset state
}
break;
case 3: //doubleClick made
if ((millis() - TRAC_buttonCounter) > longClick)
{
digitalWrite (10, LOW); //Transistor off
TRAC_buttonState = 0; //reset state
}
break;
case 4: //initialize after delay by default
if (millis() > TRAC_initializeDelay)
{
digitalWrite (10, HIGH); //Transistor on
TRAC_buttonCounter = millis(); //start counter
TRAC_buttonState = 3; //set state to doubleClick
}
break;
}
}