Пришел модуль BME280. Переделал скетч под него и еще добавил дни недели на главный экран. Сделал печатную плату и корпус из акрила на стойках уже готов. Осталось спаять.
//Meteostation Copyright by GhostLion v1.8
#define Pin_Led 3 // подсветка дисплея
#define Pin_DOWN A0 // левая кнопка
#define Pin_UP A2 // правая кнопка
#define Pin_SET A1 // центральная кнопка
#define Contrast 55 // контраст дисплея
#include <EEPROM.h>
#include <Wire.h>
#include <iarduino_RTC.h> // библиотека часов
#include <Adafruit_GFX.h> // библиотека вывода на дисплей
#include <Adafruit_PCD8544.h> // библиотека дисплея
#include <Adafruit_BME280.h> // библиотека датчика давления
float HM1, HM2, TP1, TP2, BM1, BM2, PW;
int Baza[3][24], Voltage;
boolean flag = 0, flag1 = 1, flag2 = 1, flag3 = 1;
byte s1, s2, t1, h1, t2 = 61, h2 = 61, q = 23, MODE = 0;
long LongKik;
int LedLight, Correct, ModeDisp, List = 0;
char *Dn = " ";
Adafruit_BME280 bme;
iarduino_RTC time(RTC_DS1302, 4, 6, 5);
Adafruit_PCD8544 display = Adafruit_PCD8544(10, 9, 8, 7, 2);
//===================================================
void setup()
{
pinMode(Pin_Led, OUTPUT);
pinMode(Pin_DOWN, INPUT_PULLUP);
pinMode(Pin_UP, INPUT_PULLUP);
pinMode(Pin_SET, INPUT_PULLUP);
MODE = EEPROM[0];
if (MODE == 1) {
LedLight = EEPROM[1];
Correct = EEPROM[2];
ModeDisp = EEPROM[3];
}
else {
MODE = 1; LedLight = 20; Correct = 0; ModeDisp = 1;
EEPROM[0] = MODE;
EEPROM[1] = LedLight;
EEPROM[2] = Correct + 10;
EEPROM[3] = ModeDisp;
}
MODE = 0; Correct -= 10;
Inicial(); // инициализация модулей и вывод данных о программе
}
//===================================================
void loop()
{
Parsing(); // опрос клавиатуры
Clock(); // обработка всех датчиков по часам
}
//===================================================
void Parsing()
{
boolean SET = digitalRead(Pin_SET);
boolean UP = digitalRead(Pin_UP);
boolean DOWN = digitalRead(Pin_DOWN);
if (SET == LOW && flag1 == 1)
{
LongKik = millis();
flag1 = 0;
}
if (SET == HIGH && flag1 == 0)
{
if (MODE != 0) {
MODE++;
time.blinktime(7 - MODE);
}
if (millis() - LongKik > 1500 && List != 0)Menu();
if (millis() - LongKik > 1500 && MODE == 0 && List == 0)MODE = 1;
if (MODE == 0) {
if (List != 4) {
flag = !flag;
Disp();
} else BazaData();
}
if (MODE > 6) {
MODE = 0;
time.blinktime(0);
}
if (MODE != 0)time.blinktime(7 - MODE);
flag1 = 1;
}
if (UP == LOW && flag2 == 1 && flag == 1)
{
flag2 = 0;
}
if (UP == HIGH && flag2 == 0)
{
if (MODE != 0)
{
switch (MODE)
{
/* год */ case 1: time.settime(-1, -1, -1, -1, -1, (time.year == 99 ? 0 : time.year + 1), -1); break;
/* мес */ case 2: time.settime(-1, -1, -1, -1, (time.month == 12 ? 1 : time.month + 1), -1, -1); break;
/* дни */ case 3: time.settime(-1, -1, -1, (time.day == 31 ? 1 : time.day + 1), -1, -1, -1); break;
/* час */ case 4: time.settime(-1, -1, (time.Hours == 23 ? 0 : time.Hours + 1), -1, -1, -1, -1); break;
/* мин */ case 5: time.settime(-1, (time.minutes == 59 ? 0 : time.minutes + 1), -1, -1, -1, -1, -1); break;
/* сек */ case 6: time.settime(0, -1, -1, -1, -1, -1, -1); break;
}
}
else {
List++; if (List > 4) List = 0;
if (List != 0 && List != 4) {
q = 23;
Graphik(List - 1);
}
if (List == 4) BazaData();
}
flag2 = 1;
}
if (DOWN == LOW && flag3 == 1 && flag == 1)
{
flag3 = 0;
}
if (DOWN == HIGH && flag3 == 0)
{
if (MODE != 0)
{
switch (MODE)
{
/* год */ case 1: time.settime(-1, -1, -1, -1, -1, (time.year == 0 ? 99 : time.year - 1), -1); break;
/* мес */ case 2: time.settime(-1, -1, -1, -1, (time.month == 1 ? 12 : time.month - 1), -1, -1); break;
/* дни */ case 3: time.settime(-1, -1, -1, (time.day == 1 ? 31 : time.day - 1), -1, -1, -1); break;
/* час */ case 4: time.settime(-1, -1, (time.Hours == 0 ? 23 : time.Hours - 1), -1, -1, -1, -1); break;
/* мин */ case 5: time.settime(-1, (time.minutes == 0 ? 59 : time.minutes - 1), -1, -1, -1, -1, -1); break;
/* сек */ case 6: time.settime(0, -1, -1, -1, -1, -1, -1); break;
}
}
else {
List--; if (List < 0) List = 4;
if (List != 0 && List != 4) {
q = 23;
Graphik(List - 1);
}
if (List == 4) BazaData();
}
flag3 = 1;
}
}
//===================================================
void Disp()
{
if (flag == 1) {
analogWrite(Pin_Led, LedLight);
}
if (flag == 0) {
if (ModeDisp == 1) {
analogWrite(Pin_Led, 0);
}
else {
display.clearDisplay();
display.display();
analogWrite(Pin_Led, 0);
}
}
List = 0;
}
//===================================================
void Clock()
{
time.gettime();
s1 = time.seconds;
t1 = time.minutes;
h1 = time.Hours;
switch (time.weekday)
{
case 0:{Dn = "ВС"; break;}
case 1:{Dn = "ПН"; break;}
case 2:{Dn = "ВТ"; break;}
case 3:{Dn = "СР"; break;}
case 4:{Dn = "ЧТ"; break;}
case 5:{Dn = "ПТ"; break;}
case 6:{Dn = "СБ"; break;}
}
if (MODE != 0) Output_Display();
else if (s2 != s1 && List == 0)
{
if (flag == 1) Output_Display();
if (flag == 0 && ModeDisp == 1)Output_Display();
}
if (s1 % 10 == 0 && s2 != s1) {
TP2 = TP1;
HM2 = HM1;
DHT_Read();
}
if (t1 != t2 && t1==0)
{
for (byte v = 0; v < 23; v++)
{
Baza[0][v] = Baza[0][v + 1];
Baza[1][v] = Baza[1][v + 1];
Baza[2][v] = Baza[2][v + 1];
}
Baza[0][23] = int(TP1 * 10); Baza[1][23] = int(HM1 * 10); Baza[2][23] = int(BM1 * 10);
}
if (t1 != t2) {
t2 = t1;
BM2 = BM1;
BMP_Read();
readVcc();
}
if (s2 != s1)s2 = s1;
if (h1 = 0 && t1 == 1 && s1 == 10 && Correct != 0 && h2!=h1) {
time.settime((s1 + Correct), -1, -1, -1, -1, -1, -1);
}
if (h2 != h1) h2 = h1;
}
//===================================================
void BMP_Read()
{
double P;
P = bme.readPressure()/133.3;
//P = P * 0.7500637554192;
BM1 = P;
PW = HM1 / 100; PW = (1 - PW) / 0.05; PW = TP1 - PW;
}
//===================================================
void DHT_Read()
{
TP1 = bme.readTemperature();
HM1 = bme.readHumidity();
}
//===================================================
void readVcc()
{
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
result = 1.080 * 1023 * 1000 / result; // расчёт реального VCC
Voltage = int(result);
Voltage = map(Voltage, 3200, 4100, 0, 100);
Voltage = constrain(Voltage, 0, 100);
}
//===================================================
void Status(byte k, byte n)
{
byte x, y;
if (k == 1) {
x = 32;
y = 29;
} else if (k == 2) {
x = 32;
y = 38;
} else {
x = 76;
y = 29;
}
if (n == 1) display.drawTriangle(x + 2, y, x + 5, y + 7, x, y + 7, BLACK);
if (n == 2) display.drawRect(x, y, 5, 8, BLACK);
if (n == 3) display.drawTriangle(x, y, x + 3, y + 7, x + 5, y, BLACK);
}
//====================================================
void Output_Display()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(24, 0);
display.print(time.gettime("d.m.Y"));
display.setCursor(12, 11);
display.setTextSize(2);
display.print(time.gettime("H:i"));
display.setCursor(72, 19);
display.setTextSize(1);
display.print(time.gettime("s"));
display.setCursor(0, 11);
display.print(Dn);
display.setCursor(0, 29);
display.print(TP1, 1); display.print("C");
display.setCursor(0, 38);
display.print(HM1, 1); display.print("%");
display.setCursor(44, 29);
display.print(int(BM1)); display.print("mm");
display.setCursor(44, 40);
display.print("*"); display.print(PW, 1); display.print("C");
display.fillRect(0, 0, 21, 9, BLACK);
display.setTextColor(WHITE);
display.setCursor(2, 1);
display.print(Voltage);
display.setTextColor(BLACK);
if (TP1 > TP2) Status(1, 1); else if (TP1 == TP2)Status(1, 2); else Status(1, 3);
if (HM1 > HM2) Status(2, 1); else if (HM1 == HM2)Status(2, 2); else Status(2, 3);
if (BM1 > BM2) Status(3, 1); else if (BM1 == BM2)Status(3, 2); else Status(3, 3);
display.display();
}
//==============================================
void Graphik(int d) // функция вывода графиков
{
const char *Names[] = {"Темпер.", "Влажн.", "Давлен."};
byte x = 5, y;
int z, a;
z = Baza[d][0]; a = Baza[d][0];
for (byte v = 1; v < 24; v++) {
z = min(z, Baza[d][v]);
a = max(a, Baza[d][v]);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.fillRect(0, 0, 83, 9, BLACK);
display.setCursor(1, 1); display.print(Names[d]);
display.setCursor(52, 1); display.print("за24ч");
display.setTextColor(BLACK);
display.drawTriangle(1, 10, 4, 16, 6, 10, BLACK);
display.drawTriangle(49, 10, 52, 16, 47, 16, BLACK);
display.setCursor(8, 10); display.print(float(z) / 10, 1);
display.setCursor(54, 10); display.print(float(a) / 10, 1);
display.drawLine(1, 46, 1, 20, BLACK);
display.drawLine(1, 46, 83, 46, BLACK);
display.drawLine(0, 41, 2, 41, BLACK);
display.drawLine(0, 36, 2, 36, BLACK);
display.drawLine(0, 31, 2, 31, BLACK);
display.drawLine(0, 26, 2, 26, BLACK);
display.drawLine(5, 47, 5, 45, BLACK);
display.drawLine(76, 47, 76, 45, BLACK);
display.drawLine(40, 47, 40, 45, BLACK);
display.drawLine(23, 47, 23, 45, BLACK);
display.drawLine(58, 47, 58, 45, BLACK);
display.drawLine(0, 23, 1, 20, BLACK);
display.drawLine(2, 23, 1, 20, BLACK);
display.drawLine(80, 45, 83, 46, BLACK);
display.drawLine(80, 47, 83, 46, BLACK);
for (byte v = 0; v < 24; v++)
{
y = map(Baza[d][v], z, a, 43, 19);
y = constrain(y, 19, 43);
display.drawLine(x, 43, x, y, BLACK);
display.drawLine(x + 1, 43, x + 1, y, BLACK);
x = x + 3;
}
display.display();
}
//================================================
void Inicial()
{
bme.begin();
time.begin();
DHT_Read();
BMP_Read();
TP2 = TP1; HM2 = HM1; BM2 = BM1;
for (byte v = 0; v < 24; v++)
{
Baza[0][v] = int(TP1 * 10);
Baza[1][v] = int(HM1 * 10);
Baza[2][v] = int(BM1 * 10);
}
display.begin();
display.clearDisplay();
display.setContrast(Contrast);
analogWrite(Pin_Led, 50);
readVcc();
display.display();
display.setCursor(7, 7); display.print(F("МЕТЕОСТАНЦИЯ"));
display.setCursor(14, 17); display.print(F("v 1.8 Rus"));
display.setCursor(17, 27); display.print(F("19.10.18"));
display.setCursor(0, 40); display.print(F(" By GhostLion"));
display.display();
delay(3000);
Disp();
}
//================================================
void Menu()
{
const char *Names[] = {"Режим", "Подсветка", "Коррекция", "ВЫХОД"};
int Data[] = {ModeDisp, LedLight, Correct};
int x = 0, y;
boolean flag4 = 1;
flag1 = 1;
while (flag4 != 0)
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(14, 0); display.print(F("НАСТРОЙКИ"));
display.drawLine(12, 7, 68, 7, BLACK);
for (y = 0; y < 4; y++) {
display.setCursor(0, y * 10 + 10);
display.print(Names[y]);
}
for (y = 0; y < 3; y++) {
display.setCursor(65, y * 10 + 10);
display.print(Data[y]);
}
display.fillRect(0, x * 10 + 9, 84, 9, BLACK);
display.setTextColor(WHITE);
display.setCursor(0, x * 10 + 10); display.print(Names[x]);
if (x != 3) {
display.setCursor(65, x * 10 + 10);
display.print(Data[x]);
}
display.display();
boolean SET = digitalRead(Pin_SET);
boolean UP = digitalRead(Pin_UP);
boolean DOWN = digitalRead(Pin_DOWN);
if (SET == HIGH && flag1 == 0)
{
x++;
if (x > 3)x = 0;
flag1 = 1;
}
if (SET == LOW && flag1 == 1)
{
flag1 = 0;
}
if (UP == LOW && flag2 == 1)
{
flag2 = 0;
}
if (UP == HIGH && flag2 == 0)
{
switch (x)
{
case 0: (Data[x] == 2 ? 1 : Data[x]++); break;
case 1: {
(Data[x] == 250 ? 0 : Data[x] += 10);
analogWrite(Pin_Led, Data[x]);
} break;
case 2: (Data[x] == 10 ? -10 : Data[x]++); break;
case 3: flag4 = 0; break;
}
flag2 = 1;
}
if (DOWN == LOW && flag3 == 1)
{
flag3 = 0;
}
if (DOWN == HIGH && flag3 == 0)
{
switch (x)
{
case 0: (Data[x] == 1 ? 2 : Data[x]--); break;
case 1: {
(Data[x] == 0 ? 250 : Data[x] -= 10);
analogWrite(Pin_Led, Data[x]);
} break;
case 2: (Data[x] == -10 ? 10 : Data[x]--); break;
case 3: flag4 = 0; break;
}
flag3 = 1;
}
delay(100);
}
ModeDisp = Data[0]; LedLight = Data[1]; Correct = Data[2];
EEPROM[1] = LedLight;
EEPROM[2] = Correct + 10;
EEPROM[3] = ModeDisp;
display.clearDisplay();
display.display();
LongKik = millis();
flag = 1; List = 0; MODE = 0; Disp();
}
//========================================================
void BazaData()
{
int h, d, m;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.fillRect(0, 0, 83, 9, BLACK);
display.setCursor(1, 1); display.print(F(" База за 24ч:"));
display.setTextColor(BLACK);
time.gettime();
h = time.Hours; d = time.day; m = time.month;
if (h - q < 0) {
h = 24 + h - q; d--;
if (d < 1) {
m--;
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) d = 31;
else d = 30;
}
}
else h = h - q;
display.setCursor(0, 11);
if (h < 10) {
display.print("0");
display.print(h);
} else display.print(h);
display.print(":00 ");
if (d < 10) {
display.print("0");
display.print(d);
} else display.print(d);
display.print(".");
if (m < 10) {
display.print("0");
display.print(m);
} else display.print(m);
display.setCursor(0, 21); display.print("Темп: "); display.print(float(Baza[0][q]) / 10, 1); display.print(" C");
display.setCursor(0, 31); display.print("Влаж: "); display.print(float(Baza[1][q]) / 10, 1); display.print(" %");
display.setCursor(0, 41); display.print("Давл: "); display.print(float(Baza[2][q]) / 10, 1); display.print(" мм");
display.display();
if (q == 0) q = 23; else q--;
}
//===========================================================
/home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/portable/sketchbook/sketch_nov27b/sketch_nov27b.ino: In function 'void BME_Read()':
sketch_nov27b:230: error: 'class Adafruit_BME280' has no member named 'takeForcedMeasurement'
bme.takeForcedMeasurement();
^
/home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/portable/sketchbook/sketch_nov27b/sketch_nov27b.ino: In function 'void Inicial()':
sketch_nov27b:373: error: 'class Adafruit_BME280' has no member named 'setSampling'
bme.setSampling(Adafruit_BME280::MODE_FORCED,
^
sketch_nov27b:373: error: 'MODE_FORCED' is not a member of 'Adafruit_BME280'
bme.setSampling(Adafruit_BME280::MODE_FORCED,
^
sketch_nov27b:374: error: 'SAMPLING_X4' is not a member of 'Adafruit_BME280'
Adafruit_BME280::SAMPLING_X4, // temperature
^
sketch_nov27b:375: error: 'SAMPLING_X4' is not a member of 'Adafruit_BME280'
Adafruit_BME280::SAMPLING_X4, // pressure
^
sketch_nov27b:376: error: 'SAMPLING_X4' is not a member of 'Adafruit_BME280'
Adafruit_BME280::SAMPLING_X4, // humidity
^
sketch_nov27b:377: error: 'FILTER_X4' is not a member of 'Adafruit_BME280'
Несколько библиотек найдено для "Adafruit_GFX.h"
Используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/portable/sketchbook/libraries/Adafruit_GFX_Library
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/portable/sketchbook/libraries/Adafruit-GFX-Library-master
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/libraries/Adafruit_GFX_Library
Несколько библиотек найдено для "Adafruit_PCD8544.h"
Используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/portable/sketchbook/libraries/Adafruit-PCD8544-Nokia-5110-LCD-library-master
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/libraries/Adafruit_GFX_Library
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/libraries/Adafruit_GFX_Library
Adafruit_BME280::FILTER_X4);
^
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/libraries/Adafruit_GFX_Library
Не используется: /home/linuxoid/Dropbox/Arduino/FLProg-3/ideV2/libraries/Adafruit_GFX_Library
exit status 1
'class Adafruit_BME280' has no member named 'takeForcedMeasurement'
С BMP 280 будет работать, или надо что-то переделывать? И чем BME лучше, чем BMP ? Как переделать под DS3231 ? Корпус кстати готовый использовался или распечатанный?
BME280, кроме температуры и атмосферного давления измеряет еще и влажность. Поэтому если влажность не нужна, можно применить BMP280. Скетч нужно корректировать под свое железо и свои пожелания. Если добовить еще DS3231 то это уже лучше вообще скетч новый написать.
Попробуйте датчик влажности Si7021. После того, как в течении 3-4 месяцев на улице, сгнили несколько DHT22, + в наших условиях повышенной влажности зимой, показания 99,9% норма, перешёл на него. статистики пока нет.
"Дело было вечером, делать было нечего..." (С) С. В. Михалков :)
Скрестил пару скетчей и получил ретро-барометр-барограф :) с предсказанием вероятности увеличения выпадения осадков от текущего момента (справа вверху), со знаком + на увеличение вероятности выпадения осадков, а со знаком - на уменьшение... (алгоритм предсказания от Alex Gyver https://alexgyver.ru/weatherpredict/ и барограф от allllhttps://mysku.ru/blog/aliexpress/52057.html , спасибо им за труды)
код желательно "причесать" :)
/*
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini
SCK (Serial Clock) -> A5 on Uno/Pro-Mini
*/
#include <Adafruit_BMP280.h>
#include <OLED_I2C.h>
#define PLOT_LEN 100
#define STORAGE_TIME 270
#define pressure_UP -99
#define pressure_DOWN 99
OLED myOLED(SDA, SCL, 8);
Adafruit_BMP280 bmp;
extern uint8_t BigNumbers[];
extern uint8_t SmallFont[];
struct {
byte temp = 0;
byte hum = 0;
byte pres = 0;
} infoArr[PLOT_LEN];
struct {
float temp = 0;
float hum = 0;
float pres = 0;
int counter = 0;
} avrg;
byte wait_cnt = 0;
byte shift_cnt = 0;
bool fastMode = true;
int move = 0;
//-----------------------
boolean wake_flag, move_arrow;
int delta, angle, last_angle=0;
unsigned long pressure, aver_pressure, pressure_array[6], time_array[6];
unsigned long sumX, sumY, sumX2, sumXY;
float a, b;
long previousMillis = 0; // храним время последнего измерения
long interval = 600000; // интервал между измерениями
//----------------------
void setup() {
myOLED.begin();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
while (!bmp.begin()) {
// if bmp280 not found - blink LED
delay(500);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
delay(500);
pressure = aver_sens(); // найти текущее давление по среднему арифметическому
for (byte i = 0; i < 6; i++) { // счётчик от 0 до 5
pressure_array[i] = pressure; // забить весь массив текущим давлением
time_array[i] = i; // забить массив времени числами 0 - 5
}
}
void loop() {
bool metric = true;
float temp(NAN), hum(NAN), pres(NAN);
uint8_t pressureUnit(0); // unit: B000 = Pa, B001 = hPa, B010 = Hg, B011 = atm, B100 = bar, B101 = torr, B110 = N/m^2, B111 = psi
temp = bmp.readTemperature();
//hum = bmp.readTemperature();
pres = bmp.readPressure();
pres /= 133.3; // convert to mmHg
if (move > 6) {move = 0;} // перемещение цифр для уменьшения «выгорания» oled.
myOLED.setBrightness(10);
myOLED.clrScr();
myOLED.setFont(BigNumbers);
myOLED.print(String(pres, 0), move, 0);
// myOLED.print(String((temp*1), 0), (move+80), 0); //(temp, 1) -цифра-это количество знаков после запятой
if(angle < 0 && angle > -10) {
myOLED.print(String(angle), (move+86), 0);
}
if(angle < -9) {
myOLED.print(String(angle), (move+72), 0);
}
if(angle > -1 && angle < 10){
myOLED.print(String(angle), (move+100), 0);
} if(angle > 9) {
myOLED.print(String(angle), (move+87), 0);
}
myOLED.setFont(SmallFont);
myOLED.print("mmHg", (move+44), 16);
myOLED.print(String(temp), (move+46), 0);
myOLED.print("~ ", (move+58), 0);
myOLED.print("%", (move+115), 16);
//myOLED.print("M", 122, 17);
avrg.temp += temp;
avrg.hum += hum;
avrg.pres += pres;
avrg.counter++;
if (fastMode && avrg.counter >= STORAGE_TIME) {
fastMode = false;
for (int i = 0; i < PLOT_LEN - 1; i++) {
infoArr[i].temp = 0;
infoArr[i].hum = 0;
infoArr[i].pres = 0;
}
}
if (fastMode || avrg.counter >= STORAGE_TIME) {
if (avrg.counter >= STORAGE_TIME) {
temp = avrg.temp / avrg.counter;
hum = avrg.hum / avrg.counter;
pres = avrg.pres / avrg.counter;
avrg.temp = 0;
avrg.hum = 0;
avrg.pres = 0;
avrg.counter = 0;
}
for (int i = 1; i < PLOT_LEN; i++) {
infoArr[i - 1] = infoArr[i];
}
infoArr[PLOT_LEN - 1].temp = round(temp) + 50;
infoArr[PLOT_LEN - 1].pres = round(pres) - 650;
infoArr[PLOT_LEN - 1].hum = round(hum);
}
delay(1000);
/*
Graph
*/
if (wait_cnt > 3) {
wait_cnt = 0;
shift_cnt = (shift_cnt == 0) ? 3 : 0;
//myOLED.clrScr();
byte minTemp = 255;
//byte minHum = 255;
byte minPres = 255;
byte maxTemp = 0;
//byte maxHum = 0;
byte maxPres = 0;
for (int i = PLOT_LEN - 1; i >= 0 ; i--) {
if (infoArr[i].temp == 0 && infoArr[i].hum == 0 && infoArr[i].pres == 0) break;
if (infoArr[i].temp < minTemp) minTemp = infoArr[i].temp;
//if (infoArr[i].hum < minHum) minHum = infoArr[i].hum;
if (infoArr[i].pres < minPres) minPres = infoArr[i].pres;
if (infoArr[i].temp > maxTemp) maxTemp = infoArr[i].temp;
//if (infoArr[i].hum > maxHum) maxHum = infoArr[i].hum;
if (infoArr[i].pres > maxPres) maxPres = infoArr[i].pres;
}
if (maxTemp - minTemp < 10) maxTemp = minTemp + 10;
//if (maxHum - minHum < 10) maxHum = minHum + 10;
if (maxPres - minPres < 10) maxPres = minPres + 10;
myOLED.print(String(maxPres + 650), 0, 26);
myOLED.print(String(minPres + 650), 0, 56);
int z = 0;
int x = 25;
for (int i = 0; i < PLOT_LEN; i++) {
if (infoArr[i].temp == 0 && infoArr[i].hum == 0 && infoArr[i].pres == 0) continue;
drawCol(x, map(infoArr[i].pres, minPres, maxPres, 63, 26), 63);
z++;
if (z > 15) {z = 0; x++;}
x++;
}
myOLED.update();
move = move+1; // перемещение цифр для уменьшения «выгорания» oled.
delay(1000);
}
wait_cnt++;
//-------------------------------------
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval)
{
pressure = aver_sens(); // найти текущее давление по среднему арифметическому
for (byte i = 0; i < 5; i++) { // счётчик от 0 до 5 (да, до 5. Так как 4 меньше 5)
pressure_array[i] = pressure_array[i + 1]; // сдвинуть массив давлений КРОМЕ ПОСЛЕДНЕЙ ЯЧЕЙКИ на шаг назад
}
pressure_array[5] = pressure; // последний элемент массива теперь - новое давление
sumX = 0;
sumY = 0;
sumX2 = 0;
sumXY = 0;
for (int i = 0; i < 6; i++) { // для всех элементов массива
sumX += time_array[i];
sumY += (long)pressure_array[i];
sumX2 += time_array[i] * time_array[i];
sumXY += (long)time_array[i] * pressure_array[i];
}
a = 0;
a = (long)6 * sumXY; // расчёт коэффициента наклона приямой
a = a - (long)sumX * sumY;
a = (float)a / (6 * sumX2 - sumX * sumX);
// Вопрос: зачем столько раз пересчитывать всё отдельными формулами? Почему нельзя считать одной большой?
// Ответ: а затем, что ардуинка не хочет считать такие большие числа сразу, и обязательно где-то ошибается,
// выдавая огромное число, от которого всё идёт плохо.
delta = a * 6; // расчёт изменения давления
angle = map(delta, -250, 250, pressure_DOWN, pressure_UP); // пересчитать в угол-проценты
angle = constrain(angle, -99, 99); // ограничить диапазон
previousMillis = currentMillis; // сохраняем время последнего измерения
}
//------------------------------------
}
long aver_sens() {
pressure = 0;
for (byte i = 0; i < 10; i++) {
pressure += bmp.readPressure();
}
aver_pressure = pressure / 10;
return aver_pressure;
}
void drawCol(int x, int y, int yn) {
for (int i = y; i <= yn; i++) {
myOLED.setPixel(x, i);
}
}
Код не мой. Это по 506 посту, только плату переразвёл. Перемычку возле ардуины можно не ставить, дублирующая "земля". Перемычку возле выключателя можно не ставить при условии, что корпус выключателя такой как у автора (имеет выводы для крепления, методом пайки, к плате.
Если имеется ввиду код ссылки яндекса - то пока с ним не совладал. Ссори... Если у кого есть желание выложить - отправлю на почту.
Сделал себе похожую походную метеостанцию с аккумулятором:
...
Добра всем! Возможно, мне кажется, базу выводит наоборот. Вчера давление целый день было стабильно, под вечер начало расти. Начал просматривать базу, время идет на увеличение, а данные с базы читает с конца. про остальные параметры не скажу, не примечал.
Спасибо за прошивку из поста #359 под 280 барометр. Год работало нормально сейчас заметил, что глухо виснет при нажатии кнопки. Только питание передёргивать с обнулением графика. Возможно её поправить как прошивку для BMP180 в посте #387
Добрый день всем. я новичок в ардуиностроении, и прошу простить за, возможно глупые, вопросы.
GhostLion пишет:
Пришел модуль BME280. Переделал скетч под него и еще добавил дни недели на главный экран. Сделал печатную плату и корпус из акрила на стойках уже готов. Осталось спаять.
Не засунули в корпус еще? есть фото итогового изделия?
постепенно иду к аналогичному варианту с библиотеками от Adafruit.
появилось несколько вопросов по последнему варианту:
GhostLion пишет:
Да, заметил такой глюк... исправил. И глюк с Февралём тоже обнаружил.(28 дней а не 30). С високосным годом решил не заморачиваться.
//Meteostation Copyright by GhostLion v 2.0
строка 017 intBaza[3][24], Voltage;017
Правильно я понимаю, что три дня по 24 часа? Может дни сделать переменной, а сутки - константой. Чтоб была возможность менять размер массива в дальнейшем. Для себя я не вижу потребности "долгосрочного" наблюдения. Для краткосрочного прогноза достаточно 3-х часов.
Блок строк 226-230voidBME_Read()
не совсем понимаю функцию и следующую паузу.
bme.takeForcedMeasurement();
delay(26);
что они делают? как то ускоренно снимают показания с датчика?
не совсем понимаю функцию и следующую паузу.
строка 237 PW = HM1 / 100; PW = (1 - PW) / 0.05; PW = TP1 - PW; Это расчет Точки росы? а где в дальнейшем вы ее применяете?
Можете ли вы предоставить схему и ino файл? Выглядит отлично !!! Это именно то, о чем я думал. Насколько большой экран ??? И так далее. Спасибо большое !!!
https://yadi.sk/d/vRKAQbTutaGjLQ
Проект понравился. Только один вопрос - где сейчас найти DS1302?
например на Алиэкспрес, Ебай.
Но по моему проще переделать под имеющийся
Заказал на Али BME280 - придет, переделаю под него. Да и корпус хочу сделать из акрила.
Заказал на Али BME280 - придет, переделаю под него. Да и корпус хочу сделать из акрила.
Я себе делал на BME280 и DS3231, правда только без графиков. Но точность и стабильность мне понравились.
Проект GhostLion очень даже достойный (посмотрел скетч и описание).
На досуге попробую повторить (на BME280). Автору респект!
Пришел модуль BME280. Переделал скетч под него и еще добавил дни недели на главный экран. Сделал печатную плату и корпус из акрила на стойках уже готов. Осталось спаять.
Код и библиотека к датчику в архиве. https://yadi.sk/d/30oec-8_hEUdjg
а есть плата в Sprint Layout ?
Да, в архиве.
Исправил пару ошибок в коде. Изменил метод опроса датчика BME280. Сделал установку дня недели.
p.s. Есть сильные сомнения в точности показаний BME280. Вроде он врет и очень сильно.
Я применял другую библиотеку(cactus_io_BME280_I2C.h), показания достаточно точные.
GhostLion, спасибки - на досуге потестим ))
Уважаемый GhostLion что делать у меня все русские букыв в иероглифах? Читал люди курят utf8rus в коде или библиотеки такие? (Ubuntu Arduino IDE 1.8.1)
Вот капец....
Может объяснит кто нибудь..
Это по проекту GhostLion
Используйте мои библиотеки из архива, свои всякие "адафруиты" временно уберите из папки библиотек.
https://yadi.sk/d/vGJXT9AR-Clj8g
https://yadi.sk/d/vRKAQbTutaGjLQ
https://yadi.sk/d/30oec-8_hEUdjg
Качайте все 3 архива - в первом библиотека дисплея с русским шрифтом, во втором EEPROM, в последнем библиотека BME280/
С BMP 280 будет работать, или надо что-то переделывать? И чем BME лучше, чем BMP ? Как переделать под DS3231 ? Корпус кстати готовый использовался или распечатанный?
BME280, кроме температуры и атмосферного давления измеряет еще и влажность. Поэтому если влажность не нужна, можно применить BMP280. Скетч нужно корректировать под свое железо и свои пожелания. Если добовить еще DS3231 то это уже лучше вообще скетч новый написать.
Попробуйте датчик влажности Si7021. После того, как в течении 3-4 месяцев на улице, сгнили несколько DHT22, + в наших условиях повышенной влажности зимой, показания 99,9% норма, перешёл на него. статистики пока нет.
Не понял причем здесь датчик влажности. Речь идет о барометре в целом.
Привет всем энтузиастам-ардуинщикам.
"Дело было вечером, делать было нечего..." (С) С. В. Михалков :)
Скрестил пару скетчей и получил ретро-барометр-барограф :) с предсказанием вероятности увеличения выпадения осадков от текущего момента (справа вверху), со знаком + на увеличение вероятности выпадения осадков, а со знаком - на уменьшение... (алгоритм предсказания от Alex Gyver https://alexgyver.ru/weatherpredict/ и барограф от allll https://mysku.ru/blog/aliexpress/52057.html , спасибо им за труды)
код желательно "причесать" :)
Не понял причем здесь датчик влажности. Речь идет о барометре в целом.
Здравствуйте! Собираюсь делать по схеме из поста 359 на arduino pro mini, я правильно понял что мне не надо ставить кварц и кондеры?
и ещё откуда взять библиотеки под bmp180?
С гитхаба.
[quote=GhostLion]
Пришел модуль BME280. Переделал скетч под него и еще добавил дни недели на главный экран. Сделал печатную плату ...
По следам...
Убраны перемычки... Файл приатачить , пока, не получается. Могу на почту.
Ја из Македоније!!!!! Одлична работа овај ваш проект!!!!
Урадио сам прву ПЦБ у Sprint Layout, но можда чу и ову вашу последњу!!!
Молим вас испратите ми ове Ваше нове фајлове за Ардуино и ПЦБ у Sprint Layout.
Моја Емаил адреса је: stovla02@yahoo.com
Стојанов Владо
Една голема благодарност за вашата одлична работа и многу поздрави од Македонија и од мене!!!
https://ru.aliexpress.com/item/32810394997.html?spm=a2g0v.search0104.3.2...
такой дисплей никто не думал прикрутить? он вроде как лучше 5110
Hattab, а почему не получается? Нажал на вставку кода и скопировал ... .
На ядиск блокирует вход. Могу выслать на почту.
Ја хочу поставит еден вопрос. Јел возможно уместо DS1302 употребити DS1307???
Hattab, а код где?
Код не мой. Это по 506 посту, только плату переразвёл. Перемычку возле ардуины можно не ставить, дублирующая "земля". Перемычку возле выключателя можно не ставить при условии, что корпус выключателя такой как у автора (имеет выводы для крепления, методом пайки, к плате.
Если имеется ввиду код ссылки яндекса - то пока с ним не совладал. Ссори... Если у кого есть желание выложить - отправлю на почту.
/sites/default/files/u29617/1.jpg
Сделал себе похожую походную метеостанцию с аккумулятором:
...
Добра всем! Возможно, мне кажется, базу выводит наоборот. Вчера давление целый день было стабильно, под вечер начало расти. Начал просматривать базу, время идет на увеличение, а данные с базы читает с конца. про остальные параметры не скажу, не примечал.
Да, заметил такой глюк... исправил. И глюк с Февралём тоже обнаружил.(28 дней а не 30). С високосным годом решил не заморачиваться.
Ок. Спасибо. Удостоверился в этом, записав данные со вчера на сегодня. График, как раз нарастающий, хорошо заметный.
S13
Спасибо за прошивку из поста #359 под 280 барометр. Год работало нормально сейчас заметил, что глухо виснет при нажатии кнопки. Только питание передёргивать с обнулением графика. Возможно её поправить как прошивку для BMP180 в посте #387
Всем привет !
Легко :) строку 122 и 129 из #387
поставить в 107,109 #359
запрет прерываний на время опроса датчика поможет от зависаний...
Спасибо! Буду пробовать!
Добрый день всем. я новичок в ардуиностроении, и прошу простить за, возможно глупые, вопросы.
Пришел модуль BME280. Переделал скетч под него и еще добавил дни недели на главный экран. Сделал печатную плату и корпус из акрила на стойках уже готов. Осталось спаять.
Не засунули в корпус еще? есть фото итогового изделия?
постепенно иду к аналогичному варианту с библиотеками от Adafruit.
появилось несколько вопросов по последнему варианту:
Да, заметил такой глюк... исправил. И глюк с Февралём тоже обнаружил.(28 дней а не 30). С високосным годом решил не заморачиваться.
//Meteostation Copyright by GhostLion v 2.0
строка 017
int
Baza[3][24], Voltage;
017
Правильно я понимаю, что три дня по 24 часа? Может дни сделать переменной, а сутки - константой. Чтоб была возможность менять размер массива в дальнейшем. Для себя я не вижу потребности "долгосрочного" наблюдения. Для краткосрочного прогноза достаточно 3-х часов.
Блок строк 226-230
void
BME_Read()
не совсем понимаю функцию и следующую паузу.
bme.takeForcedMeasurement();
delay(26);
что они делают? как то ускоренно снимают показания с датчика?
не совсем понимаю функцию и следующую паузу.
строка 237
PW = HM1 / 100; PW = (1 - PW) / 0.05; PW = TP1 - PW;
Это расчет Точки росы? а где в дальнейшем вы ее применяете?Заранее благодарю.
1. Корпус сделал из акрила. Фотки пока нет.
2. Не три дня по 24 часа а 3 переменные (температура, влажность, давление) за сутки.
3. Посмотрите примеры из библиотеки датчика BME 280.
4. Точка росы выводится на главном экране.
Скачал библиотеки от вас. Нашел разницу. Я старыми от Adafruit пользовался.
Уважаемый ChostLion
Почему-то у меня не запускается код из поста 536. Все остальные работают, но день недели установить невозможно, да и база наоборот.
Не могли бы вы выложить рабочий данный скетч или отправить мне на почту.
Правда проверял пока без датчика, на дисплее ничего нет , на кнопки не реагирует.
"Почему-то у меня не запускается код из поста 536" Код рабочий, в нём база исправлена.
Спасибо. Пришел датчик, установил и все заработало.
А я вот какой сделал:
Можете ли вы предоставить схему и ino файл? Выглядит отлично !!! Это именно то, о чем я думал. Насколько большой экран ??? И так далее. Спасибо большое !!!
ST7735 TFT дисплей 1,8"
В реале он очень маленький, во всяком случае для моих глаз. выше есть мой экземпляр, на 3,5" экране.