Standalone Arduino Altimeter

29K52115

Intro: Standalone Arduino Altimeter

Here is a standalone altimeter working with Arduino that you can use in RC project, hiking, cars... where you want :)

It shows on first screen the altittude, the temperature & the air pressure, and in the second, the minimum / maximum altitude reached.

Parts needed: (~12$)

  • An arduino board like a nano, pro mini or even AtTiny85 (depends on what you want, pro mini is lighter than nano and can works with an input voltage of 3.3v to 12v, perfect for light weight RC) 3.29$ on ebay
  • BMP280 chip temperature & barometric pressure sensor 1.84$ on ebay
  • An OLED display (0.96" I2C IIC Série 128X64) 5.32$ on ebay
  • Iron solder, tin and wires
  • A plastic case to put all in 1.50$ on ebay

STEP 1: The Wiring

The wiring is simple, the most "complicated" is to find the SCL and SDA pin on your arduino.

On the nano as on the photo, pin A4 is SDA and pin A5 is SCL.

On the Pro Mini, take a look at the picture, SDA is upside right to pin A2, and SCL upside right to pin A3.

Once your wiring is done, lets upload the sketch to the Arduino !

STEP 2: The Program

Code explanations (full code below):

#include "U8glib.h"
#include "BMP280.h"

They are the 2 libraries you have to put inside Documents\Arduino\libraries\

#define P0 1021.97

This is where you calibrate the altimeter, changing this value. Once it's done, it's pretty accurate !

(by default it was 1013.25, i had to up it to 1021.97 to have the right altitude in my town)

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);

Here you define the Oled screen type (128x64 etc...)

  u8g.drawStr( 5, 10, "Temp: ");
u8g.drawStr( 5, 30, "Bar : "); u8g.drawStr( 5, 50, "Alt : "); u8g.drawStr( 50, 10, sT); u8g.drawStr( 50, 30, sP); u8g.drawStr( 50, 50, sA);

Here the informations you want to display on first screen and their position ( Y, X, VALUE)

  dtostrf(A_MIN, 4, 2, sA_MIN);
dtostrf(A_MAX, 4, 2, sA_MAX); u8g.drawStr( 5, 20, "A Min: "); u8g.drawStr( 60, 20, sA_MIN); u8g.drawStr( 5, 45, "A Max: "); u8g.drawStr( 60, 45, sA_MAX);

Same for second screen

      if ( A > A_MAX) {
A_MAX = A; }
      if ( A < A_MIN || A_MIN == 0) {
        A_MIN = A;
      }

Here we update the minimum and maximun altitude stored

      do {
draw(T, P, A); } while ( u8g.nextPage() ); u8g.firstPage(); delay(1000);

Here, with the delay value (1000 in this case), you will stay 1 second on the first screen before switching to the second one. So change that if you want to customize display time :)

      do {
draw2(A_MIN, A_MAX); } while ( u8g.nextPage() ); u8g.firstPage(); delay(1000);

Same for second screen !

Hope it's clear, feel free to post a question in comments if needed !

Here is the full code:

#include "U8glib.h"
#include "BMP280.h" #include "Wire.h" #define P0 1021.97 //1013.25 BMP280 bmp; // OLED Type U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); char sT[20]; char sP[9]; char sA[9]; char sA_MIN[9]; char sA_MAX[9]; double A_MIN = 0; double A_MAX = 0; void draw(double T, double P, double A) { u8g.setFont(u8g_font_unifont); dtostrf(T, 4, 2, sT); dtostrf(P, 4, 2, sP); dtostrf(A, 4, 2, sA); u8g.drawStr( 5, 10, "Temp: "); u8g.drawStr( 5, 30, "Bar : "); u8g.drawStr( 5, 50, "Alt : "); u8g.drawStr( 50, 10, sT); u8g.drawStr( 50, 30, sP); u8g.drawStr( 50, 50, sA); } void draw2(double A_MIN, double A_MAX) { u8g.setFont(u8g_font_unifont); dtostrf(A_MIN, 4, 2, sA_MIN); dtostrf(A_MAX, 4, 2, sA_MAX); u8g.drawStr( 5, 20, "A Min: "); u8g.drawStr( 60, 20, sA_MIN); u8g.drawStr( 5, 45, "A Max: "); u8g.drawStr( 60, 45, sA_MAX); } void setup() { Serial.begin(9600); if (!bmp.begin()) { Serial.println("BMP init failed!"); while (1); } else Serial.println("BMP init success!"); bmp.setOversampling(4); u8g.setColorIndex(1); u8g.setFont(u8g_font_unifont); } void loop(void) { double T, P; char result = bmp.startMeasurment(); if (result != 0) { delay(result); result = bmp.getTemperatureAndPressure(T, P); if (result != 0) { double A = bmp.altitude(P, P0); if ( A > A_MAX) { A_MAX = A; } if ( A < A_MIN || A_MIN == 0) { A_MIN = A; } // Serial.print("T = \t"); Serial.print(T, 2); Serial.print(" degC\t"); // Serial.print("P = \t"); Serial.print(P, 2); Serial.print(" mBar\t"); // Serial.print("A = \t"); Serial.print(A, 2); Serial.println(" m"); u8g.firstPage(); do { draw(T, P, A); } while ( u8g.nextPage() ); u8g.firstPage(); delay(1000); do { draw2(A_MIN, A_MAX); } while ( u8g.nextPage() ); u8g.firstPage(); delay(1000); } else { Serial.println("Error."); } } else { Serial.println("Error."); } delay(100); }

STEP 3: Now It's Up to You !

You can move form the breadboard to the plastic case with soldering all.

Then, put it on RC plane, RC quadcopter, RC helicopter..... or a water rocket !

Hope it was helpful and that you will send me a pic once it's done =)

72 Comments

I try to modify the library name as early posted here. But has no success. I am using an Arduino IDE 2.1.0
I get the following errors on compilation process:
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino: In function 'void setup()':
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino:52:7: error: 'class BMP280' has no member named 'setOversampling'
bmp.setOversampling(4);
^~~~~~~~~~~~~~~
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino: In function 'void loop()':
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino:60:21: error: 'class BMP280' has no member named 'startMeasurment'
char result = bmp.startMeasurment();
^~~~~~~~~~~~~~~
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino:64:18: error: 'class BMP280' has no member named 'getTemperatureAndPressure'; did you mean 'getTemperature'?
result = bmp.getTemperatureAndPressure(T, P);
^~~~~~~~~~~~~~~~~~~~~~~~~
getTemperature
C:\Users\iscol\OneDrive\Documentos\Arduino\sketch_dec11b\sketch_dec11b.ino:67:22: error: 'class BMP280' has no member named 'altitude'; did you mean 'calAltitude'?
double A = bmp.altitude(P, P0);
^~~~~~~~
calAltitude
exit status 1
Compilation error: 'class BMP280' has no member named 'setOversampling'

Can anyone help me?
Alguien me puede ayudar a adaptar el código para que funcione con un BMP390 ?
Here are all the error messages I get:
F07WKJPIOW3XNQF.ino: In function 'void setup()':
F07WKJPIOW3XNQF:50:16: error: could not convert 'bmp.BMP280::begin()' from 'void' to 'bool'
if (!bmp.begin()) {
~~~~~~~~~^~
F07WKJPIOW3XNQF:50:17: error: in argument to unary !
if (!bmp.begin()) {
^
F07WKJPIOW3XNQF:56:7: error: 'class BMP280' has no member named 'setOversampling'
bmp.setOversampling(4);
^~~~~~~~~~~~~~~
C:\Users\Papa\Downloads\F07WKJPIOW3XNQF\F07WKJPIOW3XNQF.ino: In function 'void loop()':
F07WKJPIOW3XNQF:65:21: error: 'class BMP280' has no member named 'startMeasurment'
char result = bmp.startMeasurment();
^~~~~~~~~~~~~~~
F07WKJPIOW3XNQF:69:18: error: 'class BMP280' has no member named 'getTemperatureAndPressure'; did you mean 'getTemperature'?
result = bmp.getTemperatureAndPressure(T, P);
^~~~~~~~~~~~~~~~~~~~~~~~~
getTemperature
F07WKJPIOW3XNQF:72:22: error: 'class BMP280' has no member named 'altitude'; did you mean 'calAltitude'?
double A = bmp.altitude(P, P0);
^~~~~~~~
calAltitude
exit status 1
could not convert 'bmp.BMP280::begin()' from 'void' to 'bool'

And I may add that changing the lib names and including them by hand did not change things.
It is just a global no go.

Has anyone made it work as it should ?

Thanks !
So I commented the init successfull messges and now I get the following error:
"'class BMP280' has no member named 'setOversampling'"
There seems to be lots of error messages appearing one after the other one ...
Where am I wrong ?
Thanks
Hi everyone,
After downloading, the comilator gives the following message :
"could not convert 'bmp.BMP280::begin()' from 'void' to 'bool'"
What does it mean and what would be a solution ?

Thanks a lot
Great project. It inspired me to build my own Altimeter based on your code. I was able to add LED's and a Buzzer.
Hey! I put the provided files into the library, but its still not accepting it and has a different name- any ideas? Thanks!
Hello! I followed the instructions, wiring and all (with several same-color wires) and when the program is uploaded and powered on, the screen seems to be mapping some sort of data points, which is what the photo attached depicts. Is there a way to solve this?
Does this record into a log at all?
While powered it will save in memory the altitude max (and min) and display in real time the other values.
If you shut it off, you lose values. So no, it doesn't log anything as it would require more stuff like a sd card reader and more code.

Not too hard to code however if you need this feature.
No worries, I'll have a 360 camera next to it so it will be on the footage. This is going into a weather balloon.
Perfect then :)
Hello, can this be displayed on a:
Display Lcd 16x02 + Serie I2c instead the OLED?

Thanks!
Hi may I know if a 0.66" Oled display work with this
Hi, I am really keen to complete this project but I am very new to Arduino and C++.

No doubt this is something that experienced coders see every day, and I am sorry if it is frustrating that newbies don't understand it. :(
I have researched for days trying to solve this without reaching out, but it has defeated me.

I have downloaded the .ino file and libraries, and imported the libraries into my Arduino system.

When I try to compile the sketch I get the following error messages and I cannot determine where or why they are being generated?

In function 'void setup()':
standalone_altimeter.ino:56:7: error: 'class BMP280' has no member named 'setOversampling'
bmp.setOversampling(4);

In function 'void loop()':
standalone_altimeter.ino:65:21: error: 'class BMP280' has no member named 'startMeasurment'
char result = bmp.startMeasurment();

In the loop section I also have similar errors for
'getTemperatureAndPressure' and
'altitude'

If anyone is able to advise how to fix these errors I would be extremely grateful.

Thanks,
Graham
I have solved this, the problem was that the system was not loading the libraries supplied above, but was drawing them from the arduino stock library.

I was able to force the correct libraries and now it is completing verification.

Next step is to source an I2C OLED to complete the hardware setup, then it should be up and running hopefully
Hi Wooki,
I know its been some time, but how exactly did you do that? I am having the same errors as Graham stated above and don't quite know what you mean in terms of forcing the correct libraries.

Thanks
Dante
Hi Dante,
From memory the problem was because 'my' library had the same name as the arduino stock library. To fix it I gave each of my libraries a different name (for example put _GM) on the end of each library and make sure that you use the name of your customised library in your code where you call the libraries. Once you have uploaded your libraries to the project this will force the correct libraries to load.
Hope that helps,
Graham :)
Thank you Graham! To clarify cause I too am relatively new to arduino, if I upload a library, where it says include, is where I should modify the name as you stated?
More Comments