Welcome to the SR20 Community Forum - The Dash.
Register
SR20 forum logo

Thread: Flex-fuel sensor output

+ Reply To Thread
Posts: 61-70 of 72
2015-04-24 02:27:29
#61
@Y2KG20

Great test results.

Is the android app from fiskafan from sweeden on the FRS forums?
Last edited by D-Unit121 on 2015-04-24 at 02-31-57.
2015-04-24 03:26:40
#62
Originally Posted by D-Unit121
@Y2KG20

Great test results.

Is the android app from fiskafan from sweeden on the FRS forums?


Yes it is. His name is Johan and he built a prototype for me awhile back so I could help test some stuff. Awesome guy and he has put quite a bit of work into it just like Daniel has. Both are turning out to be pretty accurate. Big thanks out to both of you guys!

Edit: That app looks a lot better on a 4.7" phone. I had to use a old junk phone for the app so I could record the video on my new phone.
Last edited by Y2KG20 on 2015-04-24 at 19-05-41.
2015-04-26 10:53:48
#63
Yesterday D-unit and I checked what voltages you see in Nemu depending on ethanol content, here are the results:


And here's the newest revision of the code, which removes voltage display, and raises the output PWM frequency to 32kHz, for a smoother voltage.

Spoiler
/*******************************************************
This program will sample a 50-150hz signal depending on ethanol
content, and output a 0-5V signal via PWM.
The LCD will display ethanol content, hz input, mv output, fuel temp

Connect PWM output to NEMU Breakoutboard on ADC0-3, and tune
the "FLEX FUEL SETUP" tab accordingly. NOTE: Lowpass filter to
be used on output.

Input pin 8 (PB0) ICP1 on Atmega328
Output pin 3 PWM

If LCD Keypad shield is used, solder jumper from Pin 8 - Pin 2,
and snip leg from pin 8 http://i.imgur.com/KdlLmye.png
********************************************************/

// include the library code:
#include //LCD plugin

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 9, 4, 5, 6, 7); //LCD Keypad Shield

int inpPin = 8; //define input pin to 8
int outPin = 3; //define PWM output, possible pins with LCD are 3, 10 and 11 (UNO)

//Define global variables
volatile uint16_t revTick; //Ticks per revolution
uint16_t pwm_output = 0; //integer for storing PWM value (0-255 value)
int HZ = 0; //unsigned 16bit integer for storing HZ input
int ethanol = 0; //Store ethanol percentage here

int duty; //Duty cycle (0.0-100.0)
float period; //Store period time here (eg.0.0025 s)
float temperature = 0; //Store fuel temperature here
int fahr = 0;
int cels = 0;
static long highTime = 0;
static long lowTime = 0;
static long tempPulse;

void setupTimer() // setup timer1
{
TCCR1A = 0; // normal mode
TCCR1B = 132; // (10000100) Falling edge trigger, Timer = CPU Clock/256, noise cancellation on
TCCR1C = 0; // normal mode
TIMSK1 = 33; // (00100001) Input capture and overflow interupts enabled
TCNT1 = 0; // start from 0
}

ISR(TIMER1_CAPT_vect) // PULSE DETECTED! (interrupt automatically triggered, not called by main program)
{
revTick = ICR1; // save duration of last revolution
TCNT1 = 0; // restart timer for next revolution
}

ISR(TIMER1_OVF_vect) // counter overflow/timeout
{ revTick = 0; } // Ticks per second = 0


void setup()
{
pinMode(inpPin,INPUT);
setPwmFrequency(outPin,1); //Modify frequency on PWM output
setupTimer();
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Initial screen formatting
lcd.setCursor(0, 0);
lcd.print("Ethanol: %");
lcd.setCursor(0, 1);
lcd.print(" Hz C");
}

void loop()
{
getfueltemp(inpPin); //read fuel temp from input duty cycle

if (revTick > 0) // Avoid dividing by zero, sample in the HZ
{HZ = 62200 / revTick;} // 3456000ticks per minute, 57600 per second
else // 62200 per seconmd seems to be more accurate?
{HZ = 0;} //needs real sensor test to determine correct tickrate

//calculate ethanol percentage
if (HZ > 50) // Avoid dividing by zero
{ethanol = HZ-50;}
else
{ethanol = 0;}

if (ethanol > 99) // Avoid overflow in PWM
{ethanol = 99;}

//Screen calculations
pwm_output = 255 * (ethanol*0.01); //calculate output PWM for NEMU

lcd.setCursor(10, 0);
lcd.print(ethanol);

lcd.setCursor(2, 1);
lcd.print(HZ);

lcd.setCursor(8, 1);
lcd.print(temperature); //Use this for celsius

//PWM output
analogWrite(outPin, pwm_output); //write the PWM value to output pin

delay(100); //make screen more easily readable by not updating it too often

}

void getfueltemp(int inpPin){ //read fuel temp from input duty cycle
highTime = 0;
lowTime = 0;

tempPulse = pulseIn(inpPin,HIGH);
if(tempPulse>highTime){
highTime = tempPulse;
}

tempPulse = pulseIn(inpPin,LOW);
if(tempPulse>lowTime){
lowTime = tempPulse;
}

duty = ((100*(highTime/(double (lowTime+highTime))))); //Calculate duty cycle (integer extra decimal)
float T = (float(1.0/float(HZ))); //Calculate total period time
float period = float(100-duty)*T; //Calculate the active period time (100-duty)*T
float temp2 = float(10) * float(period); //Convert ms to whole number
temperature = ((40.25 * temp2)-81.25); // Calculate temperature for display (1ms = -40, 5ms = 80)
int cels = int(temperature);
cels = cels*0.1;
float fahrtemp = ((temperature*1.8)+32);
fahr = fahrtemp*0.1;

}

void setPwmFrequency(int pin, int divisor) {
byte mode;
if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 64: mode = 0x03; break;
case 256: mode = 0x04; break;
case 1024: mode = 0x05; break;
default: return;
}
if(pin == 5 || pin == 6) {
TCCR0B = TCCR0B & 0b11111000 | mode;
} else {
TCCR1B = TCCR1B & 0b11111000 | mode;
}
} else if(pin == 3 || pin == 11) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 32: mode = 0x03; break;
case 64: mode = 0x04; break;
case 128: mode = 0x05; break;
case 256: mode = 0x06; break;
case 1024: mode = 0x7; break;
default: return;
}
TCCR2B = TCCR2B & 0b11111000 | mode;
}
}
2015-04-27 14:42:16
#64
@Dala Is this compatible with E100?
2015-04-27 17:38:21
#65
Originally Posted by ebinkerd
Is this compatible with E100?


You can make it by shifting the PWM output, you will lose some accuracy, but gain a wider spectrum. I chose 0-85% since here that's the most you would normally encounter.

Edit this line "pwm_output = 255 * (ethanol*0.01);", and edit the 255 to 200. Then you get 0-100% Ethanol, 0-4.5V
2015-04-28 15:43:27
#66
excuse my ignorance...im no electronics whiz...
what the use of the RC filter (the cap and resistor combo)?
2015-04-28 15:48:58
#67
Originally Posted by 342Four
excuse my ignorance...im no electronics whiz...
what the use of the RC filter (the cap and resistor combo)?


The standard Arduino cannot create any analog output, it can only do pulse width modulation(PWM). If you hook up a pwm signal to Nismotronic (or any other engine management system), you only get a pulsing 0V-5V-0V-5V signal. If you apply an RC-filter, you smooth the signal out to a nice almost linear voltage as seen in the diagram above.
2015-04-29 02:11:57
#68
Originally Posted by Dala

The standard Arduino cannot create any analog output, it can only do pulse width modulation(PWM). If you hook up a pwm signal to Nismotronic (or any other engine management system), you only get a pulsing 0V-5V-0V-5V signal. If you apply an RC-filter, you smooth the signal out to a nice almost linear voltage as seen in the diagram above.


Ahhhh okay thanks for the info
now that im doing some reading...would it pay to put the resistor before the cap?
all the examples ive seen of RC filters have the resistor then the cap to ground...
2015-04-29 07:30:43
#69
Originally Posted by 342Four

Ahhhh okay thanks for the info
now that im doing some reading...would it pay to put the resistor before the cap?
all the examples ive seen of RC filters have the resistor then the cap to ground...


You are absolutely correct. Must have been sleep deprived when I made that quick sketch, resistor comes first, and then the cap. Will make a new schematic when the application is considered complete.
2015-04-30 07:18:44
#70
Here's what I configured in NEMU after permanent install:

Right, so I'm adding 40% fuel at maximum voltage (E85). At the middle spectrum, 20% fuel is added. This is good for blended mixtures. I also control the boost, raising the wastegate dutycycle abit if the fuel is good. Spark is also controlled here, advancing the spark when the fuel allows for it. Take note, this is what I run, you might need totally different settings, but it's a good place to start

I don't worry too much about the accuracy in the Fuel Trim, closed loop will pick up the slack here. If you have OCD, you could datalog different fuelmixtures, and see what injector pulsewidth is needed for each blend and make your own super accurate Flex Fuel Trim table.

Maybe we should make a how to thread soon with all the good stuff from this thread?
+ Reply To Thread
  • [Type to search users.]
  • Quick Reply
    Thread Information
    There are currently ? users browsing this thread. (? members & ? guests)
    StubUserName

    Back to top