Часы+метео. Как "прикрутить" биппер?

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Подскажите пожалуйста,как в этот скетч прикрутить подачу сигнала каждый полный час? Например:12.00-бип,бип , 13.00-бип,бип и т.д. каждый час? Обратите внимание на строки 56-62. Это я пытался сделать самостоятельно, но у меня не получилось т.к. я только учусь =)


// Ds 3231 + BMP 085 + LCD 16*2
// Время,дата,температура,давление

#include <Wire.h>
#include <BMP085.h>
#include <LCD.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
int Beeper = 4;

void setup () {
  Serial.begin(57600);
  Wire.begin();
  rtc.begin();
  pinMode(Beeper, OUTPUT);

 dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
 

  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  
}

void loop() {
  

   if (((millis() - time1)/1000.0) >= 1.0) {     
   dps.calcTrueTemperature();
   time1 = millis();      
  }
  {
  dps.getPressure(&Pressure);
  dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)

  lcd.setCursor(0, 1);
  lcd.print("t ");
  lcd.setCursor(2,1);
  lcd.print(Temperature*0.1-0.8,1); 
  
// пеатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  
}
/*  void();
  {
  if (now.minute)==0 and (now.second)==0;  
  tone(Beeper,2000,100);  
  delay(200);
  tone(Beeper,2000,100);
  } */
  
  digitalClockDisplay();  
  delay(200);
}
  // пеатаем часы,минуты,секунды

  void digitalClockDisplay(){
  DateTime now = rtc.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 

  lcd.setCursor(3, 0); 
  printDigits(now.minute());
 
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
  //рисуем разделители
  
  lcd.setCursor(13, 0);
  lcd.print(".");
  
  lcd.setCursor(2, 0);
  lcd.print(":");
  
  lcd.setCursor(5, 0);
  lcd.print(".");
  
  //рисуем число и месяц
  
  lcd.setCursor(9, 0);
  lcd.print("d ");
  lcd.setCursor(11, 0);
  printDigits(now.day());

  //рисуем месяц

  lcd.setCursor(14, 0);
  printDigits(now.month());

}

  void printDigits(int digits){
  // utility function for digital clock display:
  // prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
bwn
Offline
Зарегистрирован: 25.08.2014

Во первых, здесь нет оператора "and", а есть "&&". Во вторых, посмотрите синтаксис оператора "if". Отдельная функция здесь не требуется, вставьте это в loop после 64 строки. С функцией "tone" не работал, не знаю насколько правильно записано.

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

Udav4ik
Offline
Зарегистрирован: 13.10.2015

and исправил, void убрал и вставил в loop, tone проверял, все работает нормально, ошибка с условием.Без строки 

if (now.minute)==0 && (now.second)==0;

бипер пищит, но только непрерывно. Вот , что пишет Arduino ide

Arduino: 1.6.7 Hourly Build 2015/11/13 05:42 (Windows 7), Плата:"Arduino/Genuino Uno"
 
C:\Users\A4F7~1\AppData\Local\Temp\arduino_dbc6bf2298511009908427285247f8d9\Weather_Station_Beep.ino: In function 'void loop()':
 
Weather_Station_Beep:38: error: 'now' was not declared in this scope
 
   if (now.minute)==0 && (now.second)==0  
 
       ^
 
Weather_Station_Beep:38: error: expected primary-expression before '==' token
 
   if (now.minute)==0 && (now.second)==0  
 
                  ^
 
Weather_Station_Beep:39: error: expected ';' before 'tone'
 
   tone(Beeper,2000,100);  
 
   ^
 
exit status 1
'now' was not declared in this scope
 
bwn
Offline
Зарегистрирован: 25.08.2014

Попробуйте этот кусок после 90 строки вставить. И записать в проверке условия как (now.hour())

Udav4ik
Offline
Зарегистрирован: 13.10.2015

вставил, все равно ошибку выдает

: In function 'void digitalClockDisplay()':
 
Weather_Station_Beep:91: error: expected primary-expression before '==' token
 
   if (now.hour())==0;  
 
                  ^
exit status 1
expected primary-expression before '==' token
 
Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

==0 внесите внутрь условия

bwn
Offline
Зарегистрирован: 25.08.2014

Обратите внимание на пост 5 и еще раз "Во вторых, посмотрите синтаксис оператора "if"." Условие остается ваше, минуты и секунды. Я имел в виду обертывание их скобками.

Udav4ik
Offline
Зарегистрирован: 13.10.2015
 Пробовал так

 if ((now.minute)==0) && ((now.second)==0)
  {  
  tone(Beeper,2000,100);  
  delay(200);
  tone(Beeper,2000,100);
  }

так

  if ((now.minute)==0) && ((now.second)==0) ;
   tone(Beeper,2000,100);  
  delay(200);
  tone(Beeper,2000,100);
  }

и так

  if (now.minute==0) && (now.second==0)
  {  
  tone(Beeper,2000,100);  
  delay(200);
  tone(Beeper,2000,100);
  }
судя по описанию оператора if
​
if (someVariable > 50)
{
// выполнять действия
}

правильным должен быть вариант первый и второй

но во всех случаях выдает одну и ту же ошибку:

: In function 'void loop()':
 
Weather_Station_Beep:56: error: 'now' was not declared in this scope
 
   if ((now.minute)==0) && ((now.second)==0)
 
        ^
 
Weather_Station_Beep:56: error: expected identifier before '(' token
 
   if ((now.minute)==0) && ((now.second)==0)
 
                           ^
 
Weather_Station_Beep:56: error: expected ';' before '(' token
 
exit status 1
'now' was not declared in this scope
 
подскажите пожалуйста, что ей еще надо? Куда ей надо вставить ";"?
 

 

Araris
Offline
Зарегистрирован: 09.11.2012

Надо вынести объявление DateTime now; в самый верх скетча, перед void setup().

Затем в функции void digitalClockDisplay() строку DateTime now = rtc.now(); исправить на now = rtc.now();

Ну и с обертыванием скобками стоило бы разобраться наконец.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Есть прогресс! Спасибо.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Большое спасибо всем за помощь, особенно Araris. Со времен бейсика не занимался такими задачками, но все заработало, хотя и не совсем так, как я себе представлял. Биппер почему то выдает 4 сигнала, вместо 2 или одного, как я прописал в скетче. Не могу понять причину, ставил команду noTone, после двух сигналов, оставлял всего 1 строку tone(Beep), сигнал срабатывает на 4 бипа. Только delay как то на него влияет и при некоторх значениях он выдает 3 бипа. Двух сигналов добиться не могу.

// Ds 3231 + BMP 085 + LCD 16*2
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;

void setup () {
  Serial.begin(57600);
  Wire.begin();
  rtc.begin();
  
dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
 
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  
}

void loop() {
  
   if (((millis() - time1)/1000.0) >= 1.0) {     
   dps.calcTrueTemperature();
   time1 = millis();      
  }
  {
  dps.getPressure(&Pressure);
  dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)

  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
  
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);   
}
  digitalClockDisplay();  
  delay(200);
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {

  now = rtc.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
//сигнал биппера

  if ((now.minute()==0) && (now.second()==0))
  {
  tone(Beeper,2000,100); 
  delay(150);
  }
         
//печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
  
//рисуем разделители
     
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

}

void printDigits(int digits){
  // utility function for digital clock display:
  // prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper#comment-151995 */

 

Araris
Offline
Зарегистрирован: 09.11.2012

Сделайте так, чтобы функция digitalClockDisplay(); не вызывалась  при каждом проходе loop. Переместите строку 52 между 33-й и 34-й, пусть раз в секунду по таймеру вызывается.

Кстати, строки 37-50 тоже туда же неплохо бы переместить.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

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

// Ds 3231 + BMP 085 + LCD 16*2
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;

void setup () {
  Serial.begin(57600);
  Wire.begin();
  rtc.begin();
  
dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
 
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  
}

void loop() {
  
   if (((millis() - time1)/1000.0) >= 1.0) {     
   dps.calcTrueTemperature();
   digitalClockDisplay();  
   delay(100);     
   dps.getPressure(&Pressure);
   dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)

  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
  
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  
  time1 = millis(); 
  }
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {

  now = rtc.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
//сигнал биппера

  if ((now.minute()==0) && (now.second()==0))
  {
  tone(Beeper,2000,100); 
  delay(150);
  tone(Beeper,2000,100); 
  delay(150);
  }
         
//печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
  
//рисуем разделители
     
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

}

void printDigits(int digits){
  // utility function for digital clock display:
  // prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper#comment-151995 */

 

Araris
Offline
Зарегистрирован: 09.11.2012

Udav4ik пишет:

Отрисовка секунд стала не корректно работать, перескакивает периодически через секунду, но это мелочи, я примерно понимаю, почему это происходит.

В строке 32 сделайте немного меньший промежуток времени, тогда периодически перескакивать перестанет. Правда возникнет другая проблема - периодически бипер будет по два раза отрабатывать. Тут или изощряться надо, или выходить на качественно новый подход.

Araris
Offline
Зарегистрирован: 09.11.2012

А давайте-ка расскажу один из способов:

Идея - отслеживать изменение значения, например, секунды. Для этого заводим в самом начале скетча некую переменную, например, uint8_t currentSecond; 

А дальше, вот этот кусок скетча

//сигнал биппера

  if ((now.minute()==0) && (now.second()==0))
  {
  tone(Beeper,2000,100); 
  delay(150);
  tone(Beeper,2000,100); 
  delay(150);
  }

переделаем вот так

//сигнал биппера
  if ((now.minute()==0) && (now.second()==0))
  {
  if (now.second() != currentSecond) // проверяем, изменилось ли значение секунды
    {
    // то есть, в течение одной секунды этот кусок скетча
    // теперь можно вызывать сколько угодно раз, но исполнится
    // код только самый первый раз, при последующих (в эту секунду)
    // вызовах условие не будет выполняться вплоть до наступления 
    // следующей секунды.
    tone(Beeper,2000,100); 
    delay(150);
    tone(Beeper,2000,100); 
    delay(150);
    }
  }
 currentSecond = now.second(); // тут мы постоянно запоминаем текущее значение секунды.

Теперь идём ещё дальше. А зачем вообще нам минуты и секунды, если стоит задача сигналить каждый час ? Можно просто сделать отслеживание изменения значения часа.

Объявляем в начале скетча переменную uint8_t currentHour;

  if (now.hour() != currentHour) // проверяем, изменилось ли значение
    {

    // тут помещаем всё, что хотим делать один раз после изменения значения

    }
 сurrentHour = now.hour(); // тут мы постоянно запоминаем текущее значение.

 

 

Udav4ik
Offline
Зарегистрирован: 13.10.2015

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

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Переделал условие срабатывания сигнала , привязав к часу, как вы написали, сделав все за меня, спасибо =), уменьшил задержку вывода на дисплей, перебои с отрисовкой секунд стали реже, но не исчезли. Причем уменьшал delay до 0.1 мс , но секунды-это не критично, главное бипер срабатывает четко 2 раза и не сбоит если даже пауза между бипами 50 мс , этого я и добивался обращаясь к Вам за помощью. Назрел следущий вопрос-как правильно соеденить два рабочих скетча ? Какие будут Ваши советы, что выкинуть лишнего или может , что то нужно добавить? Скетч не мой, взял в другой ветке, кое что только подправил, скорее интуитивно, чем четко понимая все тонкости его работы. Но проверил на "железе", все работает, хотелось бы правильно соеденить их функции.

P.S. Хорошая штука эта Ардуино, жаль, что раньше таких возможностей не было.

/*Готовая версия контроллера я рад)
 * Роман Четин
 */

//Загрузка библиотек 
#include <OneWire.h>
#include <Wire.h>
#include <RTClib.h>

int TSensorPin1 = 2;
int TSensorPin2 = 3;
OneWire ds1(TSensorPin1);
OneWire ds2(TSensorPin2);

RTC_DS1307 RTC;
//Подключение выходов
const int RelayChn1 = 5;        //Используем цифровой ПОРТ 5  для ПЕРВОГО    канала релейного модуля
const int RelayChn2 = 6;        //Используем цифровой ПОРТ 6  для ВТОРОГО    канала релейного модуля
const int RelayChn3 = 7;        //Используем цифровой ПОРТ 7  для ТРЕТЬЕГО   канала релейного модуля
const int RelayChn4 = 8;        //Используем цифровой ПОРТ 8  для ЧЕТВЕРТОГО канала релейного модуля
const int RelayChn5 = 9;        //Используем цифровой ПОРТ 9  для ПЯТОГО     канала релейного модуля
const int RelayChn6 = 10;       //Используем цифровой ПОРТ 10 для ШЕСТОГО    канала релейного модуля
const int RelayChn7 = 11;       //Используем цифровой ПОРТ 11 для СЕДЬМОГО   канала релейного модуля
const int RelayChn8 = 12;       //Используем цифровой ПОРТ 12 для ВОСЬМОГО   канала релейного модуля
#define sc 1UL
#define mn 60UL
#define hr 3600UL

//----------Настройки времени и продолжительности включения реле

//----------Первый канал  LED 5ШТ.*10ВТ. Реле №3 ------------
//----------Первый канал_Первый период  ----------------------
const long StartRelCn_1 = 8*hr+00*mn+00*sc;        //ВРЕМЯ срабатывания на ПЕРВОМ канале релейного модуля
const long DurationCh_1 = 2*hr+00*mn+00*sc;        //ДЛИТЕЛЬНОСТЬ срабатывания реле на ПЕРВОМ канале
//----------Первый канал_Второй период  ----------------------
const long StartRelCn_1L = 11*hr+00*mn+00*sc;               
const long DurationCh_1L = 4*hr+00*mn+00*sc;
//----------Первый канал_Третий период  ----------------------
const long StartRelCn_1G = 17*hr+00*mn;               
const long DurationCh_1G = 5*hr+00*mn;
//----------Первый канал_Четвертый период   ------------------
const long StartRelCn_1R = 2*hr+30*mn;
const long DurationCh_1R = 0*hr+00*mn;

//----------Второй канал   LED 7ШТ.*10ВТ. Реле №4 ------------
const long StartRelCn_2 = 10*hr+00*mn+00*sc;                    
const long DurationCh_2 = 7*hr+00*mn+00*sc;     
              
//----------Третий канал   LED (24 BLUE+10 RED)*3ВТ. Реле №5 ----
const long StartRelCn_3 = 7*hr+30*mn+00*sc;                      
const long DurationCh_3 = 15*hr+00*mn+00*sc;    
                 
//----------Четвертый канал CO2   Реле №2 --------------
const long StartRelCn_4 = 9*hr+00*mn+00*sc;                     
const long DurationCh_4 = 12*hr+00*mn+00*sc;            

//----------Пятый канал   Удобрения  Реле №1 ------------
const long StartRelCn_5 = 10*hr;                
const long DurationCh_5 = 30*sc;          
          
//----------Шестой канал   Кормушка  ---------------------
const long StartRelCn_6 = 9*hr;                    
const long DurationCh_6 = 0*hr;         
           
//----------Терморегуляторы

//----------Седьмой КАНАЛ----------------------------
float t1 = 24.5;                                     //Уставка температуры для СЕДЬМОГО канала релейного модуля 1 аквариум
float tGistrsis1 = 0.7;                              //Уставка гистерезиса - т.е отклонения от темп-ры уставки т.е. в данном случае 0,7 = плюс минус 0,35 градуса

//----------Восьмой КАНАЛ----------------------------
float t2 = 24.5;                                     //Уставка температуры для ВОСЬМОГО канала релейного модуля 2 аквариум
float tGistrsis2 = 0.7;               
//*********************************************************


void setup () {
  Wire.begin();            
  RTC.begin();
   //  RTC.adjust(DateTime(__DATE__, __TIME__)); // строка только для первой компиляции!!!
  DateTime myTime = RTC.now();

  //Первоначальные установки выходов
    pinMode(RelayChn1,OUTPUT);                       //Инициализируем порт для 1 канала как ВЫХОД
    pinMode(RelayChn2,OUTPUT);                       //Инициализируем порт для 2 канала как ВЫХОД   
    pinMode(RelayChn3,OUTPUT);                       //Инициализируем порт для 3 канала как ВЫХОД  
    pinMode(RelayChn4,OUTPUT);                       //Инициализируем порт для 4 канала как ВЫХОД
    pinMode(RelayChn5,OUTPUT);                       //Инициализируем порт для 5 канала как ВЫХОД   
    pinMode(RelayChn6,OUTPUT);                       //Инициализируем порт для 6 канала как ВЫХОД 
    pinMode(RelayChn7,OUTPUT);                       //Инициализируем порт для 7 канала как ВЫХОД
    pinMode(RelayChn8,OUTPUT);                       //Инициализируем порт для 8 канала как ВЫХОД   
   
    digitalWrite(RelayChn1,LOW);                    //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень 
    digitalWrite(RelayChn2,LOW);                    //Т.к. используемый релейный модуль с опторазвязкой - управляется инверсной логикой 
    digitalWrite(RelayChn3,LOW);                       
    digitalWrite(RelayChn4,LOW);                   
    digitalWrite(RelayChn5,LOW);                    
    digitalWrite(RelayChn6,HIGH);                     
    digitalWrite(RelayChn7,LOW);                   
    digitalWrite(RelayChn8,LOW);                   
 }
//***************************************************
void loop () {
  DateTime myTime = RTC.now();
  uint32_t utime = myTime.unixtime();
  utime %=86400;
  
//----------------------------релейная настройка начало------------------
    if ((utime >= StartRelCn_1) &&              
       (utime < (StartRelCn_1+DurationCh_1)) or (utime >= StartRelCn_1L) && 
       (utime < (StartRelCn_1L+DurationCh_1L))  or (utime >= StartRelCn_1G) && 
       (utime < (StartRelCn_1G+DurationCh_1G))  or (utime >= StartRelCn_1R) &&
       (utime < (StartRelCn_1R+DurationCh_1R)))
   
      {
          digitalWrite(RelayChn1,LOW);             //Устанавливаем на входе ПЕРВОГО реле НИЗКИЙ уровень - реле срабатывает
        
       }  
    else
      {
          digitalWrite(RelayChn1,HIGH);             //Устанавливаем на входе ПЕРВОГО реле ВЫСОКИЙ уровень - реле выключается
         
      } 

    //------------КАНАЛ 2 ------------------------------
    if ((utime >= StartRelCn_2) && 
       (utime < (StartRelCn_2+DurationCh_2)))
      {
        digitalWrite(RelayChn2,LOW);                 //Устанавливаем на ВТОРОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
        
      }  
    else
      {
          digitalWrite(RelayChn2,HIGH);              //Устанавливаем на ВТОРОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
         
      } 

//------------КАНАЛ 3------------------------------
    if ((utime >= StartRelCn_3) && 
       (utime < (StartRelCn_3+DurationCh_3)))
      {
          digitalWrite(RelayChn3,LOW);               //Устанавливаем на ТРЕТЬЕМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
        
      }  
    else
      {
          digitalWrite(RelayChn3,HIGH);              //Устанавливаем на ТРЕТЬЕМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
          
      } 
//------------КАНАЛ 4------------------------------
    if ((utime >= StartRelCn_4) && 
       (utime < (StartRelCn_4+DurationCh_4)))
      {
          digitalWrite(RelayChn4,LOW);               //Устанавливаем на ЧЕТВЕРТОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
         
      }  
    else
      {
          digitalWrite(RelayChn4,HIGH);              //Устанавливаем на ЧЕТВЕРТОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
          
      } 
//------------КАНАЛ 5------------------------------
    if ((utime >= StartRelCn_5) && 
       (utime < (StartRelCn_5+DurationCh_5)))
      {
          digitalWrite(RelayChn5,LOW);               //Устанавливаем на ПЯТОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
         
      }  
    else
      {
          digitalWrite(RelayChn5,HIGH);              //Устанавливаем на ПЯТОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
         
      } 
//------------КАНАЛ 6------------------------------
    if ((utime >= StartRelCn_6) && 
       (utime < (StartRelCn_6+DurationCh_6)))
      {
          digitalWrite(RelayChn6,HIGH);               //Устанавливаем на ШЕСТОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
        
      }  
    else
      {
          digitalWrite(RelayChn6,LOW);              //Устанавливаем на ШЕСТОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
        
      } 
 //------------КАНАЛ 7 Контроль температуры -------
     float temp1 = getTemp1();                          //Читаем температуру с датчика 

    if (temp1 < t1-tGistrsis1/2)
      {
        digitalWrite(RelayChn7,LOW);                 //Устанавливаем на 7 входе релейного модуля НИЗКИЙ уровень - реле срабатывает
      
      }     
    else if (temp1 > t1+tGistrsis1/2)
      {
        digitalWrite(RelayChn7,HIGH);                //Устанавливаем на 7 входе релейного модуля ВЫСОКИЙ уровень - реле выключается
      
      }     
      
//------------КАНАЛ 8 Контроль температуры -----------
   float temp2 = getTemp2();                          //Читаем температуру с датчика 
  
    //------------КАНАЛ 3 Контроль температуры -------
    if (temp1 < t1-tGistrsis2/2)
      {
        digitalWrite(RelayChn8,LOW);                 //Устанавливаем на 8 входе релейного модуля НИЗКИЙ уровень - реле срабатывает
     
      }     
    else if (temp2 > t2+tGistrsis2/2)
      {
        digitalWrite(RelayChn8,HIGH);                //Устанавливаем на 8 входе релейного модуля ВЫСОКИЙ уровень - реле выключается

      }
}
//*****************************************************
//Функции чтения с датчиков температуры
float getTemp1(){                                       
  byte data[12];
  byte addr[8];
  if ( !ds1.search(addr)) {
    //no more sensors on chain, reset search
    ds1.reset_search();
    return -1001;  
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {

    return -1002;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {

    return -1003;
  }

  ds1.reset();
  ds1.select(addr);
  ds1.write(0x44,1); 

  byte present = ds1.reset();
  ds1.select(addr); 
  ds1.write(0xBE); 


  for (int i = 0; i < 9; i++) { 
    data[i] = ds1.read();
  }

  ds1.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;

  return Temperature;
}
float getTemp2(){                                       
  byte data[12];
  byte addr[8];
  if ( !ds2.search(addr)) {
    //no more sensors on chain, reset search
    ds2.reset_search();
    return -1001;  
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {

    return -1002;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {

    return -1003;
  }

  ds2.reset();
  ds2.select(addr);
  ds2.write(0x44,1); 

  byte present = ds2.reset();
  ds2.select(addr); 
  ds2.write(0xBE); 


  for (int i = 0; i < 9; i++) { 
    data[i] = ds2.read();
  }

  ds2.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;

  return Temperature;
}
// Ds 3231 + BMP 085 + LCD 16*2
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;
uint8_t currentHour;

void setup () {
  Serial.begin(57600);
  Wire.begin();
  rtc.begin();
  
dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
 
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  
}

void loop() {
  
   if (((millis() - time1)/1000.0) >= 1.0) {     
   dps.calcTrueTemperature();
   digitalClockDisplay();  
   delay(10);     
   dps.getPressure(&Pressure);
   dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)

  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
  
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  
  time1 = millis(); 
  }
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {

  now = rtc.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
//сигнал биппера

//  if ((now.minute()==0) && (now.second()==0))
    if (now.hour() != currentHour)
  {
  tone(Beeper,2000,100); 
  delay(150);
  tone(Beeper,2000,100); 
  delay(150);
  }
  currentHour = now.hour();
         
//печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
  
//рисуем разделители
     
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

}

void printDigits(int digits){
  // utility function for digital clock display:
  // prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper... */

 

Araris
Offline
Зарегистрирован: 09.11.2012

Я всего лишь пытался объяснить суть одного из приёмов программирования, писать скетчи за Вас - это вряд ли.

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

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

Я обычно делаю так.

Есть ещё одна причина, почему сливать придётся самому - Вы единственный, кто знает, что выкинуть, что добавить, и что же должно получиться в результирующем скетче ))

bwn
Offline
Зарегистрирован: 25.08.2014

Немного добавлю, к сказанному уважаемым Araris. Сперва внимательно просмотрите оба кода, попытайтесь определить, что в них есть хорошо, а что желательно подправить. Далее нарисуйте себе алгоритм работы вашего девайса и разбейте его на самодостаточные задачи. После чего, каждую такую задачу пытаемся описать отдельной функцией. В итоге получаем достаточно компактный loop, в котором проверяем условия и вызываем нужные нам функции.
Удобство метода, в каждый момент времени мы отлаживаем только одну функцию и больше ее не трогаем. Значительно снижается риск ошибок (если бы все работало в loop) и получается модульная наращиваемая система.
Как пример, в вашем коде есть задание временных интервалов через скетч. На начальном этапе для запуска девайса этого достаточно, но завтра возможно захочется менять эти значения кнопками из меню. Если это останется в основном цикле, придется фактически переписывать всю программу. В виде функции - только переписать ее и корректно вернуть переменные. ИМХО.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

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

Udav4ik
Offline
Зарегистрирован: 13.10.2015

И Вам спасибо, ув.bwn. Такой алгоритм нормальный или нет?

1 Снятие показания часов ds3231
2 Снятие показаний датчиков
а)ds18b20
в)вмр 085
3 Вывод на экран
4 Срабатывания реле

 

 

bwn
Offline
Зарегистрирован: 25.08.2014

Не совсем: Я хочу, чтобы мой девас делал: Отсчитывал время, измерял температуру, измерял давление, выводил значения на экран, что то делал еще..... Для этого мне понадобится: МК с обвязкой, LCD, RTC ...... Для управления всем этим требуется: два аналоговых выхода для I2C (ими смогу управлять RTC, BMP, LCD), восемь цифровых выходов на реле, один цифровой вход для DS18B20 (кстати рекомендую их вешать на один пин) и т.д. После, поняв, что входов-выходов данного МК хватает для хотелок можно переходить к программной части.
Для начала эксплуатации начинаем с дисплея и часов. Пишем-отлаживаем функцию вывода на дисплей (сразу прикидываем, будет все на одном экране или придется менять информацию) и так последовательно вводим новые функции. Для симуляции работы датчиков на начальном этапе, можем зарезервировать под них переменные с требуемым типом и присвоить им какие то значения.

bwn
Offline
Зарегистрирован: 25.08.2014

По литературе, У.Соммер "Программирование ......." это совсем для начала. Далее Керниган и Ричи "Язык С", это уже серьезнее.
Может кто еще что подкинет.

Udav4ik
Offline
Зарегистрирован: 13.10.2015
// Таймер+Ds3231+BMP085+Ds18b20+LCD16*2(по i2c)
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <OneWire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;
uint8_t currentHour;
int TSensorPin1 = 2;
int TSensorPin2 = 3;
OneWire ds1(TSensorPin1);
OneWire ds2(TSensorPin2);

int inPin = 13;
const int keyPin = 13;  // кнопка на порт 13
 
// Подключение выходов
const int RelayChn1 = 5;   // порт 5  для 1 канала реле
const int RelayChn2 = 6;   // порт 6  для 2 канала реле
const int RelayChn3 = 7;   // порт 7  для 3 канала реле
const int RelayChn4 = 8;   // порт 8  для 4 канала реле
const int RelayChn5 = 9;   // порт 9  для 5 канала реле
const int RelayChn6 = 10;  // порт 10 для 6 канала реле
const int RelayChn7 = 11;  // порт 11 для 7 канала реле
const int RelayChn8 = 12;  // порт 12 для 8 канала реле

#define hr 3600UL
#define mn 60UL
#define sc 1UL

// --Настройки времени и продолжительности включения реле --

// ----- Первый канал = pin 5 ( 5*10ВТ.Реле №3 ) ---------

// ===== ПЕРВЫЙ ПЕРИОД ======
const long StartRelCn_1 = 8*hr+00*mn+00*sc;    // ВРЕМЯ срабатывания реле на ПЕРВОМ канале
const long DurationCh_1 = 2*hr+00*mn+00*sc;    // ДЛИТЕЛЬНОСТЬ срабатывания реле на ПЕРВОМ канале

// ====  ВТОРОЙ ПЕРИОД  ======
const long StartRelCn_1L = 11*hr+00*mn+00*sc;               
const long DurationCh_1L = 4*hr+00*mn+00*sc;

// ===== ТРЕТИЙ ПЕРИОД  ======
const long StartRelCn_1G = 17*hr+00*mn;               
const long DurationCh_1G = 5*hr+00*mn;

// ===== ЧЕТВЕРТЫЙ ПЕРИОД ===== 
const long StartRelCn_1R = 2*hr+30*mn;
const long DurationCh_1R = 0*hr+00*mn;

// ------- Второй канал = pin 6 ( 7*10ВТ.Реле №4 ) -----
const long StartRelCn_2 = 10*hr+00*mn+00*sc;                    
const long DurationCh_2 = 7*hr+00*mn+00*sc;     
              
// ------- Третий канал = pin 7 ( 34*3ВТ.Реле №5 ) ------
const long StartRelCn_3 = 7*hr+30*mn+00*sc;                      
const long DurationCh_3 = 15*hr+00*mn+00*sc;    
                 
// ------- Четвертый канал = pin 8 ( CO2 Реле №2 ) ------
const long StartRelCn_4 = 9*hr+00*mn+00*sc;                     
const long DurationCh_4 = 12*hr+00*mn+00*sc;            

// ------- Пятый канал = pin 9 ( Удобрения Реле №1 ) ----
const long StartRelCn_5 = 10*hr;                
const long DurationCh_5 = 30*sc;          
          
// ------- Шестой канал = pin 10 ( Кормушка ) ------------
const long StartRelCn_6 = 9*hr;                    
const long DurationCh_6 = 0*hr;         
           
// ------- Терморегуляторы --------

//----------Седьмой канал = pin 11 ( Вентилятор ) -----------------
float t1 = 24.5;             // Установка температуры для СЕДЬМОГО канала реле
float tGistrsis1 = 0.7;      // Установка гистерезиса - в данном случае 0,7 = плюс минус 0,35 градуса

//----------Восьмой канал = pin 12 ( Нагреватель ) -----------------
float t2 = 24.5;             // Установка температуры для ВОСЬМОГО канала реле
float tGistrsis2 = 0.7; 

void setup () {
  
  pinMode(keyPin, INPUT);
  
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
  DateTime myTime = RTC.now();
// Первоначальные установки выходов
  pinMode(RelayChn1,OUTPUT);       // Иниц. порт для 1 канала
  pinMode(RelayChn2,OUTPUT);       // Иниц. порт для 2 канала
  pinMode(RelayChn3,OUTPUT);       // Иниц. порт для 3 канала
  pinMode(RelayChn4,OUTPUT);       // Иниц. порт для 4 канала
  pinMode(RelayChn5,OUTPUT);       // Иниц. порт для 5 канала 
  pinMode(RelayChn6,OUTPUT);       // Иниц. порт для 6 канала
  pinMode(RelayChn7,OUTPUT);       // Иниц. порт для 7 канала
  pinMode(RelayChn8,OUTPUT);       // Иниц. порт для 8 канала

  pinMode(inPin,INPUT);
    
  digitalWrite(RelayChn1,LOW);     // Устанавливаем на входах релейного модуля НИЗКИЙ уровень 
  digitalWrite(RelayChn2,LOW);     // т.к. используемый релейный модуль с опторазвязкой - 
  digitalWrite(RelayChn3,LOW);     // управляется инверсной логикой                   
  digitalWrite(RelayChn4,LOW);                   
  digitalWrite(RelayChn5,LOW);                    
  digitalWrite(RelayChn6,LOW);                     
  digitalWrite(RelayChn7,HIGH);                   
  digitalWrite(RelayChn8,LOW); 
     
}

void loop() {
  
  int Temp1,Temp2;
  int keyState;
  keyState = digitalRead(keyPin);
   
  if (((millis() - time1)/1000.0) >= 1.0) {     
  dps.calcTrueTemperature();
  digitalClockDisplay();  
  delay(50);     
  dps.getPressure(&Pressure);
  dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)
 
  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
      
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  time1 = millis(); 
  }

  if (keyState == LOW)
  {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temp IN  ");
  lcd.print(Temp1);

  lcd.setCursor(0, 1);
  lcd.print("Temp OUT ");
  lcd.print(Temp2);
  delay(5000);
  }
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {
  now = RTC.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
// сигнал биппера

  if (now.hour() != currentHour)
  {
  tone(Beeper,2000,200); 
  delay(300);
  tone(Beeper,2000,200);
  }
  currentHour = now.hour();
         
// печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
// рисуем разделители
  
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

  DateTime myTime = RTC.now();
  uint32_t utime = myTime.unixtime();
  utime %=86400;
  
// -------- Релейная настройка начало ------------- 
// -------- КАНАЛ 1 ---------------
  if ((utime >= StartRelCn_1) &&              
  (utime < (StartRelCn_1+DurationCh_1)) or (utime >= StartRelCn_1L) && 
  (utime < (StartRelCn_1L+DurationCh_1L))  or (utime >= StartRelCn_1G) && 
  (utime < (StartRelCn_1G+DurationCh_1G))  or (utime >= StartRelCn_1R) &&
  (utime < (StartRelCn_1R+DurationCh_1R)))
   
  {
  digitalWrite(RelayChn1,HIGH);     // Устанавливаем на входе ПЕРВОГО реле
  }                                // НИЗКИЙ уровень - реле ВКЛ.
  else
  {
  digitalWrite(RelayChn1,LOW);    // Устанавливаем на входе ПЕРВОГО реле
  }                                // ВЫСОКИЙ уровень - реле ВЫКЛ.

// --------- КАНАЛ 2 -----------------
  if ((utime >= StartRelCn_2) && 
  (utime < (StartRelCn_2+DurationCh_2)))
  {
  digitalWrite(RelayChn2,HIGH );
  }  
  else
  {
  digitalWrite(RelayChn2,LOW);
  } 

//   --------- КАНАЛ 3 -------------
  if ((utime >= StartRelCn_3) && 
  (utime < (StartRelCn_3+DurationCh_3)))
  {
  digitalWrite(RelayChn3,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn3,LOW); 
  } 
//  ------- КАНАЛ 4 -----------
  if ((utime >= StartRelCn_4) && 
  (utime < (StartRelCn_4+DurationCh_4)))
  {
  digitalWrite(RelayChn4,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn4,LOW);
  } 
// -------- КАНАЛ 5 --------------
  if ((utime >= StartRelCn_5) && 
  (utime < (StartRelCn_5+DurationCh_5)))
  {
  digitalWrite(RelayChn5,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn5,LOW);
  } 
// -------- КАНАЛ 6 ------------
  if ((utime >= StartRelCn_6) && 
  (utime < (StartRelCn_6+DurationCh_6)))
  {
  digitalWrite(RelayChn6,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn6,LOW);
 
  } 
// ---- КАНАЛ 7 Читаем температуру с 1 датчика -------
  float temp1 = getTemp1();
  if (temp1 < t1-tGistrsis1/2)
  {
  digitalWrite(RelayChn7,LOW);
  }     
  else if (temp1 > t1+tGistrsis1/2)
  {
  digitalWrite(RelayChn7,HIGH);
  
  }     
// ----- КАНАЛ 8 Читаем температуру с 2 датчика  ------
  float temp2 = getTemp2();
  if (temp1 < t1-tGistrsis2/2)
  {
  digitalWrite(RelayChn8,LOW);
  }     
  else if (temp2 > t2+tGistrsis2/2)
  {
  digitalWrite(RelayChn8,HIGH);    
  }
}
// Функции чтения с датчиков температуры
  float getTemp1()
  {                                       
  byte data[12];
  byte addr[8];
  if ( !ds1.search(addr)) {
// no more sensors on chain, reset search
  ds1.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds1.reset();
  ds1.select(addr);
  ds1.write(0x44,1); 
  byte present = ds1.reset();
  ds1.select(addr); 
  ds1.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds1.read();
  }
  ds1.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
  }
  float getTemp2()
  {
  byte data[12];
  byte addr[8];
  if ( !ds2.search(addr)) {
// no more sensors on chain, reset search
  ds2.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds2.reset();
  ds2.select(addr);
  ds2.write(0x44,1); 
  byte present = ds2.reset();
  ds2.select(addr); 
  ds2.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds2.read();
  }
  ds2.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
}

void printDigits(int digits){
// utility function for digital clock display:
// prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper... */

Подскажите пожалуйста, как вывести на экран значение переменных Temp1 и Temp2 из строк 299,310 в строки 157,161 ? 

Araris
Offline
Зарегистрирован: 09.11.2012

У Вас сейчас есть переменные int Temp1 и int Temp2, объявленные в функции loop(), а также переменные float temp1 и float temp2, объявленные в функции digitalClockDisplay().

Проще оставить только одну пару, пусть это будут int Temp1 и int Temp2. Сделайте их доступными из всех функций - строку 127 перенесите в начало скетча. Ну а теперь можно строку 299 изменить на Temp1 = int(getTemp1());, а строку 310, соответственно на Temp2 = int(getTemp2());

Если переменная будет использоваться в разных функциях скетча, то можно просто объявить её глобально для всего скетча и читать/писать везде, где надо. Но есть одно "но" - вот здесь предпоследний абзац прочитайте : http://arduino.ru/Tutorial/Variables, ну и всё остальное тоже ))).

Udav4ik
Offline
Зарегистрирован: 13.10.2015
// Таймер+Ds3231+BMP085+Ds18b20+LCD16*2(по i2c)
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <OneWire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;
uint8_t currentHour;
int TSensorPin1 = 2;
int TSensorPin2 = 3;
OneWire ds1(TSensorPin1);
OneWire ds2(TSensorPin2);

int inPin = 13;
const int keyPin = 13;  // кнопка на порт 13
int Temp1,Temp2; 
// Подключение выходов
const int RelayChn1 = 5;   // порт 5  для 1 канала реле
const int RelayChn2 = 6;   // порт 6  для 2 канала реле
const int RelayChn3 = 7;   // порт 7  для 3 канала реле
const int RelayChn4 = 8;   // порт 8  для 4 канала реле
const int RelayChn5 = 9;   // порт 9  для 5 канала реле
const int RelayChn6 = 10;  // порт 10 для 6 канала реле
const int RelayChn7 = 11;  // порт 11 для 7 канала реле
const int RelayChn8 = 12;  // порт 12 для 8 канала реле

#define hr 3600UL
#define mn 60UL
#define sc 1UL

// --Настройки времени и продолжительности включения реле --

// ----- Первый канал = pin 5 ( 5*10ВТ.Реле №3 ) ---------

// ===== ПЕРВЫЙ ПЕРИОД ======
const long StartRelCn_1 = 8*hr+00*mn+00*sc;    // ВРЕМЯ срабатывания реле на ПЕРВОМ канале
const long DurationCh_1 = 2*hr+00*mn+00*sc;    // ДЛИТЕЛЬНОСТЬ срабатывания реле на ПЕРВОМ канале

// ====  ВТОРОЙ ПЕРИОД  ======
const long StartRelCn_1L = 11*hr+00*mn+00*sc;               
const long DurationCh_1L = 4*hr+00*mn+00*sc;

// ===== ТРЕТИЙ ПЕРИОД  ======
const long StartRelCn_1G = 17*hr+00*mn;               
const long DurationCh_1G = 5*hr+00*mn;

// ===== ЧЕТВЕРТЫЙ ПЕРИОД ===== 
const long StartRelCn_1R = 2*hr+30*mn;
const long DurationCh_1R = 0*hr+00*mn;

// ------- Второй канал = pin 6 ( 7*10ВТ.Реле №4 ) -----
const long StartRelCn_2 = 10*hr+00*mn+00*sc;                    
const long DurationCh_2 = 7*hr+00*mn+00*sc;     
              
// ------- Третий канал = pin 7 ( 34*3ВТ.Реле №5 ) ------
const long StartRelCn_3 = 7*hr+30*mn+00*sc;                      
const long DurationCh_3 = 15*hr+00*mn+00*sc;    
                 
// ------- Четвертый канал = pin 8 ( CO2 Реле №2 ) ------
const long StartRelCn_4 = 9*hr+00*mn+00*sc;                     
const long DurationCh_4 = 12*hr+00*mn+00*sc;            

// ------- Пятый канал = pin 9 ( Удобрения Реле №1 ) ----
const long StartRelCn_5 = 10*hr;                
const long DurationCh_5 = 30*sc;          
          
// ------- Шестой канал = pin 10 ( Кормушка ) ------------
const long StartRelCn_6 = 9*hr;                    
const long DurationCh_6 = 0*hr;         
           
// ------- Терморегуляторы --------

//----------Седьмой канал = pin 11 ( Вентилятор ) -----------------
float t1 = 24.5;             // Установка температуры для СЕДЬМОГО канала реле
float tGistrsis1 = 0.7;      // Установка гистерезиса - в данном случае 0,7 = плюс минус 0,35 градуса

//----------Восьмой канал = pin 12 ( Нагреватель ) -----------------
float t2 = 24.5;             // Установка температуры для ВОСЬМОГО канала реле
float tGistrsis2 = 0.7; 

void setup () {
  
  pinMode(keyPin, INPUT);
  
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
  DateTime myTime = RTC.now();
// Первоначальные установки выходов
  pinMode(RelayChn1,OUTPUT);       // Иниц. порт для 1 канала
  pinMode(RelayChn2,OUTPUT);       // Иниц. порт для 2 канала
  pinMode(RelayChn3,OUTPUT);       // Иниц. порт для 3 канала
  pinMode(RelayChn4,OUTPUT);       // Иниц. порт для 4 канала
  pinMode(RelayChn5,OUTPUT);       // Иниц. порт для 5 канала 
  pinMode(RelayChn6,OUTPUT);       // Иниц. порт для 6 канала
  pinMode(RelayChn7,OUTPUT);       // Иниц. порт для 7 канала
  pinMode(RelayChn8,OUTPUT);       // Иниц. порт для 8 канала

  pinMode(inPin,INPUT);
    
  digitalWrite(RelayChn1,LOW);     // Устанавливаем на входах релейного модуля НИЗКИЙ уровень 
  digitalWrite(RelayChn2,LOW);     // т.к. используемый релейный модуль с опторазвязкой - 
  digitalWrite(RelayChn3,LOW);     // управляется инверсной логикой                   
  digitalWrite(RelayChn4,LOW);                   
  digitalWrite(RelayChn5,LOW);                    
  digitalWrite(RelayChn6,LOW);                     
  digitalWrite(RelayChn7,HIGH);                   
  digitalWrite(RelayChn8,LOW); 
     
}

void loop() {
  

  int keyState;
  keyState = digitalRead(keyPin);
   
  if (((millis() - time1)/1000.0) >= 1.0) {     
  dps.calcTrueTemperature();
  digitalClockDisplay();  
  delay(50);     
  dps.getPressure(&Pressure);
  dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)
 
  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
      
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  time1 = millis(); 
  }

  if (keyState == LOW)
  {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temp IN  ");
  lcd.print(Temp1);

  lcd.setCursor(0, 1);
  lcd.print("Temp OUT ");
  lcd.print(Temp2);
  delay(5000);
  }
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {
  now = RTC.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
// сигнал биппера

  if (now.hour() != currentHour)
  {
  tone(Beeper,2000,200); 
  delay(300);
  tone(Beeper,2000,200);
  }
  currentHour = now.hour();
         
// печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
// рисуем разделители
  
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

  DateTime myTime = RTC.now();
  uint32_t utime = myTime.unixtime();
  utime %=86400;
  
// -------- Релейная настройка начало ------------- 
// -------- КАНАЛ 1 ---------------
  if ((utime >= StartRelCn_1) &&              
  (utime < (StartRelCn_1+DurationCh_1)) or (utime >= StartRelCn_1L) && 
  (utime < (StartRelCn_1L+DurationCh_1L))  or (utime >= StartRelCn_1G) && 
  (utime < (StartRelCn_1G+DurationCh_1G))  or (utime >= StartRelCn_1R) &&
  (utime < (StartRelCn_1R+DurationCh_1R)))
   
  {
  digitalWrite(RelayChn1,HIGH);     // Устанавливаем на входе ПЕРВОГО реле
  }                                // НИЗКИЙ уровень - реле ВКЛ.
  else
  {
  digitalWrite(RelayChn1,LOW);    // Устанавливаем на входе ПЕРВОГО реле
  }                                // ВЫСОКИЙ уровень - реле ВЫКЛ.

// --------- КАНАЛ 2 -----------------
  if ((utime >= StartRelCn_2) && 
  (utime < (StartRelCn_2+DurationCh_2)))
  {
  digitalWrite(RelayChn2,HIGH );
  }  
  else
  {
  digitalWrite(RelayChn2,LOW);
  } 

//   --------- КАНАЛ 3 -------------
  if ((utime >= StartRelCn_3) && 
  (utime < (StartRelCn_3+DurationCh_3)))
  {
  digitalWrite(RelayChn3,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn3,LOW); 
  } 
//  ------- КАНАЛ 4 -----------
  if ((utime >= StartRelCn_4) && 
  (utime < (StartRelCn_4+DurationCh_4)))
  {
  digitalWrite(RelayChn4,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn4,LOW);
  } 
// -------- КАНАЛ 5 --------------
  if ((utime >= StartRelCn_5) && 
  (utime < (StartRelCn_5+DurationCh_5)))
  {
  digitalWrite(RelayChn5,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn5,LOW);
  } 
// -------- КАНАЛ 6 ------------
  if ((utime >= StartRelCn_6) && 
  (utime < (StartRelCn_6+DurationCh_6)))
  {
  digitalWrite(RelayChn6,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn6,LOW);
 
  } 
// ---- КАНАЛ 7 Читаем температуру с 1 датчика -------
  Temp1 = int(getTemp1());
  if (Temp1 < t1-tGistrsis1/2)
  {
  digitalWrite(RelayChn7,LOW);
  }     
  else if (Temp1 > t1+tGistrsis1/2)
  {
  digitalWrite(RelayChn7,HIGH);
  
  }     
// ----- КАНАЛ 8 Читаем температуру с 2 датчика  ------
  Temp2 = int(getTemp2());
  if (Temp1 < t1-tGistrsis2/2)
  {
  digitalWrite(RelayChn8,LOW);
  }     
  else if (Temp2 > t2+tGistrsis2/2)
  {
  digitalWrite(RelayChn8,HIGH);    
  }
}
// Функции чтения с датчиков температуры
  float getTemp1()
  {                                       
  byte data[12];
  byte addr[8];
  if ( !ds1.search(addr)) {
// no more sensors on chain, reset search
  ds1.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds1.reset();
  ds1.select(addr);
  ds1.write(0x44,1); 
  byte present = ds1.reset();
  ds1.select(addr); 
  ds1.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds1.read();
  }
  ds1.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
  }
  float getTemp2()
  {
  byte data[12];
  byte addr[8];
  if ( !ds2.search(addr)) {
// no more sensors on chain, reset search
  ds2.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds2.reset();
  ds2.select(addr);
  ds2.write(0x44,1); 
  byte present = ds2.reset();
  ds2.select(addr); 
  ds2.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds2.read();
  }
  ds2.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
}

void printDigits(int digits){
// utility function for digital clock display:
// prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper... */

Спасибо. Заработало! Но выводит только целое число, числа после запятой (десятые и сотые градуса) не показывает. Как исправить?

Araris
Offline
Зарегистрирован: 09.11.2012

Вместо int сделайте переменные типа float, затем уберите преобразование int() из вызовов getTemp1() и getTemp2().

Заодно и про типы переменных удачный момент почитать )).

bwn
Offline
Зарегистрирован: 25.08.2014

Udav4ik, решили все таки по максимуму в loop пихать. Если интересно, то посмотрите этот скетч и обратите внимание на его loop. Пост 282, некорректно перенаправляет.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

 Araris, Вам отдельное спасибо, пояснения конкретные и понятные. Скетч в посту 282 посмотрел, loop хорош конечно, но у меня пока мало знаний в программировании, чтобы сделать подобное, жаль конечно, но для реализации моих потребностей  и имеющегося "железа" вполне хорош и этот.И главное - все работает ! =) Сейчас реализую его в железо, запущу в работу,а для будущих изысканий у меня есть еще одна платка ардуины, на ней стану дальше практиковаться в написании скетчей. Большое всем спасибо за помощь, Керниган и Риччи верно написали, на практике теория быстрее доходит до понимания =))) Вы думаете я не прочел про переменные еще в первом совете от ув.Araris ? Читал и не единожды, но без правки скетча я бы и не вспомнил за плавающюю float. В общем буду продолжать читать литературу...Приедет второй датчик ds18b20 , тогда подправлю скетч, чтобы два датчика на одном пине висели, а пока все нормально, бипер работает стабильно, таймеры включаются вовремя, еще раз, душевное спасибо за помощь!


// Таймер+Ds3231+BMP085+Ds18b20+LCD16*2(по i2c)
// Время,число,месяц,день недели,температура,давление

#include <Wire.h>
#include <OneWire.h>
#include <BMP085.h>
#include <LCD.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
BMP085 dps = BMP085();
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);  // set the LCD address to 0x27 for a 16 chars and 2 line display
long Temperature = 0, Pressure = 0;
unsigned long time1=0;
DateTime now;
int Beeper = 4;
uint8_t currentHour;
int TSensorPin1 = 2;
int TSensorPin2 = 3;
OneWire ds1(TSensorPin1);
OneWire ds2(TSensorPin2);

int inPin = 13;
const int keyPin = 13;  // кнопка на порт 13
float Temp1,Temp2; 

// Подключение выходов
const int RelayChn1 = 5;   // порт 5  для 1 канала реле
const int RelayChn2 = 6;   // порт 6  для 2 канала реле
const int RelayChn3 = 7;   // порт 7  для 3 канала реле
const int RelayChn4 = 8;   // порт 8  для 4 канала реле
const int RelayChn5 = 9;   // порт 9  для 5 канала реле
const int RelayChn6 = 10;  // порт 10 для 6 канала реле
const int RelayChn7 = 11;  // порт 11 для 7 канала реле
const int RelayChn8 = 12;  // порт 12 для 8 канала реле

#define hr 3600UL
#define mn 60UL
#define sc 1UL

// --Настройки времени и продолжительности включения реле --

// ----- Первый канал = pin 5 ( 5*10ВТ.Реле №3 ) ---------

// ===== ПЕРВЫЙ ПЕРИОД ======
const long StartRelCn_1 = 8*hr+00*mn+00*sc;    // ВРЕМЯ срабатывания реле на ПЕРВОМ канале
const long DurationCh_1 = 2*hr+00*mn+00*sc;    // ДЛИТЕЛЬНОСТЬ срабатывания реле на ПЕРВОМ канале

// ====  ВТОРОЙ ПЕРИОД  ======
const long StartRelCn_1L = 11*hr+00*mn+00*sc;               
const long DurationCh_1L = 4*hr+00*mn+00*sc;

// ===== ТРЕТИЙ ПЕРИОД  ======
const long StartRelCn_1G = 17*hr+00*mn;               
const long DurationCh_1G = 5*hr+00*mn;

// ===== ЧЕТВЕРТЫЙ ПЕРИОД ===== 
const long StartRelCn_1R = 2*hr+30*mn;
const long DurationCh_1R = 0*hr+00*mn;

// ------- Второй канал = pin 6 ( 7*10ВТ.Реле №4 ) -----
const long StartRelCn_2 = 10*hr+00*mn+00*sc;                    
const long DurationCh_2 = 7*hr+00*mn+00*sc;     
              
// ------- Третий канал = pin 7 ( 34*3ВТ.Реле №5 ) ------
const long StartRelCn_3 = 7*hr+30*mn+00*sc;                      
const long DurationCh_3 = 15*hr+00*mn+00*sc;    
                 
// ------- Четвертый канал = pin 8 ( CO2 Реле №2 ) ------
const long StartRelCn_4 = 9*hr+00*mn+00*sc;                     
const long DurationCh_4 = 12*hr+00*mn+00*sc;            

// ------- Пятый канал = pin 9 ( Удобрения Реле №1 ) ----
const long StartRelCn_5 = 10*hr;                
const long DurationCh_5 = 30*sc;          
          
// ------- Шестой канал = pin 10 ( Кормушка ) ------------
const long StartRelCn_6 = 9*hr;                    
const long DurationCh_6 = 0*hr;         
           
// ------- Терморегуляторы --------

//----------Седьмой канал = pin 11 ( Вентилятор ) -----------------
float t1 = 24.5;             // Установка температуры для СЕДЬМОГО канала реле
float tGistrsis1 = 0.7;      // Установка гистерезиса - в данном случае 0,7 = плюс минус 0,35 градуса

//----------Восьмой канал = pin 12 ( Нагреватель ) -----------------
float t2 = 24.5;             // Установка температуры для ВОСЬМОГО канала реле
float tGistrsis2 = 0.7; 

void setup () {
  pinMode(inPin,INPUT);
  pinMode(keyPin, INPUT);
  
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  lcd.begin (16,2); // for 16 x 2 LCD module
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  dps.init(MODE_STANDARD, 7000, true);  // 70 meters, true = using meter units
  DateTime myTime = RTC.now();
// Первоначальные установки выходов
  pinMode(RelayChn1,OUTPUT);       // Иниц. порт для 1 канала
  pinMode(RelayChn2,OUTPUT);       // Иниц. порт для 2 канала
  pinMode(RelayChn3,OUTPUT);       // Иниц. порт для 3 канала
  pinMode(RelayChn4,OUTPUT);       // Иниц. порт для 4 канала
  pinMode(RelayChn5,OUTPUT);       // Иниц. порт для 5 канала 
  pinMode(RelayChn6,OUTPUT);       // Иниц. порт для 6 канала
  pinMode(RelayChn7,OUTPUT);       // Иниц. порт для 7 канала
  pinMode(RelayChn8,OUTPUT);       // Иниц. порт для 8 канала
   
  digitalWrite(RelayChn1,LOW);     // Устанавливаем на входах релейного модуля НИЗКИЙ уровень 
  digitalWrite(RelayChn2,LOW);     // т.к. используемый релейный модуль с опторазвязкой - 
  digitalWrite(RelayChn3,LOW);     // управляется инверсной логикой                   
  digitalWrite(RelayChn4,LOW);                   
  digitalWrite(RelayChn5,LOW);                    
  digitalWrite(RelayChn6,LOW);                     
  digitalWrite(RelayChn7,HIGH);                   
  digitalWrite(RelayChn8,LOW); 
     
}

void loop() {
  
  int keyState;
  keyState = digitalRead(keyPin);
   
  if (((millis() - time1)/1000.0) >= 1.0) {     
  dps.calcTrueTemperature();
  digitalClockDisplay();  
  delay(50);     
  dps.getPressure(&Pressure);
  dps.getTemperature(&Temperature);

// печать и корректировка температуры (*0.1 и -0.8 градусов)
 
  lcd.setCursor(9, 0);
  lcd.print("t ");
  lcd.print(Temperature*0.1-0.8,1); 
      
// печатаем давление
  
  lcd.setCursor(9, 1);
  lcd.print("p ");
  lcd.println(Pressure/133.3,1);
  time1 = millis(); 
  }

  if (keyState == LOW)
  {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temp IN  ");
  lcd.print(Temp1);

  lcd.setCursor(0, 1);
  lcd.print("Temp OUT ");
  lcd.print(Temp2);
  delay(5000);
  }
}

// печатаем часы,минуты,секунды

void digitalClockDisplay() {
  now = RTC.now();
  lcd.setCursor(0, 0);
  printDigits(now.hour()); 
  lcd.setCursor(3, 0); 
  printDigits(now.minute());
  lcd.setCursor(6, 0);
  printDigits(now.second());
  
// сигнал биппера

  if (now.hour() != currentHour)
  {
  tone(Beeper,2000,200); 
  delay(300);
  tone(Beeper,2000,200);
  }
  currentHour = now.hour();
         
// печатаем число, месяц и день недели
  
  lcd.setCursor(0, 1);
  printDigits(now.day());
  lcd.setCursor(3, 1);
  printDigits(now.month());
  lcd.setCursor(6, 1);
  if (now.dayOfWeek()==0) {
  lcd.print("SU");
  }
  if (now.dayOfWeek()==1) {
  lcd.print("MO");
  }
  if (now.dayOfWeek()==2) {
  lcd.print("TU");
  }
  if (now.dayOfWeek()==3) {
  lcd.print("WE");
  }
  if (now.dayOfWeek()==4) {
  lcd.print("TH");
  }
  if (now.dayOfWeek()==5) {
  lcd.print("FR");
  }
  if (now.dayOfWeek()==6) {
  lcd.print("SA");
  }
// рисуем разделители
  
  lcd.setCursor(2, 0);
  lcd.print(":");
  lcd.setCursor(5, 0);
  lcd.print(".");
  lcd.setCursor(2, 1);
  lcd.print(".");
  lcd.setCursor(5, 1);
  lcd.print(".");

  DateTime myTime = RTC.now();
  uint32_t utime = myTime.unixtime();
  utime %=86400;
  
// -------- Релейная настройка начало ------------- 
// -------- КАНАЛ 1 ---------------
  if ((utime >= StartRelCn_1) &&              
  (utime < (StartRelCn_1+DurationCh_1)) or (utime >= StartRelCn_1L) && 
  (utime < (StartRelCn_1L+DurationCh_1L))  or (utime >= StartRelCn_1G) && 
  (utime < (StartRelCn_1G+DurationCh_1G))  or (utime >= StartRelCn_1R) &&
  (utime < (StartRelCn_1R+DurationCh_1R)))
   
  {
  digitalWrite(RelayChn1,HIGH);     // Устанавливаем на входе ПЕРВОГО реле
  }                                // НИЗКИЙ уровень - реле ВКЛ.
  else
  {
  digitalWrite(RelayChn1,LOW);    // Устанавливаем на входе ПЕРВОГО реле
  }                                // ВЫСОКИЙ уровень - реле ВЫКЛ.

// --------- КАНАЛ 2 -----------------
  if ((utime >= StartRelCn_2) && 
  (utime < (StartRelCn_2+DurationCh_2)))
  {
  digitalWrite(RelayChn2,HIGH );
  }  
  else
  {
  digitalWrite(RelayChn2,LOW);
  } 

//   --------- КАНАЛ 3 -------------
  if ((utime >= StartRelCn_3) && 
  (utime < (StartRelCn_3+DurationCh_3)))
  {
  digitalWrite(RelayChn3,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn3,LOW); 
  } 
//  ------- КАНАЛ 4 -----------
  if ((utime >= StartRelCn_4) && 
  (utime < (StartRelCn_4+DurationCh_4)))
  {
  digitalWrite(RelayChn4,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn4,LOW);
  } 
// -------- КАНАЛ 5 --------------
  if ((utime >= StartRelCn_5) && 
  (utime < (StartRelCn_5+DurationCh_5)))
  {
  digitalWrite(RelayChn5,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn5,LOW);
  } 
// -------- КАНАЛ 6 ------------
  if ((utime >= StartRelCn_6) && 
  (utime < (StartRelCn_6+DurationCh_6)))
  {
  digitalWrite(RelayChn6,HIGH);
  }  
  else
  {
  digitalWrite(RelayChn6,LOW);
 
  } 
// ---- КАНАЛ 7 Читаем температуру с 1 датчика -------
  Temp1 = (getTemp1());
  if (Temp1 < t1-tGistrsis1/2)
  {
  digitalWrite(RelayChn7,LOW);
  }     
  else if (Temp1 > t1+tGistrsis1/2)
  {
  digitalWrite(RelayChn7,HIGH);
  
  }     
// ----- КАНАЛ 8 Читаем температуру с 2 датчика  ------
  Temp2 = (getTemp2());
  if (Temp1 < t1-tGistrsis2/2)
  {
  digitalWrite(RelayChn8,LOW);
  }     
  else if (Temp2 > t2+tGistrsis2/2)
  {
  digitalWrite(RelayChn8,HIGH);    
  }
}
// Функции чтения с датчиков температуры
  float getTemp1()
  {                                       
  byte data[12];
  byte addr[8];
  if ( !ds1.search(addr)) {
// no more sensors on chain, reset search
  ds1.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds1.reset();
  ds1.select(addr);
  ds1.write(0x44,1); 
  byte present = ds1.reset();
  ds1.select(addr); 
  ds1.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds1.read();
  }
  ds1.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
  }
  float getTemp2()
  {
  byte data[12];
  byte addr[8];
  if ( !ds2.search(addr)) {
// no more sensors on chain, reset search
  ds2.reset_search();
  return -1001;  
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
  return -1002;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
  return -1003;
  }
  ds2.reset();
  ds2.select(addr);
  ds2.write(0x44,1); 
  byte present = ds2.reset();
  ds2.select(addr); 
  ds2.write(0xBE); 
  for (int i = 0; i < 9; i++) { 
  data[i] = ds2.read();
  }
  ds2.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;
  return Temperature;
}

void printDigits(int digits){
// utility function for digital clock display:
// prints preceding colon and leading 0

  if(digits < 10){
  lcd.print('0');
  }
  lcd.print(digits);
}
/*Спасибо форуму http://arduino.ru
 http://arduino.ru/forum/programmirovanie/chasymeteo-kak-prikrutit-bipper... */

Araris
Offline
Зарегистрирован: 09.11.2012

Udav4ik пишет:

И главное - все работает !

Категорически поддерживаю. Первые скетчи могут быть неоптимальными, некрасивыми, какими угодно, главное - они работают. А это ох как мощно вдохновляет на продолжение и дальнейшее совершенствование. Я сам года три тому назад начинал под Ардуино писать, я всё помню (мне правда полегче было, я давно программирую).

bwn
Offline
Зарегистрирован: 25.08.2014

Udav4ik, вы похоже не заглянули в начало топика, ТС начал писать с чужого кода, по размеру меньше Вашего, 10.12.14. Закончил 17.02.15. В программировании я ему помогал очень мало, т.к. и сам профан, начал вспоминать как это делать через 25 лет после любительских Бейсика и Фортрана(см. дату регистрации на форуме). Основная помощь заключалась в разбитии на логические задачи.
А так, соглашусь с Araris, хороший код, это тот, который работает и устраивает пользователя.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

bwn, нет, я смотрел и начало топика, правда не слишком далеко и конечно пост 282 в перевую очередь глянул. По видимому мы с автором того топика отталкивались от одинакого скетча, работы реле по суточному таймеру, а потом каждый сделал под свои видения аква жизни и запросы.Меня заинтересовал один вопрос, который Вы упомянули в начале топика, проверить точность датчика влажности, насыпаем в банку от майонеза соль , капаем воду, суем туда датчик,плотно закрываем, датчик должен показать 75-76% влажности. Поподробнее не расскажите? Сколько соли, сколько воды? И зачем вообще нужна соль?

 
bwn
Offline
Зарегистрирован: 25.08.2014

Не помню, как правильно называется метод (хотите, погуглите), но суть такова: Любой насыщенный раствор солей, образует над своей поверхностью равновесное состояние влажности. Для NaCl это 75% и мало меняется от температуры, для других солей, другие значения (можно проверить всю шкалу).
В банку насыпаете с чайную ложку соли, капаете несколько капель воды (должна быть влажная, но без лужи) и закрываете от контакта с атмосферой. У меня время стабилизации занимало минут 40 - час. Поскольку берем соли не х.ч и воду не дистилированную, допустимо небольшое отклонение от табличного, но для домашних нужд вполне достаточно. Желательно конечно проверить в других диапазонах, но этих солей на кухне не найдете.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

ок, принцип понял, спасибо.А то есть несколько китайских приборов измерения влажности и все показывают по своему.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Уважаемые форумчане, кто нибудь знает как вместо бипов симитировать голос кукушки? Какой надо поставить тон и длительность? В гугле по запросу "имитация звука кукушки" ничего толком кроме этого не нашел:

http://www.junradio.com/blog/zvukovoj_imitator_golosa_kukushki/2015-07-2...

но подставив эти частоты, услышал совсем не похожий звук на кукушкин.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik, можно пойти другим путём. Находите нужный звук кукушки в виде (короткого!)  WAV в интернете, затем идёте  сюда  качаете библу, там же в обсуждении находите конвертор wav- *.h. И слушаете wav через ардуино.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Что то не работает библиотека Play sound по ссылке. Скачал ее , установил, конвертировал файл wav звука кукушки в *.h добавил его в библиотеку плей соунд, загрузил пример скетча для проигрования звуков, при компиляции выдает такую ошибку:

C:\Users\A4F7~1\AppData\Local\Temp\arduino_37b1009bba23b2a3c15c2a669eeaf87b\sketch_dec14a.ino: In function 'void loop()':
 
sketch_dec14a:10: error: 'test' was not declared in this scope
 
    PlaySound::startPlayback((uint8_t *)test,  test_length);
 
                                        ^
 
sketch_dec14a:10: error: 'test_length' was not declared in this scope
 
    PlaySound::startPlayback((uint8_t *)test,  test_length);
 
                                               ^
 
exit status 1
'test' was not declared in this scope
 
весь выходной пробовал в разных вариантах, никак не хочет воспроизвести какой либо звук.
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik, то есть "какой либо звук"? Там с библой куча примеров звуков, в библе есть готовый рабочий скетч. Всё это рабочее, я недавно пользовался.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Вот именно из библ он не может проиграть пример.При проверке, компиляии вдает ошибку.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik, судя по вашей строчке  C:\Users\A4F7~1\AppData\Local\Temp\arduino_37b1009bba23b2a3c15c2a669eeaf87b\sketch_dec14a.ino: In function 'void loop()':

вы запускаете что угодно, но не  тот пример, который идёт с библой. Хотя бы потому, что он находится в папке play_sound и называется иначе. Просто заqдите проводником в папку библиотекой, и запустите play_sound.pde

Udav4ik
Offline
Зарегистрирован: 13.10.2015

play_sound.pde я тоже открвал, вот ошибка:

Arduino: 1.6.7 Hourly Build 2015/11/13 05:42 (Windows 7), Плата:"Arduino/Genuino Uno"
 
F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde: In function 'void loop()':
 
play_sound:87: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
   PlaySound::startPlayback((uint8_t *)setup1,  setup1_length);
 
                                                             ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:89: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)traffi,  traffi_length);
 
                                                              ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:91: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)sleep,  sleep_length);
 
                                                            ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:93: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)pulp,  pulp_length);
 
                                                          ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:95: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)off2,  off2_length);
 
                                                          ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:97: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)click,  click_length);
 
                                                            ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:99: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)off1,  off1_length);
 
                                                          ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:101: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
     PlaySound::startPlayback((uint8_t *)notify2,  notify2_length);
 
                                                                 ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:103: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)pick,  pick_length);
 
                                                          ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:105: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
   PlaySound::startPlayback((uint8_t *)vibrate,  vibrate_length);
 
                                                               ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
play_sound:107: error: too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
    PlaySound::startPlayback((uint8_t *)on,  on_length);
 
                                                      ^
 
In file included from F:\Arduino\libraries\PlaySound\examples\play_sound\play_sound.pde:7:0:
 
F:\Arduino\libraries\PlaySound/PlaySound.h:20:7: note: declared here
 
  void startPlayback(uint8_t *wave_data, uint16_t wave_length, int mypin); 
 
       ^
 
exit status 1
too few arguments to function 'void PlaySound::startPlayback(uint8_t*, uint16_t, int)'
 
может надо в скетч добавить пин выхода сигнала?

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik, я не знаю где у вас косяк. Но он точно есть, потому как библа 100% рабочая.  Скорее всего что-то задублировано, типа лишняя папка в папке. Сотрите все и распакуйте аккуратно заново. Там ещё нужно не забыть wprogram.h на arduino.h поменять, но в обсуждении об этом упоминалось.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

выход там жёстко прописан, PB3 (11нога)

Udav4ik
Offline
Зарегистрирован: 13.10.2015

библиотека заработала, но файл расширением .wav (250кБ) программка конвертер переводит в расширение .h уже размером в 1,6 мБ и компилятор виснет и не может даже проверить скетч.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik, какие 250кб? В ардуине всего 32к, и это на всё про всё. На звук ку-ку вполне хватит 10кб, если всё хорошенько ужать аудиоредактором.

vk007
Offline
Зарегистрирован: 16.06.2015

"Жалко, королевство маловато, разгулятся мне негде" )

Интересно, если бы вам подвернулся десятимегабайтный wav, вы бы и его пытались впихнуть в ардуину?

Конвертер всего лишь убирает из wav служебную информацию и формирует сишный файл. По его размеру тоже сложно понять размер полученного. Размер можно посмотреть в константе (не помню формируемого названия), которая тоже записывается в этот файл.

Поэтому ориентируйтесь на размер wav, какого он размера, примерно столько же надо иметь свободного флеша в ардуине.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Пробовал конвертировать разными аудиоредакторами, меньше 3,7кБ у меня не вышло, попробуйте, кто разбирается в звукоредакторах:

https://yadi.sk/d/quuIk6j5mHUeH

vk007
Offline
Зарегистрирован: 16.06.2015

Ну так 3,7 кБ из 250 - что еще хотеть надо, при этом если еще и звучит нормально, то это есть очень гуд.

Udav4ik
Offline
Зарегистрирован: 13.10.2015

Перекодировав в расширение *.h он выходит большим размером и получается уже 22кБ

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Udav4ik вы что, размер файла смотрите? Он текстовый, и никакого отношения (почти никакого) к размеру прошиваемого блока данных не имеет.