New to the world of Arduino

Hey everyone,

Just a quick warning, this is going to be a long read and I am sorry, but I sometimes work things out myself as I try to explain it to someone else.

I have been browsing the forum to get some tips and tricks for a project I have been wanting to try out, I am getting my first ever Arduino NANO soon for this project I want to attempt for myself with a pressure sensor, yeah you guessed it, a digital boost gauge… lame I know but hey I have to start somewhere and I’m not a fan of “Hello World!”, it just seems too easy and I wanted to challenge myself a little. I know it has been done multiple times before, but I don’t want to just go and copy/paste someone else’s code without understanding what it does and why it does what it does.

Just keep in mind, I have minimal C programming exposure, some very basic self study
The closest I have ever come to an Arduino was when I helped my father build our first Delta 3D Printer about 7 years ago,
I have never coded for Arduino, just uploaded the code to the ATMega328 we used for the RepRap printers
I have never used a I2C OLED display

So all this us unchartered territory for me. Please just remember that I am basically still brand new to the world of Arduino and C for Arduino, but it’s about time to pop my cherry so to speak.

I ordered myself a Arduino NANO, I2C OLED 0.96" display (just to see if I can make it work as expected on I2C on my desk and later on “upgrade” to a OLED 2.42" SPI or color LCD screen) and a XGZP6847A (300KPGPN) pressure sensor which reads from -100kpa to 300kpa (only one in stock I could find from my local electronics shop). According to the datasheet I managed to find, it’s range is from 0.5V minimum (-100kpa) to 4.5V maximum (300kpa) and 1.5V is 0kpa so it has a linear flowing graph reading both Gage and Absolute.

Datasheet can be found here for more information (*look at the *300KPGPN):
http://cfsensor.com/static/upload/file/20210109/XGZP6847A%20Pressure%20Sensor%20Module.pdf

Ok so onto some questions and things.

Can someone please have a look at my slapped together code below, yes I say slapped together because it’s my first attempt at coding in the Arduino IDE. Just note that I have not been able to test anything until my kit arrives, so go easy on me please, haha. Please do tell me if my order or formatting in the code is incorrect etc. I would highly appreciate it as it will help me learn. I see I do not have a lot of remarks in the code, I will get to all of that once I have been able to test the actual code.

I had a look at how other people address the I2C OLED screen as well as pressure sensors and I now have a faint idea how to address them, I will obviously run the I2C Scanner prior to uploading the code to get the correct I2C address of the OLED so that I can address it correctly.

From my code below, you will see I combined all the float values into a single line to have the code less cluttered I feel, but not sure if that will indeed function correctly or if I would need to define my variables one by one. From my understanding, I need all of them to be float as I want to be able to round to 2 decimals (which I still need to figure out how) , just to display decimals on the screen because why not.

Atmospheric pressure (my atmp vaiable) in my region (South Africa) is roughly 655mmhg so converted it to kpa on google (seeing as the sensor is in kpa) as I do not know how to convert form one to the other, we also use the Metric system here, so inHG, PSI, inch, etc. are all Greek to me.

Now, because I will only have a single sensor on my bench setup, my mind says I should read the atmospheric value from the pressure sensor before any type of pressure (positive or negative) is applied and save that to a float variable before any calculations to have a more accurate result for my atmospheric pressure later on, which is why I added rawkpa = analogRead(A0) however I commented it out as I want to print both on serial first to see if there is a difference between rawkpa and atmp

I also stumbled across a video on YouTube on how to display a BMP image on the OLED, I made provisioning for that in my code but commented it out so that the code can compile, I just need to convert the images to monochrome then to image.c but will tackle that at a later stage.

My biggest concern, I am not sure whether my parameters for the map() function are at all correct, so I might be misunderstanding how the map() function works.

Anyways, if there is any way I can do the code better, I would highly appreciate your inputs.

Onto my code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define WINDOW_SIZE 6
#define LOGO_HEIGHT 64
#define LOGO_WIDTH 128
#define sensorPin A0

/*
// 'polo', 128x64px
const unsigned char VWpolo [] PROGMEM = {
  // Logo Image Code
};
*/

float rawkpa = 0.0, barboost = 0.0, realboost = 0.0, atmp =  87.32;

int INDEX = 0;
int VALUE = 0;
int SUM = 0;
int READINGS[WINDOW_SIZE];
int AVERAGED = 0;


byte count;
byte sensorArray[128];
byte drawHeight;
boolean filled = 0; // Decide either filled, or dot-display, 0==dot display

/*
// Drawing the Logo bitmap
void VW_polo() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWpolo, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500); // Pause for 1.5 seconds
}*/

void setup()
{
  delay(250); // To let the screen start up
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // This will be confirmed with I2C Scanner
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
/*  display.clearDisplay();
  display.display();
  VW_polo(); // Display the Polo Logo
  delay(1000); // Pause for 1 second*/
  for (count = 0; count <= 128; count++) // Zero all elements
  {
    sensorArray[count] = 0;
  }
  //rawkpa = (analogRead(A0); // Read sensor raw value on analog port 0 before any pressure is applied, not sure if the sensor will be able to be addressed here prior to the loop
}


void loop() // Start loop
{
  analogRead(sensorPin); // Read the value being put out by the sensor on pin A0
  float boost1 = map(analogRead(sensorPin), 102.4, 1024.0, -100.0, 300.0); // is my map function used correctly here - map(analogread(A0), min ADC (0.5V), max ADC (4.5V), -100kpa min read, 300kpa max read)
  barboost = boost1 - atmp; // To see the real boost value subtracting absolute pressure, not too sure about this equation

  SUM = SUM - READINGS[INDEX];       // Remove the oldest entry from the sum
  VALUE = barboost / 100;            // Read the sensor value and convert it to measured bar (kPa value = bar value x 100)
  READINGS[INDEX] = VALUE;           // Add the newest reading to the window
  SUM = SUM + VALUE;                 // Add the newest reading to the sum
  INDEX = (INDEX + 1) % WINDOW_SIZE; // Increment the index, and wrap to 0 if it exceeds the window size
  AVERAGED = SUM / WINDOW_SIZE;      // Divide the sum of the window by the window size for the result
  barboost = ((rawkpa * 0.19)  + 2); // Calculate boost value for the graph

  display.fillRect(0, 0, barboost, 6, WHITE); // Draws top the bar depending on the sensor value
  display.setTextSize(1);
  display.setCursor(70, 47);
  display.println("BOOST BAR");
  display.setTextColor(WHITE);
  display.setTextSize(4);
  display.setCursor(5, 13);
  display.println((((AVERAGED * 0.001) * 14) + 0.12), 1);
  delay(1);
  display.display();
  display.clearDisplay();
  delay(55); // delay between numbers

}

It looks plausible and it compiles, so it's time to test. You'll need a serial.begin in setup. There seem to be plenty of comments - it's not worth adding them just for the sake of it, especially if they just echo the code.

However, you have done what every beginner ever does and written the whole thing up front. That's great if it works but painful when it doesn't.

I suggest that you write some simpler sketches just to exercise the hardware. Happily, you can probably make them by copying what you have and removing bits :slight_smile:

  float boost1 = map(analogRead(sensorPin), 102.4, 1024.0, -100.0, 300.0); // is my map function used correctly here - map(analogread(A0), min ADC (0.5V), max ADC (4.5V), -100kpa min read, 300kpa max read)
  barboost = boost1 - atmp; // To see the real boost value subtracting absolute pressure, not too sure about this equation

The map() function only works with integers

wildbill:
It looks plausible and it compiles, so it's time to test. You'll need a serial.begin in setup. There seem to be plenty of comments - it's not worth adding them just for the sake of it, especially if they just echo the code.

However, you have done what every beginner ever does and written the whole thing up front. That's great if it works but painful when it doesn't.

I suggest that you write some simpler sketches just to exercise the hardware. Happily, you can probably make them by copying what you have and removing bits :slight_smile:

Thank you for the reply :slight_smile:
Plausible is what I'd like to hear for my first attempt 8) makes me feel good about writing sketches in the future.
Oh yes, I actually added Serial.begin(9600); in setup after posting my code in my initial post, I picked it up reading through my post so just added and saved it. WRT comments, I added most of them I am unsure about to know where to makes changes if it does not behave the way I want it to, code clean-up will be on the cards as well.

I fully understand and agree that it was not the best idea to write the sketch up front even before I have the hardware in my possession, but I was so eager once I clicked that checkout button I could not contain myself and started doing research and decided let me start something small and it ended up into my end goal, got a bit carried away.
Does my map() function look correctly assigned ?

  float boost1 = map(analogRead(sensorPin), 102.4, 1024.0, -100.0, 300.0); // is my map function used correctly here - map(analogread(A0), min ADC (0.5V), max ADC (4.5V), -100kpa min read, 300kpa max read)

Except you are mapping 0.5V.._5.0_V to -100..300, rather than 0.5V..4.5V to -100..300

Comment only the things that are non-obvious from the code - otherwise you'll come along
later, change the code and forget to change the comment to match (seen this many many times)

The way I'd code this is to make explicit reference to the values in the sensor datasheet as
defined constants:

// sensor parameters:
#define SENSOR_MIN_VOLTS 0.5
#define SENSOR_MAX_VOLTS 4.5
#define MIN_OUT -100.0
#define MAX_OUT +300.0

// ADC parameters:
#define ADC_FULL_SCALE 1024
#define ADC_REF 5.0   // note this must be floating point constant to force float arithmetic


float kPa_from_adc (int adc_reading)
{
  float volts = adc_reading * ADC_REF / ADC_FULL_SCALE ; // convert to volts

  // now we have everything in terms of datasheet values
  // the equivalent of map() for floats:
  float kPa = MIN_OUT + (MAX_OUT - MIN_OUT) * ((volts - SENSOR_MIN_VOLTS) / (SENSOR_MAX_VOLTS - SENSOR_MIN_VOLTS)) ;
  return kPa ;
}

UKHeliBob:

  float boost1 = map(analogRead(sensorPin), 102.4, 1024.0, -100.0, 300.0); // is my map function used correctly here - map(analogread(A0), min ADC (0.5V), max ADC (4.5V), -100kpa min read, 300kpa max read)

barboost = boost1 - atmp; // To see the real boost value subtracting absolute pressure, not too sure about this equation



The map() function only works with integers

Ah ok, thank you for this, I was under the impression I could use float values.

MarkT:

  float boost1 = map(analogRead(sensorPin), 102.4, 1024.0, -100.0, 300.0); // is my map function used correctly here - map(analogread(A0), min ADC (0.5V), max ADC (4.5V), -100kpa min read, 300kpa max read)

Except you are mapping 0.5V.._5.0_V to -100..300, rather than 0.5V..4.5V to -100..300

Comment only the things that are non-obvious from the code - otherwise you'll come along
later, change the code and forget to change the comment to match (seen this many many times)

The way I'd code this is to make explicit reference to the values in the sensor datasheet as
defined constants:

// sensor parameters:

#define SENSOR_MIN_VOLTS 0.5
#define SENSOR_MAX_VOLTS 4.5
#define MIN_OUT -100.0
#define MAX_OUT +300.0

// ADC parameters:
#define ADC_FULL_SCALE 1024
#define ADC_REF 5.0   // note this must be floating point constant to force float arithmetic

float kPa_from_adc (int adc_reading)
{
 float volts = adc_reading * ADC_REF / ADC_FULL_SCALE ; // convert to volts

// now we have everything in terms of datasheet values
 // the equivalent of map() for floats:
 float kPa = MIN_OUT + (MAX_OUT - MIN_OUT) * ((volts - SENSOR_MIN_VOLTS) / (SENSOR_MAX_VOLTS - SENSOR_MIN_VOLTS)) ;
 return kPa ;
}

That is correct yes, I noticed my mistake when I read the datasheet once again, max ADC is not 1024 (5V) but 921.6 (4.5V) or 921 (or do I round up to 923) seeing as the map() function can only work with integers as UKHeliBob pointed out to me.

WRT comments, that makes perfect sense thank you. I will do a proper cleanup once I've tested the sketch with the hardware. It will also make the sketch physical size smaller. I should have my hardware by next week if all goes well.

See I knew this was the correct place to come and ask some questions. I did not know how to define constraints, thank you so much for the assistance, that will also clean up the code drastically.

I will try it both ways, with the map() function and also float as per your post above (which makes more sense to me)

To all that have responded: Thank you so much for all the help and quick responses folks, I highly appreciate your efforts and patience with a newby. I have already learnt so much in such a short timespan.

I had a look at the math now using MarkT's equation from above using max voltage.

I get a maximum pressure of 1 bar at 4.5V. It is supposed to be 3 bar or I am doing something wrong, unless there is a scaling factor on the sensor I do not know about to get to 3 bar or 300 kPa at 4.5V (max ADC)

I got it as follows:

kPa_from_adc (int adc_reading)
4.5V equates to ADC - 921.6

volts = adc_reading * ADC_REF / ADC_FULL_SCALE
volts = 921.6 * 5.0 / 1024.0 = 4.5V

kPa = MIN_OUT + (MAX_OUT - MIN_OUT) * ((volts - SENSOR_MIN_VOLTS) / (SENSOR_MAX_VOLTS - SENSOR_MIN_VOLTS))
kPa = -100.0 + (+300.0 - -100.0) * ((4.5 - 0.5) / (4.5 - 0.5)
kPa = 100

// Convert to bar from kPa
Bar = kPa / 100
Bar = 100 / 100
Bar = 1

There should be some kind of scaling on the sensor because the math does not add up or I am missing the pot somewhere :o

If I run that example in my head, I get 300, which I think is what you're looking for.

wildbill:
If I run that example in my head, I get 300, which I think is what you're looking for.

You are 100% correct, I made a huge calculation mistake :blush:

kPa = -100.0 + (+300.0 - -100.0) * ((4.5 - 0.5) / (4.5 - 0.5)
kPa = -100.0 + (400) * (1)
kPa = 300

Between work and way too little sleep I was not thinking straight, apologies.

Thanks yet again, you guys are superstars 8)

Just a quick update.

My hardware was delivered today ;D 8) , so guess what I was busy doing today, except annoy my wife :smiling_imp:

Tested my code and it seems to be working fine now.

To do:

  • I just have to “calibrate” it with a compressor and vacuum pump to see if it is acceptable or not
  • Need to find my 12V to 5V step down converter to power the Arduino Nano with it

I tried the equation that MarkT suggested above, but I cannot seem to get it working as expected (think I am still too much of a noob to get it working). Spent a good 3 or 4 hours trying to get it working and eventually just gave up out of pure frustration, deleted the sketch, took a breather and decided to go with my initial map() function route (keeping in mind it can only parse int) for now until I can spend more time and create a new sketch to get it working.

Anyways, onto the code. I commented out a my bitmap “Load screens” to keep the code size down for posting here. I also used the Auto Format tool in the IDE to get the format looking decent as well as do a bit of cleanup removing irrelevant code and comments.

Please let me know if there is anything else I can do to better my sketch :slight_smile:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define sensorPin A0
#define WINDOW_SIZE 6
#define LOGO_HEIGHT 64
#define LOGO_WIDTH 128

/*
// 'vw128x64', 128x64px
const unsigned char VWround [] PROGMEM = {
// Removed to keep code smaller for forum posting
};

// 'VW GTI Logo', 128x64px
const unsigned char VWGTI [] PROGMEM = {
// Removed to keep code smaller for forum posting
};
*/


int rawval = 0; // Setup raw sensor value
int barboost = 0; // Setup value for boost bar
int INDEX = 0; 
int VALUE = 0;
int SUM = 0;
int READINGS[WINDOW_SIZE];
int AVERAGED = 0;

float atmo = 0.0;

byte count;
byte sensorArray[128];

/*
// Define VW Logo Bitmap
void VWlogo() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWround, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500);
}

// Define VW GTI Logo Bitmap
void VW_GTI() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWGTI, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500);
}
*/

void setup()
{
  Serial.begin(9600);
  delay(250); // To let the screen start up
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for my 128x64 OLED
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  atmo = analogRead(sensorPin);

/*  display.clearDisplay(); // Clear the display and ram
  display.display();
  VWlogo(); // Display the VW Logo
  delay(1000); // Pause for 1 second

  display.clearDisplay();
  display.display();
  VW_GTI(); // Display the GTI Logo
  delay(1000); // Pause for 1 second
  */
  
  for (count = 0; count <= 128; count++) // Zero all elements
  {
    sensorArray[count] = 0;
  }
}


void loop() // Start loop
{
  analogRead(sensorPin);
  int boost = map(analogRead(sensorPin), 102.4, 921.6, -100, 300);
  int boostmbar = boost;
  rawval = (analogRead(A0)); // Read MAP sensor raw value on analog port 0

  SUM = SUM - READINGS[INDEX]; // Remove the oldest entry from the sum
  VALUE = boost; // Read the new sensor value for measured Pressure
  READINGS[INDEX] = VALUE; // Add the newest reading to the window
  SUM = SUM + VALUE; // Add the newest reading to the sum
  INDEX = (INDEX + 1) % WINDOW_SIZE; // Increment the index, and wrap to 0 if it exceeds the window size
  AVERAGED = SUM / WINDOW_SIZE; // Divide the sum of the window by the window size for the result
  barboost = (rawval - atmo); // Calculate the graph value

  display.fillRect(0, 0, barboost, 10, WHITE); // Draws the bar depending on the sensor value
  display.setTextSize(1);
  display.setCursor(35, 53);
  display.println("VOLKSWAGEN");
  
  if (AVERAGED > -10) {
    display.setCursor(90, 30);
    display.println("BOOST");
  } 
  else {
    display.setCursor(90,30);
    display.println("VACUUM");
  }
  
  display.setTextColor(WHITE);
  display.setTextSize(3);
  display.setCursor(5, 13);
  display.println((((AVERAGED * 0.001) * 14) + 0.12), 1);
  delay(1);
  display.display();
  display.clearDisplay();
  delay(55); // delay between numbers
}

By bizzare coincidence , I’m doing a boost gauge for my VW polo , but have gone a different route with collecting the data from the OBD2 port .

Haha nice, glad to see I am not the only one :slight_smile:

I wanted to go the ODB2 route initially, but from research it supposedly updates way slower then having an absolute pressure sensor connected to the intake manifold, hence going this route for my specific application as I need to keep a fine eye on the pressures when tuning the car.

Would you mind sharing information with me regarding your project ?
I would need to go the OBD2 route for my friends VW Golf once I’m done with my VW Polo and do not want to reinvent the wheel persay.

Would be keen to see how you go about it

Your program is small, so these things don't matter much:

You have some local variables but you haven't been consistent in their use. barboost for example is calculated on one line in loop and used on the next and yet it is a global.

boostmbar by contrast is local, but is never used at all at the moment.

boost is sensibly local.

sensorArray doesn't seem to have a use either. Later?

Note that even things like SUM could be local, but that brings the extra subtlety that it must be declared static so that it retains its value between calls to loop.

On the subject of SUM, by convention, all caps are used for constants, not variables. It makes no difference to the compiler but it makes the code fractionally harder to understand because you're left wondering why.

All the calculation to get AVERAGED could be refactored into a function that returns the value.

RAM is scarce - check that you have used the right variable type. For example INDEX could be a byte since its maximum value is six.

C++ provides you with the option to use const. Generally it should be preferred over #define.

Thank you for the comments and advice Wildbill.
I have made some changes to clean up the code even further with your recommendations and also renamed some of my variables to lowercase not to cause issues reading and understanding the code :slight_smile:
With regards to sensorArray, I added it initially as I thought I had to have two pressure sensors, one for the current atmospheric pressure and one for doing my boost calculations however thinking about it afterwards I decided that I only needed one pressure sensor and read it’s value prior to any pressure being applied (outside of loop), with this I forgot to delete the lines of code referring to sensorArray, thank you for pointing that out to me :sunglasses:
Thank you for the tip to refactor AVERAGED as a function rather. I have now made the following amendments, please see my updated sketch below:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define sensorPin A0
#define LOGO_HEIGHT 64
#define LOGO_WIDTH 128

const WINDOW_SIZE (6);


// 'vw128x64', 128x64px
const unsigned char VWround [] PROGMEM = {
// Removed
};

// 'VW GTI Logo', 128x64px
const unsigned char VWGTI [] PROGMEM = {
// Removed
};

int rawval = 0; // Setup raw sensor value
int value = 0;
int sum = 0;
int readings[WINDOW_SIZE];
int averaged = 0;

float atmo = 0.0;

byte count;
byte index;


// Define VW Logo Bitmap
void VWlogo() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWround, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500);
}

// Define VW GTI Logo Bitmap
void VW_GTI() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWGTI, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500);
}

void setup()
{
  Serial.begin(9600);
  delay(250); // To let the screen start up
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  atmo = analogRead(sensorPin);
  
  display.clearDisplay(); // Clear the display and ram
  display.display();
  VWlogo(); // Display the VW Logo
  delay(1000); // Pause for 1 second

  display.clearDisplay();
  display.display();
  VW_GTI(); // Display the GTI Logo
  delay(1000); // Pause for 1 second
}

int averagedFunction(int x,int y){
  int result;
  result = x / y;
  return result;
}

void loop() // Start loop
{
  int boost = map(analogRead(sensorPin), 102.4, 921.6, -100, 300);
  rawval = (analogRead(A0)); // Read MAP sensor raw value on analog port 0
  sum = sum - readings[index]; // Remove the oldest entry from the sum
  value = boost; // Read the new sensor value for measured Pressure
  readings[index] = value; // Add the newest reading to the window
  sum = sum + value; // Add the newest reading to the sum
  index = (index + 1) % WINDOW_SIZE; // Increment the index, and wrap to 0 if it exceeds the window size
  averaged = averagedFunction(sum, WINDOW_SIZE);
  int barboost = (rawval - atmo); // Calculate the graph value

  display.fillRect(0, 0, barboost, 10, WHITE); // Draws the bar depending on the sensor value
  display.setTextSize(1);
  display.setCursor(35, 53);
  display.println("VOLKSWAGEN");
  
  if (averaged > -10) {
    display.setCursor(90, 30);
    display.println("BOOST");
  } 
  else {
    display.setCursor(90,30);
    display.println("VACUUM");
  }
  
  display.setTextColor(WHITE);
  display.setTextSize(3);
  display.setCursor(5, 13);
  display.println((((averaged * 0.001) * 14) + 0.12), 1);
  delay(1);
  display.display();
  display.clearDisplay();
  delay(55); // delay between numbers
}

Hey everyone,

Just an update, I think I am done for now with this project, it has given me enough sleepless nights for a while.

Busy designing a case for everything in CAD now to 3D Print once I have time to sit and babysit my printer. Thanks again to MarkT for suggesting how to code for this sensor, it worked a treat and the response is so much faster then with using the map() function. The complete sketch uses about 60% of the program storage space, so I am happy.

I went out to the car and tested it a few times (tried to calibrate it lol) as I do not have a compressor or vacuum pump accurate enough to trust for the calibration, so had to “hardcode” it slightly as you will see in my sketch below.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Define analog sensor pin on Arduino
#define sensorPin A0

// Define Logo Parameters
#define LOGO_HEIGHT 64
#define LOGO_WIDTH 128

// Define Sensor Parameters
#define SENSOR_MIN_VOLTS 0.5
#define SENSOR_MAX_VOLTS 4.5
#define MIN_OUT -100.0
#define MAX_OUT +300.0

// Define ADC Parameters:
#define ADC_FULL_SCALE 1024
#define ADC_REF 5.0

// 'vw128x64', 128x64px
const unsigned char VWround [] PROGMEM = {
// Removed for readability
};

// 'VW GTI Logo', 128x64px
const unsigned char VWGTI [] PROGMEM = {
// Removed for Readability
};


float boost = 0.0;

float kPa_from_adc (int adc_reading)
{
  float volts = adc_reading * ADC_REF / ADC_FULL_SCALE ; // convert to volts

  // now we have everything in terms of datasheet values
  // the equivalent of map() for floats:
  float kPa = MIN_OUT + (MAX_OUT - MIN_OUT) * ((volts - SENSOR_MIN_VOLTS) / (SENSOR_MAX_VOLTS - SENSOR_MIN_VOLTS)) ;
  return kPa ;
}

// Note when compiling - the following will display gibberish on the OLED screen due to the bitmap being removed above.
// Define VW Logo Bitmap
void VWlogo() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWround, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
  display.invertDisplay(true);
  delay(100);
  display.invertDisplay(false);
  delay(200);
  display.invertDisplay(true);
  delay(200);
  display.invertDisplay(false);
  delay(100); 
}

// Define VW GTI Logo Bitmap
void VW_GTI() {
  display.clearDisplay();
  display.drawBitmap(0, 1, VWGTI, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1500); 
  display.clearDisplay();
} 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(250); // To let the screen start up
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  display.clearDisplay(); // Clear the display and ram
  display.display();
  VWlogo(); // Display the VW Logo
  delay(1000); // Pause for 1 second
  display.clearDisplay();
  display.display();
  VW_GTI(); // Display the GTI Logo
  delay(1000); // Pause for 1 second
}

void loop() {
  // put your main code here, to run repeatedly:
 display.clearDisplay();
 display.setTextColor(WHITE);
 display.fillRect(0, 0, (kPa_from_adc(analogRead(A0)) - 54), 10, WHITE); // Draws the bar depending on the sensor value
 display.setTextSize(1);
 display.setCursor(35, 53);
 display.println("VOLKSWAGEN");
 display.setTextSize(3);
 display.setCursor(0, 20);
 display.print((kPa_from_adc(analogRead(A0)) - 54) / 100); //54kPa = Sensor Value on start-up, kPa to Bar conversion - Bar = kPa / 100.
 display.setCursor(0, 50);
 if ((kPa_from_adc(analogRead(A0)) - 54) / 100 > -0.00) {
    display.setTextSize(1);
    display.setCursor(95, 20);
    display.println("BOOST");
  } 
  else {
    display.setTextSize(1);
    display.setCursor(90,20);
    display.println("VACUUM");
  }
 delay(1);
 display.display();
 display.clearDisplay();
 delay(60); // Delay between numbers to make it more readable
}

Please note, I wanted to edit the post but decided against it as it messes up the formatting of the post.

My uploaded sketch already has the following items removed as per below:

// Define analog sensor pin on Arduino[color=#222222][/color]
#define sensorPin A0
float boost = 0.0;

Seems I had an older version in my clipboard when I pasted it here.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.