Переход с аналоговых кнопок на цифровые, помогите!
- Войдите на сайт для отправки комментариев
Сб, 25/07/2015 - 23:53
Переход с аналоговых кнопок на цифровые не получается, кнопка на пине 7 работает, вхожу в установочное меню, а вот дальше все останавсливается. Подскажите пожалуйста, что я делаю неправильно?
На аналоговых кнопках все работало, в коде закоменторованые остатки обработки аналоговых кнопок.
// термостат, один датчик DS18B20
//
//
#include <EEPROM.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
#include <OLED_I2C.h>
#define OUT1 13 // выход для реле
OneWire ds(15); // 15 вход датчика 18b20
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OLED myOLED(SDA, SCL, 8);
extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];
// constants won't change
//int analogPin = 2;
//int val = 0; // variable for reading the pushbutton status
long previousMillis = 0;
int flag1=0;
int flag2=0;
int flag3=0;
// variables will change:
float tempON;
// ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА
byte gradus[8] = {
0b00110,
0b01001,
0b01001,
0b00110,
0b00000,
0b00000,
0b00000,
0b00000
};
byte on[8] = {
0b00000,
0b00000,
0b10001,
0b01110,
0b01110,
0b10001,
0b00000,
0b00000
};
// ОБРАБОТКА ОШИБОК
void erorr(){ // останавливает работу программы и показываем ошибку
digitalWrite(OUT1, LOW); // выключаем реле
while(1){ // крутим бесконечный цикл
digitalWrite(13, !digitalRead(13));
delay(100);
}
}
// ОПИСАНИ КНОПОК
byte key()
{
// int val = analogRead(analogPin);
// Serial.print(val);
// if (val < 50) return 1;
// else if (val < 500) return 2; //Left Button
// else if (val < 900) return 3; //Right Button
// else return 0;
//"SETUP" Button connected to 7
if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ...
{
if (millis() -previousMillis >500) return 1;
{
previousMillis = millis();
flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие
}
}
if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
flag1=0;//обнуляем переменную flag
}
//"DOWN" Button connected to 4
if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ...
{
if (millis() -previousMillis >500) return 2;
{
previousMillis = millis();
flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие
}
}
if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ...
{
flag2=0;//обнуляем переменную flag
}
// else return 0;
}
// ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV)
void setMenu()
{
byte pos;
digitalWrite(OUT1, LOW); // выключаем реле
while(1)
{ // крутим бесконечный цикл
byte KEY = key(); // читаем состояние кнопок
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("SV: ");
lcd.blink();
lcd.setCursor(4, 0); // выводим на экран
lcd.print(tempON); //установленное знанчение температуры
lcd.write(1); //символ градуса
lcd.print("C ");
lcd.setCursor(0, 0);
//TEST OLED
myOLED.clrScr();
myOLED.setFont(SmallFont);
myOLED.print("SV", 10, 20);
myOLED.setFont(BigNumbers);
myOLED.printNumF(tempON, 2, 30, 20);
myOLED.drawCircle(110, 23, 2); // hor, ver ,size
myOLED.setFont(SmallFont);
myOLED.print("C", 114, 22);
myOLED.update();
// обработка кнопок
if (KEY == 2) // если кнопка DOWN нажата
{
tempON-= 0.5; // изменяем значение
if (tempON < 20) tempON = 95; //проверяем пределы
}
else if (KEY == 3) // если правая кнопка нажата
{
tempON+= 0.5; // изменяем значение
if (tempON > 95) tempON = 20; //проверяем пределы
}
else if (KEY == 1) // если правая кнопка нажата
{
EEPROM.put(0, tempON); // сохраняем в eeprom
//return;
}
// delay(100);
}
}
// ОПРОС ДАТЧИКА
float getTemp(){ // возвращает температуру с датчика
byte data[12]; // и останавливает программу на секунду
byte addr[8];
if (!ds.search(addr)) { //если адрес датчика не получен сообщаем об ошибке
lcd.clear();
lcd.print("No sensor");
//OLED TEST
myOLED.begin();
myOLED.setFont(SmallFont);
myOLED.print("NO SENSOR", 37, 30);
myOLED.update();
erorr();
}
ds.reset_search();
if (OneWire::crc8(addr, 7) != addr[7]) {
lcd.clear();
lcd.print("Sensor CRC erorr");
//OLED TEST
myOLED.begin();
myOLED.setFont(SmallFont);
myOLED.print("SENSOR CRC ERROR", 30, 30);
myOLED.update();
erorr();
}
ds.reset();
ds.select(addr);
ds.write(0x44);
delay(500);
ds.reset();
ds.select(addr);
ds.write(0xBE);
for (int i = 0; i < 9; i++) data[i] = ds.read();
int raw = (data[1] << 8) | data[0]; // Переводим в температуру
if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];
return raw / 16.0;
}
void setup() {
Serial.begin(9600);
//digitalWrite(2, HIGH); // Button pin
pinMode(13, OUTPUT);
// Buttons setup
pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin
digitalWrite(7, HIGH);
pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin
digitalWrite(4, HIGH);
pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin
digitalWrite(2, HIGH);
lcd.createChar(1, gradus);
lcd.createChar(2, on);
lcd.begin(16, 2);
lcd.clear();
myOLED.begin();
pinMode(13, OUTPUT);
pinMode(OUT1, OUTPUT);
tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром
}
void loop() {
if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры
float temperature = getTemp(); // читаем температуру
if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру
else digitalWrite(OUT1, LOW); // и управляем выходами
// ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ
lcd.setCursor(0, 1); /// вывод на экран заданной температуры
lcd.print("SV:");
lcd.print(tempON);
lcd.write(1);
lcd.print("C ");
if (digitalRead(OUT1)) lcd.write(2); // вывод на экран состояние выхода
else lcd.print(" ");
lcd.setCursor(0, 0); // вывод на экран текущей температуры
lcd.print("PV:");
lcd.print(temperature);
lcd.write(1);
lcd.print("C");
lcd.setCursor(9, 1);
// TEST OLED
myOLED.setFont(SmallFont);
myOLED.print("PV", 10, 05);
myOLED.print("SV", 10, 39);
myOLED.print("C", 115, 05);
myOLED.print("C", 115, 39);
if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода
else myOLED.print(" ", 13, 16);
myOLED.setFont(BigNumbers);
myOLED.printNumF(temperature, 2, 30, 03);
myOLED.printNumF(tempON, 2, 30, 37);
myOLED.drawCircle(111, 06, 2); // hor, ver ,size
myOLED.drawCircle(111, 40, 2); // hor, ver ,size
myOLED.update();
}
Переход с аналоговых кнопок на цифровые...
не бывает ни тех , ни других :(
...ставьте галочку - "свернуть код" при размещении , а не только - "пронумеровать"....
пины 4 и 7 отведены под LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
а ты читаешь их как кнопки :(
задефайнь под кнопки другие пины , с подтяжкой пинов к VСС , а кнопки на GND ( резисторов будет меньше )
переход с резистивной клавы на две кнопки по одному аналоговому пину
приведёт к использованию двух пинов в цифровом режиме....
нуууу , и обработка нажатий кнопок изменится :)
Переход с аналоговых кнопок на цифровые...
не бывает ни тех , ни других :(
...ставьте галочку - "свернуть код" при размещении , а не только - "пронумеровать"....
пины 4 и 7 отведены под LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
а ты читаешь их как кнопки :(
задефайнь под кнопки другие пины , с подтяжкой пинов к VСС , а кнопки на GND ( резисторов будет меньше )
переход с резистивной клавы на две кнопки по одному аналоговому пину
приведёт к использованию двух пинов в цифровом режиме....
нуууу , и обработка нажатий кнопок изменится :)
Спасибо! Уже и сам понял :) Заработало!
Пины подтянуты к VCC и сажаются на ноль кнопкой.
Второй диспелей не используется, это остатки экспериментов, закоментировал все относящиеся к LED, отключил библиотеку и заработали кнопки. Но при одном нажатии кнопки установки темепературы (прибавить/отнять) идет быстрая прокрутка, так как пробавление идет в цикле, как это побороть бед delay?
Не подскажете, как сделать чтоб после повторного нажания (при этом новое значение темепературы записыавется в память) программа перезапускалась сначала? Сейчас для этого надо надавить ресет.
код покажи :)
Не подскажете, как сделать чтоб после повторного нажания (при этом новое значение темепературы записыавется в память) программа перезапускалась сначала? Сейчас для этого надо надавить ресет.
В даташите ATmega48PA/88PA/168PA/328P описано как программно вызвать Reset через Watch Dog Timer. Почитайте главу 10 даташита, там даже есть примеры на С и на ассемблере.
Не подскажете, как сделать чтоб после повторного нажания (при этом новое значение темепературы записыавется в память) программа перезапускалась сначала? Сейчас для этого надо надавить ресет.
...для этого надо правильно написать ЛУУП , а не ресетить !
см. #3
строки 36...45 - это стандартный символ , зачем ещё один определять ?
код покажи :)
Вот. Работает приемлемо, но хотелось бы от delay избавится при обработке кнопок, почему идет прокрутка при нажатой кнопке? Получается flag не реботает?
Ну и выход из меню установки темепературы пока не знаю как правильно сделать.
// термостат, один датчик DS18B20 // // #include <EEPROM.h> #include <OneWire.h> #include <OLED_I2C.h> #define OUT1 13 // выход для реле OneWire ds(15); // 15 вход датчика 18b20 OLED myOLED(SDA, SCL, 8); extern uint8_t SmallFont[]; extern uint8_t BigNumbers[]; long previousMillis = 0; int flag1=0; int flag2=0; int flag3=0; // variables will change: float tempON; // ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00000, 0b00000, 0b10001, 0b01110, 0b01110, 0b10001, 0b00000, 0b00000 }; // ОБРАБОТКА ОШИБОК void erorr(){ // останавливает работу программы и показываем ошибку digitalWrite(OUT1, LOW); // выключаем реле while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(100); } } // ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag } //"DOWN" Button connected to 4 if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 2; { previousMillis = millis(); flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag2=0;//обнуляем переменную flag } //"UP" Button connected to 2 if(digitalRead(2)==LOW&&flag3==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 3; { previousMillis = millis(); flag3=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(2)==HIGH&&flag3==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag3=0;//обнуляем переменную flag } else return 0; } // ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV) void setMenu() { byte pos; digitalWrite(OUT1, LOW); // выключаем реле while(1) { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок // delay(150); // OLED display myOLED.clrScr(); myOLED.setFont(SmallFont); myOLED.print("SV", 10, 20); myOLED.setFont(BigNumbers); myOLED.printNumF(tempON, 2, 30, 20); myOLED.drawCircle(110, 23, 2); // hor, ver ,size myOLED.setFont(SmallFont); myOLED.print("C", 114, 22); myOLED.update(); // обработка кнопок if (KEY == 2) // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы } else if (KEY == 3) // если правая кнопка нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы } else if (KEY == 1) // если правая кнопка нажата { EEPROM.put(0, tempON); // сохраняем в eeprom } delay(200); } } // ОПРОС ДАТЧИКА float getTemp(){ // возвращает температуру с датчика byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) //если адрес датчика не получен сообщаем об ошибке { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("NO SENSOR", 37, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("SENSOR CRC ERROR", 30, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(500); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); pinMode(13, OUTPUT); // Buttons setup pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin digitalWrite(7, HIGH); pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin digitalWrite(4, HIGH); pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin digitalWrite(2, HIGH); myOLED.begin(); pinMode(13, OUTPUT); pinMode(OUT1, OUTPUT); tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры float temperature = getTemp(); // читаем температуру if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру else digitalWrite(OUT1, LOW); // и управляем выходами // ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ myOLED.setFont(SmallFont); myOLED.print("PV", 10, 05); myOLED.print("SV", 10, 39); myOLED.print("C", 115, 05); myOLED.print("C", 115, 39); if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода else myOLED.print(" ", 13, 16); myOLED.setFont(BigNumbers); myOLED.printNumF(temperature, 2, 30, 03); myOLED.printNumF(tempON, 2, 30, 37); myOLED.drawCircle(111, 06, 2); // hor, ver ,size myOLED.drawCircle(111, 40, 2); // hor, ver ,size myOLED.update(); }строки 36...45 - это стандартный символ , зачем ещё один определять ?
В библитеке шрифтов мало, нужного размера вроде там нет, ну или я не увидел :) проверю еще раз.
Не подскажете, как сделать чтоб после повторного нажания (при этом новое значение темепературы записыавется в память) программа перезапускалась сначала? Сейчас для этого надо надавить ресет.
...для этого надо правильно написать ЛУУП , а не ресетить !
Попробовал то что нашел здесь на форуме
Вставил вызов функции после:
При входе в меню сразу срабатыавет ресет, значит флаги у меня не работают и кнопка выдат сигнал все время пока нажата :(
строки 18...20 - зачем три флага да ещё по 4 байта ?
хватит и одного - см. enum
В библитеке шрифтов мало, нужного размера вроде там нет, ну или я не увидел :) проверю еще раз.
не проверяй... я тупанул не зная что за дисплей....
почему идет прокрутка при нажатой кнопке? Получается flag не реботает?
кроме события "нажатие на кнопку" нужно ещё следить за событием "отпускание кнопки"
и кнопка выдат сигнал все время пока нажата :(
дык , у неё работа такая ! выдавать или не выдавать....
...независимо от того что происходит в программе :)-
в лупе в строке 265 при нажатии попадаем в setMenu() , и как оттуда выбраться если там while(1) ?
или я что-то просмотрел...
162...180 будет читаемееееее если сделать через switch-case .....
key() возвращает 0....3 , а обрабатываешь почему только 1....3 ?
key() возвращает 0....3 , а обрабатываешь почему только 1....3 ?
возврат 0 наследие из использованного примера :) если если убрать ничего вроде не меняется. Обрабатывается нажание трех кнопок т.е. 1, 2, 3
а где это в коде
EEPROM.put(0, tempON);// сохраняем в eeprom?в лупе в строке 265 при нажатии попадаем в setMenu() , и как оттуда выбраться если там while(1) ?
или я что-то просмотрел...
162...180 будет читаемееееее если сделать через switch-case .....
Из лупа выбираемся ресетом. Я только осваиваю программирование, так что модифицирую подходящие примеры найденные в интернете и по ходу разбираюсь, выбиратся из этого лупа пока не научился, сижу, изучаю документацию.
как "сделать через switch-case" я пока не знаю
а где это в коде
EEPROM.put(0, tempON);// сохраняем в eeprom?строка 183
183}162.....180
switch ( KEY )
{
case 1 :
{
делаем раз
break;
}
case 2 :
{
делаем два
break;
}
case 3 :
{
делаем три
break;
}
}
так удобнее чем через ифы
#5 ...для этого надо правильно написать ЛУУП , а не ресетить !
:)
183}Вот кусок с записью в eeprom нумерация на фориме н есовпадает с нумерацией в моем редакторе // обработка кнопок if (KEY == 2) // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы } else if (KEY == 3) // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы } else if (KEY == 1) // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom // break; } delay(200); } } // ОПРОС ДАТЧИКА162.....180
switch ( KEY )
{
case 1 :
{
делаем раз
break;
}
case 2 :
{
делаем два
break;
}
case 3 :
{
делаем три
break;
}
}
так удобнее чем через ифы
Спасибо! Сейяас буду пробовать.
183}Вот кусок с записью в eeprom нумерация на фориме н есовпадает с нумерацией в моем редакторе // обработка кнопок if (KEY == 2) // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы } else if (KEY == 3) // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы } else if (KEY == 1) // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom // break; } delay(200); } } // ОПРОС ДАТЧИКАдык , если что-то дописал-изменил в коде - обновляй здесь ! :)
завтра в отпуск....
там тырнета ваааааще нет :(
пока-пока....
http://arduino.ru/Reference/SwitchCase
162.....180
switch ( KEY )
{
case 1 :
{
делаем раз
break;
}
case 2 :
{
делаем два
break;
}
case 3 :
{
делаем три
break;
}
}
так удобнее чем через ифы
Так компилятор ругается :(
Arduino: 1.6.5 (Mac OS X), Board: "Arduino Uno"
TEMP_Digital_Button_Thermostat_V2.ino: In function 'void setMenu()':
TEMP_Digital_Button_Thermostat_V2.ino:152:30: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
TEMP_Digital_Button_Thermostat_V2.ino:157:30: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
TEMP_Digital_Button_Thermostat_V2.ino:214:18: error: a function-definition is not allowed here before '{' token
TEMP_Digital_Button_Thermostat_V2.ino:319:2: error: expected '}' at end of input
TEMP_Digital_Button_Thermostat_V2.ino:319:2: error: expected '}' at end of input
a function-definition is not allowed here before '{' token
Со скобками вроде не напутал
// термостат, один датчик DS18B20 // // #include <EEPROM.h> #include <OneWire.h> #include <OLED_I2C.h> #define OUT1 13 // выход для реле OneWire ds(15); // 15 вход датчика 18b20 OLED myOLED(SDA, SCL, 8); //OLED display extern uint8_t SmallFont[]; //OLED display extern uint8_t BigNumbers[]; //OLED display long previousMillis = 0; int flag1=0; int flag2=0; int flag3=0; // variables will change: float tempON; // ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00000, 0b00000, 0b10001, 0b01110, 0b01110, 0b10001, 0b00000, 0b00000 }; //Функция перезапуска void(* resetFunc) (void) = 0; // Reset MC function // ОБРАБОТКА ОШИБОК void erorr(){ // останавливает работу программы и показываем ошибку digitalWrite(OUT1, LOW); // выключаем реле while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(100); } } // ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag } //"DOWN" Button connected to 4 if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 2; { previousMillis = millis(); flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag2=0;//обнуляем переменную flag } //"UP" Button connected to 2 if(digitalRead(2)==LOW&&flag3==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 3; { previousMillis = millis(); flag3=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(2)==HIGH&&flag3==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag3=0;//обнуляем переменную flag } else return 0; } // ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV) void setMenu() { byte pos; digitalWrite(OUT1, LOW); // выключаем реле while(1) { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок myOLED.clrScr(); // OLED display myOLED.setFont(SmallFont); // OLED display myOLED.print("SV", 10, 20); // OLED display myOLED.setFont(BigNumbers); // OLED display myOLED.printNumF(tempON, 2, 30, 20); // OLED display myOLED.drawCircle(110, 23, 2); // hor, ver ,size myOLED.setFont(SmallFont); // OLED display myOLED.print("C", 114, 22); // OLED display myOLED.update(); // OLED display /*// обработка кнопок if (KEY == 2) // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы } else if (KEY == 3) // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы } else if (KEY == 1) // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom // break; } delay(200); */ switch ( KEY ) { case 2 : // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы break; } case 3 : // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы break; } case 1 : // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom break; } } // ОПРОС ДАТЧИКА float getTemp() // возвращает температуру с датчика { byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) //если адрес датчика не получен сообщаем об ошибке { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("NO SENSOR", 37, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("SENSOR CRC ERROR", 30, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(500); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); pinMode(13, OUTPUT); // Buttons setup pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin digitalWrite(7, HIGH); pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin digitalWrite(4, HIGH); pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin digitalWrite(2, HIGH); myOLED.begin(); pinMode(13, OUTPUT); pinMode(OUT1, OUTPUT); tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры float temperature = getTemp(); // читаем температуру if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру else digitalWrite(OUT1, LOW); // и управляем выходами // ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ myOLED.setFont(SmallFont); myOLED.print("PV", 10, 05); myOLED.print("SV", 10, 39); myOLED.print("C", 115, 05); myOLED.print("C", 115, 39); if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода else myOLED.print(" ", 13, 16); myOLED.setFont(BigNumbers); myOLED.printNumF(temperature, 2, 30, 03); myOLED.printNumF(tempON, 2, 30, 37); myOLED.drawCircle(111, 06, 2); // hor, ver ,size myOLED.drawCircle(111, 40, 2); // hor, ver ,size myOLED.update(); }Ошибку нашел, код поправил, теперь работатет Switch вместо If
// термостат, один датчик DS18B20 // // #include <EEPROM.h> #include <OneWire.h> #include <OLED_I2C.h> #define OUT1 13 // выход для реле OneWire ds(15); // 15 вход датчика 18b20 OLED myOLED(SDA, SCL, 8); //OLED display extern uint8_t SmallFont[]; //OLED display extern uint8_t BigNumbers[]; //OLED display long previousMillis = 0; int flag1=0; int flag2=0; int flag3=0; // variables will change: float tempON; // ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00000, 0b00000, 0b10001, 0b01110, 0b01110, 0b10001, 0b00000, 0b00000 }; //Функция перезапуска void(* resetFunc) (void) = 0; // Reset MC function // ОБРАБОТКА ОШИБОК void erorr(){ // останавливает работу программы и показываем ошибку digitalWrite(OUT1, LOW); // выключаем реле while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(100); } } // ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag } //"DOWN" Button connected to 4 if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 2; { previousMillis = millis(); flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag2=0;//обнуляем переменную flag } //"UP" Button connected to 2 if(digitalRead(2)==LOW&&flag3==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 3; { previousMillis = millis(); flag3=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(2)==HIGH&&flag3==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag3=0;//обнуляем переменную flag } else return 0; } // ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV) void setMenu() { byte pos; digitalWrite(OUT1, LOW); // выключаем реле while(1) { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок myOLED.clrScr(); // OLED display myOLED.setFont(SmallFont); // OLED display myOLED.print("SV", 10, 20); // OLED display myOLED.setFont(BigNumbers); // OLED display myOLED.printNumF(tempON, 2, 30, 20); // OLED display myOLED.drawCircle(110, 23, 2); // hor, ver ,size myOLED.setFont(SmallFont); // OLED display myOLED.print("C", 114, 22); // OLED display myOLED.update(); // OLED display // обработка кнопок /* if (KEY == 2) // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы } else if (KEY == 3) // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы } else if (KEY == 1) // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom // break; } delay(200); } } */ switch ( KEY ) { case 2 : // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы break; } case 3 : // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы break; } case 1 : // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom break; } } } } // ОПРОС ДАТЧИКА float getTemp() // возвращает температуру с датчика { byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) //если адрес датчика не получен сообщаем об ошибке { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("NO SENSOR", 37, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("SENSOR CRC ERROR", 30, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(500); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); pinMode(13, OUTPUT); // Buttons setup pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin digitalWrite(7, HIGH); pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin digitalWrite(4, HIGH); pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin digitalWrite(2, HIGH); myOLED.begin(); pinMode(13, OUTPUT); pinMode(OUT1, OUTPUT); tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры float temperature = getTemp(); // читаем температуру if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру else digitalWrite(OUT1, LOW); // и управляем выходами // ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ myOLED.setFont(SmallFont); myOLED.print("PV", 10, 05); myOLED.print("SV", 10, 39); myOLED.print("C", 115, 05); myOLED.print("C", 115, 39); if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода else myOLED.print(" ", 13, 16); myOLED.setFont(BigNumbers); myOLED.printNumF(temperature, 2, 30, 03); myOLED.printNumF(tempON, 2, 30, 37); myOLED.drawCircle(111, 06, 2); // hor, ver ,size myOLED.drawCircle(111, 40, 2); // hor, ver ,size myOLED.update(); }51...53 - выкинь из кода и из головы :)
где же выход из цикла 143....217 ?
или + , или - , или запись в епром.... а остальное ?
51...53 - выкинь из кода и из головы :)
Это остатки экспериментов, убрал.
Добавил delay в обработкю кнопок, без этого значения крутятся слишком быстро при нажатии кнопки
Но попрежнему не понятно, как выйти из цикла после записэ измененного значения темепературы в eeprom?
// термостат, один датчик DS18B20 // // #include <EEPROM.h> #include <OneWire.h> #include <OLED_I2C.h> #define OUT1 13 // выход для реле OneWire ds(15); // 15 вход датчика 18b20 OLED myOLED(SDA, SCL, 8); //OLED display extern uint8_t SmallFont[]; //OLED display extern uint8_t BigNumbers[]; //OLED display long previousMillis = 0; int flag1=0; int flag2=0; int flag3=0; // variables will change: float tempON; // ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00000, 0b00000, 0b10001, 0b01110, 0b01110, 0b10001, 0b00000, 0b00000 }; // ОБРАБОТКА ОШИБОК void erorr(){ // останавливает работу программы и показываем ошибку digitalWrite(OUT1, LOW); // выключаем реле while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(100); } } // ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag } //"DOWN" Button connected to 4 if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 2; { previousMillis = millis(); flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag2=0;//обнуляем переменную flag } //"UP" Button connected to 2 if(digitalRead(2)==LOW&&flag3==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 3; { previousMillis = millis(); flag3=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(2)==HIGH&&flag3==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag3=0;//обнуляем переменную flag } else return 0; } // ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV) void setMenu() { byte pos; digitalWrite(OUT1, LOW); // выключаем реле while(1) { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок myOLED.clrScr(); // OLED display myOLED.setFont(SmallFont); // OLED display myOLED.print("SV", 10, 20); // OLED display myOLED.setFont(BigNumbers); // OLED display myOLED.printNumF(tempON, 2, 30, 20); // OLED display myOLED.drawCircle(110, 23, 2); // hor, ver ,size myOLED.setFont(SmallFont); // OLED display myOLED.print("C", 114, 22); // OLED display myOLED.update(); // OLED display // обработка кнопок switch ( KEY ) { case 2 : // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы delay(200); break; } case 3 : // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы delay(200); break; } case 1 : // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom break; } } } } // ОПРОС ДАТЧИКА float getTemp() // возвращает температуру с датчика { byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) //если адрес датчика не получен сообщаем об ошибке { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("NO SENSOR", 37, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("SENSOR CRC ERROR", 30, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(500); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); pinMode(13, OUTPUT); // Buttons setup pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin digitalWrite(7, HIGH); pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin digitalWrite(4, HIGH); pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin digitalWrite(2, HIGH); myOLED.begin(); pinMode(13, OUTPUT); pinMode(OUT1, OUTPUT); tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры float temperature = getTemp(); // читаем температуру if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру else digitalWrite(OUT1, LOW); // и управляем выходами // ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ myOLED.setFont(SmallFont); myOLED.print("PV", 10, 05); myOLED.print("SV", 10, 39); myOLED.print("C", 115, 05); myOLED.print("C", 115, 39); if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода else myOLED.print(" ", 13, 16); myOLED.setFont(BigNumbers); myOLED.printNumF(temperature, 2, 30, 03); myOLED.printNumF(tempON, 2, 30, 37); myOLED.drawCircle(111, 06, 2); // hor, ver ,size myOLED.drawCircle(111, 40, 2); // hor, ver ,size myOLED.update(); }где же выход из цикла 143....217 ?
или + , или - , или запись в епром.... а остальное ?
Так пока еще не понял, как правильно выход сделать :(
не while ( 1 ) , а пока код кнопки не равен 1
while ( KEY !=1 )
при 2 или 3 - + или -
при 1 - запись и выход из "бесконечного цикла" в ЛУУП
И остается не понятная для меня проблема, почему не работают флаги? кнопки плюс и монус не важно, с delay они работают приемлемо и даже удобно, но кнопка SETUP каждый раз многократно переписывает EEPROM при вызове меню, а это по моему не хорошо так как количество циклов перезаписи ограничено.
274...276 переделать под гистерезис....
если меньше чем tempON-1 то включить
если больше чем tempON+1 то выключить
или можешь попасть на прослушивание реле в режиме тик-так-тик-так-тик.....
не while ( 1 ) , а пока код кнопки не равен 1
while ( KEY !=1 )
при 2 или 3 - + или -
при 1 - запись и выход из "бесконечного цикла" в ЛУУП
Чего то не работает, компилятор ругается.
------
'KEY' was not declared in this scope
-----
Но так по моему работать не будет. так как при нажатии кнопки происходит повторяющееся событие (флаг не работает) принажатии будет сразу и вход в меню и выход.
274...276 переделать под гистерезис....
если меньше чем tempON-1 то включить
если больше чем tempON+1 то выключить
или можешь попасть на прослушивание реле в режиме тик-так-тик-так-тик.....
С этим позже буду разбиратся, как раз по алгоритму управления идеи есть, буду эксперементировать, но хочу сначала с кнопками разобратся.
кусок кода с флагами никогда не выполняется !!!!!!!
сетап - бла , бла - читаем из епрома
запуск - крутим лопинг :
270 - ждём кнопку Сетап ( нет - дальше )
272 - опрашиваем датчик
274...298 - управление реле и отображение
из 270 по Сетап-кнопке попадаем на + , - , или запись в епром - И снова крутим лопинг :(
ВСЁ - больше код ничё не делает ( не умеет ) :)
не while ( 1 ) , а пока код кнопки не равен 1
while ( KEY !=1 )
при 2 или 3 - + или -
при 1 - запись и выход из "бесконечного цикла" в ЛУУП
Разобрался, заработало вот так:
while ( (key()) !=1 );
НО сразу вылетает из меню так как флаги не работают и кнопка при однократном нажатии генерит серию событий (дребезг контактов или просто очень быстро обрабатывается кнопка) :( а delay в основной цикл я вставлять очень не хочу.
не while ( 1 ) , а пока код кнопки не равен 1
while ( KEY !=1 )
при 2 или 3 - + или -
при 1 - запись и выход из "бесконечного цикла" в ЛУУП
Чего то не работает, компилятор ругается.
------
'KEY' was not declared in this scope
-----
Но так по моему работать не будет. так как при нажатии кнопки происходит повторяющееся событие (флаг не работает) принажатии будет сразу и вход в меню и выход.
139А -
byteKEY = 0;144 -
KEY = key();KEY был определён внутри while() - вот и ругается , что нет такой переменнойДобавил delay в обработкю кнопок, без этого значения крутятся слишком быстро при нажатии кнопки
на велосипед - нажатия/отпускания обрабатываются один раз.
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1); } void loop() { BUTTON_00(); } ////////////////////////////////////////////// void BUTTON_00() { boolean nb00 = digitalRead(3); if (nb00 != b00) {b00 = nb00; if (b00 == 0) {BUTTON_00_on();} // срабатывает один раз при нажатии кнопки. if (b00 == 1) {BUTTON_00_of();} // срабатывает один раз при отпускании кнопки. } } void BUTTON_00_on() { // обработка нажатия кнопки. // здесь происходит при нажатии кнопки. } void BUTTON_00_of() { // обработка отпускания кнопки. // здесь происходит при отпускании кнопки. } //////////////////////////////////////////////Но попрежнему не понятно, как выйти из цикла после записэ измененного значения темепературы в eeprom?
а, зачем оно у тебя в цикле?
прочитал из еепром, сравнил с актуальным значением, если есть разница, то перезаписал в еепром - если часто будешь перезаписывать, то сотрёшь еепром за год или раньше.
кусок кода с флагами никогда не выполняется !!!!!!!
сетап - бла , бла - читаем из епрома
запуск - крутим лопинг :
270 - ждём кнопку Сетап ( нет - дальше )
272 - опрашиваем датчик
274...298 - управление реле и отображение
из 270 по Сетап-кнопке попадаем на + , - , или запись в епром - И снова крутим лопинг :(
ВСЁ - больше код ничё не делает ( не умеет ) :)
Ну как же он не выполняется? Я ведь могу из режима показа температуры войти в меню?
А это вот этот кусок как я понимаю:
/ ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag }По крайней мере программа
получает, без этого я бы не воешел в меню установки темепературы.
return 2;return 3; Программа тоже получает, так как я могу менять темепературу в меню установки, значит код работает? Но флаги при этом не работают...
Добавил delay в обработкю кнопок, без этого значения крутятся слишком быстро при нажатии кнопки
на велосипед - нажатия/отпускания обрабатываются один раз.
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1); } void loop() { BUTTON_00(); } ////////////////////////////////////////////// void BUTTON_00() { boolean nb00 = digitalRead(3); if (nb00 != b00) {b00 = nb00; if (b00 == 0) {BUTTON_00_on();} // срабатывает один раз при нажатии кнопки. if (b00 == 1) {BUTTON_00_of();} // срабатывает один раз при отпускании кнопки. } } void BUTTON_00_on() { // обработка нажатия кнопки. // здесь происходит при нажатии кнопки. } void BUTTON_00_of() { // обработка отпускания кнопки. // здесь происходит при отпускании кнопки. } //////////////////////////////////////////////Но попрежнему не понятно, как выйти из цикла после записэ измененного значения темепературы в eeprom?
а, зачем оно у тебя в цикле?
прочитал из еепром, сравнил с актуальным значением, если есть разница, то перезаписал в еепром - если часто будешь перезаписывать, то сотрёшь еепром за год или раньше.
Спасибо, буду разбиратся и пробовать, уже завтра наверное.
В цикле оно так как фактически есть два режима, контроль температуры и установка темепературы, переход в режим установки по кнопке SETUP , return 1; из основного цикла, во вторм цикле считвание кнопок для корррекции температуры и запись в EEPROM вот из него я и не умею пока организовать выход.
Надеюсь заработатет когда поправлю обработку кнопок и они будут давать только по одному срабатыванию. Перепишу обработку кнопок завтра на свежую голову.
Спасибо огромное за помощь!
получает 1 , но раз в полсекунды - не быстрее...
и флаги меняются , но в коде ( который компилится ) нигде не анализируются ( флаги )
покрути код в голове вместо МК - сам всё увидишь :)
вот из него я и не умею пока организовать выход.
#39
вот из него я и не умею пока организовать выход.
#39
Да, спасибо, так сейчас и сделано, но надо переписать обработку кнопок, чтоб заработало корректно, сейчас входит в меню и сразу вываливается (так как кнопка не корректно работатет), при этом еще экран не обновляется, мусор, с этим разберусь
Сейчас вот так
// термостат, один датчик DS18B20 // // #include <EEPROM.h> #include <OneWire.h> #include <OLED_I2C.h> #define OUT1 13 // выход для реле OneWire ds(15); // 15 вход датчика 18b20 OLED myOLED(SDA, SCL, 8); //OLED display extern uint8_t SmallFont[]; //OLED display extern uint8_t BigNumbers[]; //OLED display long previousMillis = 0; int flag1=0; int flag2=0; int flag3=0; // variables will change: float tempON; // ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА byte gradus[8] = { 0b00110, 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; byte on[8] = { 0b00000, 0b00000, 0b10001, 0b01110, 0b01110, 0b10001, 0b00000, 0b00000 }; // ОБРАБОТКА ОШИБОК void erorr(){ // останавливает работу программы и показываем ошибку digitalWrite(OUT1, LOW); // выключаем реле while(1){ // крутим бесконечный цикл digitalWrite(13, !digitalRead(13)); delay(100); } } // ОПИСАНИ КНОПОК byte key() { //"SETUP" Button connected to 7 if(digitalRead(7)==LOW&&flag1==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 1; { previousMillis = millis(); flag1=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(7)==HIGH&&flag1==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag1=0;//обнуляем переменную flag } //"DOWN" Button connected to 4 if(digitalRead(4)==LOW&&flag2==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 2; { previousMillis = millis(); flag2=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(4)==HIGH&&flag2==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag2=0;//обнуляем переменную flag } //"UP" Button connected to 2 if(digitalRead(2)==LOW&&flag3==0) //если кнопка нажата и перемення flag равна 0 , то ... { if (millis() -previousMillis >500) return 3; { previousMillis = millis(); flag3=1; //это нужно для того что бы с каждым нажатием кнопки происходило только одно действие } } if (digitalRead(2)==HIGH&&flag3==1) //если кнопка НЕ нажата и переменная flag равна - 1 ,то ... { flag3=0;//обнуляем переменную flag } else return 0; } // ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV) void setMenu() { byte pos; digitalWrite(OUT1, LOW); // выключаем реле //while(1) while ( (key()) !=1 ); { // крутим бесконечный цикл byte KEY = key(); // читаем состояние кнопок myOLED.clrScr(); // OLED display myOLED.setFont(SmallFont); // OLED display myOLED.print("SV", 10, 20); // OLED display myOLED.setFont(BigNumbers); // OLED display myOLED.printNumF(tempON, 2, 30, 20); // OLED display myOLED.drawCircle(110, 23, 2); // hor, ver ,size myOLED.setFont(SmallFont); // OLED display myOLED.print("C", 114, 22); // OLED display myOLED.update(); // OLED display // обработка кнопок switch ( KEY ) { case 2 : // если кнопка DOWN нажата { tempON-= 0.5; // изменяем значение if (tempON < 20) tempON = 95; //проверяем пределы delay(200); break; } case 3 : // если кнопка UP нажата { tempON+= 0.5; // изменяем значение if (tempON > 95) tempON = 20; //проверяем пределы delay(200); break; } case 1 : // если кнопка SETUP нажата { EEPROM.put(0, tempON); // сохраняем в eeprom break; } } } } // ОПРОС ДАТЧИКА float getTemp() // возвращает температуру с датчика { byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)) //если адрес датчика не получен сообщаем об ошибке { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("NO SENSOR", 37, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]) { myOLED.begin(); //OLED display myOLED.setFont(SmallFont); //OLED display myOLED.print("SENSOR CRC ERROR", 30, 30); //OLED display myOLED.update(); //OLED display erorr(); } ds.reset(); ds.select(addr); ds.write(0x44); delay(500); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; } void setup() { // Serial.begin(9600); pinMode(13, OUTPUT); // Buttons setup pinMode(7, INPUT); // устанавливает режим работы - вход для 7го вход/выхода it is "SETUP" pin digitalWrite(7, HIGH); pinMode(4, INPUT); // устанавливает режим работы - вход для 4го вход/выхода it is "DOWN" pin digitalWrite(4, HIGH); pinMode(2, INPUT); // устанавливает режим работы - вход для 2го вход/выхода it is "UP" pin digitalWrite(2, HIGH); myOLED.begin(); pinMode(13, OUTPUT); pinMode(OUT1, OUTPUT); tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром } void loop() { if (key() == 1) setMenu(); // если нажата кнопка SETUP, уходим в меню задания температуры float temperature = getTemp(); // читаем температуру if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру else digitalWrite(OUT1, LOW); // и управляем выходами // ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ myOLED.setFont(SmallFont); myOLED.print("PV", 10, 05); myOLED.print("SV", 10, 39); myOLED.print("C", 115, 05); myOLED.print("C", 115, 39); if (digitalRead(OUT1)) myOLED.print("*", 13, 16); // вывод на экран состояние выхода else myOLED.print(" ", 13, 16); myOLED.setFont(BigNumbers); myOLED.printNumF(temperature, 2, 30, 03); myOLED.printNumF(tempON, 2, 30, 37); myOLED.drawCircle(111, 06, 2); // hor, ver ,size myOLED.drawCircle(111, 40, 2); // hor, ver ,size myOLED.update(); }получает 1 , но раз в полсекунды - не быстрее...
и флаги меняются , но в коде ( который компилится ) нигде не анализируются ( флаги )
покрути код в голове вместо МК - сам всё увидишь :)
Потихоньку разбираюсь, к сожалениу на это только 3-4 часа по вечерам возможно использовать. Воображение у меня на HW натренировано, на SW никогда времени не было, вот сейчас решил освоить.
в key() в конце добавь delay( 200 ) , например 200 - и от дребезга поможет и темп опроса кнопок снизится...
delay( 200.....500 )
Добавил delay в обработкю кнопок, без этого значения крутятся слишком быстро при нажатии кнопки
на велосипед - нажатия/отпускания обрабатываются один раз.
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1); } void loop() { BUTTON_00(); } ////////////////////////////////////////////// void BUTTON_00() { boolean nb00 = digitalRead(3); if (nb00 != b00) {b00 = nb00; if (b00 == 0) {BUTTON_00_on();} // срабатывает один раз при нажатии кнопки. if (b00 == 1) {BUTTON_00_of();} // срабатывает один раз при отпускании кнопки. } } void BUTTON_00_on() { // обработка нажатия кнопки. // здесь происходит при нажатии кнопки. } void BUTTON_00_of() { // обработка отпускания кнопки. // здесь происходит при отпускании кнопки. } //////////////////////////////////////////////Но попрежнему не понятно, как выйти из цикла после записэ измененного значения темепературы в eeprom?
а, зачем оно у тебя в цикле?
прочитал из еепром, сравнил с актуальным значением, если есть разница, то перезаписал в еепром - если часто будешь перезаписывать, то сотрёшь еепром за год или раньше.
Я не понимаю как программа понимает, что input 3 это именно BUTTON_00 ? Какая строчка из примера это описывает?
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1);в key() в конце добавь delay( 200 ) , например 200 - и от дребезга поможет и темп опроса кнопок снизится...
delay( 200.....500 )
Я очень хочу избавится от delay в основном цикле, т.е. убрать дребезг и сделать все остальное программно, без delay.
Я не понимаю как программа понимает, что input 3 это именно BUTTON_00 ? Какая строчка из примера это описывает?
ты считываешь состояние пина 3 в локальную переменную nb00
boolean nb00 = digitalRead(3);
если это состояние изменилось
if(nb00 != b00) {}то, что-то делаешь
что бы это делать один раз, то обновляешь переменную состояния пина
b00 = nb00;
далее, что-то делаешь при нажатии или отпускании
или я не понял вопроса - назови кнопку не BUTTON_00 , а как тебе захочется, но это будет пин 3.
Добавил delay в обработкю кнопок, без этого значения крутятся слишком быстро при нажатии кнопки
на велосипед - нажатия/отпускания обрабатываются один раз.
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1); } void loop() { BUTTON_00(); } ////////////////////////////////////////////// void BUTTON_00() { boolean nb00 = digitalRead(3); if (nb00 != b00) {b00 = nb00; if (b00 == 0) {BUTTON_00_on();} // срабатывает один раз при нажатии кнопки. if (b00 == 1) {BUTTON_00_of();} // срабатывает один раз при отпускании кнопки. } } void BUTTON_00_on() { // обработка нажатия кнопки. // здесь происходит при нажатии кнопки. } void BUTTON_00_of() { // обработка отпускания кнопки. // здесь происходит при отпускании кнопки. } //////////////////////////////////////////////Но попрежнему не понятно, как выйти из цикла после записэ измененного значения темепературы в eeprom?
а, зачем оно у тебя в цикле?
прочитал из еепром, сравнил с актуальным значением, если есть разница, то перезаписал в еепром - если часто будешь перезаписывать, то сотрёшь еепром за год или раньше.
Я не понимаю как программа понимает, что input 3 это именно BUTTON_00 ? Какая строчка из примера это описывает?
boolean b00; // переменная, хранящая значение кнопки b00. void setup() { pinMode(3, INPUT); // BUTTON_00 digitalWrite(3, 1);Торможу, понял:
boolean nb00 = digitalRead(3);Но все разво не понимаю, почему не будет обработам дребезг контактов как многократное нажатие отпускание?