Управление подсветкой дисплея 1602 I2C
- Войдите на сайт для отправки комментариев
Добрый день. Прошу помощи, пнуть в нужном направлении. Есть связка ардуино нано, LCD 1602 на шине I2C, DHT22, часы реального времени на базе DS3231 (тоже I2C). Подсветка включается посредством команды lcd.backlight(); Отключить ее можно командой lcd.noBacklight(); Основную задумку по коду почти реализовал кроме листинга выводимой на дисплей информации (код прилагаю), основная проблема с реализацией задумки вкл. и выкл. подсветки кнопкой. Идея такая, есть кнопка подключенная к пину D2 при ее нажатии подсветка должна отключится и при повторном нажатии снова включится. Планировалась реализация без коственно програмно без использования транзистора. Я перечитал много тем, примеров, но так и не нашел как реализовать это. Если не сложно подскажите пожалуйста. Буду очень благодарен.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <iarduino_RTC.h>
#include "DHT.h"
#define DHTPIN 2
DHT dht(DHTPIN, DHT22);
iarduino_RTC time(RTC_DS3231);
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup() {
dht.begin();
lcd.init();
lcd.backlight();
time.begin();
}
void loop(){
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
if(millis()%1000==0){
lcd.setCursor(0, 0);
lcd.print(time.gettime("H"));
lcd.setCursor(2, 0);
lcd.print(":");
lcd.setCursor(3, 0);
lcd.print(time.gettime("i"));
lcd.setCursor(5, 0);
lcd.print(":");
lcd.setCursor(6, 0);
lcd.print(time.gettime("s"));
lcd.setCursor(9, 0);
lcd.print(time.gettime("d"));
lcd.setCursor(12, 0);
lcd.print(time.gettime("Y"));
lcd.setCursor(0, 1);
lcd.print("t=");
lcd.setCursor(3, 1);
lcd.print(t, 1);
lcd.setCursor(7, 1);
lcd.print("c");
lcd.setCursor(9, 1);
lcd.print("h=");
lcd.setCursor(11, 1);
lcd.print(h, 1);
lcd.print("%");
}
}
А в чем проблема? Команды lcd.noBacklight(); /lcd.backlight(); работают?
Естественно работают. Я писал выше что не нашел информации как реализовать включение и выключение подсветки кнопкой не прибегая к отрезанию подсветки и управлению ею через транзистор.
Цитирую сам себя:
"Идея такая, есть кнопка подключенная к пину D2 при ее нажатии подсветка должна отключится и при повторном нажатии снова включится. "
Не понял. Если lcd.noBacklight() работает. То пошлите эту команду по нажатию кнопки. А по второму нажатию пошлите lcd.backlight().
Причем здесь транзистор?
Я пробовал, но видать где то я туплю. Не до конца понимаю как подставить эту команду. За основу взял этот кусок кода. Но не могу понять как правильно подсунуть команду, отладчик все время ругается на приставку lcd.
Я писал его для отработки флагов на кнопке, но как всунуть ему команду не могу понять((
ПС. Если вдруг что я не студент и курсак не пишу, я еще в 2015 закончил институт)) Я просто изучаю ардуинки.
boolean butt_flag = 0; boolean butt; boolean button_flag = 0; unsigned long last_press; void setup() { pinMode(3, INPUT_PULLUP); pinMode(4, OUTPUT); Serial.begin (9600); } void loop() { butt = !digitalRead(3); if (butt == 1 && butt_flag == 0 && millis() - last_press > 200) { butt_flag = 1; Serial.println("on"); button = !button; digitalWrite(4, button); last_press = millis(); } if (butt == 0 && butt_flag == 1) { butt_flag = 0; Serial.println("off"); } }Ну в коде от сообщения №1 на lcd же не ругается. Посмотрите там на строку 8 и помедетируйте.
Ну да, а еще на 2 и 13.
Попробую впарить ТСу свою кнопку)) Пусть разбирается.
#define CLICK_DOWN B10 #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,16,2); word carrMillis, prevMillis; const word interval = 20; const byte pinButt = 7; byte stateButt = 0xFF;//отпущена boolean stateLight = 0; void setup() { lcd.init(); lcd.backlight(); pinMode(pinButt, INPUT_PULLUP); } void loop() { carrMillis = millis();//интервалы до 1 минуты if(carrMillis - prevMillis >= interval){ prevMillis = carrMillis; stateButt <<= 1;//сдвиг.влево (в млад.бите ноль) stateButt |= digitalRead(pinButt);//пишем в млад.бит состояние кнопки if((stateButt & B11) == CLICK_DOWN){ stateLight ? lcd.backlight() : lcd.noBacklight(); stateLight = !stateLight; } } }Я писал выше что не нашел информации как реализовать включение и выключение подсветки кнопкой не прибегая к отрезанию подсветки и управлению ею через транзистор.
без транзистора и даже без МК
В перерывах от выходных забот немного занимался этой задачей в итоге основной код приобрел такой вид. Теперь подсветка включается и выключается тактовой кнопкой.
Единственный момент. Т.к. задействовал прерывание attachInterrupt(); вылез жесткий дребезг контактов кнопки, пытался избавится путем задержки но что то не выходит. Возможно где то не так делаю. Посмотрите, будьте любезны.
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <iarduino_RTC.h> #include "DHT.h" #define DHTPIN 2 DHT dht(DHTPIN, DHT22); iarduino_RTC time(RTC_DS3231); LiquidCrystal_I2C lcd(0x3F, 16, 2); boolean button_flag = 1; int ledPin = 13; unsigned long last_time; void setup() { dht.begin(); lcd.init(); delay(200); Serial.begin(9600); time.begin(); pinMode(3, INPUT_PULLUP); attachInterrupt(1, button, FALLING); } void loop() { if(button_flag) { lcd.backlight(); if (millis() - last_time > 100) { } } else { if (millis() - last_time > 100) { } lcd.noBacklight(); } float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); if(millis()%1000==0){ lcd.setCursor(0, 0); lcd.print(time.gettime("H")); lcd.setCursor(2, 0); lcd.print(":"); lcd.setCursor(3, 0); lcd.print(time.gettime("i")); lcd.setCursor(5, 0); lcd.print(":"); lcd.setCursor(6, 0); lcd.print(time.gettime("s")); lcd.setCursor(9, 0); lcd.print(time.gettime("d")); lcd.setCursor(12, 0); lcd.print(time.gettime("Y")); lcd.setCursor(0, 1); lcd.print("t="); lcd.setCursor(3, 1); lcd.print(t, 1); lcd.setCursor(7, 1); lcd.print("c"); lcd.setCursor(9, 1); lcd.print("h="); lcd.setCursor(11, 1); lcd.print(h, 1); lcd.print("%"); delay(1); } } void button(){ button_flag = !button_flag; }задействовать для кнопки целое прерывание не очень хорошая идея
Подскажите пожалуйста как надо. И почему идея плоха? Хочется понять. Буду очень признателен.
задействовать для кнопки целое прерывание не очень хорошая идея
Это ведь, как для одной тарелки холодца целого кабанчика заколоть!! ;)))))
Внешние прерывания attachInterrupt служат для отлавливания и обработки коротких импульсов, поэтому с кнопками, которые дают дребезг и относительно длительный импульс, их не используют.
Как правильно сделать - смотри предпоследний пример головного сообщения http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku
Ну не хочешь самый простой вариант, тогда пробуй так
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <iarduino_RTC.h> #include "DHT.h" #define DHTPIN 2 DHT dht(DHTPIN, DHT22); iarduino_RTC time(RTC_DS3231); LiquidCrystal_I2C lcd(0x3F, 16, 2); boolean button_flag = 0; int led_backlight=1; int ledPin = 13; unsigned long last_time=0; void setup() { dht.begin(); lcd.init(); delay(200); Serial.begin(9600); time.begin(); pinMode(3, INPUT_PULLUP); pinMode(13,OUTPUT); // attachInterrupt(1, button, FALLING); } void loop() { if(digitalRead(3)==HIGH && button_flag==0) button_flag=1; if(digitalRead(3)==LOW && button_flag==1) { if(led_backlight==1) { lcd.backlight(); led_backlight=0; } else { lcd.noBacklight(); led_backlight=1; } button_flag=0; if (millis() - last_time > 100) last_time=millis(); } float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); if(millis()%1000==0){ lcd.setCursor(0, 0); lcd.print(time.gettime("H")); lcd.setCursor(2, 0); lcd.print(":"); lcd.setCursor(3, 0); lcd.print(time.gettime("i")); lcd.setCursor(5, 0); lcd.print(":"); lcd.setCursor(6, 0); lcd.print(time.gettime("s")); lcd.setCursor(9, 0); lcd.print(time.gettime("d")); lcd.setCursor(12, 0); lcd.print(time.gettime("Y")); lcd.setCursor(0, 1); lcd.print("t="); lcd.setCursor(3, 1); lcd.print(t, 1); lcd.setCursor(7, 1); lcd.print("c"); lcd.setCursor(9, 1); lcd.print("h="); lcd.setCursor(11, 1); lcd.print(h, 1); lcd.print("%"); delay(1); } }Поставьте кнопку с фиксацией или тумблер, зачем извращаться-то в данном вопросе?
Поставьте кнопку с фиксацией или тумблер, зачем извращаться-то в данном вопросе?
Замена возможности программного управления (в данном случае: вкл-выкл) на аппаратное, конечно упрощает решение, но не прибавляет мыслей для развития проекта. С помощью той же (одной) кнопки довольно просто реализовать не только включение-выключение подсветки, но и изменение яркости подсветки с помощью ШИМ. Или сделать то же самое дистанционно на IR. Или сделать автоматическое выключение подсветки через заданное время, чтобы лишний раз не давить на кнопку.
Можно даже этой кнопкой в космос запускать ракету.
Но коли человек мучается с прерыванием, то пусть уж для начала опрашивает нормально замкнутую или разомкнутую кнопку в лупе. Научится - перейдет к прерыванию, если захочет.
Спасибо. Вот именно исходя из этих соображений (пробовать руками и научится, понять) я вникаю в этот момент. Тумблер беспорно простое решение, но это шаг назад в развитии.
Ну не хочешь самый простой вариант, тогда пробуй так
Спасибо. Вот оно, как говорится рядом было. Я ковырял вот этот кусок кода. Только у меня подсвет включался по нажатию и отключался когда я отпускал кнопку.
boolean butt_flag = 0; boolean butt; boolean led_flag = 0; unsigned long last_press; void setup() { pinMode(3, INPUT_PULLUP); Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { butt = !digitalRead(3); // считать текущее положение кнопки if (butt == 1 && butt_flag == 0 && millis() - last_press > 100) { butt_flag = 1; Serial.println("On"); led_flag = !led_flag; digitalWrite(13, led_flag); last_press = millis(); } if (butt == 0 && butt_flag == 1) { butt_flag = 0; Serial.println("Off"); } }Добрый день! Я начинающий программист-любитель.Ни одного скетча еще не написал. Но встретил в сети любопытную систему программирования FLProg называется. Программирование с помощью соединения графических изображений элементов. Таких систем видимо существует несколько, но я попал на эту. Захотелось сделать на базе Ардуино нано схему управления насосом пневомобака установленного в колодце, дабы заменить механические реле давления аналоговым датчиком давления. И, о чудо, все получилось с нескольких попыток.
Попробовал порешать Вашу проблему, получился вот такой скетч:
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C _lcd1(0x27, 16, 2); int _dispTempLength1=0; boolean _isNeedClearDisp1; int _disp6oldLength = 0; bool _D1B2 = 0; bool _bounseInputD2S = 0; bool _bounseInputD2O = 0; unsigned long _bounseInputD2P = 0UL; bool _trgt1 = 0; bool _trgt1I = 0; void setup() { Wire.begin(); delay(10); pinMode(2, INPUT_PULLUP); _lcd1.init(); _lcd1.noBacklight(); _bounseInputD2O = digitalRead(2); } void loop() {if (_isNeedClearDisp1) {_lcd1.clear(); _isNeedClearDisp1= 0;} bool _bounceInputTmpD2 = (digitalRead (2)); if (_bounseInputD2S) { if (millis() >= (_bounseInputD2P + 40)) {_bounseInputD2O= _bounceInputTmpD2; _bounseInputD2S=0;} } else { if (_bounceInputTmpD2 != _bounseInputD2O ) {_bounseInputD2S=1; _bounseInputD2P = millis();} } //Плата:1 if (!(0)) { _dispTempLength1 = (String("Out of date")).length(); if (_disp6oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;} _disp6oldLength = _dispTempLength1; _lcd1.setCursor(int((16 - _dispTempLength1)/2), 1); _lcd1.print(String("Out of date")); } else { if (_disp6oldLength > 0) {_isNeedClearDisp1 = 1; _disp6oldLength = 0;} } bool _tmp1 = !(_bounseInputD2O); if (_tmp1) { if (! _trgt1I) _trgt1 = ! _trgt1; } _trgt1I = _tmp1; if(_trgt1) {if(! _D1B2){_lcd1.backlight(); _D1B2=1; }} else {if(_D1B2){_lcd1.noBacklight(); _D1B2=0; }} }Немедленно выкинь каку!!!!
Во, во, и руки с мылом помой.))))
Виктор50 - для обсуждения программ, написанных на ФЛПРОГе и ей подобных системах существуют специальные форумы. На нашем форуме не стоит даже упоминать, что вы этой системой пользуетесь - с вами после этого и пары слов никто не захочет сказать.
Чтобы вы не думали, что это просто ретроградство - могу сказать что даже поверхностный взгляд на ваш код сразу вылавливает кучу косяков. Вот некоторые
строка 31 - неверная работа со временем
строка 42 - бредовое условие
строки 43 и 47 - неаккуратное отношение к памяти - повтороное использование одной и тоже строки в формате String
Система FLProg генерит монструозный, абсолютно нечитаемый код, который содержит много корявых конструкций и не слишком эффективно работает. Зачем пользоваться этим костылем, когда вручную можно написать короче и красивее? :)
Для многих здешних обиталей программирование - это творчество, это игра, это похоже на флирт. А вы нам предлагаете флиртовать с надувной куклой из секс-шопа? :)