logo elektroda
logo elektroda
X
logo elektroda

DIY barograph/barometer with BME280 and Arduino Nano - how to build cheaply and get up and running w

JanuszArtur 3726 10

TL;DR

  • Zbudowano tani barograf/barometr na Arduino Nano, czujniku BME280 i wyświetlaczu LCD 20x4 z zapisem historii ciśnienia.
  • Układ rysuje wykres z 128 próbek w EEPROM, odświeża pomiar okresowo i pozwala zmieniać interwał przyciskiem.
  • W projekcie wykorzystano Nano za około 12 zł, wyświetlacz za około 50 zł i czujnik za 4 zł; zamiast AdaFruit BME280 wybrano tańszy moduł.
  • Działa poprawnie i wygląda dobrze, a jasność LCD regulowanym potencjometrem 5 kΩ można dostroić przez jumper I2C; autor chciałby jeszcze automatycznego skalowania osi Y.
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • I bought a barometer. The seller said there was a mistake, not 50pln but 500pln it was supposed to be. He refunded the money.

    I bought another one - broken, it's sitting under the kitchen table waiting for a return label.

    I bought a third one - a new USSR, but it didn't survive transport....
    So much for the basic question "why do this, isn't it easier to buy on the alegro?", or: "they are available online - why waste time?".

    I found the projects SECRET and closed on the electrode, so had to look elsewhere. It was supposed to be simple, easy, clear, not very expensive.

    I rummaged through my resources. I had a display (about 50pln), a Nano (about 12pln), and for 4pln I bought an I2C SPI BMP280 3.3V pressure transmitter.
    I used this development: Link but it proved problematic to use the AdaFruit BME280 product because of the price (over 70pln cheapest I could find).

    I have converted the code to the following, as the regular BME280 does not support all the commands as the AdaFruit does:
    
    #include <LiquidCrystal_I2C.h>
    #include <Wire.h>
    #include "GyverButton.h"
    #include <BME280I2C.h>                      
    #define BTN_PIN 3                            
    #define BASE_PERIOD 675000                   
    #define MIN_VAL 990                          
    #define MAX_VAL 1035                         
    LiquidCrystal_I2C lcd(0x27, 20, 4);          
    GButton butt1(BTN_PIN);
    BME280I2C bme;                               
    uint32_t tmr1, tmr2;                         
    uint32_t set_period = BASE_PERIOD;           
    int16_t plot_array[20];                      
    uint16_t base_array[128];                    
    int16_t value, delta;                        
    byte interval = 1 ;                          
    void setup() {
      read_all();
      attachInterrupt(1, isr, CHANGE);
      butt1.setDebounce(80);                     
      butt1.setTimeout(300);                     
      lcd.init();
      lcd.backlight();
      lcd.clear();
      Wire.begin();
      if (!bme.begin()) { // Initialization of the BME280 sensor
        lcd.setCursor(3, 1);
        lcd.print(F("NIE WIDZE CZUJKI"));
        lcd.setCursor(7, 2);
        lcd.print(F("BME280"));
        while (1);
      }
      if (!digitalRead(BTN_PIN)) {                         
        for (byte i = 0; i < 128; i++) base_array[i] = 0;  
        update_all();                                      
        lcd.setCursor(4, 1);                               
        lcd.print(F("KASUJ HISTORIE"));
        lcd.setCursor(8, 2);
        lcd.print(F("<OK>"));
      }
      while (!digitalRead(BTN_PIN));
      lcd.clear();
      initPlot();                                
      float pres, temp, hum;
      bme.read(pres, temp, hum);
      value = round(pres);                        
      base_array[0] = value;
      get_data();
    }
    void isr() {                                  
      butt1.tick();
    }
    void loop() {
      butt1.tick();                               
      if (butt1.isClick()) {                      
        interval *= 2;                            
        if (interval > 8) interval = 1;
        set_period = BASE_PERIOD * interval;      
        get_data();                               
      }
      if (millis() - tmr1 >= BASE_PERIOD) {       
        tmr1 = millis();                          
        for (int i = 126; i >= 0; i--) {          
          base_array[i + 1] = base_array[i];
        }
        float pres, temp, hum;
        bme.read(pres, temp, hum);
        value=round(pres);                                     
        base_array[0] = value;                                 
        update_all();                                          
      }
      if (millis() - tmr2 >= set_period) {                     
        tmr2 = millis();                                       
        get_data();
      }
    }
    void get_data() {                                           
      for (int i = 15; i >= 0; i--) {
        drawPlot(0, 3, 16, 4, MIN_VAL, MAX_VAL, (base_array[i * interval]));
      }
      delta = ((base_array[0]) - (base_array[15 * interval]));  
      screen_data(value, delta, (interval * 3));                
    }
    void screen_data(int value, int delta, byte interval) {    
      lcd.setCursor(16, 0);
      lcd.print(int(value));
      lcd.setCursor(17, 2);
      if (delta == value) delta = 0;
      if (delta > 0) {
        lcd.print("+");
      } else if (delta < 0) {
        lcd.print("-");
      } else if (delta == 0) {
        lcd.print(" ");
      }
      lcd.setCursor(18, 2);
      lcd.print(abs(delta));
      if (abs(delta) < 10) {
        lcd.setCursor(19, 2);
        lcd.print(" ");
      }
      lcd.setCursor(17, 1);
      lcd.print("hPa");
      lcd.setCursor(17, 3);
      lcd.print(interval);
      (interval < 10) ? lcd.print("h ") : lcd.print("h");
    }
    void initPlot() {
      byte row8[8] = {0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111};
      byte row7[8] = {0b00000,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111};
      byte row6[8] = {0b00000,  0b00000,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111};
      byte row5[8] = {0b00000,  0b00000,  0b00000,  0b11111,  0b11111,  0b11111,  0b11111,  0b11111};
      byte row4[8] = {0b00000,  0b00000,  0b00000,  0b00000,  0b11111,  0b11111,  0b11111,  0b11111};
      byte row3[8] = {0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b11111,  0b11111,  0b11111};
      byte row2[8] = {0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b11111,  0b11111};
      byte row1[8] = {0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b00000,  0b11111};
      lcd.createChar(0, row8);
      lcd.createChar(1, row1);
      lcd.createChar(2, row2);
      lcd.createChar(3, row3);
      lcd.createChar(4, row4);
      lcd.createChar(5, row5);
      lcd.createChar(6, row6);
      lcd.createChar(7, row7);
    }
    void drawPlot(byte pos, byte row, byte width, byte height, int min_val, int max_val, int fill_val) {
      for (byte i = 0; i < width; i++) {
        plot_array[i] = plot_array[i + 1];
      }
      fill_val = constrain(fill_val, min_val, max_val);
      plot_array[width - 1] = fill_val;
      for (byte i = 0; i < width; i++) {
        int infill, fract;
        infill = floor((float)(plot_array[i] - min_val) / (max_val - min_val) * height * 10);
        fract = (infill % 10) * 8 / 10;
        infill = infill / 10;
        for (byte n = 0; n < height; n++) {
          if (n < infill && infill > 0) {
            lcd.setCursor(i, (row - n));
            lcd.write(0);
          }
          if (n >= infill) {
            lcd.setCursor(i, (row - n));
            if (fract > 0) lcd.write(fract);
            else lcd.write(16);
            for (byte k = n + 1; k < height; k++) {
              lcd.setCursor(i, (row - k));
              lcd.write(16);
            }
            break;
          }
        }
      }
    }
    void update_all() {
      eeprom_update_block((void*)&base_array, 0, sizeof(base_array));
    }
    void read_all() {
      eeprom_read_block((void*)&base_array, 0, sizeof(base_array));
    }
    
    .

    I connected a 5kOhm potentiometer to the I2C converter jumper so that I could 'adjust the brightness' of the display.
    Power supply with samsung cable - I cut off the broken USB-C end.
    A bend from a broken power supply.
    3D printing I made ABS. SolidWorks, STEP, STL files - attached.
    Works cool. Recommended.
    It looks like this:

    Black barometer in a rectangular casing with an LCD display, set on a red background. .

    Black electronic DIY project with a cable on a red background. .

    DIY digital barometer with LCD display in a black casing. .

    LCD screen showing pressure readings and bar graph .

    LCD display showing barometer data. .

    LCD display with pressure graph and data .

    3D render of a housing with three separate components, part of an electronic project. .

    3D case design for a barometer created in CAD software. .

    LCD display layout with dimension details. .

    IF YOU WOULD LIKE, please suggest changing the code as described below.

    TO:
    - The dream would be that the graph would be scaled for each interval (3, 6, 12, 24h) and start with the minimum measured pressure value as the minimum of the Y axis and end with the maximum measured pressure value and this would be the MAX of the Y axis.

    Of course, this is a redesign. Not my design. The author is Mirko Pavleski. I only adapted to the poor-elements.
    Attachments:
    • 3D-szkice.rar (744.41 KB) You must be logged in to download this attachment.

    Cool? Ranking DIY
    About Author
    JanuszArtur
    Level 14  
    Offline 
    JanuszArtur wrote 301 posts with rating 94. Live in city Warszawa. Been with us since 2007 year.
  • ADVERTISEMENT
  • #2 21422190
    Jawi_P
    Level 36  
    Posts: 3193
    Help: 259
    Rate: 691
    JanuszArtur wrote:
    I bought a barometer. The seller said there was a mistake, it was not 50pln but 500pln. He refunded the money.

    I bought another one - broken, it's sitting under the kitchen table waiting for a return label.

    Bought a third - new USSR, but it didn't survive transport...
    .
    I don't think I understand you quite well, but for a foreigner you handle Polish quite well. A little more and you'll be ok.
    As for "hardware" - you could also think about some ESP32, already with a built-in display. OLED/TFTs look much better than the clunky ones on HD44780. And they have very narrow bezels.
  • ADVERTISEMENT
  • #3 21422360
    efi222
    Level 21  
    Posts: 655
    Help: 12
    Rate: 1057
    For such small changes in the graph, you could try displaying it on an automatic scale. This looks more dynamic (pictorial).
  • #4 21422553
    JanuszArtur
    Level 14  
    Posts: 301
    Rate: 94
    Jawi_P wrote:
    What about "hardware" - you could also think about some ESP32, already with built-in display. OLED/TFT
    .
    Super. Please quote me an ESP32 with already built-in display of the same - or larger size, at a similar price. I would be happy to buy a 4x20 OLED for 50pln in the BIG version. Will you provide a link or are you just writing what to write?
    Once again:
    - simple = uncomplicated
    - easy to install
    - clear = you can see from a few metres the trend of changes
    - low cost = max 150pln total

    Regards!

    Added after 2 [minutes]:

    efi222 wrote:
    For such small changes in the graph, you could try displaying it on an auto scale. This looks more dynamic (pictorial).



    yes, will you write a modification? :) So long as it's in 'open code', no hex or other secrets.
  • ADVERTISEMENT
  • #5 21422660
    efi222
    Level 21  
    Posts: 655
    Help: 12
    Rate: 1057
    JanuszArtur wrote:
    yes, you will write a modification?
    .
    You've written that you've rewritten a ready-made one, so keep trying to make modifications yourself.
    JanuszArtur wrote:
    the dream would be....
    .
    You can dream on, or take matters into your own hands :) .
    I am an amateur with no connection to programming or electronics and I know full well that sometimes it is hard. But you have to try to achieve your goal. :)
  • #6 21425096
    Anonymous
    Level 1  
  • #7 21441489
    vodiczka
    Level 43  
    Posts: 30170
    Help: 1183
    Rate: 4287
    JanuszArtur wrote:
    I purchased a barometer. The seller said there was a mistake, not 50pln but 500pln it was supposed to be. He returned the cash.
    .
    That what?
  • ADVERTISEMENT
  • #8 21441698
    efi222
    Level 21  
    Posts: 655
    Help: 12
    Rate: 1057
    My understanding is this:
    The author of the topic found the barometer in an online shop for 50pln and ordered it. The seller realised that the price displayed was wrong and that the barometer actually costs 500pln. For the author, the amount was too high and he cancelled the purchase. The seller refunded 50pln.
    But maybe I am wrong :) .
    I had a similar case once....
  • #9 21441727
    vodiczka
    Level 43  
    Posts: 30170
    Help: 1183
    Rate: 4287
    This may have been the case, but juxtaposed with the next two cases, it looks like an invention of the author rather than actual problems related to the purchase of three barometers consecutively. In addition, he wrote
    JanuszArtur wrote:
    On the electrode I found SECRET and closed projects, so had to look elsewhere.
    .
    He built it, it works, ''honour and glory to him'', confabulation unnecessary.
  • #10 21443202
    JanuszArtur
    Level 14  
    Posts: 301
    Rate: 94
    vodiczka wrote:
    JanuszArtur wrote:
    I purchased a barometer. The seller stated that there was a mistake, not 50pln but 500pln it was supposed to be. He refunded the cash.
    .
    That what?
    .
    I stated at the beginning the reason why I got pissed....m and instead of buying more junk, I looked and did. One of the barometers purchased is lying under the table still waiting for a return label. The prints dotted around - it indicates something.

    Usually when someone looks on the electrode, the first response is 'why make one, isn't it better to buy one? so I described the need to build one at the beginning, because it was impossible to buy one....
  • #11 21443363
    efi222
    Level 21  
    Posts: 655
    Help: 12
    Rate: 1057
    JanuszArtur wrote:
    the first responses are of the type: 'why make one, isn't it better to buy one
    .
    Maybe not the first, but it's a fact. Consumer visits to this section are not that uncommon at all. I understand the comparison of the presented design with factory equipment. I just don't know what the proposal to buy the device instead of constructing it myself is supposed to serve. And here we have a peculiar paradox, where the author in the DIY section explains in the introduction why he built the device and not bought a ready-made one....
📢 Listen (AI):

Topic summary

✨ The discussion revolves around the challenges faced by a user in purchasing barometers, leading to the decision to build a DIY barograph/barometer using an Arduino Nano and a BMP280 pressure sensor. The user initially encountered issues with purchased barometers, including incorrect pricing and damage during transport. They sought a cost-effective and straightforward solution, ultimately utilizing existing components: a display, an Arduino Nano, and a BMP280 sensor. Participants in the forum suggested alternatives like the ESP32 with built-in displays and discussed the merits of DIY projects versus purchasing ready-made devices. The conversation emphasized the importance of simplicity, clarity, and low cost in the design of the barometer.
Generated by the language model.

FAQ

TL;DR: For makers with a 150 PLN budget, “Works cool. Recommended.” This Arduino Nano barograph uses a 20x4 I2C LCD, a cheap BME280/BMP280 module, EEPROM history, and one button to switch 3 h, 6 h, 12 h, and 24 h views without buying an expensive ready-made barometer. [#21421897]

Why it matters: This project shows how to build a large, readable home pressure trend display cheaply when ready-made barometers are overpriced, broken, or hard to source.

Option Display Cost signal from thread Best fit
Arduino Nano + 20x4 LCD + BME280/BMP280 Large 4x20 character LCD Approx. 66 PLN for core parts already listed Cheapest, simple, readable from a few metres
ESP board + OLED Small OLED From 35 PLN plus BME280 Better looks, smaller display
ESP board + 2" TFT Color TFT up to 2" From 35 PLN plus sensor Better graphics, less “big display” clarity

Key insight: The thread’s strongest takeaway is that a big 20x4 character LCD can beat a prettier OLED or TFT when you want a low-cost barograph that stays readable from several metres away and remains easy to assemble.

Quick Facts

  • Core parts named in the build were a 20x4 display (~50 PLN), Arduino Nano (~12 PLN), and I2C SPI BMP280 3.3 V transmitter (4 PLN), keeping the main electronics around 66 PLN before enclosure and wiring. [#21421897]
  • The code stores pressure history in base_array[128], plots 16 points on the display, and switches interval views by doubling interval from 1 to 8, giving 3 h, 6 h, 12 h, and 24 h windows. [#21421897]
  • The fixed graph scale in the posted code uses MIN_VAL 990 and MAX_VAL 1035, so small pressure changes can look visually flat until auto-scaling is added. [#21421897]
  • The author’s target was explicit: simple, easy to install, clear from a few metres, and low cost = max 150 PLN total. [#21422553]

How do I build a cheap Arduino Nano barograph with a BME280 or BMP280 sensor and a 20x4 I2C LCD display?

Build it from three main parts: an Arduino Nano, a 20x4 I2C LCD, and a cheap BME280 or BMP280 pressure module. 1. Wire the Nano, LCD backpack, sensor, and one button. 2. Load code that reads pressure, stores history, and draws a graph on the LCD. 3. Mount everything in a printed case and power it from a USB cable. The posted build used a display for about 50 PLN, a Nano for about 12 PLN, and a pressure module for 4 PLN. [#21421897]

What changes are needed to adapt barograph code written for an Adafruit BME280 library to a regular BME280I2C module?

You need to replace the Adafruit-specific sensor calls with the BME280I2C library’s simpler interface. In the posted code, the sensor object becomes BME280I2C bme;, startup uses bme.begin(), and readings come from bme.read(pres, temp, hum). That change let the author use a regular low-cost module instead of the Adafruit version that was quoted at over 70 PLN. [#21421897]

Why does my Arduino barometer show "I can't see the BME280 sensor" during startup, and how do I troubleshoot the connection?

That message appears when bme.begin() fails, so the Nano does not detect the BME280 on startup. 1. Check power and make sure the sensor module matches the expected voltage, noted as 3.3 V in the build description. 2. Recheck the I2C wiring between the Nano and the module. 3. Verify that the code really targets the connected sensor library and module type. In this project, the LCD then prints NIE WIDZE CZUJKI and halts in while (1);. [#21421897]

How can I make the pressure graph auto-scale for each 3 h, 6 h, 12 h, and 24 h interval instead of using fixed MIN_VAL and MAX_VAL?

Use the minimum and maximum values from the currently displayed history window instead of fixed constants. The requested behavior was to scale each view separately for 3 h, 6 h, 12 h, and 24 h, with the Y-axis minimum equal to the lowest measured pressure and the maximum equal to the highest. That change matters because the original graph uses fixed limits of 990 and 1035, which can hide small shifts. Another poster explicitly recommended automatic scaling because it looks more dynamic. [#21422360]

What is the BME280I2C library, and how is it different from the Adafruit BME280 library in Arduino projects?

“BME280I2C” is an Arduino sensor library that reads a BME280 over the I2C bus, using a compact interface built around begin() and read(pres, temp, hum) for pressure, temperature, and humidity. In this thread, it replaced an Adafruit-oriented codebase because the regular module did not support all the same commands and the Adafruit-branded part was much pricier. [#21421897]

What is ESPEasy, and how could it be used with an ESP board and BME280 for pressure logging and remote viewing?

“ESPEasy” is firmware for ESP boards that can collect sensor readings and send them to a server, with the key advantage that you can archive data and view it on a phone. In the thread, it was suggested as a way to pair an ESP board and BME280 with remote logging instead of keeping everything on a local LCD barograph. That makes it useful if you want history outside the device itself. [#21425096]

Arduino Nano with HD44780 20x4 LCD vs ESP32 with built-in OLED or TFT - which is better for a low-cost, easy-to-read home barograph?

The Nano plus 20x4 LCD fits the thread’s goal better if you want low cost and readability from a few metres. The author preferred the big character display because it stays clear at distance and kept the total target under 150 PLN. Other posters argued that ESP32 boards with OLED or TFT screens look better and can be bought from about 35 PLN, but those displays are physically smaller, even when a 2-inch TFT is used. [#21422553]

What's the cheapest practical parts list for a DIY barometer/barograph that stays under about 150 PLN?

A practical low-cost list is: 20x4 I2C LCD for about 50 PLN, Arduino Nano for about 12 PLN, and a BMP280 I2C/SPI 3.3 V module for 4 PLN. Add one button, wiring, a reused USB cable for power, and a simple enclosure or printed case. That puts the main electronics near 66 PLN, leaving margin inside the stated 150 PLN total budget. The author also reused a broken USB-C cable and a bent part from a damaged power supply. [#21421897]

How do I wire a BME280 sensor, a 20x4 LiquidCrystal_I2C display, and a button to an Arduino Nano for a barograph project?

Wire the LCD and sensor to the Nano over I2C, then wire one interval button to digital pin 3. The code shows LiquidCrystal_I2C lcd(0x27, 20, 4); and #define BTN_PIN 3, so the display expects I2C address 0x27 and the button is read on pin 3 with an interrupt. The startup logic also checks the button state to clear history, so the button wiring must work before power-up. The exact SDA and SCL pins are not listed in the thread. [#21421897]

Why would someone choose a large 4x20 character LCD over an OLED or TFT for displaying barometric trend data from a few meters away?

A large 4x20 character LCD wins when you need trend data visible from several metres, not the prettiest graphics. The author stated that “clear” meant you can see the trend from a few metres away, and pushed back on OLED suggestions for that reason. OLED and TFT modules may look better, but the thread’s design goal prioritized a physically larger display area and simple installation over sleek bezels. [#21422553]

How can I save barometer history in Arduino EEPROM and clear it with a button at startup?

Save the history array to EEPROM after each new sample and clear it when the button is held during startup. In the posted code, update_all() writes base_array to EEPROM with eeprom_update_block, and read_all() restores it at boot with eeprom_read_block. If the button on pin 3 is pressed at startup, the code sets all 128 entries to 0, writes them back, and shows KASUJ HISTORIE on the LCD. [#21421897]

What does the GyverButton library do in this project, and why is interrupt plus debounce used for the interval button?

GyverButton handles button events cleanly, so one press changes the graph interval without false triggers. The code sets butt1.setDebounce(80) and butt1.setTimeout(300), then calls butt1.tick() both in the main loop and from an interrupt service routine attached with attachInterrupt(1, isr, CHANGE). That combination helps catch presses reliably while filtering bounce on the interval button connected to pin 3. [#21421897]

How should I connect a potentiometer to an I2C LCD backpack to adjust display contrast or perceived brightness safely?

Connect the potentiometer to the LCD’s I2C converter jumper only if that backpack supports such adjustment, and treat it as a contrast tweak rather than true backlight dimming. The builder used a 5 kOhm potentiometer on the I2C converter jumper to “adjust the brightness” of the display. That is a practical mod, but the thread gives no backpack schematic, so the safe limit is to follow the specific board layout you actually have. [#21421897]

What are the practical differences between using a BMP280 and a BME280 in a simple DIY barograph?

For this barograph, both parts serve the same core job of measuring pressure, but the posted code path was adapted around a BME280I2C library and reads pressure, temperature, and humidity variables together. The author also mentions buying a cheap BMP280 3.3 V module for 4 PLN, showing that low-cost pressure hardware was the main priority. In practice here, the project focuses on pressure display and history, not on extra sensor outputs. [#21421897]

How can I extend this Arduino barograph to archive readings on a server or view pressure trends on a phone?

Move the project to an ESP-based board and use ESPEasy if you want server logging and phone access. A poster said this setup can send readings to a server, keep an archive, and let you view the data on a phone. That extends the project beyond the Nano’s local LCD-and-EEPROM model, which only stores history inside the device itself. [#21425096]
Generated by the language model.
ADVERTISEMENT