Hey Everyone,
We'll start off with I have no idea what im doing, or the correct search terms to solve my problems.
I have followed a guide to build a fuel content sensor, the board works and the car's ecu can read the output from the board, great!
However, I would also like to remote mount a small oled to display the data.
This code I am using from the guide.
/*******************************************************
This program will sample a 50-150hz signal depending on ethanol
content, and output a 0-5V signal via PWM.
The LCD (for those using an Arduino Uno + LCD shield) will display ethanol content, hz input, mv output, fuel temp
Connect PWM output to TGV. 3.3kOhm resistor works fine.
Input pin 8 (PB0) ICP1 on Atmega328
Output pin 3 or 11, defined below
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 <LiquidCrystal.h> //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 = 11; //define PWM output, possible pins with LCD and 32khz freq. are 3 and 11 (Nano and 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; //unsigned 16bit integer for storing HZ input
int ethanol = 0; //Store ethanol percentage here
float expectedv; //store expected voltage here - range for typical GM sensors is usually 0.5-4.5v
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()
{
Serial.begin(9600);
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
{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;}
expectedv = ((((HZ-50.0)*0.01)*4)+0.5);
//Screen calculations
pwm_output = 1.1 * (255 * (expectedv/5.0)); //calculate output PWM for ECU
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
Serial.println(ethanol);
Serial.println(pwm_output);
Serial.println(expectedv);
Serial.println(HZ);
delay(1000);
}
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) { //This code snippet raises the timers linked to the PWM outputs
byte mode; //This way the PWM frequency can be raised or lowered. Prescaler of 1 sets PWM output to 32KHz (pin 3, 11)
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;
}
}
The display GND VCC CLK MOSI RES DC C5 but all the guides I can find show the screens with SCL/SDA
There is this code which i belive is for an oled screen, but im unsure of what wires from the screen I need to connect to A4 and A5
// Adafruit_SSD1306 - Version: Latest
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
int inpPin = 8;
//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
float expectedv; //store expected voltage here - range for typical GM sensors is usually 0.5-4.5v
uint16_t voltage = 0; //store display millivoltage here (0-5000)
//temperature variables
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;
int celstemp = 0;
float fahrtemp = 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() {
setupTimer();
Serial.begin(9600);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
// init done
}
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 calibrated for more accuracy
{HZ = 0;}
//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
display.display();
display.clearDisplay();
display.setCursor(0,16);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print("Eth: ");
display.print(ethanol);
display.print("%");
display.setCursor(0,36);
display.print("Temp: ");
display.print(cels);
display.print("C");
delay(250);
}
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)
celstemp = int(temperature);
cels = celstemp;
fahrtemp = ((temperature*1.8)+32);
fahr = fahrtemp;
}
There is already code for a screen but I belive it is for a different screen.
Any help would be apprecited in getting this working.
