Здравствуйте товарищи. В общем делаю контроллер для аквариума, ну часть уже сделал - но нужно, чтобы кнопкой была возможность отключения системы (т.е. кнопке должен даваться флаг 0,1 или 2) - пока значение флага выводится на экран 16х2 - флаг записывается в переменную svet. Попробовал сделать задержку в 400 миллисекунд, но кнопка работает нестабильно - т.е. не всегда срабатывает - в общем случае переключается и выдает на экран значения 0,1,2 - но иногда требуется несколько раз нажать кнопку - хотелось бы решить проблему, но вот с библиотекой дебоунс совсем не знаком - только учусь - помогите разобраться - как сделать, чтобы кнопка меняла флаг нормально, с первого раза Буду очень благодарен за ответы Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); LiquidCrystal_I2C lcd(0x27,16,2); // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2) int Relay1 = 3; //реле на нагреватель int Relay2 = 4; // реле на кулеры int ButPin = 5; // пин на кнопку int theat=25; //температура при которой включается нагреватель int tcool=29; //температура при которой включается кулер int svet = 0; //флаг по умолчанию равен нулю void setup(void) { pinMode(Relay1, OUTPUT); pinMode(Relay2, OUTPUT); // pinMode(ButPin, INPUT); digitalWrite(3, HIGH); digitalWrite(4, HIGH); lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку lcd.clear(); // очистка дисплея // start serial port Serial.begin(9600); Serial.println("Dallas Temperature IC Control Library Demo"); // Start up the library sensors.begin(); lcd.setCursor(0, 0); // устанавливаем курсор на 1 строку, 1 символ lcd.print("H:"); // вывод надписи lcd.setCursor(4, 0); // устанавливаем курсор на 1 строку, 9 символ lcd.print("C:"); lcd.setCursor(8, 0); // устанавливаем курсор на 1 строку, 9 символ lcd.print("F:"); lcd.setCursor(12, 0); // устанавливаем курсор на 1 строку, 9 символ lcd.print("S:"); lcd.setCursor(8, 1); // устанавливаем курсор на 1 строку, 9 символ lcd.print("t:"); lcd.setCursor(0, 1); // устанавливаем курсор на 1 строку, 9 символ lcd.print("S:"); lcd.setCursor(4, 1); // устанавливаем курсор на 1 строку, 9 символ lcd.print("O:"); } void loop() { { if(digitalRead(ButPin) == LOW && svet == 0) { svet = 1; Serial.print("1"); lcd.setCursor(2, 1); lcd.print("1"); delay(400); } if(digitalRead(ButPin) == LOW && svet == 1) { svet = 2; Serial.print("2"); lcd.setCursor(2, 1); lcd.print("2"); delay(400); } if(digitalRead(ButPin) == LOW && svet == 2) { svet = 0; Serial.print("0"); lcd.setCursor(2, 1); lcd.print("0"); delay(400); } } sensors.requestTemperatures(); // Send the command to get temperatures //Serial.print("Temperature for the device 1 (index 0) is: "); //Serial.println(sensors.getTempCByIndex(0)); float temp = sensors.getTempCByIndex(0); lcd.setCursor(10, 1); lcd.print(temp,1); lcd.print((char)223); lcd.print("C "); if (temp < theat) { digitalWrite(3, LOW); lcd.setCursor(2, 0); lcd.print("1"); } else { digitalWrite(3, HIGH); lcd.setCursor(2, 0); lcd.print("0"); } if (temp > tcool) // { digitalWrite(4, LOW); lcd.setCursor(6, 0); lcd.print("1"); } else { digitalWrite(4, HIGH); lcd.setCursor(6, 0); lcd.print("0"); } }
И еще - подскажите - какое питание нужно подать на ардуино - будет использоваться ардуино про мини. Вообще хочу сделать, чтобы в коробку подавалось 220в - далее пойдет развязка на реле - чтобы управлять 3 устройствами 220 и 1 устройством 12в + питание самой ардуины. Я так понимаю нужно взять драйвер или что то похожее - подскажите что заказать - желательно на али или ебее. И еще такой вопрос - достаточно будет подать например 5в на ардуино с юсб - потянет для питания шилда 4 реле + экрана, блютуф и датчика температуры? Или на реле лучше отдельно питание подать? В общем подскажите нубу как все правильно сделать. Заранее всем спасибо за помощь И извините за глупые вопросы
Всё просмотрел не увидел где у Вас "дребезг". Нет непосредственной команды от кнопки ButPin = 5? Тогда и антидребезг не нужен (дребезг идёт только от кнопки от других датчиков-нет)код на Си тем более в "обвёртке" от Ардуино выполняется медленно но если будет такая необходимость добавьте строку Delay (100); этого вполне хватит. Теперь про питание:подойдёт любое 5-12 в Ардуино есть стабилизатор-поэтому можно и от USB смотря какие релюхи у Вас стоят если на 5 вольт то можно и не париться если на 12 то смело подавайте 12 на всех шилдах есть встроенные стабилизаторы.Реле шилд можно заказать на Ебае придёт за 2 недели но я делал сам с релюхами на 5 вольт чтоб питать по USB.
вы не верно обрабатываете не только "анти дребезг" но и обработку переменной svet!поэтому вам как новичку лучше будет все-же с библиотекой Bounce PHP: #include <Bounce.h> #define ButPin 5 // пин на кнопку int svet = 0; //флаг по умолчанию равен нулю Bounce bouncer = Bounce(ButPin, 50); //создаем экземпляр класса Bounce для ButPin void setup() { pinMode(ButPin, INPUT); //переключаем ButPin (5) вывод в режим входа digitalWrite(ButPin, 1); //включаем на нем подтягивающий резистор } void loop() { if (bouncer.update()) { //если произошло событие if (bouncer.read()==LOW) { //если кнопка нажата switch (svet) { case 0: svet = 1; // здесь любой код для svet=0 break; case 1: // по аналогии case 0: break; } } } // дальше трудимся } библиотеку можно поискать здесь на форуме
Пробовал с этой библиотекой - но как то не получилось - но Ваш пример мне очень понравился - нафиг делать кучу условий, если можно поставить выбор Блин как же я про case забыл то Спасибки - буду копать. Вообще понял - надо наверно будет полностью переделать программку - начать с общего скелета, а то пытался все последовательно делать, но в результате код очень некрасивый и путанный получался - попробую переделать. Ну вроде делей поставил - лучше всего кнопка срабатывала при 600 - на черновом варианте так и оставил - но буду переделывать под библиотеку дебоунс, как советовали ниже. реле у меня шилдом идет блок на 4 реле (питание 5в). Если питаю от ардуино (подключена к ПК) - то при включении реле экран 16х2 заметно темнеет - при отключении реле - ярче загорается. Т.е. как понимаю - лучше запитать от 5 в - отдельно каждое устройство - чтобы не грузить МК. В идеале хочу чтобы в коробку со всеми устройствами приходило 220в, далее шла микросхема(ну как назвать - преобразователь 220-5, драйвер или еще как это называется) которая из 220 делает 5в (ну в общем чтобы отдельный блок питания не использовать - можно конечно просто разобрать БП на 5в 2А - но наверняка есть вариант поинтереснее - где то на ебее видел что то типа dc-dc 220 - (5-15) - но не могу найти PS - а вот сейчас нашел - вот это подойдет? http://www.ebay.com/itm/AC-to-DC-Po...357?pt=LH_DefaultDomain_0&hash=item3a86c22815 - я так понимаю, что подаю 220в - на выходе получаю 5в 1а ???? - и от этого уже параллельно запитать ардуино, экран, реле?
Вот поморочился сегодня - переделал программу - правда времени мало было - хоккей все таки. В общем получилось вот что Код (Text): #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <DS1307new.h> #include <Bounce.h> #define ButPin 5 // пин на кнопку 1 #define ButPin2 8 // пин на кнопку 2 #define ONE_WIRE_BUS 2 //на 2 пин подключаем датчик температуры // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); LiquidCrystal_I2C lcd(0x27,16,2); // устанавливаем адрес 0x27, и дисплей 16 символов в 2 строки (16х2) //для часиков uint16_t startAddr = 0x0000; // Начальный адрес для хранения в NV-RAM uint16_t lastAddr; // новый адрес для хранения в NV-RAM uint16_t TimeIsSet = 0xaa55; // По этой переменной проверяется то, что время не нужно устанавливать заново int Relay1 = 3; //реле на нагреватель int Relay2 = 4; // реле на кулеры int Relay3 = 6; // реле на фильтр int Relay4 = 7; // реле на свет int theat=25; //температура при которой включается нагреватель int tcool=29; //температура при которой включается кулер int svet = 0; //флаг по умолчанию равен нулю - свет int oborud = 0; //флаг по умолчанию равен нулю - все остальное оборудование int vkl = 10; int vykl = 22; Bounce bouncer = Bounce(ButPin, 50); //создаем экземпляр класса Bounce для ButPin Bounce bouncer2 = Bounce(ButPin2, 50); //создаем экземпляр класса Bounce для ButPin2 void setup(void) { pinMode(Relay1, OUTPUT); pinMode(Relay2, OUTPUT); pinMode(Relay3, OUTPUT); pinMode(Relay4, OUTPUT); pinMode(ButPin, INPUT); //переключаем ButPin (5) вывод в режим входа pinMode(ButPin2, INPUT); //переключаем ButPin2 (8) вывод в режим входа digitalWrite(ButPin, 1); //включаем на нем подтягивающий резистор digitalWrite(ButPin2, 1); //включаем на нем подтягивающий резистор digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); lcd.init(); // инициализация LCD lcd.backlight(); // включаем подсветку lcd.clear(); // очистка дисплея Serial.begin(9600); RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t)); RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); if (TimeIsSet != 0xaa55) { RTC.stopClock(); RTC.fillByYMD(2014,5,11); //устанавливаем дату RTC.fillByHMS(15,23,0); //устанавливаем время RTC.setTime(); TimeIsSet = 0xaa55; RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); RTC.startClock(); } else { RTC.getTime(); } RTC.setCTRL(); sensors.begin(); lcd.setCursor(0, 0); lcd.print("H:"); lcd.setCursor(4, 0); lcd.print("C:"); lcd.setCursor(8, 0); lcd.print("F:"); lcd.setCursor(12, 0); lcd.print("S:"); lcd.setCursor(8, 1); lcd.print("t:"); lcd.setCursor(0, 1); lcd.print("S:"); lcd.setCursor(4, 1); lcd.print("O:"); } void loop() { sensors.requestTemperatures(); float temp = sensors.getTempCByIndex(0); lcd.setCursor(10, 1); lcd.print(temp,1); lcd.print((char)223); lcd.print("C "); if (bouncer.update()) { //если произошло событие if (bouncer.read()==LOW) { //если кнопка нажата switch (svet) { case 0:// здесь любой код для svet=0 svet = 1; Serial.print("1"); lcd.setCursor(2, 1); lcd.print("1"); digitalWrite(7, LOW); lcd.setCursor(14, 0); lcd.print("1"); break; case 1: svet = 2; Serial.print("A"); lcd.setCursor(2, 1); lcd.print("A"); RTC.getTime(); if (vkl < RTC.hour & RTC.hour < vykl) // если время больше времени включения и меньше времени выключения (в часах), включаем свет {digitalWrite(7, LOW); lcd.setCursor(14, 0); lcd.print("1");} else {digitalWrite(7, HIGH); lcd.setCursor(14, 0); lcd.print("0");} break; case 2: svet = 0; Serial.print("0"); lcd.setCursor(2, 1); lcd.print("0"); digitalWrite(7, HIGH); lcd.setCursor(14, 0); lcd.print("0"); break; } } } if (bouncer2.update()) { if (bouncer2.read()==LOW) { switch (oborud) { case 0: oborud = 1; Serial.print("1"); lcd.setCursor(6, 1); lcd.print("1"); break; case 1: oborud = 2; Serial.print("A"); lcd.setCursor(6, 1); lcd.print("A"); break; case 2: oborud = 0; Serial.print("0"); lcd.setCursor(6, 1); lcd.print("0"); break; } } } switch (oborud){ case 0: digitalWrite(3, HIGH); lcd.setCursor(2, 0); lcd.print("0"); digitalWrite(4, HIGH); lcd.setCursor(6, 0); lcd.print("0"); break; case 1: digitalWrite(3, LOW); lcd.setCursor(2, 0); lcd.print("1"); digitalWrite(4, LOW); lcd.setCursor(6, 0); lcd.print("1"); break; case 2: if (temp < theat) // если температура воды меньше theat, включаем нагреватель {digitalWrite(3, LOW); lcd.setCursor(2, 0); lcd.print("1");} else {digitalWrite(3, HIGH); lcd.setCursor(2, 0); lcd.print("0");} if (temp > tcool) // если температура воды больше tcool, включаем кулеры {digitalWrite(4, LOW); lcd.setCursor(6, 0); lcd.print("1");} else {digitalWrite(4, HIGH); lcd.setCursor(6, 0); lcd.print("0");} break;} } Теперь одна проблема - строка sensors.requestTemperatures(); В общем она тормозит программу - т.е. дребезг кнопок перестает работать - вернее кнопки вообще стали редко переключаться - можно 10-15 раз нажать чтобы переключилась - если ее закомментировать - то все работает быстро и без проблем - дребезг кнопки решается - но как только идет опрос датчика температуры - начинается затык программы - тормозит - и из-за этого вероятно плохое срабатывание кнопок - может эту функцию куда в другое место вынести? Моих мозгов и опыта пока не хватает
здесь я вам могу посоветовать обратное , наоборот отказаться от библиотеке DallasTemperature.h и обращаться к датчику на прямую через OneWire.h,примеров здесь предостаточно!