собрал я наконец то таймер в железе. Сразу после заливки скетчя до подключения нагрузки захотелось посмотреть как работает и возник вопрос а можно ли в мониторе порта увидеть работу скетча в лаконичной форме. Ну чтобы serial print одно событие один раз отпечатывал типа :
svet on
vent on
vent off
vent on
svet off
что то типаswitch case break должно быть? Прошу прощения если вопрос совсем дурацкий.
#include <Wire.h>
#include "RTClib.h"
#define vozdux 13 // к реле вентиллятора
#define svet 3 // к реле света
unsigned long time = 0;
boolean flag=0;
RTC_DS1307 rtc;
void setup () {
Wire.begin();
rtc.begin();
pinMode(svet, OUTPUT);
pinMode(vozdux, OUTPUT);
Serial.begin(9600);
//установка вручную
//rtc.adjust(DateTime(2017, 3, 10, 15, 50, 0));
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
}
void loop () {
DateTime now = rtc.now();
if (now.hour() >= 5 && now.hour() <17) digitalWrite(svet, 1);
else digitalWrite(svet, 0);
if ((now.hour() == 0 || now.hour() == 1 || now.hour() == 2 || now.hour() == 3 || now.hour() == 4 || now.hour() == 5 ||
now.hour() == 6 || now.hour() == 8 || now.hour() == 9 || now.hour() == 10 || now.hour() == 11 || now.hour() == 12 ||
now.hour() == 13 || now.hour() == 14 || now.hour() == 15 || now.hour() == 16 || now.hour() == 17 || now.hour() == 18 ||
now.hour() == 19 || now.hour() == 20 || now.hour() == 21 || now.hour() == 22 || now.hour() == 23)
&& now.minute() == 0 || now.minute() == 5 || now.minute() == 10 || now.minute() == 15 || now.minute() == 20 ||
now.minute() == 25 || now.minute() == 30 || now.minute() == 35 || now.minute() == 40 || now.minute() == 45 ||
now.minute() == 50 || now.minute() == 55 && flag == 0) {
digitalWrite(vozdux, 1);
time = millis();
flag=1;
}
if (flag==1 && ((millis()-time)>10000)){ // если влажность воздуха не будет устраивать поиграюсь с секундами
digitalWrite(vozdux, 0);
flag=0;
}
}
да я ж говорю. хотел чтобы после заливки в мониторе порта каждое действие отображалось 1раз. Да конечно можно и нагрузку подцепить и на 13 пин посадить (что для вентилятора и сделал). ну вот такой дурацкий вопрос возник
смотрю добавил. но забыл скобки. в 38 строке скобками объеденяй условия. например для часов сработает для любого часа и нуля минут. а другие минуты не сработают. засунь минуты как часы в скобки
так как вариантов много как можно сделать предложу еще, постепенно усложняя. коды для примера, может какие то ошибки, главное идея
через delay
#define fan 5
#define time_on 5 // время на которое включится, тут 5 минут
#define period 60 //время между включениями
void setup(){
pinMode(fan, OUTPUT);
}
void loop(){
digitalWrite(fan, HIGH); // включили вентилятор
delay(time_on*60*1000); //задержка на 5 минут, в минуте 60сек, в секунде 1000мс
digitalWrite(fan, LOW); // выключили вентилятор
delay(period*60*1000); //задержка на 5 минут, в минуте 60сек, в секунде 1000мс
}
но если бы точнее получился не период включения, а период между выключением и включением, период в данном случае получился 65 мин. исправим. просто отнимем из периода
#define fan 5
#define time_on 5 // время на которое включится, тут 5 минут
#define period 60 //время между включениями
void setup(){
pinMode(fan, OUTPUT);
}
void loop(){
digitalWrite(fan, HIGH); // включили вентилятор
delay(time_on*60*1000); //задержка на 5 минут, в минуте 60сек, в секунде 1000мс
digitalWrite(fan, LOW); // выключили вентилятор
delay((period-time_on)*60*1000); //задержка на 5 минут, в минуте 60сек, в секунде 1000мс
}
но как обычно с delay лучше не связываться, если ардуина кроме включения выключения должна еще что то делать, то делай не даст, не зря на форуме есть не один способ избавится от делай
через millis()
millis это как посмотреть на часы, вызвал и узнал текущее время
#define fan 5
#define time_on 5 // время на которое включится, тут 5 минут
#define period 60 //время между включениями
unsigned long time;
boolean on_off; // этот флаг нужен чтобы знать сейчас включен или выключен вентилятор
void setup(){
pinMode(fan, OUTPUT);
time = millis(); // запоминаем текущее время
digitalWrite(fan, HIGH); // включаем вентилятор
on_off=1; // выставляем флаг что вентилятор включен
}
void loop(){
if(on_off==1){
if((millis()-time)>(time_on*60*1000)){ //если разница между которое запомнили и текущием больше 5 минут
digitalWrite(fan, LOW);
time = millis();
on_off=0;
}
}
if(on_off==0){
if((millis()-time)>(period*60*1000)){ //если разница между которое запомнили и текущием больше 60 минут
digitalWrite(fan, HIGH);
time = millis();
on_off=1;
}
}
}
но тут снова период получился 65мин. поправим, заодно немного изменим немного код для удобства. условие внутри другого можно объеденить через логическую И
if(on_off==1) и if(on_off) одно и тоже, просто разные записи
if(on_off==0) и if(!on_off) тоже самое (почти)
#define fan 5
#define time_on 5*60*1000 // время на которое включится, тут 5 минут
#define period 55*60*1000 //время между включениями
unsigned long time;
boolean on_off; // этот флаг нужен чтобы знать сейчас включен или выключен вентилятор
void setup(){
pinMode(fan, OUTPUT);
time = millis(); // запоминаем текущее время
digitalWrite(fan, HIGH); // включаем вентилятор
on_off=1; // выставляем флаг что вентилятор включен
}
void loop(){
if(on_off && ((millis()-time)>time_on)){ //если разница между которое запомнили и текущием больше 5 минут
digitalWrite(fan, LOW);
time = millis();
on_off=0;
}
if(!on_off && ((millis()-time)>period)){ //если разница между которое запомнили и текущием больше 60 минут
digitalWrite(fan, HIGH);
time = millis();
on_off=1;
}
}
теперь часть кода оформим в функцию, если код станет сложнее так будет проще его править и читать
#define fan 5
#define time_on 5*60*1000 // время на которое включится, тут 5 минут
#define period 60*60*1000 //время между включениями
unsigned long time;
boolean on_off; // этот флаг нужен чтобы знать сейчас включен или выключен вентилятор
void setup(){
pinMode(fan, OUTPUT);
time = millis(); // запоминаем текущее время
digitalWrite(fan, HIGH); // включаем вентилятор
on_off=1; // выставляем флаг что вентилятор включен
}
void loop(){
if(on_off && ((millis()-time)>time_on)){ //если разница между которое запомнили и текущием больше 5 минут
vent_off();
}
if(!on_off && ((millis()-time)>period)){ //если разница между которое запомнили и текущием больше 60 минут
vent_on();
}
}
//=================================================================
// Функции
//=================================================================
// включение вентилятора
void vent_on(){
digitalWrite(fan, HIGH);
time = millis();
on_off=1;
}
// выключение вентилятора
void vent_off(){
digitalWrite(fan, LOW);
time = millis();
on_off=0;
}
тут одно уточнение. если пример не будет компилироваться, ругаться что нет такой функции, значит ее просто поставить выше места где ее вызвали. в ардуино 1.0.6 и последней на данный момент 1.8.1 например такой проблемы нет, ставь где хочешь)) а вот например 1.6.12 более "требовательный"
но это все равными промежутками. а если нужно с утра до вечера каждый час, а ночью каждые 2 часа этот код не подойдет
и тут пришли к тому что нужно писать когда и на сколько включить что то. это ведь не относится именно к вентилятору, можно и полив также ведь. но ардуина будет относительно времени включения это делать, а не по часам, значит нужно прицепить часы, возьму из кода выше на основе DS1307. вентилятор будет включатся в 00:00 01:00 02:00 03:00 04:00. дальше не стал продолжать, запись слишком длинная и неудобная
сделаем настройку когда включатся более читаемой и удобной через массив. работает также, перебираем значения массива и если есть совпадение включаем вентилятор
#include <Wire.h>
#include "RTClib.h"
#define fan 5
#define time_on 5 // время вентилирования, мин
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[5] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
pinMode(fan, OUTPUT);
}
void loop(){
DateTime now = rtc.now();
for(byte i=0;i<5;i++){ // перебираем элементы массива
if(now.hour() == time_vent[i] && now.minute()==0 && on_off==0){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
}
}
if((millis()-time)>(time_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
}
}
но у этого кода есть небольшой недостаток, если нужно изменять количество элементов массива, нужно менять и размерность массива и в цикле. это неудобно. уберем размерность массива и сделаем автоопределение его размера
#include <Wire.h>
#include "RTClib.h"
#define fan 5
#define time_on 5 // время вентилирования, мин
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
pinMode(fan, OUTPUT);
}
void loop(){
DateTime now = rtc.now();
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i] && now.minute()==0 && on_off==0){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
}
}
if((millis()-time)>(time_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
}
}
все бы правильно, но по хорошему если вентилятор сейчас включен, а loop очень быстро крутится, цикл будет бесполезно выполнятся много много раз и тратить процессорное время, значит проверку что включен вентилятор нужно вынести выше. да и минуты нас интересуют только когда равны нулю. смысла перебирать часы нет ведь если минуты не равны нулю
#include <Wire.h>
#include "RTClib.h"
#define fan 5
#define time_on 5 // время вентилирования, мин
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
pinMode(fan, OUTPUT);
}
void loop(){
DateTime now = rtc.now();
if(!on_off && now.minute()==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i]){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
}
}
}
if((millis()-time)>(time_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
}
}
что можно еще доработать. например если случайно записали число не входящее в диапазон 0...23. сделаем это на начальном этапе программы. а также добавим отправку в терминал текущее состояние вентилятора и если диапазон содержит ошибку
#include <Wire.h>
#include "RTClib.h"
#define fan 5
#define time_on 5 // время вентилирования, мин
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
pinMode(fan, OUTPUT);
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_vent[i] < 0 || time_vent[i] > 23){
Serial.println("Massiv error");
}
}
}
void loop(){
DateTime now = rtc.now();
if(!on_off && now.minute()==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i]){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
Serial.println("Ventilator on");
}
}
}
if((millis()-time)>(time_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
Serial.println("Ventilator off");
}
}
setup и loop становятся все более сложными, и если еще что то добавить будет тяжело разобраться. добавим функции
#include <Wire.h>
#include "RTClib.h"
#define fan 5
#define time_on 5 // время вентилирования, мин
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
pinMode(fan, OUTPUT);
test_massiv(); // проверяем массив на ошибки
}
void loop(){
cooling(); // управление вентилятором
}
//==================================================================
// Функции
//==================================================================
//========================================проверяем массив на ошибки
void test_massiv(){
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_vent[i] < 0 || time_vent[i] > 23){
Serial.println("Massiv error");
}
}
}
//==========================================управление вентилятором
void cooling(){
DateTime now = rtc.now();
if(!on_off && now.minute()==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i]){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
Serial.println("Ventilator on");
}
}
}
if((millis()-time)>(time_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
Serial.println("Ventilator off");
}
}
теперь все разбито на функции. добавить например управление светом не составит проблемм, но сразу будем делать функцию для него. также переименуем time_on в vent_on чтобы не запутаться потом
#include <Wire.h>
#include "RTClib.h"
#define licht 4 // пин для света
#define fan 5 // пин вентилятора
#define vent_on 5 // время вентилирования, мин
#define licht_on 5 // время включения света, часы
#define licht_off 5 // время выключения света, часы
RTC_DS1307 rtc;
unsigned long time;
boolean on_off=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
pinMode(licht, OUTPUT);
pinMode(fan, OUTPUT);
test_massiv(); // проверяем массив на ошибки
}
void loop(){
cooling(); // управление вентилятором
lichting();
}
//==================================================================
// Функции
//==================================================================
//========================================проверяем массив на ошибки
void test_massiv(){
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_vent[i] < 0 || time_vent[i] > 23){
Serial.println("Massiv error");
}
}
}
//==========================================управление вентилятором
void cooling(){
DateTime now = rtc.now();
if(!on_off && now.minute()==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i]){
digitalWrite(fan, HIGH);
on_off=1;
time=millis();
Serial.println("Ventilator on");
}
}
}
if((millis()-time)>(vent_on*60*1000) && on_off==1){
digitalWrite(fan, LOW);
on_off=0;
Serial.println("Ventilator off");
}
}
//==========================================управление светом
void lichting(){
DateTime now = rtc.now();
if(now.hour()>=licht_on && now.hour()<licht_off){
digitalWrite(licht, HIGH);
Serial.println("Ocveshenie on");
}
else{
digitalWrite(licht, LOW);
Serial.println("Ocveshenie off");
}
}
в терминал отправляются текущие состояния, но непонятно когда именно это происходило. может не тогда когда нужно. сделаем что кроме состояния еще и время отправлялось когда это состояние изменилось
также условие освещения будет много раз срабатывать и постоянно слать в терминал что свет включен или выключен, добавим флаг чтобы этого не происходило. у нас есть уже флаг on_off и когда управляется и вентиляцией и освещением непонятно за что отвечает флаг. переименуем
также уже нельзя использовать else для освещения, так как не будет использоваться флаг, и включение будет происходит один раз, а выключение многократно повторятся
#include <Wire.h>
#include "RTClib.h"
#define licht 4 // пин для света
#define fan 5 // пин вентилятора
#define vent_on 5 // время вентилирования, мин
#define licht_on 5 // время включения света, часы
#define licht_off 5 // время выключения света, часы
RTC_DS1307 rtc;
unsigned long time;
boolean on_off_vent=0;
boolean on_off_licht=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
pinMode(licht, OUTPUT);
pinMode(fan, OUTPUT);
test_massiv(); // проверяем массив на ошибки
}
void loop(){
cooling(); // управление вентилятором
lichting();
}
//==================================================================
// Функции
//==================================================================
//========================================проверяем массив на ошибки
void test_massiv(){
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_vent[i] < 0 || time_vent[i] > 23){
Serial.println("Massiv error");
}
}
}
//==========================================управление вентилятором
void cooling(){
DateTime now = rtc.now();
if(!on_off_vent && now.minute()==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(now.hour() == time_vent[i]){
digitalWrite(fan, HIGH);
on_off_vent=1;
time=millis();
current_time(); // текущее время и дата
Serial.println("Ventilator on");
}
}
}
if((millis()-time)>(vent_on*60*1000) && on_off_vent){
digitalWrite(fan, LOW);
on_off_vent=0;
current_time(); // текущее время и дата
Serial.println("Ventilator off");
}
}
//==========================================управление светом
void lichting(){
DateTime now = rtc.now();
if(now.hour()>=licht_on && now.hour()<licht_off && !on_off_licht){
digitalWrite(licht, HIGH);
current_time(); // текущее время и дата
Serial.println("Ocveshenie on");
on_off_licht=1;
}
if(now.hour()<licht_on && now.hour()>=licht_off && on_off_licht){
digitalWrite(licht, LOW);
current_time(); // текущее время и дата
Serial.println("Ocveshenie off");
on_off_licht=0;
}
}
//======================================вывод текущего времени
void current_time(){
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('.');
Serial.print(now.month(), DEC);
Serial.print('.');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.print(".\t"); // это табуляция
}
можно изменить функцию current time. сначала соберем строку с датой и временем, а только потом будем отправлять. но по отдельности дату и время, если нужно где то только время или дата. итого соберем 2 строки
но тогда чтобы вывести дату или время, или вместе придется вызвать функцию чтобы собрались строки, а потом выводить каждую строку. не совсем удобно. добавим параметров для функции current time что нужно вывести
у кода есть еще один недостаток, функции cooling lichting current_time каждый раз считывают время. а использовать считанные данные без обновления не дает. оптимальнее один раз считать все данные, и записать например в массив и использовать их в функциях. плюс если захочется сменить часы на что то посовременнее, например DS3231 или blynk использовать, придется достаточно много менять, изза других названий. правда сейчас придется везде поменять функции из библиотеки часов на элементы массива
#include <Wire.h>
#include "RTClib.h"
#define licht 4 // пин для света
#define fan 5 // пин вентилятора
#define vent_on 5 // время вентилирования, мин
#define licht_on 5 // время включения света, часы
#define licht_off 5 // время выключения света, часы
String cur_time, cur_date;
RTC_DS1307 rtc;
unsigned long time;
boolean on_off_vent=0;
boolean on_off_licht=0;
byte time_vent[] = {0, 1, 2, 17, 20}; //время когда должен включится вентилятор
int time_date[6]; //здесь будем хранить текущее время и дату. int потому что год имеет 4 цифры
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.begin(9600);
pinMode(licht, OUTPUT);
pinMode(fan, OUTPUT);
test_massiv(); // проверяем массив на ошибки
}
void loop(){
time_read();
cooling(); // управление вентилятором
lichting();
}
//==================================================================
// Функции
//==================================================================
//========================================проверяем массив на ошибки
void test_massiv(){
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_vent[i] < 0 || time_vent[i] > 23){
Serial.println("Massiv error");
}
}
}
//==========================================управление вентилятором
void cooling(){
if(!on_off_vent && time_date[4]==0){ // писал уже что это за запись выше
for(byte i=0;i<sizeof(time_vent);i++){ // перебираем элементы массива, но размер определяем с помощью sizeof
if(time_date[3] == time_vent[i]){
digitalWrite(fan, HIGH);
on_off_vent=1;
time=millis();
current_time(1,1); // текущее время и дата
Serial.println("Ventilator on");
}
}
}
if((millis()-time)>(vent_on*60*1000) && on_off_vent){
digitalWrite(fan, LOW);
on_off_vent=0;
current_time(1,1); // текущее время и дата
Serial.println("Ventilator off");
}
}
//==========================================управление светом
void lichting(){
if(time_date[3] >= licht_on && time_date[3] < licht_off && !on_off_licht){
digitalWrite(licht, HIGH);
current_time(1,1); // текущее время и дата
Serial.println("Ocveshenie on");
on_off_licht=1;
}
if(time_date[3]<licht_on && time_date[3]>=licht_off && on_off_licht){
digitalWrite(licht, LOW);
current_time(1,1); // текущее время и дата
Serial.println("Ocveshenie off");
on_off_licht=0;
}
}
//======================================вывод текущего времени
void current_time(boolean t, boolean d){
if(t){
cur_time = String(time_date[3]) + ":" + String(time_date[4]) + ":" + String(time_date[5])+ " ";
Serial.print(cur_time);
}
if(d){
cur_date = String(time_date[0]) + "." + String(time_date[1]) + "." + String(time_date[2])+ " ";
Serial.print(cur_date);
}
}
//==========считывание текущего времени и записывание в массив
void time_read(){
DateTime now = rtc.now();
time_date[0] = now.year(); // год
time_date[1] = now.month(); // месяц
time_date[2] = now.day(); // день
time_date[3] = now.hour(); // часы
time_date[4] = now.minute(); // минуты
time_date[5] = now.second(); // секунды
}
теперь если использовать другие часы достаточно изменить эту функцию, ну и библиотеку конечно и что с ней связано
void time_read(){
DateTime now = rtc.now();
time_date[0] = now.year(); // год
time_date[1] = now.month(); // месяц
time_date[2] = now.day(); // день
time_date[3] = now.hour(); // часы
time_date[4] = now.minute(); // минуты
time_date[5] = now.second(); // секунды
}
это гораздо проще чем искать по коду что там нужно поменять
далее можно добавить кнопки, дисплей, датчики и т.д. но продолжать думаю смысла нет. идея понятна
Доброго времени суток. А как допилить шилд с дисплеем и кнопками? Не очень силен в программировании, точнее на стадии обучения. Заранее огромное спасибо...
добрый день. хочу сделать, (условно назовем это) прибор, для поддержания заданой влажности. на 10 пин подключен увлажнитель. программа проверяет значения с датчика каждые 15 секунд сравнивает их с заданой влажностью и мринимает решение на какой период включить увлажнитель. задается влажность кнопкой 5 пин, проблема в том, что с delay кнопка работает не корректно. Спасибо, что ответили!!!
можешь использовать титановый класс для кнопки, а обработку делать иначе
умножаешь значения на 2 и делишь на 10. это чтобы без флоат.
получаешь целые числа. задержку делаешь исходя из этого числа, которое будет сразу в миллис домноженное на 500. надеюсь понятно описал. можно было бы конечно без этой математики, но это если тебе не будут нужны значения для вывода на дисплей например или еще какой то обработки
кнопка подтянута. с кнопкой не хотелось бы морочиться, а вот что дальше вы написали, извините не могу понять, из-за того, что я совсем зеленый в этой сфере. значения возможно будут выводиться на экран который идет в комплекте кит для новичков, помоему LCD 1602 называется, но это позже, когда разберусь с функцией миллис, подскажите где найти информацию кроме определения (возвращает колличество....) не могу сообразить что оно значит. С функ-ей delay все гораздо проще и логичней, где нужна задержка там и ставим, а здесь пока что не вкуриваю. Спасибо за ваш ответ.
миллис это как внутренние часы, вот у тебя есть часы, ты на них смотришь время.
Вот тебе например надо в 10 вечера Дом 2 посмотреть, веришь в любовь видиш ли. А мама тебе сказала в 22:30 выключить духовку, а то пирог сгорит. И ты периодически время проверяешь чтобы не пропустить дом 2 и пирог не сжечь. до 10 ты просто проверяешь время, после 10 смотришь эту херню и проверяешь текущее время, как только 22:30 выключил духовку и дальше смотришь...
Ты ардуина, миллис твои часы, а посмотреть на часы это как миллис возвращает. но есть разница, миллис показывает время от включения ардуины, а не абсолютное время как часы.
по твоей задаче: ты периодически смотришь в миллис и при определенной ситуации запоминаешь его (например после нажатия кнопки), а сколько прошло времени от предыдущего запоминания просто из текущего времени отнять запомненное, и узнаешь например прошло пять секунд. сравнивать ардуина будет много раз в секунду, и если ты поставишь условие если разница между запомненным временем и текущим больше опяти секунд, то делать то то. и записываешь в запомненное время текущее. и теперь ардуина будет искать совпадение по условию от новой временной точки
Вот тебе например надо в 10 вечера Дом 2 посмотреть, веришь в любовь видиш ли. А мама тебе сказала в 22:30 выключить духовку, а то пирог сгорит. И ты периодически время проверяешь чтобы не пропустить дом 2 и пирог не сжечь. до 10 ты просто проверяешь время, после 10 смотришь эту херню и проверяешь текущее время, как только 22:30 выключил духовку и дальше смотришь...
Ты ардуина, миллис твои часы, а посмотреть на часы это как миллис возвращает. но есть разница, миллис показывает время от включения ардуины, а не абсолютное время как часы.
Жека, ты это, никаких новых культур в тепличке не завел? Курят которые?)))))
Очень образно расписываешь.))))
тоесть, грубо говоря, миллис ведет отсчет с момента запуска проги и если например мне нужно узнать не пора ли запустить определенный процесс я отнимаю текущее время от начального, результат сравниваю с нужным мне временем, если все ок, то выполняю действие, так?
сначала запоминаешь это начальное время, когда запоминать тебе виднее. далее правильно. но ты должен четко понимать как должно работать, прежде чем писать
пример: та же ситуация, но мама тебе сказала выключи духовку через полтора часа, и напомнила тебе что дом 2 начнется через час. ты мальчик очень послушный, но будильником пользоваться не умеешь, зато считаешь хорошо
ты запомнил время текущее и занимаешься своими делами, периодически сравниваешь время между запомненным и текущим, и вычисляешь разницу. прошел час включил телек, прошло 1.5 от запомненного выключил духовку. и тут ведь понятно что ты вроде не дебил, и можешь делать как тебе удобнее, или подождать час и запомнить снова время, и нужно еще полчаса ждать, или считать от первой временной точки
и так и так будет правильно, разница сколько то миллисекунд между решениями. в ряде случаев точность важна поэтому нужно исходить из ситуации и понимать что делаешь
от души жека!!! по красоте двиганулся!!! буду разбираться сидеть. только дом 2 даже в качестве примера не алё=)) еще раз спасибо большое. Если что пойдет не так отпишусь=)
добавляем переменную статус, которая будет хранить состояние текущее включен или выключен свет.
24 строка проверяем время и заодно что статус =0, то есть свет выключен. если даже время подходит по условию, но статус=1 (свет уже включен) то условие не выполнится, и свет повторно ардуина не будет пытаться включить
если время подходит и свет выключен выполнится условие, свет включили в 25 строке заодно и изменяем статус на 1, указывая что свет включен, и теперь это условие не выполнится, пока не выполнится условие в 29 строке и в 31 статус не изменит свое состояние. триггер своеобразный
хотя не знаю какой ресурс записи в регистры, он же очень много раз будет это делать, если продолжать мысль постоянно время проверять тоже нет смысла. какая разница. ровно в 7:00 включится например или 7:01
Arduino: 1.8.5 (Windows 7), Плата:"Arduino Pro or Pro Mini, ATmega168 (5V, 16 MHz)"
C:\Users\555\Documents\Arduino\prostoy_timer2\prostoy_timer2.ino: In function 'void time_chek()':
prostoy_timer2:26: error: 'now' was not declared in this scope
if (now.hour() >= 0 && now.hour() <= 7 && !status){
^
Несколько библиотек найдено для "RTClib.h"
Используется: C:\Users\555\Documents\Arduino\libraries\RTClib
Не используется: C:\Users\555\Documents\Arduino\libraries\RTCLib_by_NeiroN
exit status 1
'now' was not declared in this scope
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
собрал я наконец то таймер в железе. Сразу после заливки скетчя до подключения нагрузки захотелось посмотреть как работает и возник вопрос а можно ли в мониторе порта увидеть работу скетча в лаконичной форме. Ну чтобы serial print одно событие один раз отпечатывал типа :
svet on
vent on
vent off
vent on
svet off
что то типа switch case break должно быть? Прошу прощения если вопрос совсем дурацкий.
вставь правильно код, чтобы ты понял куда тебе добавить строку
исправился . а вот так прокатит? 16 29-31 ,33-35 ,48-50 ,55-57.
должно быть 1 раз в setup
хз зачем тебе
остальное так
да я ж говорю. хотел чтобы после заливки в мониторе порта каждое действие отображалось 1раз. Да конечно можно и нагрузку подцепить и на 13 пин посадить (что для вентилятора и сделал). ну вот такой дурацкий вопрос возник
добавь флаг
смотрю добавил. но забыл скобки. в 38 строке скобками объеденяй условия. например для часов сработает для любого часа и нуля минут. а другие минуты не сработают. засунь минуты как часы в скобки
так как вариантов много как можно сделать предложу еще, постепенно усложняя. коды для примера, может какие то ошибки, главное идея
через delay
но если бы точнее получился не период включения, а период между выключением и включением, период в данном случае получился 65 мин. исправим. просто отнимем из периода
но как обычно с delay лучше не связываться, если ардуина кроме включения выключения должна еще что то делать, то делай не даст, не зря на форуме есть не один способ избавится от делай
через millis()
millis это как посмотреть на часы, вызвал и узнал текущее время
но тут снова период получился 65мин. поправим, заодно немного изменим немного код для удобства. условие внутри другого можно объеденить через логическую И
теперь часть кода оформим в функцию, если код станет сложнее так будет проще его править и читать
тут одно уточнение. если пример не будет компилироваться, ругаться что нет такой функции, значит ее просто поставить выше места где ее вызвали. в ардуино 1.0.6 и последней на данный момент 1.8.1 например такой проблемы нет, ставь где хочешь)) а вот например 1.6.12 более "требовательный"
но это все равными промежутками. а если нужно с утра до вечера каждый час, а ночью каждые 2 часа этот код не подойдет
и тут пришли к тому что нужно писать когда и на сколько включить что то. это ведь не относится именно к вентилятору, можно и полив также ведь. но ардуина будет относительно времени включения это делать, а не по часам, значит нужно прицепить часы, возьму из кода выше на основе DS1307. вентилятор будет включатся в 00:00 01:00 02:00 03:00 04:00. дальше не стал продолжать, запись слишком длинная и неудобная
сделаем настройку когда включатся более читаемой и удобной через массив. работает также, перебираем значения массива и если есть совпадение включаем вентилятор
но у этого кода есть небольшой недостаток, если нужно изменять количество элементов массива, нужно менять и размерность массива и в цикле. это неудобно. уберем размерность массива и сделаем автоопределение его размера
все бы правильно, но по хорошему если вентилятор сейчас включен, а loop очень быстро крутится, цикл будет бесполезно выполнятся много много раз и тратить процессорное время, значит проверку что включен вентилятор нужно вынести выше. да и минуты нас интересуют только когда равны нулю. смысла перебирать часы нет ведь если минуты не равны нулю
что можно еще доработать. например если случайно записали число не входящее в диапазон 0...23. сделаем это на начальном этапе программы. а также добавим отправку в терминал текущее состояние вентилятора и если диапазон содержит ошибку
setup и loop становятся все более сложными, и если еще что то добавить будет тяжело разобраться. добавим функции
теперь все разбито на функции. добавить например управление светом не составит проблемм, но сразу будем делать функцию для него. также переименуем time_on в vent_on чтобы не запутаться потом
в терминал отправляются текущие состояния, но непонятно когда именно это происходило. может не тогда когда нужно. сделаем что кроме состояния еще и время отправлялось когда это состояние изменилось
также условие освещения будет много раз срабатывать и постоянно слать в терминал что свет включен или выключен, добавим флаг чтобы этого не происходило. у нас есть уже флаг on_off и когда управляется и вентиляцией и освещением непонятно за что отвечает флаг. переименуем
также уже нельзя использовать else для освещения, так как не будет использоваться флаг, и включение будет происходит один раз, а выключение многократно повторятся
можно изменить функцию current time. сначала соберем строку с датой и временем, а только потом будем отправлять. но по отдельности дату и время, если нужно где то только время или дата. итого соберем 2 строки
но тогда чтобы вывести дату или время, или вместе придется вызвать функцию чтобы собрались строки, а потом выводить каждую строку. не совсем удобно. добавим параметров для функции current time что нужно вывести
теперь функция имеет параметры. вот так будет выглядеть ее использование
итого общий код получился такой
у кода есть еще один недостаток, функции cooling lichting current_time каждый раз считывают время. а использовать считанные данные без обновления не дает. оптимальнее один раз считать все данные, и записать например в массив и использовать их в функциях. плюс если захочется сменить часы на что то посовременнее, например DS3231 или blynk использовать, придется достаточно много менять, изза других названий. правда сейчас придется везде поменять функции из библиотеки часов на элементы массива
теперь если использовать другие часы достаточно изменить эту функцию, ну и библиотеку конечно и что с ней связано
это гораздо проще чем искать по коду что там нужно поменять
далее можно добавить кнопки, дисплей, датчики и т.д. но продолжать думаю смысла нет. идея понятна
Доброго времени суток. А как допилить шилд с дисплеем и кнопками? Не очень силен в программировании, точнее на стадии обучения. Заранее огромное спасибо...
писать код. учиться. а как еще
вот вы неугомонный. вот и код дописал, а что мне за это будет))
кстати 43200 это 43.2 секунды
А как можно в код добавить минуты? Чтобы реле запускалось скажем в 8:30.
jeka_tm, а как можно добавить минуты в ваш код, чтобы можно было регулировать включение/отключение не только по часам, но и по минутам?
Что-то у меня последняя версия скетча компилируется с ошибками. Да и первая тоже...
jeka_tm, а как можно добавить минуты в ваш код, чтобы можно было регулировать включение/отключение не только по часам, но и по минутам?
аналогично часам. и проверять не только часы, но и минуты. но сначала нужно точно представлять как должно работать
судя по ошибке, не виден класс DateTime
RTClib видимо нет
опиши словами что ты хочешь сделать. мне кажется все строки с 32 по 55 можно заменить на 2-3 строки
Что-то незаметно, чтоб вы пытались освоить millis() - в коде одни delay(), ни одной попытки освоить миллис не видать
#63 О_О
добрый день. хочу сделать, (условно назовем это) прибор, для поддержания заданой влажности. на 10 пин подключен увлажнитель. программа проверяет значения с датчика каждые 15 секунд сравнивает их с заданой влажностью и мринимает решение на какой период включить увлажнитель. задается влажность кнопкой 5 пин, проблема в том, что с delay кнопка работает не корректно. Спасибо, что ответили!!!
кнопка подтянута резистором?
можешь использовать титановый класс для кнопки, а обработку делать иначе
умножаешь значения на 2 и делишь на 10. это чтобы без флоат.
получаешь целые числа. задержку делаешь исходя из этого числа, которое будет сразу в миллис домноженное на 500. надеюсь понятно описал. можно было бы конечно без этой математики, но это если тебе не будут нужны значения для вывода на дисплей например или еще какой то обработки
и как у нас кнопка задаеть влажность?
и как у нас кнопка задаеть влажность?
от 20 до 100 по кругу с шагом 5
кнопка подтянута. с кнопкой не хотелось бы морочиться, а вот что дальше вы написали, извините не могу понять, из-за того, что я совсем зеленый в этой сфере. значения возможно будут выводиться на экран который идет в комплекте кит для новичков, помоему LCD 1602 называется, но это позже, когда разберусь с функцией миллис, подскажите где найти информацию кроме определения (возвращает колличество....) не могу сообразить что оно значит. С функ-ей delay все гораздо проще и логичней, где нужна задержка там и ставим, а здесь пока что не вкуриваю. Спасибо за ваш ответ.
миллис это как внутренние часы, вот у тебя есть часы, ты на них смотришь время.
Вот тебе например надо в 10 вечера Дом 2 посмотреть, веришь в любовь видиш ли. А мама тебе сказала в 22:30 выключить духовку, а то пирог сгорит. И ты периодически время проверяешь чтобы не пропустить дом 2 и пирог не сжечь. до 10 ты просто проверяешь время, после 10 смотришь эту херню и проверяешь текущее время, как только 22:30 выключил духовку и дальше смотришь...
Ты ардуина, миллис твои часы, а посмотреть на часы это как миллис возвращает. но есть разница, миллис показывает время от включения ардуины, а не абсолютное время как часы.
по твоей задаче: ты периодически смотришь в миллис и при определенной ситуации запоминаешь его (например после нажатия кнопки), а сколько прошло времени от предыдущего запоминания просто из текущего времени отнять запомненное, и узнаешь например прошло пять секунд. сравнивать ардуина будет много раз в секунду, и если ты поставишь условие если разница между запомненным временем и текущим больше опяти секунд, то делать то то. и записываешь в запомненное время текущее. и теперь ардуина будет искать совпадение по условию от новой временной точки
Вот тебе например надо в 10 вечера Дом 2 посмотреть, веришь в любовь видиш ли. А мама тебе сказала в 22:30 выключить духовку, а то пирог сгорит. И ты периодически время проверяешь чтобы не пропустить дом 2 и пирог не сжечь. до 10 ты просто проверяешь время, после 10 смотришь эту херню и проверяешь текущее время, как только 22:30 выключил духовку и дальше смотришь...
Ты ардуина, миллис твои часы, а посмотреть на часы это как миллис возвращает. но есть разница, миллис показывает время от включения ардуины, а не абсолютное время как часы.
Жека, ты это, никаких новых культур в тепличке не завел? Курят которые?)))))
Очень образно расписываешь.))))
Жека, ты это, никаких новых культур в тепличке не завел? Курят которые?)))))
Очень образно расписываешь.))))
Образно гораздо лучше доходит)) А те самые культуры я не понимаю, мне пиво больше нравится, а выращивать их думаю проще простого, сорняк же все таки
тоесть, грубо говоря, миллис ведет отсчет с момента запуска проги и если например мне нужно узнать не пора ли запустить определенный процесс я отнимаю текущее время от начального, результат сравниваю с нужным мне временем, если все ок, то выполняю действие, так?
сначала запоминаешь это начальное время, когда запоминать тебе виднее. далее правильно. но ты должен четко понимать как должно работать, прежде чем писать
пример: та же ситуация, но мама тебе сказала выключи духовку через полтора часа, и напомнила тебе что дом 2 начнется через час. ты мальчик очень послушный, но будильником пользоваться не умеешь, зато считаешь хорошо
ты запомнил время текущее и занимаешься своими делами, периодически сравниваешь время между запомненным и текущим, и вычисляешь разницу. прошел час включил телек, прошло 1.5 от запомненного выключил духовку. и тут ведь понятно что ты вроде не дебил, и можешь делать как тебе удобнее, или подождать час и запомнить снова время, и нужно еще полчаса ждать, или считать от первой временной точки
и так и так будет правильно, разница сколько то миллисекунд между решениями. в ряде случаев точность важна поэтому нужно исходить из ситуации и понимать что делаешь
от души жека!!! по красоте двиганулся!!! буду разбираться сидеть. только дом 2 даже в качестве примера не алё=)) еще раз спасибо большое. Если что пойдет не так отпишусь=)
ну должна же быть ложка дегтя, как без нее учится, слишком просто
Спасибо тебе jeka_tm. Как только понадобился таймер тут же и срукожопил не мудрствуя лукаво.
Зарядка от сотового, часы, реле(низкого уровня), про мини все это поместилось в старом удлинителе после вырезания двух гнезд.
Вообще очень понравился вариант встраивать таймер прямо в управляемое устройство.
я бы немного поправил. правда моя правка корявенько выглядит
это чтобы ардуина не выключала 100500 раз когда итак выключено, и аналогично с включением
поясни дураку
добавляем переменную статус, которая будет хранить состояние текущее включен или выключен свет.
24 строка проверяем время и заодно что статус =0, то есть свет выключен. если даже время подходит по условию, но статус=1 (свет уже включен) то условие не выполнится, и свет повторно ардуина не будет пытаться включить
если время подходит и свет выключен выполнится условие, свет включили в 25 строке заодно и изменяем статус на 1, указывая что свет включен, и теперь это условие не выполнится, пока не выполнится условие в 29 строке и в 31 статус не изменит свое состояние. триггер своеобразный
Перезалить имеет смысл? Все таки скотч отклеить придется.
да нет. необязательно. так на будущее
хотя не знаю какой ресурс записи в регистры, он же очень много раз будет это делать, если продолжать мысль постоянно время проверять тоже нет смысла. какая разница. ровно в 7:00 включится например или 7:01
У меня чего то не хватает?
я не вижу что там написано пришли ошибку
Arduino: 1.8.5 (Windows 7), Плата:"Arduino Pro or Pro Mini, ATmega168 (5V, 16 MHz)"
C:\Users\555\Documents\Arduino\prostoy_timer2\prostoy_timer2.ino: In function 'void time_chek()':
prostoy_timer2:26: error: 'now' was not declared in this scope
if (now.hour() >= 0 && now.hour() <= 7 && !status){
^
Несколько библиотек найдено для "RTClib.h"
Используется: C:\Users\555\Documents\Arduino\libraries\RTClib
Не используется: C:\Users\555\Documents\Arduino\libraries\RTCLib_by_NeiroN
exit status 1
'now' was not declared in this scope
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
так это тот же код, и этот кусок я не менял))
да. но у меня вываливается эта ошибка при сборке. Чего то не хватает?
последний код пробовал?
#93 отличается от #85 ? еще не сравнивал
конечно. я бы тогда его не выкладывал
этот собрался без матюков. Спасибо.
#29 не лишняя?
#29 не лишняя?
да нет. без нее будет при невыполнении условия постоянно выключать свет, даже если он выключен