Open rolextm opened 3 years ago
@rolextm sounds awesome!!
I'd love to see the files but they weren't attached correctly. Happy to accept PR if you want to do that too.
I think I am due to reflash my arduinos with some updates from this project so I'd really like to give your additions a go!
Id love to see the updated code too!
ouch! i was sure they were attached. I need to pull them of the work Laptop and will do so tonight. Thanks for the heads up in the M5 vid gurvir44 :D funny how things go :D
// Version 2 mit Median und Auto Nullpunkt
#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>
#include <RunningMedian.h>
// RunningMedian samples = RunningMedian(9);
RunningMedian samples = RunningMedian(3);
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2);
int boostPressure;
int boostMax = 0;
int boostMin = 0;
int correction = 0;
bool flashTracker = false;
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 50;
const int sensorHistoryLength = 128;
int sensorHistory[sensorHistoryLength];
int sensorHistoryPos = sensorHistoryLength - 1;
void setup(void) {
u8g2.begin();
startMillis = millis();
// u8g2.setContrast(0x2B * 255); //Set Contrast
// u8g2.sendF("c", 0x0a7); // inversion
}
void loop(void) {
// Only read from the sensors every 50 ms
readSensorData();
currentMillis = millis();
if (currentMillis - startMillis >= period)
{
flashTracker = !flashTracker;
startMillis = currentMillis;
}
u8g2.firstPage();
do {
// Draw current pressure
u8g2.setFont(u8g2_font_fub20_tf);
char cstr[6];
dtostrf((float)boostPressure / 100, 1, 1, cstr);
u8g2.drawStr(0, 20, cstr);
// Draw max pressure
u8g2.setFont(u8g2_font_fub11_tf);
char indicator[5];
if (boostPressure < 5000) {
// LOW
if (flashTracker) { strcpy(indicator, "LOW") ;
u8g2.setContrast(255); //Set Contrast
// u8g2.sendF("c", 0x0a7);
}
else { strcpy(indicator, "");
// u8g2.sendF("c", 0x0a6 & 1);
//u8g2.setContrast(0); //Set Contrast
}
} else if (boostPressure < 8000) {
// IDLE
strcpy(indicator, "IDLE");
//u8g2.setContrast(255); //Set Contrast
} else {
// LOAD
strcpy(indicator, "LOAD");
//u8g2.setContrast(255); //Set Contrast
}
int yPos = u8g2.getStrWidth(indicator);
u8g2.drawStr(128 - yPos, 11, indicator);
drawBarGraph(0, 22, 128, 8);
drawGraph(0, 32, 128, 31);
} while ( u8g2.nextPage() );
}
float normaliseSensorData(int m) {
/*
Scale the sensor reading into range
m = measurement to be scaled
rmin = minimum of the range of the measurement
rmax = maximum of the range of the measurement
tmin = minimum of the range of the desired target scaling
tmax = maximum of the range of the desired target scaling
normalisedValue = ((m − rmin) / (rmax − rmin)) * (tmax − tmin) + tmin
https://stats.stackexchange.com/a/281164
*/
/*
Sensor voltage ranges from 0.5v to 4.5v, converted to analogRead values (0 min, 1023 max) that's 102 to 921
rmin = 102
rmax = 921
Sensor reads from 0 to 140psi
tmin = 0
tmax = 14000
normalisedValue = ((m − 102) / (921 − 102)) * (14000 − 0) + 0
normalisedValue = ((m − 102) / 819) * 14000
normalisedValue = (m − 102) / 0.0585
*/
samples.add((m - 102) / 0.0585);
//return (m - 102) / 0.0585 ;
return samples.getMedian();
}
void readSensorData(void) {
float absolutePressure = normaliseSensorData(analogRead(A0));
// Subtract 14.7 psi == pressure at sea level
boostPressure = absolutePressure - 1470 + correction;
// Oil pressure should never be negative
//if (boostPressure < 0) boostPressure = 0;
if ((absolutePressure - 1470) < 0)
{
//boostPressure = 0;
correction = 0 - (absolutePressure - 1470);
}
// Update max and min
if (boostPressure > boostMax) boostMax = boostPressure;
if (boostPressure < boostMin) boostMin = boostPressure;
// Log the history
addSensorHistory(boostPressure);
}
void addSensorHistory(int val) {
sensorHistory[sensorHistoryPos] = val;
sensorHistoryPos--;
if (sensorHistoryPos < 0) sensorHistoryPos = sensorHistoryLength - 1;
}
int getSensorHistory(int index) {
index += sensorHistoryPos;
if (index >= sensorHistoryLength) index = index - sensorHistoryLength;
return sensorHistory[index];
}
// Display functions
void drawGraph(int x, int y, int len, int height) {
// Draw the lines
drawHorizontalDottedLine(x, y, len);
drawHorizontalDottedLine(x, y + height, len);
//var absMin = Math.abs(boostMin);
int absMin = abs(boostMin);
int range = absMin + boostMax;
// Draw 0 line
int zeroYPos = mapValueToYPos(absMin, range, y, height);
drawHorizontalDottedLine(x, zeroYPos, len);
// Draw the graph line
for (int i = 0; i < 128; i++) {
// Scale the values so that the min is always 0
int valueY = getSensorHistory(i) + absMin;
// Calculate the coordinants
int yPos = mapValueToYPos(valueY, range, y, height);
int xPos = len - i;
if (yPos < zeroYPos) {
// Point is above zero line, fill in space under graph
u8g2.drawVLine(xPos, yPos, zeroYPos + 1 - yPos);
} else {
// Point is below zero line, draw graph line without filling in
u8g2.drawPixel(xPos, yPos);
}
}
}
void drawBarGraph(int x, int y, int len, int height) {
if (boostPressure > 0) {
// Draw the pressure bar behind the graph
int barLength = ((float)boostPressure / boostMax) * len;
u8g2.setDrawColor(2);
u8g2.drawBox(x, y, barLength, height);
u8g2.setDrawColor(1);
}
}
// Maps a value to a y height
int mapValueToYPos(int val, int range, int y, int height) {
float valueY = ((float)val / range) * height;
return y + height - (int)valueY;
}
void drawHorizontalDottedLine(int x, int y, int len) {
for (int i = 0; i < len; i++) {
if (!(i % 4)) u8g2.drawPixel(x + i, y);
}
}
Im having a issue where its reading a random value when ever my finger is touching the arduino or the cable is moved in a certain way. Is this a floating input? Any ideas on how to solve this?
Sorry to bring up an old project, but how would I go about running both the boost and oil ino files on a single arduino uno? I’ve already take care of the oled address.
Hey man,
i have been using your oil pressure program, and i made some minor improvements.
First, the sensor calibration is off. I dont know if its because voltage drop over the cable, but just cutting negative pressure is not accurate. Instead i try to raise the baseline for 0 PSI as long as the value is negative. Second, i am building a median in values to make the display a little more consistent. I generate the measurements as fast as it runs and then feed the average to the display.
See the attached files, it were only minor fast hacks while sitting in the car, forgive the lacking code style, but for me its making the final thing a bit better ;)
Regards Alex