Не пойму как сделать..

gulin176
Offline
Зарегистрирован: 03.09.2016

спасибо про скобки не знал. теперьОК

lcd.print(dt.hour);
  lcd.print(":");
  if (dt.minute >= 10) {
  lcd.setCursor(11, 1);
  lcd.print(dt.minute);
  }
  if (dt.minute >= 0 && dt.minute < 10) {
  lcd.setCursor(11, 1);
  lcd.print(0);
  lcd.setCursor(12, 1);
  lcd.print(dt.minute);
  }
  delay(5000);
 }

 

gulin176
Offline
Зарегистрирован: 03.09.2016

не прошу готового кода, но буду рад посмотреть либо похожие примеры либо алгоритм. надо запоминать показание в 00 минут и хранить час. в следующие 00 минут сравнить с прошлыми  данными 00 минут. стереть старую запись и вновь записать данное

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

алгоритм

флаг=false;(до лупа)

если (минуты==0&&!флаг)

{

флаг=true;

запоминаемая_переменная=значение;

}

если (минуты!=0)флаг=false;

p.s. флаг нужен чтобы действие выполнялось 1 раз

kite
Offline
Зарегистрирован: 05.09.2016
    byte prevHour = 255; //значение не 0, чтобы произошло первое вхождение в if , т.к. время 0 часов существует. Можно любое из диапазона 25-255

    //ваши данные
    byte yourNewData =0; //новые данные
    byte yourPrevData = 0; //данные прошлого часа
    
// в loop()

    byte nowHour = dt.hour;
    byte nowMinutes = dt.minutes;
    
  if ( nowHour !=prevHour && nowMinutes == 0)
  {
      prevHour = nowHour; //после этого присвоения условие if (nowHour !=prevHour && nowMinutes == 0) для следующих миллисекунд, секунд этой минуты не выполнится, дальше ему помешает выполнится условие nowMinutes == 0
      
      //-------------работа с данными, ваш код--------------------
      yourNewData = //читаем откуда-то
      //сравниваем yourNewData и yourPrevData, что-то здесь делаем
      //--------------------------------------------------  
      
      yourPrevData = yourNewData; //готовимся к новому циклу через час
      
  }
С datetime не знаком. Не уверен, что dt.hour является byte.
gulin176
Offline
Зарегистрирован: 03.09.2016
[code]
#include <DS3231.h>
#include <LiquidCrystal_I2C.h>
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
BME280 mySensor;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
DS3231 clock;
RTCDateTime dt;
byte prevHour = 255;
void setup()
{
  lcd.begin();
  mySensor.settings.commInterface = I2C_MODE;
  mySensor.settings.I2CAddress = 0x76;
  mySensor.settings.runMode = 3; //  3, Normal mode
  mySensor.settings.tStandby = 0; //  0, 0.5ms
  mySensor.settings.filter = 4; //  0, filter off
  mySensor.settings.tempOverSample = 1;
  mySensor.settings.pressOverSample = 1;
  mySensor.settings.humidOverSample = 1;
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  (mySensor.begin(), HEX);
  byte yourNewData = 0;
  byte yourPrevData = 0;
}
void loop()
{
  byte nowHour = dt.hour;
  byte nowMinutes = dt.minute;
  if ( nowHour != prevHour && nowMinutes == 0)
  {
    prevHour = nowHour;
    yourNewData = ((uint32_t)mySensor.readFloatPressure() / 100);
  }
  dt = clock.getDateTime();
  mySensor.readTempC();
  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print((uint32_t)mySensor.readFloatPressure() / 100);
  lcd.print(" Pa "); lcd.print(mySensor.readTempC());
  lcd.print("C");

  lcd.setCursor(3, 1);
  lcd.print((uint8_t)mySensor.readFloatHumidity());
  lcd.print(" % ");
  if (dt.hour >= 10) {
    lcd.setCursor(8, 1);
    lcd.print(dt.hour);
  }
  if (dt.hour >= 0 && dt.hour < 10) {
    lcd.setCursor(8, 1);
    lcd.print(0);
    lcd.setCursor(9, 1);
    lcd.print(dt.hour);
  }
  lcd.print(":");
  if (dt.minute >= 10) {
    lcd.setCursor(11, 1);
    lcd.print(dt.minute);
  }
  if (dt.minute >= 0 && dt.minute < 10) {
    lcd.setCursor(11, 1);
    lcd.print(0);
    lcd.setCursor(12, 1);
    lcd.print(dt.minute);
  }
  delay(5000);
}
[/code]

ругается на строчку yourNewData = ((uint32_t)mySensor.readFloatPressure() / 100);

ошибка: USPEH_BME280.ino: In function 'void loop()':

 
USPEH_BME280:34: error: 'yourNewData' was not declared in this scope
 
exit status 1
'yourNewData' was not declared in this scope
пробовал менять строчку по разному не помогает
Что хочу получить? сравнить показания давления за час назад и сейчас и выводить стрелочку(вверх вниз равно) в зависимости от сравнения
kite
Offline
Зарегистрирован: 05.09.2016

Jбъявление  нужно сделать не в строках 25 и 26, а перенести выше setup() (выше строки 12), чтобы они стали глобальными, т.е. доступными во всей программе. Так как вы написали, программе они видны только в функции setup() в строках 14-26. Ниже закрывающей фигурной скобки их уже нет. Они "уничтожены".

Т.к. .....readFloatPressure(), то yourNewData и yourPrevData можно объявить не byte, а float или double.(float yourNewData =0; float yourNewData =0; ). И их названия можно поменять на более осмысленные типа newPressure, prevPressure (ну или novoeDavlenie, predDavenie), вам будет проще через некоторое время вспомнить, что они означают.

 

gulin176
Offline
Зарегистрирован: 03.09.2016

решил посмотреть 

float prevHour = 255;
float novoeDavlenie = 0;
float predDavenie = 0;

с помощью 

Serial.print ((uint32_t)mySensor.readFloatPressure() / 100);
  Serial.print(dt.minute);
  Serial.print(prevHour);
  Serial.print(novoeDavlenie);
  Serial.print(predDavenie);

первая строчка пишет давление. Вторая смотрю минуты для перехода через 00 минут, минуты идут. В третьей при переходе через 00 записывается наступивший час. Следующие 2 строчки не заполняются, ждал 2 часа. видимо чтото поправить надо бы

kite
Offline
Зарегистрирован: 05.09.2016

Менять с byte на float prevHour было не обязательно:-) 

Исправьте это, и покажите, пожалуйста, всю программу. Сложно без этого ответить на ваш вопрос.

gulin176
Offline
Зарегистрирован: 03.09.2016
[code]
#include <DS3231.h>
#include <LiquidCrystal_I2C.h>
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
BME280 mySensor;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
DS3231 clock;
RTCDateTime dt;
byte prevHour = 255;
float novoeDavlenie = 0;
float predDavenie = 0;
void setup()
{
  lcd.begin();
  Serial.begin(9600);
  mySensor.settings.commInterface = I2C_MODE;
  mySensor.settings.I2CAddress = 0x76;
  mySensor.settings.runMode = 3; //  3, Normal mode
  mySensor.settings.tStandby = 0; //  0, 0.5ms
  mySensor.settings.filter = 4; //  0, filter off
  mySensor.settings.tempOverSample = 1;
  mySensor.settings.pressOverSample = 1;
  mySensor.settings.humidOverSample = 1;
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  (mySensor.begin(), HEX);
}
void loop()
{
  byte nowHour = dt.hour;
  byte nowMinutes = dt.minute;
  if ( nowHour != prevHour && nowMinutes == 0)
  {
    prevHour = nowHour;
    novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure() / 100);
  }
  if (novoeDavlenie > predDavenie )
  {
    lcd.setCursor(14, 1);
    lcd.print("0");
  }
  if (novoeDavlenie < predDavenie )
  {
    lcd.setCursor(14, 1);
    lcd.print("1");
  }
  if (novoeDavlenie = predDavenie )
  {
    lcd.setCursor(14, 1);
    lcd.print("2");
  }
  predDavenie = novoeDavlenie;
  dt = clock.getDateTime();
  mySensor.readTempC();
  lcd.clear();
  lcd.setCursor(2, 0);
  lcd.print((uint32_t)mySensor.readFloatPressure() / 100);
  lcd.print(" Pa "); lcd.print(mySensor.readTempC());
  lcd.print("C");

  lcd.setCursor(3, 1);
  lcd.print((uint8_t)mySensor.readFloatHumidity());
  lcd.print(" % ");
  if (dt.hour >= 10) {
    lcd.setCursor(8, 1);
    lcd.print(dt.hour);
  }
  if (dt.hour >= 0 && dt.hour < 10) {
    lcd.setCursor(8, 1);
    lcd.print(0);
    lcd.setCursor(9, 1);
    lcd.print(dt.hour);
  }
  lcd.print(":");
  if (dt.minute >= 10) {
    lcd.setCursor(11, 1);
    lcd.print(dt.minute);
  }
  if (dt.minute >= 0 && dt.minute < 10) {
    lcd.setCursor(11, 1);
    lcd.print(0);
    lcd.setCursor(12, 1);
    lcd.print(dt.minute);
  }
  Serial.print ((uint32_t)mySensor.readFloatPressure() / 100);
  Serial.print(dt.minute);
  Serial.print(prevHour);
  Serial.print(novoeDavlenie);
  Serial.print(predDavenie);
  delay(5000);
}
[/code]

не пойму как свернуть код чтобы места не занимал на странице форума столько

gulin176
Offline
Зарегистрирован: 03.09.2016

нашёл ошибку строчку predDavenie = novoeDavlenie; не туда воткнул

CADAS
Offline
Зарегистрирован: 30.05.2016

Прошу помощи в проверке и оптимизации кода.


#include <SoftwareSerial.h>
#include <Nextion.h>
#include "stDHT.h"
#include <Wire.h>
#include <BMP180.h>
DHT sens(DHT22); // Указать датчик DHT11, DHT21, DHT22
SoftwareSerial nextion(2, 3);// Nextion TX к контакту 2 и RX к контакту 3 из Arduino
Nextion myNextion(nextion, 9600); //создаем объект с именем myNextion с использованием последовательного порта nextion @ 9600 бит в секунду
boolean button1State;
boolean button2State;
boolean button3State;
boolean button4State;
#define RELAY1 8 // реле 1 к ПИН 8
#define RELAY2 9 // реле 2 к ПИН 9
BMP180  sensor;
String prevState="";

void setup() 
{
Serial.begin(9600);
myNextion.init();
sensor.begin();
delay(2000);// даем датчику DHT22 время ожить. 2 секунд достаточно!!!
pinMode(RELAY1, OUTPUT);//ПИН (8) к которому подключено первое реле объявляем как "выход"
digitalWrite(RELAY1, HIGH);// состояние "выключено"
pinMode(RELAY2, OUTPUT);//ПИН (9) к которому подключено второе реле объявляем как "выход"
digitalWrite(RELAY2, HIGH);// состояние "выключено"
pinMode(5, INPUT);// датчик DHT22 на ПИН 5 "выход"
digitalWrite(5, HIGH);// состояние "выключено"
}

void loop()
{
             // работаем с датчиком DHT22
int t = sens.readTemperature(5); // чтение температуры с датчика на пине 5 ( создаем переменную (t) в которую пишем температуру с датчика DHT22)
int h = sens.readHumidity(5);    // чтение влажности с датчика на пине 5 ( создаем переменную (h) в которую пишем влажность с датчика DHT22)
myNextion.setComponentText("t0", String(t));// выводим в текстовое поле "t0" на экране Nextion данные из переменной "t", в нашем случае данные температуры
myNextion.setComponentText("t1", String(h));// выводим в текстовое поле "t1" на экране Nextion данные из переменной "h", в нашем случае данные влажности
if ( t>=25 && prevState!="hot" )// если температура равна или больше 25 
{
myNextion.setComponentText("t2", "Жарко");// выводим в текстовое поле "t2" на экране Nextion слово "Жарко"
prevState="hot"; 
}
if ( t>=15 && t<25 && prevState!="optim" )// если температура равна или больше 15, но меньше 25  
{
myNextion.setComponentText("t2", "Оптимально");// выводим в текстовое поле "t2" на экране Nextion слово "Оптимально"
prevState="optim";
}
if ( t>0 && t<15 && prevState!="cold" )// если температура больше 0 но меньше 15 
{
myNextion.setComponentText("t2", "Прохладно");// выводим в текстовое поле "t2" на экране Nextion слово "Прохладно"
prevState="cold";
}
if ( t<= 0 && prevState!="veryCold"  )// если температура равно или меньше 0
{
myNextion.setComponentText("t2", "Холодно");// выводим в текстовое поле "t2" на экране Nextion слово "Холодно"
prevState="veryCold";
}

                 // работаем с датчиком BMP180
if(sensor.read())// если датчик BMP180 готов и с него поступают данные
{
int p = sensor.pres; // создаем переменную (p) в которую пишем давление с датчика BMP180 
myNextion.setComponentText("t3", String(p));// выводим в текстовое поле "t3" на экране Nextion данные из переменной "p", в нашем случае данные давления
}
else // если что-то не так
{
myNextion.setComponentText("t3", String ("HET OTBETA"));// выводим в текстовое поле "t3" на экране Nextion слово " НЕТ ОВЕТА"
}
delay(120000);// обновляем данные с датчиков через каждые 2 минуты!!!

             //Работаем с реле
String message = myNextion.listen(); //проверяем сообщение
if (message == "65 0 3 1 ffff ffff ffff") //  если пришло сообщение (в кавычках пишем код кнопки)
{
myNextion.buttonToggle(button1State, "b3", 0, 2);
digitalWrite(RELAY1,LOW); // Включаем реле 1 
}
if (message == "65 0 2 1 ffff ffff ffff") //  если пришло сообщение  (в кавычках пишем код кнопки)
{
myNextion.buttonToggle(button2State, "b2", 0, 2);
digitalWrite(RELAY1, HIGH);// Выключаем реле 1
}
if (message == "65 0 4 1 ffff ffff ffff") //  если пришло сообщение (в кавычках пишем код кнопки)
{
myNextion.buttonToggle(button1State, "b4", 0, 2);
digitalWrite(RELAY1,LOW); // Включаем реле 2 
}
if (message == "65 0 5 1 ffff ffff ffff") //  если пришло сообщение  (в кавычках пишем код кнопки)
{
myNextion.buttonToggle(button2State, "b5", 0, 2);
digitalWrite(RELAY1, HIGH);// Выключаем реле 2
}

}

 

kite
Offline
Зарегистрирован: 05.09.2016

Попробуйте убрать приведение к int32. Т.е. в строке 36 просто удалить (uint32_t). 

Upd. Раз заработало, не пробуйте :-) .

 

gulin176
Offline
Зарегистрирован: 03.09.2016

подскажите пожалуйста как работает строчка if ( nowHour != prevHour && nowMinutes == 0)

почему то в 

float novoeDavlenie = 0;

данные не равны novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure() / 100);

допустим в ((uint32_t)mySensor.readFloatPressure() / 100) давление 986

а float novoeDavlenie = 0; в мониторе порта показывает 946.00

такое ощущение что в 

float novoeDavlenie = 0;
  float predDavenie = 0;

 

пишет одно и тоже

P.S. наблюдал интересное, при переходе через 00 стало выводить в

Serial.print(novoeDavlenie);

  Serial.print(predDavenie);

реальные значения, но может минуту от силы в мониторе порта опять пишет 943.00943.00

kite
Offline
Зарегистрирован: 05.09.2016

В nowHour изначально ничего не записано. prevHour= 255. Перед сравнением if нужно записать  текущее значение часов в значение в nowHour, т.е. сделать, то что написано в строке 54. Перенесите строку 54 (  dt = clock.getDateTime();)выше 31.  Этим действием текущее время из часов записывается в структуру DT. После этого имеем:

prevHour=255; nowHour= текущее значение часов, допустим если сейчас 05:58:33, то в nowHour запишется число 5. В nowMinutes запишется 58.

Далее доходим до 

 if ( nowHour != prevHour && nowMinutes == 0)

У нас (5 !=255)Выполняется и (nowMinutes == 58)НЕвыполняется. && означает логическое "И". Вцелом условие НЕ выполняется, значит, то что в фигурных скобках ниже if не будет выполнено. Оно выполнится только в 06:00, когда 6 != 255 и 0==0. prevHour станет равно 6. Очередное сравнение 6!=6 Невыполняется и 0==0 выполняется. Ну или 6!=6 и 0!=1. В целом условие в if Не выполняется. И так будет продолжаться до (7!=6 и 0==0) которое наступит в 7:00.

Т.к. вам нужно все действия с дисплеем и давлением выполнять только при достижении этого условия, значит закрывающую фигурную скобку этого if нужно переносить в самый низ, т.е. строку 92. Там станет }}, где первая закрывает if, вторая loop.

kite
Offline
Зарегистрирован: 05.09.2016

Вместо print() пишите println() каждая переменная будет с новой строки.

gulin176
Offline
Зарегистрирован: 03.09.2016

строчку dt = clock.getDateTime(); 

поднял. скобку условия переносить вниз нельзя. перенес и все что ниже условия перестало работать. 

теперь в 

Serial.println(novoeDavlenie);
  Serial.println(predDavenie);
  Serial.println(prevHour);

пишет

0.00

0.00

255

что правильно я думаю и надо ждать накопления данных в Davlenie

kite
Offline
Зарегистрирован: 05.09.2016

Должно работать или нет - это только вам решать. Если хотите, чтобы опрос датчика и обновление на дисплее выполнялись каждые 5 секунд - не переносить, если раз в час - переносить.

gulin176
Offline
Зарегистрирован: 03.09.2016

может я сильно выразился, но если скобку условия опустить в низ то не в мониторе не на экране ничего нет. я это хотел сказать

kite
Offline
Зарегистрирован: 05.09.2016

Ну так и должно быть. Такой код. Обновление произойдет в 00 минут следующего часа.

Чтобы экран не был пустой, нужно принять некие меры, типа вывести  что-то на экран.

Каков желаемый алгоритм работы всей программы? На дисплее всегда отображается текущее давление, а символы 0, 1, 2 должны изменяться раз в час? Или обновление значения давленияч тоже раз в час?

CADAS
Offline
Зарегистрирован: 30.05.2016

Мой вопрос остался без ответа. 

Жаль.

gulin176
Offline
Зарегистрирован: 03.09.2016

"Каков желаемый алгоритм работы всей программы?"

чтобы тенденция изменения давления мерялась раз в час(00 минут это же условность)

"На дисплее всегда отображается текущее давление, а символы 0, 1, 2 должны изменяться раз в час?"

на дисплее кроме давления есть темперратура влажность время. время не эстетично если начнёт раз в час обновляться. влажность с температурой каждые 5 секунд конечно лишнее но хотя бы раз в 1 минуту

"Или обновление значения давления тоже раз в час?"

ну изменение давления не такая важная вещь чтобы мониторить часто, если тенденция изменения давления заработает можно и раз в час менять показания

кстати символы 0 1 2 это так заготовка что бы было видно что работает

а если скобку не отпускать до самого низа а закрыть условие так 

BME280 mySensor;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
DS3231 clock;
RTCDateTime dt;
byte prevHour = 255;
float novoeDavlenie = 0;
float predDavenie = 0;
void setup()
{
  lcd.begin();
  Serial.begin(9600);
  mySensor.settings.commInterface = I2C_MODE;
  mySensor.settings.I2CAddress = 0x76;
  mySensor.settings.runMode = 3; //  3, Normal mode
  mySensor.settings.tStandby = 0; //  0, 0.5ms
  mySensor.settings.filter = 4; //  0, filter off
  mySensor.settings.tempOverSample = 1;
  mySensor.settings.pressOverSample = 1;
  mySensor.settings.humidOverSample = 1;
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  (mySensor.begin(), HEX);
}
void loop()
{
  lcd.clear();
  dt = clock.getDateTime();
  byte nowHour = dt.hour;
  byte nowMinutes = dt.minute;
  if ( nowHour != prevHour && nowMinutes == 0)
  {
    prevHour = nowHour;
    novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure() / 100);
    predDavenie = novoeDavlenie;
  if (novoeDavlenie > predDavenie )
  {
    lcd.setCursor(15, 1);
    lcd.print("0");
  }
  if (novoeDavlenie < predDavenie )
  {
    lcd.setCursor(15, 1);
    lcd.print("1");
  }
  if (novoeDavlenie = predDavenie )
  {
    lcd.setCursor(15, 1);
    lcd.print("2");
  }
  }
  mySensor.readTempC();

не стал весь код вставлять а то и так "простыни" растут. принцип понятен, что верхнее условиеif ( nowHour != prevHour && nowMinutes == 0)  связать с условиями"0" "1" "2" 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

CADAS пишет:

Прошу помощи в проверке и оптимизации кода.

 

небольшая критика от новичка для новичка

1) прописывайте все пины через #define (у вас пин 5 датчика DHT), сделайте как с реле, потом удобнее при сборке будет. проводок не туда припаял, пин поменял и все...

2)по моему не нужно при чтении температуры писать пин в скобочках, пин задается при создании класса в 6 строке, либо у вас какая то библеотека другая (не как у меня)

3) В строках с 73 по 95 Вы читаете сообщения с экрана, я с данным экраном не работал поэтому могу предположить что это сообщения от сенсора. Код у Вас выполняется последовательно! А теперь представьте что вы нажали в тот момент, когда наш процессор спит 2 минуты в строке 70. получит ли ардуино ваше нажатие? я не знаю, но если и получит то отработает его через 2 минуты. выход-уйти от делая, то есть обновлять датчики хоть раз в 2 минуты (но DHT 22 можно хоть каждую секунду), а сообщение ждать постоянно. Посмотрите урок blink without delay. Это вообще та ступенька, на которой почти все новички спотыкаются. Чтобы програмировать ардуину нужно думать как ардуина :)

ну я так понимаю вы еще его нигде не крутили на железе? как закрутите будет видно, а вообще если работа Вас устраивает (как новичка) то хрен сней с оптимизацией (пока что).

 

p.s. посмотрите мой проект http://arduino.ru/forum/proekty/sistema-ventelyatsii-podvala-etyud-v-3-chastyakh-chast-1-teoriya

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

gulin176
Offline
Зарегистрирован: 03.09.2016

решил строчку novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure() / 100);

поднять выше if ( nowHour != prevHour && nowMinutes == 0)

чтобы не ждать час а заносить в float novoeDavlenie = 0;

данные сразу. а то получается надо ждать час первые данные ждать час вторые

P.S или я не верно решил?  каждые следующие то данные пойдут уже после 00

kite
Offline
Зарегистрирован: 05.09.2016

Подождите минут 30-40. Добрался до компьтера. Сейчас все сделаем.

kite
Offline
Зарегистрирован: 05.09.2016
Знаете в чем проблема?
44   if (novoeDavlenie = predDavenie )
45   {
46     lcd.setCursor(15, 1);
47     lcd.print("2");
48   }

В строке с if. Для проверки равенства нужно использовать оператор "==", а не "=".  Этим вы не сравнивали, а присваивали. Поэтому novoeDavlenie всегда должно было получаться 0.

Вторая ошибка:
lcd.clear()  в 25 строке. Его нужно удалить.
Удачи.
kite
Offline
Зарегистрирован: 05.09.2016

Ещё один совет. Вместо

27   byte nowHour = dt.hour;
28   byte nowMinutes = dt.minute;

на время отладки напишите

27   byte nowHour = dt.minute;
28   byte nowMinutes = dt.second;

Вместо часа вам придётся ждать минуту.

Когда отладите, вернете как было.

gulin176
Offline
Зарегистрирован: 03.09.2016

хочу вас отблагодарить за помощь. напишите номер яндекс деньги или киви закину немного

kite
Offline
Зарегистрирован: 05.09.2016

Если это предложение мне, то спасибо. Но не нужно. Суть простая. У меня был вопрос, я зарегистрировался, мне помогли. Спасибо ЕвгениюП. После у самого возникает желание помочь.

gulin176
Offline
Зарегистрирован: 03.09.2016

странно... жаль моя благодарность вам искренняя.

gulin176
Offline
Зарегистрирован: 03.09.2016

а посмотрите ещё. вот вторая строчка не делает новое и старое давление одинаковое?

novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure());
    predDavenie = novoeDavlenie;

просто всегда выполняется условие

if (novoeDavlenie == predDavenie )
    {
      lcd.setCursor(15, 1);
      lcd.print("\3");
    }

я уже в строке ((uint32_t)mySensor.readFloatPressure()) убрал /100 чтобы записывало 5 знаков. а 5 знаков меняются уже постоянно в разные напрвления. сделал обновление условия каждую минуту, однако всегда новое давление равно старому, что почти не возможно

#include <DS3231.h>
#include <LiquidCrystal_I2C.h>
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
byte vverh[8] =
{
  B00100,
  B01110,
  B11111,
  B00100,
  B00100,
  B00100,
  B00100,
};
byte vniz[8] =
{
  B00100,
  B00100,
  B00100,
  B00100,
  B11111,
  B01110,
  B00100,
};
byte ravno[8] =
{
  B11111,
  B00000,
  B11111,
  B00000,
  B11111,
  B00000,
  B11111,
};
BME280 mySensor;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
DS3231 clock;
RTCDateTime dt;
byte prevHour = 255;
float novoeDavlenie = 0;
float predDavenie = 0;
void setup()
{
  lcd.begin();
  lcd.createChar(1, vverh);
  lcd.createChar(2, vniz);
  lcd.createChar(3, ravno);
  mySensor.settings.commInterface = I2C_MODE;
  mySensor.settings.I2CAddress = 0x76;
  mySensor.settings.runMode = 3; //  3, Normal mode
  mySensor.settings.tStandby = 0; //  0, 0.5ms
  mySensor.settings.filter = 4; //  0, filter off
  mySensor.settings.tempOverSample = 1;
  mySensor.settings.pressOverSample = 1;
  mySensor.settings.humidOverSample = 1;
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  (mySensor.begin(), HEX);
}
void loop()
{
  dt = clock.getDateTime();
  byte nowHour = dt.minute;
  byte nowMinutes = dt.second;
  if ( nowHour != prevHour && nowMinutes == 0)
  {
    prevHour = nowHour;
    novoeDavlenie  = ((uint32_t)mySensor.readFloatPressure());
    predDavenie = novoeDavlenie;
    if (novoeDavlenie > predDavenie )
    {
      lcd.setCursor(15, 1);
      lcd.print("\1");
    }
    if (novoeDavlenie < predDavenie )
    {
      lcd.setCursor(15, 1);
      lcd.print("\2");
    }
    if (novoeDavlenie == predDavenie )
    {
      lcd.setCursor(15, 1);
      lcd.print("\3");
    }
  }
  mySensor.readTempC();

вы выше писали"yourPrevData = yourNewData; //готовимся к новому циклу через час" а не происходит ли эта строчка сразу. может ей надо условие типа дождаться 59 секунды(минуты) и тогда сменить старое на новое

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

у вас новое давление всегда равно старому потому что вы их приравниваете в строке 69. Попробуйте поменять строки 68 и 69 местами, тогда у вас сначало сохранится старое давление, потом с датчика считается новое

gulin176
Offline
Зарегистрирован: 03.09.2016

супер, сработали все 3 варианта событий

kite
Offline
Зарегистрирован: 05.09.2016
68   

Совет по типам переменных

Раньше я предложил использовать тип переменных давления float. Причиной этому стало название функции readFloatPressure. Судя по ее названию, эта функция возвращает тип float. Но в вашем коде текстом (uint32_t) производится преобразование к целому типу. Потом этот целый тип неявно приводится к float.

Получается, что читается из датчика значение с высокой точность (float). Затем точное значение приводим к целочисленному типу uint32, точность снижается путём отбрасывания знаков после запятой. А потом мы опять зачем-то записываем целочисленное значение в переменную, которая имеет тип с плавающей точкой (float novoeDavlenie). Оно то и работает, ошибки здесь нет, но явно что-то лишнее.

Вариантов два.

1.Использовать в программе значение давления с высокой точностью. Тогда не нужно производить преобразование к целочисленному типу

novoeDavlenie  = mySensor.readFloatPressure()/100;

 

2й вариант. Использовать целочисленные значения.  Для этого объявить novoeDavlenie и predDavlenie не float, а long. 

06 long novoeDavlenie = 0;
07 long predDavenie = 0;

Я бы предпочел второй вариант.

Кроме того. Судя по тому, что я прочитал о модуле bme280, значение давления он выдаёт в паскалях. Лично мне удобнее и понятнее атмосферное давление в мм ртутного столба. Если и для вас так же, и появится необходимость отобразить значение давления, то его при чтении из датчика можно сразу перевести в мм. рт. ст. Для второго варианта с целыми типами это выглядеть может так:

novoeDavlenie  = (uint32_t)(mySensor.readFloatPressure()*0,0075);

 

Upd.2. Значение атмосферного давления в мм,рт.ст. врядли превысит хотя бы 800. Значит тип long избыточен. Хватит и int.

 
06 int novoeDavlenie = 0;
07 int predDavenie = 0;

Тогда 

32     novoeDavlenie  = (int)(mySensor.readFloatPressure() * 0.0075);

 

gulin176
Offline
Зарегистрирован: 03.09.2016

вынес в отдельную программу кусок отвечающий за "тенденцию", запустил работает. вставляю в целую программу не работает. подумал И если вместо byte nowMinutes = dt.minute; вставить byte nowMinutes = dt.second; для отладки то условие if ( nowHour != prevHour && nowMinutes == 0) не выполнимо, поймать 00 секунд для выполнения условия почти невозможно. внизу всего кода же стоит delay для того чтобы данные не выводились слишком часто. попробовал без delay совсем. заработало но надо как то округлять показания влажности и температуры чтобы цифры не мельтешили. давление в мм,рт.ст не интересует. дома метеостанция орегон уже несколько лет и она показывает в паскалях. привык и мм,рт.ст мне уже ничего не говорят

kite
Offline
Зарегистрирован: 05.09.2016

Это предложение касалось только отладки кода которое выполняется раз в час. Использовать это для всей программы тоже можно, но названные неудобства будут присутствовать. Чуть улучшить можно временно уменьшив delay до значения меньше 1 секунды, например delay(500).

Округлять значения не нужно.

lcd.print((uint8_t)mySensor.readFloatHumidity());

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

CADAS
Offline
Зарегистрирован: 30.05.2016

Mr.Privet пишет:

CADAS пишет:

Прошу помощи в проверке и оптимизации кода.

 

небольшая критика от новичка для новичка

1) прописывайте все пины через #define (у вас пин 5 датчика DHT), сделайте как с реле, потом удобнее при сборке будет. проводок не туда припаял, пин поменял и все...

2)по моему не нужно при чтении температуры писать пин в скобочках, пин задается при создании класса в 6 строке, либо у вас какая то библеотека другая (не как у меня)

3) В строках с 73 по 95 Вы читаете сообщения с экрана, я с данным экраном не работал поэтому могу предположить что это сообщения от сенсора. Код у Вас выполняется последовательно! А теперь представьте что вы нажали в тот момент, когда наш процессор спит 2 минуты в строке 70. получит ли ардуино ваше нажатие? я не знаю, но если и получит то отработает его через 2 минуты. выход-уйти от делая, то есть обновлять датчики хоть раз в 2 минуты (но DHT 22 можно хоть каждую секунду), а сообщение ждать постоянно. Посмотрите урок blink without delay. Это вообще та ступенька, на которой почти все новички спотыкаются. Чтобы програмировать ардуину нужно думать как ардуина :)

ну я так понимаю вы еще его нигде не крутили на железе? как закрутите будет видно, а вообще если работа Вас устраивает (как новичка) то хрен сней с оптимизацией (пока что).

 

p.s. посмотрите мой проект http://arduino.ru/forum/proekty/sistema-ventelyatsii-podvala-etyud-v-3-chastyakh-chast-1-teoriya

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


Вы правы. Работает, причем так как нужно.
На железе все тестил, кроме bmp( еще в пути).
Да я это так, просто... может чаво проще можно сделать.

gulin176
Offline
Зарегистрирован: 03.09.2016

данная строка LEDbrightness = map(photocellReading, 0, 1023, 0, 255);

соответствует чёрному графику. так как в данном конкретном случае показатель 1023 не достижим. возможно ли построить зелёный график с помощью функции map

nevkon
Offline
Зарегистрирован: 20.01.2015

Можно любой линейный. Вот описание команды: http://arduino.ru/Reference/Map

Как именно менять решать вам. Что будет при выходе из указанного диапазона не знаю.

gulin176
Offline
Зарегистрирован: 03.09.2016

вместо 1023 поставить 511(например) и пропорция будет не 1/4 а 1/2