Arduino барометр - барограф

lavr
Offline
Зарегистрирован: 03.05.2017

Да, возможно у Вас BME 280 3,3 В? У меня 5 вольтовая.

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Перепрошил, с изменениями... Почему-то фото вставить не получается. Впрочем, сразу не сделал фото, по сему и изменений не заметил. Пытаюсь победить бме-шку.

Genri5
Offline
Зарегистрирован: 31.05.2016

Модули могут отличаться по способу подключения I2C или SPI, а также питанием от 5 В или 3,3 В.

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Genri5 пишет:

Модули могут отличаться по способу подключения I2C или SPI, а также питанием от 5 В или 3,3 В.

Обычные, четырёхвыводные модули с микрой 662К. Надпись - GYBMEP...

Genri5
Offline
Зарегистрирован: 31.05.2016

 

 

Если четырехвыводный значит I2C и 5 В. Возможно, в библиотеке нужно указать как подключен модуль.

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Genri5 пишет:

Если четырехвыводный значит I2C и 5 В. Возможно, в библиотеке нужно указать как подключен модуль.

К превеликому сожалению, я в программировании, чуть больше нуля...

lavr
Offline
Зарегистрирован: 03.05.2017

https://yadi.sk/d/Z-_a-_zrVLAaJA

 

Может, мои библиотеки прокатят?

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

lavr пишет:

Может, мои библиотеки прокатят?

Прошивка зашла без запинок. И, рядом стоит проверенный... но, не мой. Там DHT22 и BMP180, Mega2560, 3.2", с часами но без изм. СО2. У BME-шек же - 745 вместо 757, 26 по Цельсию вместо 23, 19% влаж. вместо 23. При чём, две бме и ведут себя почти одинаково. Странно...

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

lavr
Offline
Зарегистрирован: 03.05.2017

С моей точки зрения, все эти приборы на китайских датчиках с Али только для индикации, точные значения получают с приборов, входящих в госреестр стран с обязательной поверкой.
Тенденции изменений параметров видны и в наших проектах.
Изменение прошивки делает симпотичнее график, когда нарисуются все 5 суток(не затирается вертикальными и горизонтальными координатными линиями)
Мне интересен конечный вариант - в корпусе! Полуфабрикаты у всех одинаковые...

Genri5
Offline
Зарегистрирован: 31.05.2016

Точность датчиков соответствует описанию. Сравнивал с показаниями штатных приборов. Есть знакомый из гидрометцентра(КИПовец). Я проверял BME280.

 

 

 

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

lavr пишет:
С моей точки зрения, все эти приборы на китайских датчиках с Али только для индикации, точные значения получают с приборов, входящих в госреестр стран с обязательной поверкой. Тенденции изменений параметров видны и в наших проектах. Изменение прошивки делает симпотичнее график, когда нарисуются все 5 суток(не затирается вертикальными и горизонтальными координатными линиями) Мне интересен конечный вариант - в корпусе! Полуфабрикаты у всех одинаковые...

Пока что обошёлся "костылями", просто вставил +/- недостающее... наблюдаю.

Igor_116
Offline
Зарегистрирован: 09.11.2017

lavr

Мне интересен конечный вариант - в корпусе!

так нужно в магазинах поискать готовое,

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Genri5 пишет:

Точность датчиков соответствует описанию. Сравнивал с показаниями штатных приборов. Есть знакомый из гидрометцентра(КИПовец). Я проверял BME280.

Просто как в книге известной получается: - И тут Остапа понесло... Я с `73-го был занят ремонтом радиостанций. Сначала войсковых, потом гражданских... разных в общем. Занимался и телеметрией.
И помня наказ К. Пруткова: - Зри в корень! - старался ему следовать.
Вот и сейчас - желая всё же разобраться с этими датчиками, побрёл по нетям... И оказалось, разные поставщики метеоданных играют ими как угодно - ничуть не стесняя себя. Так и получилось, что один источник сообщает: - 771 мм рт.ст., другой же утверждает: - 758 ... А на моём приборе - 768...
 Игрушки... я понимаю... однако, с возрастом, метеозависимость иногда даёт о себе знать. Особенно погодные перепады. И лучше было бы знать заранее - к чему готовым быть. Наверное бытовые барометры-барографы к сему и призваны, не взирая на их неточность... но не такую же!
Я написал письмо в FORECA, в коем и задавал вопрос о разночтениях. У них, на сайте одно, от них же в мобилке другое. Они попросили отправить им скриншоты. Отправил - вот, четвёртый день молчат - обдумывают...

Genri5
Offline
Зарегистрирован: 31.05.2016

У меня, на сегодня, один датчик BME280 в портативном барометре и BMP180 в матричных часах - давление показывают совершенно одинаковое до десятых, температура отличается, потому, что часы стоят в нише.

 

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Genri5 пишет:

У меня, на сегодня, один датчик BME280 в портативном барометре и BMP180 в матричных часах - давление показывают совершенно одинаковое до десятых, температура отличается, потому, что часы стоят в нише.

Вопрос стоит ещё и в том, что почти все программисты используют свои алгоритмы вычисления и пересчёта данных. Я пересмотрел, по меньшей мере, десяток разных прошивок - у всех по разному. Ну или почти у всех
К примеру:
 myGLCD.print( String(bme.readPressure()/133.3),43,7);               // выводим mmHg на дисплей  0 десятичных знаков
или
 Serial.print((bmp.readPressure() * 0.007501) + 12.13);;
или
 myGLCD.drawLine(81+i,-9.0 * pressure[i] + 8885,81+i+1,-9.0 * pressure[i+1] + 8885);
и т.д.
Я понимаю, что примеры, следует рассматривать лишь в составе всей программы. Здесь лишь результирующие фрагменты.

sartoil
Offline
Зарегистрирован: 28.02.2020

Сделал вот такую метеостанцию на основе прошивки GhostLion.

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

Моја метеостанција на основе прошивки GhostLion.

Genri5
Offline
Зарегистрирован: 31.05.2016

А у меня для мониторинга :

Для мониторинга

sel_oleg
Offline
Зарегистрирован: 08.02.2020

Муар картинку портит. Интервал меняется 12-24-48 часов, обычно стоит на 48 часах (правый нижний угол),

верхний левый угол - обратный отсчет секунд до замера, и видно что работает а не повис.

Enjoy
Enjoy аватар
Offline
Зарегистрирован: 07.05.2020

 Всем привет. Кто поможет? Вот проект высотомера https://github.com/voltnik/AltMeter на основе BMP280. 

/*********************************************************************
HELLO WORLD! ANYBODY HOME?
Высотомер на модуле барометра BMP-280

SITE: http://voltnik.ru/
YOUTUBE: https://www.youtube.com/channel/UC4s13gPVOMQVX3P1ZpdUwjA
Креатед бай voltNik 2017
*********************************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <EEPROMex.h>

#define OLED_RESET 4
#define but1 2                    // пин кнопки1
#define but2 3                    // пин кнопки2

#define longpress 3000            // сколько длительное нажатие 
#define screen_ref 300            // обновление экрана каждые милисекунд
#define but_protect 100           // защита дребегза кнопки
#define mass_l 10                 // длинна массива средних

Adafruit_SSD1306 display(OLED_RESET);
Adafruit_BMP280 bmp; // I2C

long now_millis, last_millis, last_but1, last_but2;       // миллисекунды для отсчета
byte num_ekr = 0 ;                        // номер отображения экрана
float pressure_zero = 1005.00;           // нулевая точка давления

float pressure[mass_l];  // массив давления
float temp[mass_l];      // массив температуры
float pres_sr = 0, temp_sr = 0, alt_sr = 0; // среднее давление и температура
byte pos = 0, sensorVal1, sensorVal2;
boolean pressed = false;
//=====================================
void setup()   {        
  boolean baro = false;        
  Serial.begin(9600);

  pinMode(but1, INPUT_PULLUP);
  pinMode(but2, INPUT_PULLUP);

  pinMode(5, OUTPUT);  // использую контакт как массу для одной из кнопок
  digitalWrite(5, 0);

  pressure_zero = EEPROM.readFloat(0); // читаем из памяти значение давления в нулевой точке

 if (!bmp.begin()) {  
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    while (1);
  }

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  display.cp437(true);
  display.clearDisplay();  
  testdrawrect();
  delay(200);
  
  // начальное заполнение массива
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(30,40);
  display.println("Loading...");
  pres_sr = 0;
  temp_sr = 0;
  for (byte i=0; i<mass_l; i++) {
    pressure[i] = bmp.readPressure();
    temp[i] = bmp.readTemperature();
    pres_sr = pres_sr + pressure[i];
    temp_sr = temp_sr + temp[i];
    //display.print(i);
    display.drawRect(0, 30, i*8, 5, WHITE);
    display.display();
    delay(50);
  }
  pres_sr /= mass_l;
  temp_sr /= mass_l;
}
//=====================================
void loop() {
  sensorVal1 = digitalRead(but1);
  sensorVal2 = digitalRead(but2);
  now_millis = millis();  // разово на цикл запоминаем старт милисекунд

 // обработка нажатия кнопки 1
  if ((sensorVal1 == LOW) & (now_millis - last_but1)> but_protect) { 
    num_ekr = (num_ekr+1) % 6;
    Serial.println(num_ekr);
    last_but1 = now_millis + 500;  // +500мс задержка следующего нажатия кнопки 1
  }

// обработка длинного нажатия кнопки 2
  if ((sensorVal2 == LOW) & (!pressed)) { 
    last_but2 = now_millis;
    pressed = true;
  }
// если держали более 3 секунд  
  if (pressed & ((now_millis-last_but2) > longpress)) { 
      pressure_zero = pres_sr / 100;
      EEPROM.writeFloat(0,pressure_zero); // записываем в память значение давления в нулевой точке  
      display.clearDisplay();  
      display.setTextSize(2);
      display.setCursor(0,0);
      display.print("Writing..");
      display.display();
      pressed = false;
      delay(500);
      last_but2 = now_millis;
    }
// обработка отпускания кнопки 2  
  if ((sensorVal2 == HIGH) & pressed) {
    if ((now_millis - last_but2)> but_protect) { // короткое нажатие кнопки 2 если надо
      Serial.println("Short Press!");
    }
    pressed = false;
  }

  // цикл обновления экрана
  if (now_millis - last_millis > screen_ref) {

    //цикл обновления массива температуры и давления
    pos = (pos + 1) % mass_l;
    pressure[pos] = bmp.readPressure();
    temp[pos] = bmp.readTemperature();
    
    // пересчет средних значений
    pres_sr = 0; 
    temp_sr = 0;
    // пересчет средних значений
    for (byte i=0; i<mass_l; i++) {
      //Serial.print(pressure[i]); Serial.print(" ");
      pres_sr = pres_sr + pressure[i];
      temp_sr = temp_sr + temp[i];
    }
    pres_sr /= mass_l;
    temp_sr /= mass_l;
    
  // вывод на экран
  switch (num_ekr) {
  case 0:
    display.clearDisplay();  
    display.setTextSize(1);
    display.setCursor(0,0);
    display.println("     Baro-280"); display.println();    
    display.print("Press: "); display.println(pres_sr);
    display.print("Alt Sea: "); display.println(bmp.readAltitude());
    display.print("Alt Zero: "); display.println(calcAltitude(pressure_zero, pres_sr));
    display.print("Temp: "); display.println(temp_sr);
    display.display();
    break;
  case 1:
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Pressure");
    display.setCursor(0,24);
    display.println(pres_sr);
    display.display();
    break;
  case 2:
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Alt Sea");
    display.setCursor(0,24);
    display.println(bmp.readAltitude());
    display.display();
    break;
  case 3:
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Alt Zero1");
    display.setCursor(0,24);
    display.println(calcAltitude(pressure_zero, pres_sr));
    display.setTextSize(1);
    display.setCursor(0,48);
    display.print("filtered");
    display.display();
    break;
  case 4:
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Alt Zero2");
    display.setCursor(0,24);
    display.println(calcAltitude(pressure_zero, pressure[pos]));
    display.display();
    break;    
  case 5:   
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Temp");
    display.setCursor(0,24);
    display.println(temp_sr);
    display.display();
    break;
  }
    
   last_millis = now_millis;
  }
  
}
//===================================== квадратики на старте
void testdrawrect(void) {
  for (int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display();
    delay(1);
  }
}
//===================================== расчет высоты
float calcAltitude(float seaLevelhPa, float pressure) {
  float altitude;
  pressure /= 100;
  altitude = 44330 * (1.0 - pow(pressure / seaLevelhPa, 0.1903));
  return altitude;
}
//=====================================

Как изменить показания давления из Паскалей в мм рт. столба, что бы это не повлияло на другие вычесления ? Заранее спасибо!

ra6fnq
ra6fnq аватар
Offline
Зарегистрирован: 26.10.2011

интернета нет? поисковиком не владеем? Примеры не читаем?

    Serial.print("Pressure = ");
    Serial.print(bme.readPressure());
    Serial.println(" Pa");
    
    Serial.print("Pressure = ");
    Serial.print(bme.readPressure()/133,3);
    Serial.println(" mmHg");  
Enjoy
Enjoy аватар
Offline
Зарегистрирован: 07.05.2020

ra6fnq пишет:

интернета нет? поисковиком не владеем? Примеры не читаем?

  А че так резко? Интернет есть, поисковиком владеем. В Ардуино я никогда ничего не изменял.
Не стоит быть столь категоричным, Евгений.
ra6fnq
ra6fnq аватар
Offline
Зарегистрирован: 26.10.2011

Может быть. но это преобразование есть в каждом здешнем проекте.

Ulliss
Offline
Зарегистрирован: 16.09.2019

везде, где встречается "bmp.readPressure()" поменяйте на формулу перевода Па в мм рт.ст

Enjoy
Enjoy аватар
Offline
Зарегистрирован: 07.05.2020

Ulliss пишет:

везде, где встречается "bmp.readPressure()" поменяйте на формулу перевода Па в мм рт.ст

 Везде как-раз нельзя, иначе вся математика будет неверно считать высоту и прочее. Разобрался. Изменил всего в одном месте - теперь при выборе кнопкой первого пункта,  показывает в "мм рт. столба".  Участок с изменением и коррекцией показаний:

  case 1:
    display.clearDisplay();  
    display.setTextSize(2);
    display.setCursor(0,0);
    display.print("Pressure");
    display.setCursor(0,24);
    display.println(bmp.readPressure()/133.3-0.1);
    display.display();
    break;

Теперь все ОК

Так же пробовал кидать скетч со страницы 11

#520 "Барограф" работал два дня - мне понравилось, буду повторять.

 

Всем спасибо за участие и разработки!

 

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

Enjoy

Большое спасибо!

neitron10
Offline
Зарегистрирован: 29.05.2020

Подскажите кто нибудь пробовал часы ds3231 под прошивку GhostLion прикручивать?

Там что реально нужно все переписывать?

 

Genri5
Offline
Зарегистрирован: 31.05.2016

neitron10, там библиотека универсальная "iarduino_RTC.h". Достаточно в строчке " iarduino_RTC time" указать "(RTC_DS3231);" и должно работать.

neitron10
Offline
Зарегистрирован: 29.05.2020

Спасибо за подсказку. Буду пробовать. Пардон не заметил в библиотеке PDF где указаны мои часы

DrMavr
Offline
Зарегистрирован: 08.06.2020

sartoil, Очень понравилась ваша работа! Не поделитесь своим модернизированным скетчем и схемой?

DrMavr
Offline
Зарегистрирован: 08.06.2020

sartoil, Как делали корпус?

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

sel_oleg пишет:

Муар картинку портит. Интервал меняется 12-24-48 часов, обычно стоит на 48 часах (правый нижний угол),

верхний левый угол - обратный отсчет секунд до замера, и видно что работает а не повис.

Пожалуйста, подключите "ino" файл и схему !!!

Jevega
Jevega аватар
Offline
Зарегистрирован: 27.12.2016

Enjoy пишет:

 Везде как-раз нельзя, иначе вся математика будет неверно считать высоту и прочее. Разобрался. Изменил всего в одном месте - теперь при выборе кнопкой первого пункта,  показывает в "мм рт. столба".  Участок с изменением и коррекцией показаний:

 

Дело в том, что существующая распространённая практика измерения высоты относительно атм. давления, не выдерживает критики. К примеру, работающие у меня (в двух разных конструкциях BMP180 и BME280 ), в разное время могут показывать высоту от 150-и м до 230 м, при изменении давления. Наверное для этого и предлагается дополнять эти датчики, датчиками позиционирования.

sartoil
Offline
Зарегистрирован: 28.02.2020

Добрый день, скетч только  немного изменил, подключения по схеме от Meteostation Copyright by GhostLion v 2.0 на форуме есть, корпус делал из коробки разветвитель взятая в электрике за 20 р. брал пару штук клеил дихлорэтаном склеивает намертво.

sartoil
Offline
Зарегистрирован: 28.02.2020

Вот подставку сделал.

sel_oleg
Offline
Зарегистрирован: 08.02.2020

For stojano

Код сырой, писался на скорую руку чтобы работало. Кнопка на PIN 3 замыкается на землю, индикатор и сенсор стандартно

#include "U8glib.h"                                            // Подключаем библиотеку U8glib
#include <Adafruit_Sensor.h>                                   // 1мм=133,322 Па,  730=97325, 740=98658
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp280;

U8GLIB_ST7920_128X64_1X u8g(10);                               // Создаём объект u8g для работы с дисплеем, указывая номер вывода CS для аппаратной шины SPI
float n_press;
int n_pr;
int p_pr;
int takt;
int dlit;
int stolb;
uint8_t vert[64] ;
char buf[5];
char buf2[5];


void setup() {
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
  n_pr = 0;
  p_pr = 0;
  takt = 0;
  dlit = 675;
    Serial.begin(9600);
    Serial.println(F("BMP280"));
  while (!bmp280.begin(BMP280_ADDRESS - 1)) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    delay(1000);
  }
}
void loop () {
  if (digitalRead(3) == LOW) {
    switch(dlit){
    case 675  : dlit = 1350;break;
    case 1350 : dlit = 2700;break;
    case 2700 : dlit =  675;break;}
   // цикл обнуления массива
    for (int i = 0; i < 63; i++) {
      vert[i] = 0;}
     takt = 0;
    delay(2000);
  }

  takt = takt - 1;
  if (takt <= 1) {
    n_press = bmp280.readPressure();
    // цикл перезаписи массива
    for (int i = 0; i < 63; i++) {
      vert[i] = vert[i + 1];
    }
    stolb = ( n_press - 97325 ) / 45 - 2 ;
    if ( stolb > 120 ) {
      stolb = 120; }
    if ( stolb < 1 ) {
      stolb = 1  ; }
    vert[63] = stolb;
    takt = dlit;
  }
  u8g.firstPage();     // Всё что выводится на дисплей указывается в цикле: u8g.firstPage(); do{ ... команды ... }while(u8g.nextPage());
  do {
    u8g.setColorIndex(1);                                 // Выбираем белый цвет
    u8g.setFont(u8g_font_6x10);
    //----- рисуем график--------------------------------------
    for (int i = 0; i < 64; i++) {
      u8g.drawHLine(0, i, vert[i] );
    }
    //------ рисуем давление и разность -----------------------
    p_pr = n_pr;
    n_pr = 100 * n_press / 13333 - 1 ;


    sprintf (buf, "%dmm", n_pr);
    u8g.drawStr90(120, 35 , buf);

    //--------  рисуем разметку ------------------------------------

//    u8g.setColorIndex(1);                                 // Выбираем белый цвет
    u8g.setFont(u8g_font_4x6);
    
    u8g.setColorIndex(0);                                 // Выбираем черный цвет
    u8g.drawBox(0, 0, 7, 12);
    u8g.drawBox(57, 0, 7, 12);
    u8g.drawBox(0, 56, 7, 8);

    u8g.drawVLine(60, 0, 64);
    u8g.drawVLine(30, 0, 64);
    u8g.drawVLine(90, 0, 64);

    u8g.setColorIndex(1);                                 // Выбираем белый цвет
//    u8g.setFont(u8g_font_4x6);

    u8g.drawStr90(0, 0 , "730");

    switch(dlit){
    case 675  : u8g.drawStr90(0, 57 , "12");break;
    case 1350 : u8g.drawStr90(0, 57 , "24");break;
    case 2700 : u8g.drawStr90(0, 57 , "48");break;
 }
    
    u8g.drawStr90(57, 0 , "750");
    sprintf (buf2, "%d",  takt );
    u8g.drawStr90(122, 0 , buf2);


    u8g.drawVLine(60, 13, 5);
    u8g.drawVLine(60, 23, 5);
    u8g.drawVLine(60, 33, 5);
    u8g.drawVLine(60, 43, 5);
    u8g.drawVLine(60, 53, 5);

    u8g.drawVLine(30, 03, 5);
    u8g.drawVLine(30, 13, 5);
    u8g.drawVLine(30, 23, 5);
    u8g.drawVLine(30, 33, 5);
    u8g.drawVLine(30, 43, 5);
    u8g.drawVLine(30, 53, 5);

    u8g.drawVLine(90, 03, 5);
    u8g.drawVLine(90, 13, 5);
    u8g.drawVLine(90, 23, 5);
    u8g.drawVLine(90, 33, 5);
    u8g.drawVLine(90, 43, 5);
    u8g.drawVLine(90, 53, 5);
    
  }    while (u8g.nextPage());
  delay(1000);
}

 

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

Я очень, очень благодарен вам !!!! Многие приветствия от Битола Македония !!!!

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

Я очень, очень благодарен вам !!!! Многие приветствия от Битола Македония !!!!

neitron10
Offline
Зарегистрирован: 29.05.2020

Мои поделки в Мыльнице и колонке.

runaway
Offline
Зарегистрирован: 25.09.2012

Моя поделка на основе прошивки участника s13, сообщение №243: 

http://arduino.ru/forum/proekty/arduino-barometr-barograf?page=4#comment-195389

Точнее, самый свежий вариант прошивки, там надо смотреть ниже по ветке. "Дизайн" минималистский (по деньгам), но старался как мог, чтобы прибор своим внешним видом не оскорблял прикроватную тумбочку, например...

Особенности конструкции.

Модули Ардуино и датчика смонтированы на кросс-плате по технологии СМД. Для этого модуль Ардуино Про Мини доработан на точиле слесарном до состояния ESP8266-12 (которая с металлизированными лунками по периметру). Модуль датчика не дорабатывался - залил припоем прямо сквозь металлизированные отверстия, прогревая под флюсом до успешной прозвонки. Паяется, кстати, неожиданно удобно и быстро. 

Корпус - самая дешёвая ($ 0,25) распределительная коробка для скрытой электропроводки; полиэтилен. Лицевая панель - комплектная крышка указанной коробки; полистирол. Поскольку полиэтилен ничем не клеится, кронштейн аккумулятора 14500 (кусок кабельного ПВХ канала 16 мм) и угловой кронштейн зарядного модуля (ПВХ 2 мм - стенка канализ. трубы 100 мм) закреплены на задней крышке пустотелыми заклёпками. Плоская площадка под подставку (текстолитовую шайбу, полученную путём высверливания листа текстолита корончатым сверлом 42 мм) сформирована прижатием корпуса коробки к слегка разогретой подошве ЛУТ-утюга, под некоторым небольшим углом к горизонту - так, чтобы лицевая панель прибора смотрела чуть вверх. Температура подошвы утюга и прижим (тычками) подбирались такими, чтобы материал корпуса постепенно, в течение нескольких минут, получал местную деформацию, но при этом не прилипал к подошве. Шайба подставки закреплена на площадке термоклеем; нитроэмаль под цвет корпуса. Окно под ЖКИ Нокиа 5110 - дремель; углы окна - треугольный надфиль. Крепление кросс-платы ко внутренней стороне лицевой панели - термоклей. Межмодульные соединения - МГТФ-0,05; зачистка концов - зажигалка обыкновенная.

Для снижения потребления питания применён модуль Ардуино Про Мини 328, 8 МГц, 3,3 В со снятыми "лишними компонентами" - светодиодом питания и стабилизатором напряжения. В такой конфигурации продолжительность непрерывной работы системы составляет около трёх месяцев (при этом минимальное напряжение питания может снижаться вплоть до 3,0 В), после чего необходима подзарядка аккумулятора от телефонного зарядного устройства.

https://mega.nz/file/wAU0mKBT#xVToYj06tKTt7dXDZ1tRvItsgEGt6GYgm1lN2TauSbM

https://mega.nz/file/cUECzSyR#M8tHA7bO-j-Gc-FxhJI9Aq1iHdLbf5ADus0HItKet8M

 
 
 
 
 
 
 
Огромное спасибо s13 за проделанную работу. Из пожеланий - можно бы добавить удобную коррекцию показаний давления и температуры. Я смог скорректировать только целую часть числа давления (мне нужно было уменьшить показания на 1 мм.рт.ст.), и всё число температуры. Хотелось бы добиться полного контроля над показаниями давления - не только над целой их частью, но и над дробной. В остальном - всё супер... Спасибо за внимание!
neitron10
Offline
Зарегистрирован: 29.05.2020

А как вы сделали маленькие цифры после точки? Просто это уже другой шрифт и если поставить значение с давление оно продублирует его. Или вы то что перед точкой за большими цифрами замаскировали?

runaway
Offline
Зарегистрирован: 25.09.2012
    myGLCD.clrScr(); // Очистка экрана
    myGLCD.setFont(BigNumbers);  //Давление с BMP180
    myGLCD.printNumI((Pressure / 133.3)+1, 15, 5, 3); //расчет атмосферного давления
    myGLCD.setFont(SmallFont);
    myGLCD.print(".", 57, 22);
    sotki = ((Pressure / 133.3)-int(Pressure / 133.3))*100;
    myGLCD.printNumI((sotki / 10), 63, 22, 1);// десятые 
    myGLCD.printNumI((sotki % 10), 69, 22, 1);// сотые
    myGLCD.print("Hg", 63, 6);
    myGLCD.print("C", 29, 35);
    myGLCD.printNumF(temp+0.3, 1, LEFT, 35);  //температура
    myGLCD.print("V", RIGHT, 35);    
   
    myGLCD.printNumF(analogRead(batPin)/176.5, 2, 53, 35);  //напряжение питания (коэффициент xxx.x подбирается, точка и десятые обязательны)
    myGLCD.setFont(TinyFont);                                                   //одна единица коэффициента (ххХ.х) =~ 0,02 В; (чем коэффициент >, тем напряжение <)
    myGLCD.print("o", 26, 33);
    break;                                           
                                                        

 

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

sel_oleg  Я сделал твой вариант Барографа. Я немного исправил squetch, поправил его в mB и установил высоту до 620 метров.Для лучшей наглядности я добавил 8 столбцов с цифрами слева. Это прекрасно работает, и еще раз большое спасибо за отправку мне вашей работы !!!

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

sel_oleg
Offline
Зарегистрирован: 08.02.2020

stojanov  Очень рад что Вам пригодилось и понравилось!

stojanov
stojanov аватар
Offline
Зарегистрирован: 14.06.2017

Вы сделали очень хорошую графику, которая мне очень понравилась! Если хочешь, я могу отправить тебе свой чужой файл, если хочешь посмотреть, я все исправил! Еще раз, я очень благодарен вам за то, что прислали мне вашу работу. Чтобы немного пополнить его, я также установлю литий-ионную батарею, чтобы обеспечить память измеренных состояний, потому что, как вы знаете, если по какой-либо причине нет питания, чтение начинается с нуля !!!

witaly_k
Offline
Зарегистрирован: 21.07.2020

Доброго времени суток, уважаемая публика!
Пришел в эту ветку случайно. Мой товарищ, Юра, захотел барометр для рыбалки и предложил мне ему помочь.
Я согласился, и когда посмотрел варианты в и-нете, попал сюда. Все очень понравилось!
Но подходящего для моих задач на нашел, может плохо (не долго) искал.
У товарища Юрия есть Arduino Mega 2560 и Шилд TFT дисплея 3.5" для Arduino.
Датчик я купил и вот что у меня получилось:

 

 

Устройство измеряет температуру воздуха и величину атмосферного давления.
По измеренным точкам давления строит 3-х часовой график.
Пределы значений давления расчитываются по входным данным.
За основу взят скетч из #45, от soznik.
Устройство, конечно не претендует на метеостанцию, потребление большое, но если брать с собой на
рыбалку - повер-банка с 2-мя элементами должно хватить на несколько часов.
А после рыбалки можно "залить" другой скетч, под настроение. :-)

Шилд TFT дисплея 3.5" для Arduino Uno и Mega2560
http://arduino.ua/prod2261-shild-tft-displeya-3-5-dlya-arduino-uno-i-meg...
код: ASC225

Барометр BMP180
http://arduino.ua/prod664-Barometr_BMP085
код: DAT148

Arduino Mega 2560 R3 (CH340)
http://arduino.ua/prod2611-arduino-mega2560-r3-ch340
 код: APC157

Скетч:

/*********************************
скетч "Барограф" от Виталия Клишина
Устройство измеряет температуру воздуха и величину атмосферного давления. 
По измеренным точкам давления строит 3-х часовой график.
Пределы значений давления расчитываются по входным данным.
Аппаратная часть - Барометр BMP180, Arduino Mega 2560, Шилд TFT дисплея 3.5",
/******************************************************************************
//Шилд TFT дисплея 3.5" для Arduino Uno и Mega2560
//http://arduino.ua/prod2261-shild-tft-displeya-3-5-dlya-arduino-uno-i-mega2560 
// код: ASC225
/******************************************************************************
//Барометр BMP180
//http://arduino.ua/prod664-Barometr_BMP085
// код: DAT148
************** Подключение датчика BMP180 к Arduino Mega 2560 *****************
// 1 - VCC---------- +3v3 от шилда дисплея
// 2 - GND------------------- к общему GND
// 3 - SCL--- SCL pin 21 Arduino Mega 2560
// 4 - SDA--- SDA pin 20 Arduino Mega 2560
**********************************/

	#include <Wire.h>              // библиотека шины получения и передачи данных
	#include <BMP085.h>            // библиотека для работы с датчиком давления BMP085
  //-----------------------------------------------------------------
	#include <Adafruit_GFX.h>      // библиотека для работы дисплея 
	#include <Adafruit_TFTLCD.h> 
 //-----------------------------------------------------------------
  #include <TimeHelpers.h>       // библиотека для работы с периодами времени   
  #include <EEPROM.h>

#define LCD_CS A3 
#define LCD_CD A2 
#define LCD_WR A1 
#define LCD_RD A0 
#define LCD_RESET A4 

#define TFT_BLACK   0x0000
#define TFT_GREY    0x7BEF
#define TFT_BLUE    0x001F
#define TFT_RED     0xF800
#define TFT_GREEN   0x07E0
#define TFT_CYAN    0x07FF
#define TFT_MAGENTA 0xF81F
#define TFT_YELLOW  0xFFE0
#define TFT_WHITE   0xFFFF
#define TFT_COLOR1  0x01E0

#define TFT_BEGIN_STR 25
#define TFT_STR_STEP  50
#define TFT_CENTER_STR 120
#define TFT_STR0    TFT_STR_STEP/2
#define TFT_STR1    TFT_STR_STEP*1+TFT_STR_STEP/2
#define TFT_STR2    TFT_STR_STEP*2+TFT_STR_STEP/2
#define TFT_STR3    TFT_STR_STEP*3+TFT_STR_STEP/2
#define TFT_STR4    TFT_STR_STEP*4+TFT_STR_STEP/2
#define TFT_STR5    298
#define TFT_TEXT_SIZE    3
#define TFT_W_VAL        395
#define TFT_STEP_LINE    3

#define TFT_DRAW_X0     380 	// константы области отрисовки графика
#define TFT_DRAW_X1     30 
#define TFT_DRAW_Y0     315
#define TFT_DRAW_Y1     115
#define INIT_VAL_PRESH  97300

#define CENTRE 240
#define WAIT 1000 // Delay between tests, set to 0 to demo speed, 2000 to see what it does!

#define NORM_PRESS    70000   // относительно этой константы сохраняем значение в памяти
#define MAX_PRESS     77900   // максимальное значение давления
#define MIN_PRESS     73000   // миниимальное значение давления
#define CNT_PRESS     117     // счетчик отсчетов давления в EEPROM * 2


#define Diagram_interval _SEC_(93)  // переодичность вывода данных на дисплей (93 cекунд)
                                     // полное заполнение 116 позиции графика = 3 часa)
//#define Diagram_interval _SEC_(5) // переодичность вывода данных на дисплей=2 cек (Исп. для настройки)
   
   ////////////  активизируем дисплей  //////////////////
   //-----------------------------------------------------------------
   Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
   //ILI9481 tft = ILI9481();
   //-----------------------------------------------------------------
   /////////// активизируем датчик давления ////////////
   BMP085 bmp = BMP085();     // Модель Digital Pressure Sensor - BMP085

   long Themp;
   float Themp1;
   long Pressure = 0; // переменная для получения данных с датчика давления
   float Press = 0;        //  переменная  давление
   long Press_t1;           // целая часть нормировенного давления (P-700) 
   byte nPressHi;
   byte nPressLow;
   long PressEP;          //  высота столбца
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = TFT_DRAW_X0;         //  место столбца графика
   byte tmp_rd = 0 ;          //  временная переменная
   long hiLimit;
   long lowLimit;
   float kScale;
   char buff[8];
   int cntByte;

void setup()
{        
   Wire.begin();
   //bmp.begin();            //  
   bmp.init(MODE_ULTRA_HIGHRES, 0, true);   // высота над уровнем моря - 17500 -> 175m для Любимовки
   //-----------------------------------------------------------------
   tft.reset();
   tft.begin(0x9481);
   //tft.init();   
   //-----------------------------------------------------------------
   delay(100);         // время на инициализацию датчика и дисплея
   tft.setRotation(1);    // старт дисплея
   tft.fillScreen(TFT_BLACK); // очищаем дисплей   
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
   /*
    for(int ci=35; ci<CNT_PRESS; ci++)
    {
      writeEeValue(ci, 4400);
    }
   Serial.println("write ok!");
   */
   Meterage();
}

void loop()
{  
  DO_EVERY(Diagram_interval, {Meterage();});
/*
  if(Serial.available() > 0)  
    {  
      buff[cntByte++] = Serial.read();      
    }
    if(cntByte > 2)
    {      
      int temp;
      for(int ci = 0; ci < CNT_PRESS; ci++)
      {
        temp = readEeValue(ci);
        Serial.println(temp);
      }      
      cntByte = 0;
    }  
*/       
}
 
                     //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void Meterage()
  {
    bmp.getTemperature(&Themp);  //получаем данные о температуре
    Themp1 = Themp/10;
    bmp.getPressure(&Pressure);     // получаем данные о давлении
    Press = Pressure/133.3;  
    Press_t1 = (long)(Press * 100); 
    //Serial.println("pressure");
    //Serial.println(Press_t1);
    if(Press_t1 > NORM_PRESS)
    {
      Press_t1 = Press_t1 - NORM_PRESS;   // часть давления без 700 мм, умноженная на 100 (чтобы видеть сотые) 
    }
    else
    {
      Press_t1 = 0;
    }
    Press_t1 = Press_t1 & 0x0000FFFF;
    nPressLow = Press_t1 & 0x000000FF;
    nPressHi = (Press_t1 & 0x0000FF00) >> 8;
    //Serial.println(Press_t1);
    
  /////////////  пишем часть высоты столбца в EEPROM /////////////////////////////
   writeEeValue(addressP, Press_t1);   
   autoscale();                                          
   grafik();                                //  рисуем график       
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP > CNT_PRESS)                      //  адреса 0 - CNT_PRESS
   {addressP = 0;}
  }

  void autoscale()
  {
    //////////////// находим минимальное и максимальное значение ////////////
    int tempL, tempH, temp;
    tempL = 32765;
    tempH = 0;
    for(int ci = 0; ci < CNT_PRESS; ci++)
    {
      temp = readEeValue(ci);
      if(temp >= tempH)   tempH = temp;
      if(temp <= tempL)   tempL = temp;      
    }    
    hiLimit = NORM_PRESS + tempH;

    if(hiLimit > MAX_PRESS)   hiLimit = MAX_PRESS;
    hiLimit = (hiLimit / 100) + 1;    					// определяем верхний предел
    lowLimit = NORM_PRESS + tempL;
    if(lowLimit < MIN_PRESS)   lowLimit = MIN_PRESS;
    lowLimit = lowLimit / 100;							// определяем нижний предел
    kScale = (TFT_DRAW_Y0 - TFT_DRAW_Y1) / ((hiLimit - lowLimit) * 100);
    //Serial.println("max");
    //Serial.println(hiLimit);
    //Serial.println("min");
    //Serial.println(lowLimit);
    //Serial.println("koef");
    //Serial.println(kScale);
  }
  
  void grafik()
  { 
    Pressing();                            //  рисуем текущее давление и все надписи    
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle < CNT_PRESS; cycle ++)   //  60 циклов вывода линий на дисплей
    { 
      stolb();
    }
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
   tft.fillScreen(TFT_BLACK); 					// очищаем дисплей
   tft.setTextSize(TFT_TEXT_SIZE+1);             // покрупнее 
   tft.setTextColor(TFT_GREEN);
   tft.setCursor(TFT_BEGIN_STR,TFT_STR0);
   tft.print(Press);             				// давление    
   tft.print("mm, "); 
   tft.print(Themp1,1);
   tft.print("*C");  
   tft.setTextSize(TFT_TEXT_SIZE);
   tft.setCursor(TFT_BEGIN_STR,TFT_STR1);
   tft.print("<-------3hour------|");
	////////////  пределы отображения давления  ////////////
   tft.setCursor(TFT_W_VAL,TFT_STR1+15);
   tft.println("_");         
   tft.setCursor(TFT_W_VAL+20,TFT_STR2-17);
   tft.println(hiLimit);   
   tft.setCursor(TFT_W_VAL,TFT_STR2+83);
   tft.println("-");  
   tft.setCursor(TFT_W_VAL,TFT_STR5);
   tft.println("_");
   tft.setCursor(TFT_W_VAL+20,TFT_STR5);
   tft.println(lowLimit);
  }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
  int temp;
   PressEP = readEeValue(adresP);                               //  читаем из памяти высоту столбца
   PressEP = PressEP + NORM_PRESS;   							//  восстанавливаем значение давления
   if(PressEP > MAX_PRESS)   PressEP = MAX_PRESS;
   if(PressEP < MIN_PRESS)   PressEP = MIN_PRESS;   
   PressEP = PressEP - (lowLimit * 100);   
   PressEP = (int) PressEP * kScale;   
   tft.drawLine (adrP, TFT_DRAW_Y1, adrP,TFT_DRAW_Y0, TFT_BLACK);  // очищаем столбец
   temp = TFT_DRAW_Y0 - PressEP;
   if(temp < TFT_DRAW_Y1)     temp = TFT_DRAW_Y1;
   tft.drawLine (adrP, temp, adrP,TFT_DRAW_Y0, TFT_COLOR1);  	// рисуем столбец  
   tft.drawPixel (adrP, temp, TFT_YELLOW);  					// рисуем пиксель  
   tft.drawPixel (adrP-1, temp, TFT_YELLOW);   					// рисуем пиксель еще раз 
   adrP = adrP - TFT_STEP_LINE;                               // устанавливаем место следующего столбца
   if (adrP < TFT_DRAW_X1)                                     // следим за местом
   {adrP = TFT_DRAW_X0; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = CNT_PRESS - 1;} 
 }

 //////////////////////// запись, чтение EEPROM по 2 байта ////////////////////////
 int readEeValue(byte addr)
 {    // в памяти текущий адрес - старший байт, текущий+1 - младший байт
    int val;
    byte adr2, valH, valL;

    adr2 = addr*2;
    valH = EEPROM.read(adr2) & 0xFF;
    valL = EEPROM.read(adr2+1) & 0xFF;
    val = valH << 8;
    val |= valL;
    return val;  
 }
 
 void writeEeValue(byte addr, int val)
 {    // в памяти текущий адрес - старший байт, текущий+1 - младший байт
    byte tmp, adr2, valH, valL;

    adr2 = addr*2;
    valH = (val & 0x00FF00) >> 8;
    valL = val & 0x0000FF;
    tmp = EEPROM.read(adr2);
    if(tmp != valH)     EEPROM.write(adr2,valH);
    tmp = EEPROM.read(adr2+1);
    if(tmp != valL)     EEPROM.write(adr2+1,valL);
 }
 

 

Genri5
Offline
Зарегистрирован: 31.05.2016

Извиниwitaly_k, для одного датчика BMP-180 использовать такие ресурсы - это расточительство. Взял бы уже BME-280 и добавил график влажности, получилась полноценная метеостанция. Но "Хозяин - барин". :-)

ra6fnq
ra6fnq аватар
Offline
Зарегистрирован: 26.10.2011

Во первых можно допилить, во вторых, этот экран сильно жрущий, у меня дома метеостанция на таком, с графиком, влажностью и двумя температурами.

Зато он наглядный и не надо щуриться пытаясь сломать глаза об экранчик 48х48