Часы+метео. Как "прикрутить" биппер?
- Войдите на сайт для отправки комментариев
Сб, 05/12/2015 - 01:32
Подскажите пожалуйста,как в этот скетч прикрутить подачу сигнала каждый полный час? Например: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); }
Во первых, здесь нет оператора "and", а есть "&&". Во вторых, посмотрите синтаксис оператора "if". Отдельная функция здесь не требуется, вставьте это в loop после 64 строки. С функцией "tone" не работал, не знаю насколько правильно записано.
И проверьте соответствие фигурных скобок, по моему в loop одна лишняя.
and исправил, void убрал и вставил в loop, tone проверял, все работает нормально, ошибка с условием.Без строки
if (now.minute)==0 && (now.second)==0;
бипер пищит, но только непрерывно. Вот , что пишет Arduino ide
Попробуйте этот кусок после 90 строки вставить. И записать в проверке условия как (now.hour())
вставил, все равно ошибку выдает
==0 внесите внутрь условия
Обратите внимание на пост 5 и еще раз "Во вторых, посмотрите синтаксис оператора "if"." Условие остается ваше, минуты и секунды. Я имел в виду обертывание их скобками.
if
(someVariable > 50)
{
// выполнять действия
}
правильным должен быть вариант первый и второй
но во всех случаях выдает одну и ту же ошибку:
Надо вынести объявление DateTime now; в самый верх скетча, перед void setup().
Затем в функции
void
digitalClockDisplay()
строку DateTime now = rtc.now(); исправить на now = rtc.now();Ну и с обертыванием скобками стоило бы разобраться наконец.
Есть прогресс! Спасибо.
Большое спасибо всем за помощь, особенно Araris. Со времен бейсика не занимался такими задачками, но все заработало, хотя и не совсем так, как я себе представлял. Биппер почему то выдает 4 сигнала, вместо 2 или одного, как я прописал в скетче. Не могу понять причину, ставил команду noTone, после двух сигналов, оставлял всего 1 строку tone(Beep), сигнал срабатывает на 4 бипа. Только delay как то на него влияет и при некоторх значениях он выдает 3 бипа. Двух сигналов добиться не могу.
Сделайте так, чтобы функция digitalClockDisplay(); не вызывалась при каждом проходе loop. Переместите строку 52 между 33-й и 34-й, пусть раз в секунду по таймеру вызывается.
Кстати, строки 37-50 тоже туда же неплохо бы переместить.
Спасибо еще раз, переделал, как Вы написали, бипер заработал стабильно. Отрисовка секунд стала не корректно работать, перескакивает периодически через секунду, но это мелочи, я примерно понимаю, почему это происходит. Продолжу дальше над ним работать, надо "прикрутить " суточный таймер для управления оборудованием аквариума, спасибо.
Отрисовка секунд стала не корректно работать, перескакивает периодически через секунду, но это мелочи, я примерно понимаю, почему это происходит.
В строке 32 сделайте немного меньший промежуток времени, тогда периодически перескакивать перестанет. Правда возникнет другая проблема - периодически бипер будет по два раза отрабатывать. Тут или изощряться надо, или выходить на качественно новый подход.
А давайте-ка расскажу один из способов:
Идея - отслеживать изменение значения, например, секунды. Для этого заводим в самом начале скетча некую переменную, например, uint8_t currentSecond;
А дальше, вот этот кусок скетча
переделаем вот так
Теперь идём ещё дальше. А зачем вообще нам минуты и секунды, если стоит задача сигналить каждый час ? Можно просто сделать отслеживание изменения значения часа.
Объявляем в начале скетча переменную uint8_t currentHour;
Вот, я не знал как притянуть условие к часу, поэтому и пошел к секундам и минутам. Буду курить переменные, спасибо.
Переделал условие срабатывания сигнала , привязав к часу, как вы написали, сделав все за меня, спасибо =), уменьшил задержку вывода на дисплей, перебои с отрисовкой секунд стали реже, но не исчезли. Причем уменьшал delay до 0.1 мс , но секунды-это не критично, главное бипер срабатывает четко 2 раза и не сбоит если даже пауза между бипами 50 мс , этого я и добивался обращаясь к Вам за помощью. Назрел следущий вопрос-как правильно соеденить два рабочих скетча ? Какие будут Ваши советы, что выкинуть лишнего или может , что то нужно добавить? Скетч не мой, взял в другой ветке, кое что только подправил, скорее интуитивно, чем четко понимая все тонкости его работы. Но проверил на "железе", все работает, хотелось бы правильно соеденить их функции.
P.S. Хорошая штука эта Ардуино, жаль, что раньше таких возможностей не было.
Я всего лишь пытался объяснить суть одного из приёмов программирования, писать скетчи за Вас - это вряд ли.
Насчёт слияния скетчей - возьмите один из них за основу (тот, в котором больше нужного кода содержится), доведите его "до ума" под свою задачу, вычистите ненужное.
А потом уже в другом окне открываем другой скетч и начинаем потихоньку дёргать из него нужные куски и внедрять в основной скетч. Время от времени компилируем, читаем сообщения компилятора, устраняем ошибки, продвигаемся дальше и т.д.
Я обычно делаю так.
Есть ещё одна причина, почему сливать придётся самому - Вы единственный, кто знает, что выкинуть, что добавить, и что же должно получиться в результирующем скетче ))
Немного добавлю, к сказанному уважаемым Araris. Сперва внимательно просмотрите оба кода, попытайтесь определить, что в них есть хорошо, а что желательно подправить. Далее нарисуйте себе алгоритм работы вашего девайса и разбейте его на самодостаточные задачи. После чего, каждую такую задачу пытаемся описать отдельной функцией. В итоге получаем достаточно компактный loop, в котором проверяем условия и вызываем нужные нам функции.
Удобство метода, в каждый момент времени мы отлаживаем только одну функцию и больше ее не трогаем. Значительно снижается риск ошибок (если бы все работало в loop) и получается модульная наращиваемая система.
Как пример, в вашем коде есть задание временных интервалов через скетч. На начальном этапе для запуска девайса этого достаточно, но завтра возможно захочется менять эти значения кнопками из меню. Если это останется в основном цикле, придется фактически переписывать всю программу. В виде функции - только переписать ее и корректно вернуть переменные. ИМХО.
Спасибо, Вы очень хорошо объяснили. Я начал учиться. Посоветуйте литературу для новичка в программировании.
И Вам спасибо, ув.bwn. Такой алгоритм нормальный или нет?
Не совсем: Я хочу, чтобы мой девас делал: Отсчитывал время, измерял температуру, измерял давление, выводил значения на экран, что то делал еще..... Для этого мне понадобится: МК с обвязкой, LCD, RTC ...... Для управления всем этим требуется: два аналоговых выхода для I2C (ими смогу управлять RTC, BMP, LCD), восемь цифровых выходов на реле, один цифровой вход для DS18B20 (кстати рекомендую их вешать на один пин) и т.д. После, поняв, что входов-выходов данного МК хватает для хотелок можно переходить к программной части.
Для начала эксплуатации начинаем с дисплея и часов. Пишем-отлаживаем функцию вывода на дисплей (сразу прикидываем, будет все на одном экране или придется менять информацию) и так последовательно вводим новые функции. Для симуляции работы датчиков на начальном этапе, можем зарезервировать под них переменные с требуемым типом и присвоить им какие то значения.
По литературе, У.Соммер "Программирование ......." это совсем для начала. Далее Керниган и Ричи "Язык С", это уже серьезнее.
Может кто еще что подкинет.
Подскажите пожалуйста, как вывести на экран значение переменных Temp1 и Temp2 из строк 299,310 в строки 157,161 ?
У Вас сейчас есть переменные int Temp1 и int Temp2, объявленные в функции loop(), а также переменные float temp1 и float temp2, объявленные в функции digitalClockDisplay().
Проще оставить только одну пару, пусть это будут int Temp1 и int Temp2. Сделайте их доступными из всех функций - строку 127 перенесите в начало скетча. Ну а теперь можно строку 299 изменить на T
emp1 = int(getTemp1());
, а строку 310, соответственно на Temp2 = int(getTemp2());
Если переменная будет использоваться в разных функциях скетча, то можно просто объявить её глобально для всего скетча и читать/писать везде, где надо. Но есть одно "но" - вот здесь предпоследний абзац прочитайте : http://arduino.ru/Tutorial/Variables, ну и всё остальное тоже ))).
Спасибо. Заработало! Но выводит только целое число, числа после запятой (десятые и сотые градуса) не показывает. Как исправить?
Вместо int сделайте переменные типа float, затем уберите преобразование int() из вызовов getTemp1() и getTemp2().
Заодно и про типы переменных удачный момент почитать )).
Udav4ik, решили все таки по максимуму в loop пихать. Если интересно, то посмотрите этот скетч и обратите внимание на его loop. Пост 282, некорректно перенаправляет.
Araris, Вам отдельное спасибо, пояснения конкретные и понятные. Скетч в посту 282 посмотрел, loop хорош конечно, но у меня пока мало знаний в программировании, чтобы сделать подобное, жаль конечно, но для реализации моих потребностей и имеющегося "железа" вполне хорош и этот.И главное - все работает ! =) Сейчас реализую его в железо, запущу в работу,а для будущих изысканий у меня есть еще одна платка ардуины, на ней стану дальше практиковаться в написании скетчей. Большое всем спасибо за помощь, Керниган и Риччи верно написали, на практике теория быстрее доходит до понимания =))) Вы думаете я не прочел про переменные еще в первом совете от ув.Araris ? Читал и не единожды, но без правки скетча я бы и не вспомнил за плавающюю float. В общем буду продолжать читать литературу...Приедет второй датчик ds18b20 , тогда подправлю скетч, чтобы два датчика на одном пине висели, а пока все нормально, бипер работает стабильно, таймеры включаются вовремя, еще раз, душевное спасибо за помощь!
И главное - все работает !
Категорически поддерживаю. Первые скетчи могут быть неоптимальными, некрасивыми, какими угодно, главное - они работают. А это ох как мощно вдохновляет на продолжение и дальнейшее совершенствование. Я сам года три тому назад начинал под Ардуино писать, я всё помню (мне правда полегче было, я давно программирую).
Udav4ik, вы похоже не заглянули в начало топика, ТС начал писать с чужого кода, по размеру меньше Вашего, 10.12.14. Закончил 17.02.15. В программировании я ему помогал очень мало, т.к. и сам профан, начал вспоминать как это делать через 25 лет после любительских Бейсика и Фортрана(см. дату регистрации на форуме). Основная помощь заключалась в разбитии на логические задачи.
А так, соглашусь с Araris, хороший код, это тот, который работает и устраивает пользователя.
bwn, нет, я смотрел и начало топика, правда не слишком далеко и конечно пост 282 в перевую очередь глянул. По видимому мы с автором того топика отталкивались от одинакого скетча, работы реле по суточному таймеру, а потом каждый сделал под свои видения аква жизни и запросы.Меня заинтересовал один вопрос, который Вы упомянули в начале топика, проверить точность датчика влажности, насыпаем в банку от майонеза соль , капаем воду, суем туда датчик,плотно закрываем, датчик должен показать 75-76% влажности. Поподробнее не расскажите? Сколько соли, сколько воды? И зачем вообще нужна соль?
Не помню, как правильно называется метод (хотите, погуглите), но суть такова: Любой насыщенный раствор солей, образует над своей поверхностью равновесное состояние влажности. Для NaCl это 75% и мало меняется от температуры, для других солей, другие значения (можно проверить всю шкалу).
В банку насыпаете с чайную ложку соли, капаете несколько капель воды (должна быть влажная, но без лужи) и закрываете от контакта с атмосферой. У меня время стабилизации занимало минут 40 - час. Поскольку берем соли не х.ч и воду не дистилированную, допустимо небольшое отклонение от табличного, но для домашних нужд вполне достаточно. Желательно конечно проверить в других диапазонах, но этих солей на кухне не найдете.
ок, принцип понял, спасибо.А то есть несколько китайских приборов измерения влажности и все показывают по своему.
Уважаемые форумчане, кто нибудь знает как вместо бипов симитировать голос кукушки? Какой надо поставить тон и длительность? В гугле по запросу "имитация звука кукушки" ничего толком кроме этого не нашел:
http://www.junradio.com/blog/zvukovoj_imitator_golosa_kukushki/2015-07-2...
но подставив эти частоты, услышал совсем не похожий звук на кукушкин.
Udav4ik, можно пойти другим путём. Находите нужный звук кукушки в виде (короткого!) WAV в интернете, затем идёте сюда качаете библу, там же в обсуждении находите конвертор wav- *.h. И слушаете wav через ардуино.
Что то не работает библиотека Play sound по ссылке. Скачал ее , установил, конвертировал файл wav звука кукушки в *.h добавил его в библиотеку плей соунд, загрузил пример скетча для проигрования звуков, при компиляции выдает такую ошибку:
Udav4ik, то есть "какой либо звук"? Там с библой куча примеров звуков, в библе есть готовый рабочий скетч. Всё это рабочее, я недавно пользовался.
Вот именно из библ он не может проиграть пример.При проверке, компиляии вдает ошибку.
Udav4ik, судя по вашей строчке C:\Users\A4F7~1\AppData\Local\Temp\arduino_37b1009bba23b2a3c15c2a669eeaf87b\sketch_dec14a.ino: In function 'void loop()':
вы запускаете что угодно, но не тот пример, который идёт с библой. Хотя бы потому, что он находится в папке play_sound и называется иначе. Просто заqдите проводником в папку библиотекой, и запустите play_sound.pde
play_sound.pde я тоже открвал, вот ошибка:
Udav4ik, я не знаю где у вас косяк. Но он точно есть, потому как библа 100% рабочая. Скорее всего что-то задублировано, типа лишняя папка в папке. Сотрите все и распакуйте аккуратно заново. Там ещё нужно не забыть wprogram.h на arduino.h поменять, но в обсуждении об этом упоминалось.
программ на ардуино я тоже менял, а пин на выход спикера надо назначать?
выход там жёстко прописан, PB3 (11нога)
библиотека заработала, но файл расширением .wav (250кБ) программка конвертер переводит в расширение .h уже размером в 1,6 мБ и компилятор виснет и не может даже проверить скетч.
Udav4ik, какие 250кб? В ардуине всего 32к, и это на всё про всё. На звук ку-ку вполне хватит 10кб, если всё хорошенько ужать аудиоредактором.
"Жалко, королевство маловато, разгулятся мне негде" )
Интересно, если бы вам подвернулся десятимегабайтный wav, вы бы и его пытались впихнуть в ардуину?
Конвертер всего лишь убирает из wav служебную информацию и формирует сишный файл. По его размеру тоже сложно понять размер полученного. Размер можно посмотреть в константе (не помню формируемого названия), которая тоже записывается в этот файл.
Поэтому ориентируйтесь на размер wav, какого он размера, примерно столько же надо иметь свободного флеша в ардуине.
Пробовал конвертировать разными аудиоредакторами, меньше 3,7кБ у меня не вышло, попробуйте, кто разбирается в звукоредакторах:
https://yadi.sk/d/quuIk6j5mHUeH
Ну так 3,7 кБ из 250 - что еще хотеть надо, при этом если еще и звучит нормально, то это есть очень гуд.
Перекодировав в расширение *.h он выходит большим размером и получается уже 22кБ
Udav4ik вы что, размер файла смотрите? Он текстовый, и никакого отношения (почти никакого) к размеру прошиваемого блока данных не имеет.