Вот это: Код (C++): while(time.second < tmp_s+10) {//motor run} Эквивалентно вот этому: Код (C++): {//motor run}; delay(10000); т.к. все десять секунд висим в цикле не переключаясь на другие задачи. Преимущества отключения по таймеру не используются. Трудности начинаются если скетч из "начать в х часов, у минут, z секунд", "закончить в х2 часов, у2 минут, z2 секунд" начать переделывать в скетч действительно позволяющий сделать какое-либо действие через 10 сек или через 9 часов. Поясняю "трудности". Пусть нам нужно сделать какое-то действие через 9 часов после текущего момента, тогда можно записать: Код (C++): alarmOn = true; alarm_h = current_h + 9; if (alarm_h > 23) alarm_h = alarm_h - 24; alarm_m = current_m; alarm_s = current_s; Затем вставить в loop() проверку Код (C++): if (alarmOn && current_h == alarm_h && current_m == alarm_m && current_s == alarm_s) { alarmOn = false; // действия по таймеру } Имеем следующие проблемы: 1. Громоздкая и выносящая мозг формула вычисления значений переменных времени контролируемого события. 2. Громоздкое условие проверяющее наступление события. 3. В условии нельзя использовать операции "больше" и "меньше", следовательно если по каким-либо причинам в нужную секунду условие не будет проверено, то событие "уйдет на следующий круг", т.е. на следующие сутки. 4. Необходимость использовать дополнительную переменную-флаг
У меня что то ругается.... Код (C++): #include <config.h> #include <ds3231.h> #include <RTClib.h> int motor = 9; int led = 8; int H; //Установленное время часы int M;//Установленное время минуты int S;//Установленное время секунды int tmp_h; int tmp_m; int tmp_s; tmp_h = time.Hours; tmp_m = time.minutes; tmp_s = time.second; void setup () { { setTime(17, 35, 30, 28, 12, 2015);//выставляем текущее время //RTC.set(now()); } //Мотор if (tmp_h==9 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } else (tmp_h==9 && tmp_m==00 && tmp_s==15) { //Выключаем digitalWrite(motor, LOW); } if (tmp_h==21 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } else (tmp_h==21 && tmp_m==00 && tmp_s==15) { //Выключаем digitalWrite(motor, LOW); } //Свет if (tmp_h==6 && tmp_m==00 && tmp_s==00) { //Включаем свет digitalWrite(led, HIGH); } else (tmp_h==22 && tmp_m==00 && tmp_s==00) { //Выключаем свет digitalWrite(led, LOW); } //Кулер (Пока нериализованно) /* if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(9, HIGH); } else { digitalWrite(9, LOW); } } */ void loop()
Вот, так то лучше Код (C++): #include <config.h> #include <ds3231.h> #include <RTClib.h> int motor = 9; int led = 8; int H; //Установленное время часы int M;//Установленное время минуты int S;//Установленное время секунды int tmp_h,tmp_m,tmp_s; tmp_h = time.Hours; tmp_m = time.minutes; tmp_s = time.second; void setup () { //Мотор if (tmp_h==9 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } else (tmp_h==9 && tmp_m==00 && tmp_s==15); { //Выключаем digitalWrite(motor, LOW); } if (tmp_h==21 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } else (tmp_h==21 && tmp_m==00 && tmp_s==15); { //Выключаем digitalWrite(motor, LOW); } //Свет if (tmp_h==6 && tmp_m==00 && tmp_s==00) { //Включаем свет digitalWrite(led, HIGH); } else (tmp_h==22 && tmp_m==00 && tmp_s==00); { //Выключаем свет digitalWrite(led, LOW); } } //Кулер (Пока нериализованно) /* if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(9, HIGH); } else { digitalWrite(9, LOW); } } */ void loop(){}
Ругается компилятор на то, что пытаетесь вычислить выражение, содержащее переменную, вне тела функции. Вот такое присваивание вне тела функции использовать нельзя: Код (C++): tmp_h = time.Hours; Но он ведь не только на это ругается, правда? Посмотрите в справочнике по языку как допустимо писать оператор if-else и как он работает.
В else не должно быть условий, это то, что выполниться в случае, если не одно из условий не выполненно. А так же, возможно, компилятор ругается на то, что вы используете мой код с неправильной библиотекой, прикладываю ту, что сам использую. Код (C++): // ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ: // // в библиотеке реализованы 4 функции: begin, settime, gettime и period. // функция begin вызывается первой и предназначена для инициализации модуля, выбора шины, и выводов arduino // количество и порядок вызовов функций settime, gettime и period, значения не имеет. // // инициализация модуля // time.begin(название, RST или SS, CLK, DAT) если модуль работает на шине I2C или SPI, то достаточно указать только название модуля, например: time.begin(RTC_DS3231); // если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: time.begin(RTC_DS1305,22); // если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: time.begin(RTC_DS1302, 1, 2, 3); // RST, CLK, DAT // запись даты и времени // time.settime(сек,мин,час,д,м,г,дн) должен присутствовать хотябы 1 параметр // часы указываются в 24-часовом формате, год указывается от 0 до 99, день недели указывается числом: 1-ПН, 2-ВТ, ... 6-СБ, 0-ВС. // если предыдущий(ие) параметр(ы) надо оставить без изменений, то указывается отрицательное значение // чтение даты и времени // time.gettime("строка с параметрами") функция получает и выводит строку заменяя описанные ниже символы на текущее время // указанные символы эдентичны символам для функции date() в PHP // s секунды от 00 до 59 (два знака) // i минуты от 00 до 59 (два знака) // h часы в 12-часовом формате от 01 до 12 (два знака) // H часы в 24-часовом формате от 00 до 23 (два знака) // d день месяца от 01 до 31 (два знака) // w день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота) // D день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun) // m месяц от 01 до 12 (два знака) // M месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) // Y год от 2000 до 2099 (четыре знака) // y год от 00 до 99 (два знака) // a полдень am или pm (два знака, в нижнем регистре) // A полдень AM или PM (два знака, в верхнем регистре) // строка не должна превышать 50 символов // пример: gettime("d-m-Y, H:i:s, D"); ответит строкой "01-10-2015, 14:00:05, Thu" // пример: gettime("s"); ответит строкой "05" // чтение даты и времени в виде цифр // time.gettime() без параметра // результат читается из переменных: // time.seconds секунды 0-59 // time.minutes минуты 0-59 // time.hours часы 1-12 // time.Hours часы 0-23 // time.midday полдень 0-1 (0-am, 1-pm) // time.day день месяца 1-31 // time.weekday день недели 0-6 (1-понедельник, 6-суббота, 0-воскресенье) // time.month месяц 1-12 // time.year год 0-99 // не обязательная функция // time.period(минуты) указывает минимальный период чтения времени из модуля в минутах. (от 1 до 255 минут) // пример: // если после вызова функции time.period(5); в течении 5 минут несколько раз была вызвана функция gettime, // то запрос времени к модулю пройдёт только в первый раз, а ответом на все остальные вызовы функции gettime // будет результат последнего полученного от модуля времени + время прошедшее с этого запроса // уменьшение числа запросов уменьшает время обработки запросов, разгружает шину, и уменьшает потребляемый модулем ток // при отсутствии вызова функции time.period(минуты), ответ на запрос даты и времени будет всегда читаться из модуля
Если после else убрать скобки и условие, то это будет синтаксически правильно. Но сформулированная Вами цель "включить вовремя и выключить вовремя" достигнута не будет. Как реализовать такие алгоритмы - см. мои сообщения в этой теме. Ваш же простой алгоритм, когда заранее известно точно время включения и точное время выключения, реализуется так: Код (C++): if (tmp_h==21 && tmp_m==00 && tmp_s==00) { //Включаем digitalWrite(motor, HIGH); }; if (tmp_h==21 && tmp_m==00 && tmp_s==15) { //Выключаем digitalWrite(motor, LOW); }; Т.е. два независимых друг от друга оператора условия. При каждом проходе (выполнении) функции loop() эти условия проверяются раз за разом. В какой-то момент условие оказывается верным и микроконтроллер выполняет соответствующее действие.
в конечном итоге у меня получилось так Код (C++): #include <Wire.h> #include <RTC.h> #include <config.h> #include <ds3231.h> RTC time; int motor = 9; int led = 8; int h; //Установленное время часы int m;//Установленное время минуты int s;//Установленное время секунды int tmp_h,tmp_m,tmp_s; void setup () { delay(300); Serial.begin(9600); time.begin(RTC_DS3231); time.settime(0,51,21,27,10,15,2); // 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник tmp_h = time.Hours; tmp_m = time.minutes; tmp_s = time.seconds; //Мотор if (tmp_h==9 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } if (tmp_h==9 && tmp_m==00 && tmp_s==10); { //Выключаем digitalWrite(motor, LOW); } if (tmp_h==21 && tmp_m==00 && tmp_s==00) { //Включаем на 10 секунд digitalWrite(motor, HIGH); } if (tmp_h==21 && tmp_m==00 && tmp_s==15);{ //Выключаем digitalWrite(motor, LOW); } //Свет if (tmp_h==6 && tmp_m==00 && tmp_s==00) { //Включаем свет digitalWrite(led, HIGH); } if (tmp_h==22 && tmp_m==00 && tmp_s==00); { //Выключаем свет digitalWrite(led, LOW); } } //Кулер (Пока нериализованно) /* if (tmp_h==H && tmp_m==M && tmp_s==S) { digitalWrite(9, HIGH); } else { digitalWrite(9, LOW); } } */ void loop() { delay(1000); Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс }
как я понял, вот эту строчку нужно устанавливать только один раз для установки часов, а дальше ее не использовать? Код (C++): time.settime(0,51,21,27,10,15,2); // 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник вот только часы устанавливают эту дату даже когда строка закоментированна
А что? никто не думал использовать опрос линии прерывания с микросхемы? и будильники?? как говорится... задал время - ждешь сигнала. дождался - выполнил действие, задал новый будильник...
Добрый день! Проблема с компиляцией. Библиотека RTS, модуль DS3231/ При компиляции выдает ошибку в чем дело? Пробовал разные библиотеки, та же самая ошибка
Здравствуйте! Возникает сложность с форматом времени /даты ds3231,(библиотеку использую DS1307RTC - может это мешать?). Помогите разобраться, при чтении в серийном мониторе - всё корректно, при записи в файл на SD карту - время/дата превращаются в какие-то цифры вида: 95.27,253:251:237,24,20,426 9527- дата, 253:251:237 - время, 24,20,426 - мои параметры. Кусок кода записи в файл: Код (C++): String dataString = (String(tm.Day) + "." + String(tm.Month) + "," + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second) + "," + String(t) + "," + String(h) + "," + String(sensor)); myFile = SD.open("SOLAR.csv", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.println(sensor); myFile.println(dataString); myFile.close(); Весь код: Код (C++): #include <SPI.h> #include <SD.h> File myFile; //////////////////////// #include <DS1307RTC.h> #include <Wire.h> #include <Time.h> #include <DS1307RTC.h> #include "DHT.h" #define DHTPIN 2 // what pin we're connected to #define DHTTYPE DHT11 // DHT 22 (AM2302) DHT dht(DHTPIN, DHTTYPE); int BUZZER = 6; [SIZE=14px]int analogPin = 0; /[/SIZE] void setup() { //////////////////////////////// dht.begin(); // Open serial communications and wait for port to open: Serial.begin(9600); ///while (!Serial) { ///; // wait for serial port to connect. Needed for Leonardo only ///} Serial.print("Initializing SD card..."); if (!SD.begin(10)) { Serial.println("initialization failed!"); tone(BUZZER, 3900, 300); delay (500); tone(BUZZER, 3900, 300); delay (500); tone(BUZZER, 3900, 300); return; } else { Serial.println("initialization done."); tone(BUZZER, 3900, 1000); } } void loop() { tmElements_t tm; int h = dht.readHumidity(); int t = dht.readTemperature(); // читаем данные с датчика и делим на коэффициент int sensor = analogRead(analogPin);/////int sensor = analogRead(analogPin) / 2.515; String dataString = (String(tm.Day) + "." + String(tm.Month) + "," + String(tm.Hour) + ":" + String(tm.Minute) + ":" + String(tm.Second) + "," + String(t) + "," + String(h) + "," + String(sensor)); myFile = SD.open("SOLASR.csv", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.println(sensor); myFile.println(dataString); myFile.close(); tone(BUZZER, 3900, 1); delay (1500); } else { Serial.println("error writing to SOLAR.csv"); } } Код для вывода в сериал - стандартный из программы Код (C++): #include <Wire.h> #include <Time.h> #include <DS1307RTC.h> void setup() { Serial.begin(9600); while (!Serial) ; // wait for serial delay(200); Serial.println("DS1307RTC Read Test"); Serial.println("-------------------"); } void loop() { tmElements_t tm; if (RTC.read(tm)) { Serial.print("Ok, Time = "); print2digits(tm.Hour); Serial.write(':'); print2digits(tm.Minute); Serial.write(':'); print2digits(tm.Second); Serial.print(", Date (D/M/Y) = "); Serial.print(tm.Day); Serial.write('/'); Serial.print(tm.Month); Serial.write('/'); Serial.print(tmYearToCalendar(tm.Year)); Serial.println(); } else { if (RTC.chipPresent()) { Serial.println("The DS1307 is stopped. Please run the SetTime"); Serial.println("example to initialize the time and begin running."); Serial.println(); } else { Serial.println("DS1307 read error! Please check the circuitry."); Serial.println(); } delay(9000); } delay(1000); } void print2digits(int number) { if (number >= 0 && number < 10) { Serial.write('0'); } Serial.print(number); }
Смотрим здесь: Код (C++): Serial.println(sensor); myFile.println(dataString); Пробуем так: Код (C++): Serial.println(dataString); myFile.println(dataString); Далее смеемся над своей невнимательностью и читаем мануалы на тему как работает такая запись: Код (C++): String(tm.Day)
Спасибо за ответ! В первом замечании всё верно, это для вывода в монитор данных только датчика и есть. А про String(tm.Day) расскажите пожалуйста поподробнее, или скажите, где почитать?
Возникли у меня странности с этиим модулем. Нужны были по быстрому часы, вобщем все собрал-настроил вроде порядок. Библиотеку использовал RTC (ту что выкладывал), с ней проще, сразу можно читать из переменных цифровые значения. Но вот глюк, поставил 31 февраля 2016 года- и оно это приняло, ладно думаю, мало ли, вызываю дату- так и есть 31 февраля! Как так то!? Разве в ней нет проверки даты, а как же с високосными годами? К тому же если я меняю день, месяц или год (каждый щелчек энкодера обновляет значение и тут же его выводит на экран), название дня не изменяется.