Gроект для аквариума (акваконтроллер для led, temp, time, co2)

bwn
Онлайн
Зарегистрирован: 25.08.2014

В loop у меня это было, чтобы понять где нахожусь. Как там будет это не принципиально за исключением куска входа в меню. А он получается отрабатывает корректно или что то изменяли?

Да и непосредственно вход в функции key()  промониторить. Попадаем ли мы туда?

bwn
Онлайн
Зарегистрирован: 25.08.2014

И еще, что делает вот этот кусочек у вас в коде? Если его закоментить мы будем значения с IR получать?

 if (irrecv.decode(&results)){

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

В loop у меня это было, чтобы понять где нахожусь. Как там будет это не принципиально за исключением куска входа в меню. А он получается отрабатывает корректно или что то изменяли?

Да и непосредственно вход в функции key()  промониторить. Попадаем ли мы туда?

В loop я добавил лиш работу с кнопками IR и если не окмментить очистку то надпись cikl перерисовывается циклически. Вот такой у меня loop 



void loop() {
//  tft.fillScreen(ST7735_BLACK); // Clear screen
  if (irrecv.decode(&results)){
 //  lcd.clear();
  //____________________________________________________________
  
   //***ВХОД В МЕНЮ и проверка блокировки от возврата.
  byte KEY=key();            //Принимаем код клавиши
  if (KEY==1 && temp[0]<millis()) 
      {
        temp[0]=millis()+5000;
        menu();
      }                       //Если setup идем в меню
      irrecv.resume(); }
  //____________________________________________________________
  
  tft.setCursor(10,100);
  tft.print("cikl");
  
}

 

bwn пишет:

Тогда добавьте после 132 строки переменную KEY на экран, посмотреть какие значения она принимает. У меня на обычных кнопках все срабатывало нормально.

Сделал, всё отлично обрабатывает, вход в меню и возврат нажатой кнопки 1 select. Тоесть все корректно, далее 5 сек и снова возварт в cikl

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

И еще, что делает вот этот кусочек у вас в коде? Если его закоментить мы будем значения с IR получать?

 if (irrecv.decode(&results)){

Ежели это убрать то мои IR нажатия вообще остаются незамеченными. Это я так понял стандартный код для работы с IR:

/*
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}

void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
}
}

 

bwn
Онлайн
Зарегистрирован: 25.08.2014

От, тогда получается, что этот кусок надо добавить в функцию key().

Мы уходя в меню перестаем взаимодействовать с loop, на все время работы с меню. Соответственно и не получаем никаких данных с IR (у вас опрос в loop). Надо его продублировать в функции.

"Сделал, всё отлично обрабатывает, вход в меню и возврат нажатой кнопки 1 select. Тоесть все корректно, далее 5 сек и снова возварт в cikl" - а вот это неправильно. Возврат должен был быть только при повторном нажатии select через две секунды. Получается, что у вас остается запомненным предыдущее состояние KEY и оно возвращает в loop. (кстати на 5 секунд зря меняли, это задержка, чтобы сразу не вернутся - вход и выход из первого меню по одной и той же клавише, автовозврата я сюда не писал, усложнить никогда не поздно.)

P/S примерно понял, почему происходит возврат - мы прекратили опрос и results.value == 0x41BEC03F остался в том же состоянии.

 

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

От, тогда получается, что этот кусок надо добавить в функцию key().

Мы уходя в меню перестаем взаимодействовать с loop, на все время работы с меню. Соответственно и не получаем никаких данных с IR (у вас опрос в loop). Надо его продублировать в функции.

Хехе всё пучком, наконецто вошли в menu?z же вот одним местом чуял что неспроста в старом коде где всё висело - ничего невисело ПРОСТО там необрабатывались кнопки IR - я то лол совсем забыл что когда мы в menu то loop НЕРАБОТАЕт и цикла по нему НЕТ.ВОт сюда продублировал:

while(1) //Бесконечный цикл
  
  {   
      KEY=0;
      if (irrecv.decode(&results)){
...
...
         break;} 
         irrecv.resume(); }
  }
} 

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Рано обрадовался :( - висит у меня счас первый таймер вида:

1    10:00  11:00  

set to save 

(значения видимо из моих СТАРЫХ проб записи в ЕПРОМ)

... и всё, видимо надо ещё кудато добавлять обработку кнопок . И вот ещё что, вы писали... "P/S примерно понял, почему происходит возврат - мы прекратили опрос и results.value == 0x41BEC03F остался в том же состоянии." ежели выводить в serial.print кнопки ТО именно 1-ка и возвращалась (setup) после того как я НTвошёл в menu, меня выкидывало в cikle а 1-ка - продолжала возвращаться!!! Так что всё верное вы догадались.

bwn
Онлайн
Зарегистрирован: 25.08.2014

Отнюдь отнюдь, это должно быть в функции key(). Иначе вы начнете плодить эти строки во всех циклах, а это неправильно, хоть и будет работать.

Thorn
Offline
Зарегистрирован: 07.11.2014

Вот меня смущает что немогу в tft обрабатывать blink курсором -  я так понял после входа в меню сначала курсор становится на часы и начинает мигать?

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

Вот меня смущает что немогу в tft обрабатывать blink курсором -  я так понял после входа в меню сначала курсор становится на часы и начинает мигать?

Да, сперва мигает разряд единиц часов, потом минут и т.д. Как у вас в библиотеке и есть ли он там, тут уже не помогу. А без него не понять что устанавливаем.

Thorn
Offline
Зарегистрирован: 07.11.2014

На сегодня меня выгоняют из компьютера с ардуинкой :( . Доброй ночи.

Я всё-же вставил обработку IR аналогично с функции key в функцию void setOnOff() - ну чтоб наверняка. Вобщем тепреь заработали кнопки однако любое нажатие вызывает saved и всё, снова зависон - видимо кнопки IR работают иначе физических.

Завтра на работе буду отлаживать - главное знать где и мы с вами знаем :)

bwn
Онлайн
Зарегистрирован: 25.08.2014

А я все таки настоятельно рекомендую делать это в key(), в том числе и из loop убрать. Когда что то происходит в одной функции, отладка намного проще становится, вы получили на выходе функции стабильный результат и больше к ней не возвращаетесь. А так вам приходится лазать по всему коду и ловить мелких блох.

Еще вопрос, что делает вот эта строка irrecv.resume();? Я так подозреваю, что дает разрешение на следующее считывание. Если так, то делает это с очисткой results.value или без?

Thorn
Offline
Зарегистрирован: 07.11.2014

Приветы. Сегодня на работе заметил... при входе в setup я кнопками (up - down) могу выбирать номер расписания от 1 до 5, однако они прорисовываются в одной строке поверх и собственно сами понимаете - нечитабельно, счас покурю где мне надо очищать дисплей перед выбором следующего расписания. 

Далее я вхожу в расписание и всё, тут уже ничего непроисходит и кнопки необрабатываются. Работу с IR убрал пока отовсюду кроме loop и KEY. 

Следуя вашему совету я счас уберу из loop? однако боюсь тогда несмогу войти в setup (кнопки то обрабатыватсья до него небудут).

Thorn
Offline
Зарегистрирован: 07.11.2014

Ну вот как я и думал из loop IR убирать НЕЛЬЗЯ, можно к примеру если работа с IR есть в функции которая запускается из loop, у меня так в моем акваконтроллере если вы помните в loop()

eEPROMread();
// program_clock();
timeRtc();
timer();
ir_manual_key();
auto_key_dimmer();
dallas(); //flagDallas==0;
tempRelay();
voltM();
bar();
bluetooth();
}

и как раз IК содержится в ir_manual_key();

 

а вот  irrecv.resume(); сильно влияет своим положение в конце какой либо функции, либо перестают отвечать кнопки либо зацикливается выбор.

Thorn
Offline
Зарегистрирован: 07.11.2014

Когда я нахожусь в (setup) оно же char menuTxt[5][14] = {"set menu1 >>", "set menu2 >>","set menu3 >>","set menu4 >>","set menu5 >>"};

то Serial.println(key(),DEC); delay(500); - невозвращает мне НИЧЕГО хотя я спокойно выбираю set menu1 >> стрелками (up - down) как уже писал выше - чудес небывает я так понял снова пресловутый loop не лупицца и надо serial.Print дописат mb в KEY

bwn
Онлайн
Зарегистрирован: 25.08.2014

Убрать отовсюду я имел в виду - перенести в key() и обращатся только к нему по мере надобности. Сейчас у вас уже пять мест где происходит это обращение (loop, dimmer и три меню), дальше будет больше. irrecv.resume(); думаю должно стоять перед каждым return в функции key(). Функцию key() переписать, чтобы она возвращала как KEY№ , так и от 0 до 5. Тогда вы сможете к ней обращатся из любого места, а брать нужное вам значение.

Экран на LCD у меня сам затирался, очистку не делал, лекарство - напечатать сперва пустую строку (можете ее даже в массив внести для тренировки.)

Thorn
Offline
Зарегистрирован: 07.11.2014

Ага интеренсная картинка вырисовывается. Вот с такой функцией menu() и  кнопок KEY:

void menu(){
    //Массив с наименованиями для экрана
  char menuTxt[5][14] = {"set menu1 >>", "set menu2 >>","set menu3 >>","set menu4 >>","set menu5 >>"};
  byte pos = 0;
  byte KEY;
  while(1) {//Бесконечный цикл
  if (irrecv.decode(&results)){
    Serial.println(key(),DEC); delay(500); 
      KEY=0;
      if (temp[1]<millis()) KEY = key(); //Если прошел интервал, читаем код
    tft.setCursor(5,55);
    tft.print(pos+1);  //Печатаем номер.
    tft.print(".");
    tft.print(menuTxt[pos]); //Печатаем название
    // Уменьшить увеличить + блокировка кнопки
    if (KEY == 3 && pos > 0) {pos--; temp[1]=millis()+300;}
    if (KEY == 4 && pos < 4) {pos++; temp[1]=millis()+300;}
    
    win=pos; //Переменная номера таймера
    
    // Здесь переходим на подменю. Если останется как сейчас, то достаточно
    // if (KEY == 5) setOnOff();
    // Сейчас можно перейти на разные подменю.
    if (KEY == 5 && pos == 0) setOnOff();
    if (KEY == 5 && pos == 1) setOnOff();
    if (KEY == 5 && pos == 2) setOnOff();
    if (KEY == 5 && pos == 3) setOnOff();
    if (KEY == 5 && pos == 4) setOnOff();
    //Выход из меню с проверкой и установкой блокировки от возврата
    if (KEY ==1 && temp[0]<millis())        
       { 
         temp[0]=millis()+2000;
        
//         lcd.clear(); 
tft.fillScreen(ST7735_BLACK); // Clear screen
         break;} 
    irrecv.resume(); }        
  }
} 
//_________________________________________________________________

я получаю нажатые кнопки ДО собственно моента входа в set menu1 >> и тп. Ка ктолько вошёл всё снова кнопки IR необрабатываются. И кстаи снова навернео какието задержки потмоу как невсегда СРАЗУ я могу пробежаться по char menuTxt[5][14] = {"set menu1 >>", "set menu2 >>","set menu3 >>","set menu4 >>","set menu5 >>"};

чаще  serial.Print мне вывел нажатую кнопку а собственно строка несменилась, Ну а далее если и сменилась то прорисовав поверх старой название

bwn
Онлайн
Зарегистрирован: 25.08.2014

А куда вы этот Serial прописывали?

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

Убрать отовсюду я имел в виду - перенести в key() и обращатся только к нему по мере надобности. Сейчас у вас уже пять мест где происходит это обращение (loop, dimmer и три меню), дальше будет больше. irrecv.resume(); думаю должно стоять перед каждым return в функции key(). Функцию key() переписать, чтобы она возвращала как KEY№ , так и от 0 до 5. Тогда вы сможете к ней обращатся из любого места, а брать нужное вам значение.

Экран на LCD у меня сам затирался, очистку не делал, лекарство - напечатать сперва пустую строку (можете ее даже в массив внести для тренировки.)

Про то думал, но у меня на самом деле IR кнопки обрабатываются ТОЛЬКО один раз имеено в функции работы с диммированием (удержанием кнопки и отключение релюшек). Там пока тьфу три раза всё работает как часики. А тут да - меню штука своебразная. Счас подправлю согласн овашим рекомендациям irrect.resume

bwn
Онлайн
Зарегистрирован: 25.08.2014

Если по вашему коду, он и не должен работать. Если лепить таким образом, то 37 строка должна быть после 10. Иначе вы производите инициацию после того, как уже ушли из меню.

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

А куда вы этот Serial прописывали?

Serial в самом начале loop () 

void loop() {
Serial.println(key(),DEC); delay(100);
if (irrecv.decode(&results)){

...

}

и в menu(), код выше

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

bwn пишет:

А куда вы этот Serial прописывали?

Serial в самом начале loop () 

void loop() {
Serial.println(key(),DEC); delay(100);
if (irrecv.decode(&results)){

...

}

и в menu(), код выше

А в меню, добавлять в 10 строку после KEY=key() и мониторить KEY. delay() не нужен. Когда вы вызываете конструкцией (key(),DEC) вы обращаетесь к функции и печатаете ее результат, а нас интересует переменная.

bwn
Онлайн
Зарегистрирован: 25.08.2014

bwn пишет:

Если по вашему коду, он и не должен работать. Если лепить таким образом, то 37 строка должна быть после 10. Иначе вы производите инициацию после того, как уже ушли из меню.

Здесь немного вас обманул, работать будет, но возможно некорректная обработка при переходе на следующее меню.

Thorn
Offline
Зарегистрирован: 07.11.2014

не ничево неполучается, двигаю irrecv.resume(); }  - меняется но не в лучьшую сторону, добавил перед return но уже в виде irrecv.resume();

Всё потмоу что для мнея сложно понимание массива и его переменных

byte pos = 0;
byte KEY;

if (temp[1]<millis()) KEY = key();

if (KEY == 3 && pos > 0) {pos--; temp[1]=millis()+300;}

вот этого всего :(((

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

не ничево неполучается, двигаю irrecv.resume(); }  - меняется но не в лучьшую сторону, добавил перед return но уже в виде irrecv.resume();

Всё потмоу что для мнея сложно понимание массива и его переменных

byte pos = 0;
byte KEY;

if (temp[1]<millis()) KEY = key();

if (KEY == 3 && pos > 0) {pos--; temp[1]=millis()+300;}

вот этого всего :(((

Так массив это та же переменная - уберите из него квадратные скобки и получите temp0, temp1 и т.д. все остальные действия как с обычными переменными. В данном коде - задержка 0,3сек иначе у вас цифры будут лететь со скоростью цикла.

Thorn
Offline
Зарегистрирован: 07.11.2014

П О Л У Ч И Л О С Ь !!

Правда "раком" стопроцентов, именно как вы НЕСОВЕТОВАЛИ. Всётаки дело в "непотребном" коде при работе с кнопками. Значит вот как у меня и всё работает и нажимается, весь код:

#include <EEPROM.h>
#include <Wire.h>
#include <IRremote.h>                        //Подключаем библиотеку для IR сенсора
//#include <LiquidCrystal.h>

#define DS1307_I2C_ADDRESS 0x68
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

 //=====Tft*
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#define sclk 52
#define mosi 51
#define cs   4
#define dc   2
#define rst  3  // you can also connect this to the Arduino reset
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

//=====IR*
#define RECV_PIN 11                          //IR-приемник
uint32_t val; 
IRrecv irrecv(RECV_PIN);
decode_results results;

//_____________________________________________________________
//  Переменные для меню
byte setMinClockOn; 
byte setHorClockOn;
byte setMinClockOff;  
byte setHorClockOff;
byte win;              //Номер экрана меню
unsigned long temp[2]; //Массив для задержек меню
//_____________________________________________________________

void setup() {
//  lcd.begin(16, 2);
//  lcd.clear();
  Wire.begin();
  Serial.begin(9600);
  irrecv.enableIRIn(); 
  tft.initR(INITR_BLACKTAB);   
  tft.fillScreen(ST7735_BLACK);                       // Clear screen  
}

//______________________________________________________________
//   Здесь вставите свою функцию, которая возвращает от 0 до 5

byte key(){
  if (results.value == 0x41BEB04F) return 5;
  if (results.value == 0x41BE609F) return 4;
  if (results.value == 0x41BED02F) return 3;
  if (results.value == 0x41BE40BF) return 2;
  if (results.value == 0x41BEC03F) return 1;
  else return 0; 
}

/*
byte key()
{ 
    int val = analogRead(0);
    if (val < 50) return 5;
    else if (val < 150) return 3;
    else if (val < 350) return 4;
    else if (val < 500) return 2;
    else if (val < 800) return 1;
    else return 0;  
}
*/

//_____________________________________________________________

void setOnOff(){    
  byte pos = 0;   
     
      //Считываем записанные значения таймеров.
      //Адрес определяется как номер таймера*4+четыре ячейки.
  setMinClockOn = EEPROM.read(win*4+0); //
  setHorClockOn = EEPROM.read(win*4+1);
  setMinClockOff = EEPROM.read(win*4+2);
  setHorClockOff = EEPROM.read(win*4+3);
    
//    lcd.clear();
//    lcd.blink();
tft.fillScreen(ST7735_BLACK); // Clear screen

    while(key() != 1) {//Крутим цикл пока не будет Setup
    if (irrecv.decode(&results)){
    byte KEY = key(); // читаем состояние кнопок
    Serial.println(key(),DEC); delay(500);
      delay(200); //Если убрать, не работает подсветка уст.позиции
//    lcd.setCursor(1, 1);
     tft.setCursor(5,75);
     tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
     tft.setTextSize(1);
    tft.print("set to save");
    tft.setCursor(5, 55);
    tft.print(win+1,DEC);    //Печатаем номер прогр.таймера.
    tft.setCursor(35, 55);     // выводим инфу
     if (setHorClockOn < 10) tft.print("0");
    tft.print(setHorClockOn,DEC);
    tft.print(":");
     if (setMinClockOn < 10) tft.print("0"); 
    tft.print(setMinClockOn,DEC);  
    tft.print(" ");     
     if (setHorClockOff < 10) tft.print("0");
    tft.print(setHorClockOff,DEC);
    tft.print(":");
     if (setMinClockOff < 10) tft.print("0");
    tft.print(setMinClockOff,DEC); 
    
    tft.setCursor(pos, 0); // устанавливаем курсор согласно позиции
    
    if (KEY == 5 && pos < 11) pos += 3; // крутим позицию право-лево
    else if (KEY == 2 && pos > 3) pos -= 3;
    
    else if (pos == 3 && KEY == 3) setHorClockOn++; // крутим значения
    else if (pos == 3 && KEY == 4) setHorClockOn--;
    else if (pos == 6 && KEY == 3) setMinClockOn++;
    else if (pos == 6 && KEY == 4) setMinClockOn--;    
    else if (pos == 9 && KEY == 3) setHorClockOff++;
    else if (pos == 9 && KEY == 4) setHorClockOff--;    
    else if (pos == 12 && KEY == 3) setMinClockOff++;
    else if (pos == 12 && KEY == 4) setMinClockOff--;    
    
    if (setHorClockOn > 23) setHorClockOn = 0;  //Ограничиваем значения
    else if (setMinClockOn > 59) setMinClockOn = 0;
    else if (setHorClockOff > 23) setHorClockOff = 0;
    else if (setMinClockOff > 59) setMinClockOff = 0;
 irrecv.resume(); }   
  }// конец цикла
//   lcd.noBlink(); 
//   lcd.clear();
tft.fillScreen(ST7735_BLACK); // Clear screen

   EEPROM.write(win*4+0, setMinClockOn); //Записываем значения
   EEPROM.write(win*4+1, setHorClockOn);
   EEPROM.write(win*4+2, setMinClockOff);
   EEPROM.write(win*4+3, setHorClockOff);

   tft.print("     Saved");
   delay(1500);
}
//_________________________________________________________________
void menu(){
    //Массив с наименованиями для экрана
  char menuTxt[5][14] = {"set menu1 >>", "set menu2 >>","set menu3 >>","set menu4 >>","set menu5 >>"};
  byte pos = 0;
  byte KEY;
  while(1) {//Бесконечный цикл
  if (irrecv.decode(&results)){
      KEY=0;
      if (temp[1]<millis()) KEY = key(); //Если прошел интервал, читаем код
//      irrecv.resume();
      Serial.println(key(),DEC); delay(500);
    tft.setCursor(5,55);
    tft.print(pos+1);  //Печатаем номер.
    tft.print(".");
    tft.print(menuTxt[pos]); //Печатаем название
    // Уменьшить увеличить + блокировка кнопки
    if (KEY == 3 && pos > 0) {pos--; temp[1]=millis()+300;}
    if (KEY == 4 && pos < 4) {pos++; temp[1]=millis()+300;}
    
    win=pos; //Переменная номера таймера
    
    // Здесь переходим на подменю. Если останется как сейчас, то достаточно
    // if (KEY == 5) setOnOff();
    // Сейчас можно перейти на разные подменю.
    if (KEY == 5 && pos == 0) setOnOff();
    if (KEY == 5 && pos == 1) setOnOff();
    if (KEY == 5 && pos == 2) setOnOff();
    if (KEY == 5 && pos == 3) setOnOff();
    if (KEY == 5 && pos == 4) setOnOff();
    //Выход из меню с проверкой и установкой блокировки от возврата
    if (KEY ==1 && temp[0]<millis())        
       { 
         temp[0]=millis()+2000;
//         lcd.clear(); 
tft.fillScreen(ST7735_BLACK); // Clear screen
         break;} 
   irrecv.resume(); }         
  }
} 

//_________________________________________________________________
void loop() {
    if (irrecv.decode(&results)){
Serial.println(key(),DEC); delay(500);
//  tft.fillScreen(ST7735_BLACK); // Clear screen
//  lcd.clear();
//____________________________________________________________
  
   //***ВХОД В МЕНЮ и проверка блокировки от возврата.
  byte KEY=key();            //Принимаем код клавиши
  if (KEY==1 && temp[0]<millis()) 
      {
        temp[0]=millis()+2000;
        menu();
      }                       //Если setup идем в меню
      irrecv.resume(); }
  //____________________________________________________________
  tft.setCursor(10,100);
  tft.print("cikl");
}

а именно как только вставил в void setOnOff() работу с IR, немного подвигал  irrecv.resume(); } и всё завелось. То что невидно настраиваемого параметра в меню (нет блинка) небеда для отладки сойдёт, а вот то что НЕВСЕГДА каждое нажатие обрабатывает строку char menuTxt[5][14] = {"set menu1 >>", "set menu2 >>","set menu3 >>","set menu4 >>","set menu5 >>"}; - весьма напрягает.

Ну и немного замыленно (с запозданием после нажатия) обрабатываются 

else if (pos == 3 && KEY == 3) setHorClockOn++; // крутим значения
else if (pos == 3 && KEY == 4) setHorClockOn--; 

Как я понял нужно ВОВСЕ теперь отказатья от множествафункций, запускающих работу с IR - верно? Чтоб невозник коллапс :)

Но результат на сейчас уже РАДУЕТ.

bwn
Онлайн
Зарегистрирован: 25.08.2014

Вам задержку 90 и 155 строки дают, возможно пропускает значение во время delay().

В key() я имел в виду как то так:

//Первый вариант.
byte key(){
  
  if (irrecv.decode(&results))
  
  if (results.value == 0x41BEB04F) irrecv.resume(); return 5;
  if (results.value == 0x41BE609F) irrecv.resume(); return 4;
  if (results.value == 0x41BED02F) irrecv.resume(); return 3;
  if (results.value == 0x41BE40BF) irrecv.resume(); return 2;
  if (results.value == 0x41BEC03F) irrecv.resume(); return 1;
  else irrecv.resume(); return 0; 
}

//_____________________________________________________________
//Второй выриаант

byte key(){
  
  if (irrecv.decode(&results))
  {irrecv.resume();}
  Serial.println(results.value,HEX);
  if (results.value == 0x41BEB04F)  return 5;
  if (results.value == 0x41BE609F)  return 4;
  if (results.value == 0x41BED02F)  return 3;
  if (results.value == 0x41BE40BF)  return 2;
  if (results.value == 0x41BEC03F)  return 1;
  else  return 0; 
}

Но здесь меня смущает синтаксис, после decode до resume получается должно быть обернуто в фигурные скобки. Во втором варианте включил промониторить, обнуляется results.value или нет. Надо как то таким способом находить решение.

Thorn
Offline
Зарегистрирован: 07.11.2014

ПО первому варианту пробовал - неработает. ПО второму начинаются проблеммы с обновлениями экранов, НО это так навскидку. Счас заместто теста "cikl" вывел часики и кусок отображаемого кода с температурой. 

Замечено что после установки времени к примеру и так как я сейчас невижу обновления экранчика блинком то нужно нажиать любую клавишу пульта чтобы обновить показания, иначе нажатие кнопки setup одновременно обновляет и записывает показания, которые на 1 ед. больше :)

Блин и размер - огромный матье го етить выходит. У меня всего на НАНО осталось 5-6кб (неоптимизированных) коненчое, но имеется ввиду то то сейчас работает, ка кбы непришлось отказываться от чего то в виде лишнего таймера или термо-реле :(

Счас поколдую ваш вариант KEY 2(вариант) 

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

ПО первому варианту пробовал - неработает. ПО второму начинаются проблеммы с обновлениями экранов, НО это так навскидку. Счас заместто теста "cikl" вывел часики и кусок отображаемого кода с температурой. 

Замечено что после установки времени к примеру и так как я сейчас невижу обновления экранчика блинком то нужно нажиать любую клавишу пульта чтобы обновить показания, иначе нажатие кнопки setup одновременно обновляет и записывает показания, которые на 1 ед. больше :)

Блин и размер - огромный матье го етить выходит. У меня всего на НАНО осталось 5-6кб (неоптимизированных) коненчое, но имеется ввиду то то сейчас работает, ка кбы непришлось отказываться от чего то в виде лишнего таймера или термо-реле :(

Счас поколдую ваш вариант KEY 2(вариант) 

Я думаю это ваш дисплей кушает с душой. Да и потом повторяющиеся куски можно будет в функции завернуть. Кстати скиньте, что сейчас получилось, когда обновления экрана нет.

Thorn
Offline
Зарегистрирован: 07.11.2014

Чёрт побери - да вы гений. Убрал отовсюду работу с кнопками. Кнопки поменял на ваш вариант 2 (первый я делал - безрезультатно то синтаксис то неработают). Вынес в отдельную функцию ваш старый loop(), стало так ну неззаю мне чт ото работать с каждой по отдеьности приятнее чтоли:





void keyM(){
//  if (irrecv.decode(&results)){
//  timer();
//  Serial.println(key(),DEC); delay(500);
//  tft.fillScreen(ST7735_BLACK); // Clear screen
//  lcd.clear();
   //***ВХОД В МЕНЮ и проверка блокировки от возврата.
  byte KEY=key();            //Принимаем код клавиши
  if (KEY==1 && temp[0]<millis()) 
      {
        temp[0]=millis()+2000;
        menu();
      }                       //Если setup идем в меню
//     irrecv.resume(); }
//  tft.setCursor(10,100);
//  tft.print("cikl"); 
}

Остались небольшие грабельки, после сохранения настроек на дисплейчик выводится вся инфа которая периодическ и прорисовывается. Если убрать коммент с очистки экрана в keyM9 то само собой экран начинает переисовыватсья после запуска скетча. И если войти в setup и потом нажать ОДЯИН раз up\down то меню САМО листается от 1 до 5 смотря куда жмакнуть :(

А вот так выглядит сейчас мой цикл():



void loop() {
  eEPROMread();
  timeRtc();
  keyM();
}

где Епромчтение -это от старого, нынедействующего таймера и сам таймер. Счас покажу чего вышло когда есть часики и таймер :)

ПО дисплейчикам, разница в скетчах около 7 кб. НАНО имеет всего 30кб - счас у меня свободно как раз 6-7,

bwn
Онлайн
Зарегистрирован: 25.08.2014

По уму, перед выходом из меню , самое правильное давать команду lcd.clear. Эта информация уже не нужна. А следующий блок уже должен выводить свою информацию.

Thorn
Offline
Зарегистрирован: 07.11.2014

Вот, тут косок с часиками простыми на ds1307, таймер и нагрузка в виде леидков. Весь код:

#include <EEPROM.h>
#include <Wire.h>                     //Подключаем библиотеку для использования однопроводного интерфейса                                     
#include <OneWire.h>                  //Подключаем библиотеку для температурного датчика DS18B20
#include <IRremote.h>                 //Подключаем библиотеку для IR сенсора

 //=====Tft*
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#define sclk 52
#define mosi 51
#define cs   4
#define dc   2
#define rst  3  // you can also connect this to the Arduino reset
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

//=====Переменные для меню
byte setMinClockOn; 
byte setHorClockOn;
byte setMinClockOff;  
byte setHorClockOff;
byte win;              //Номер экрана меню
unsigned long temp[2]; //Массив для задержек меню

#define RECV_PIN 11               //Вход IR-приемника и кнопки пульта
uint32_t val; 
IRrecv irrecv(RECV_PIN);
decode_results results;

#define KEY10 0x41BE30CF           //кнопка Setup пвход в меню настроек параметров
#define KEY2 0x41BEC03F            //кнопка enter принятие установок и запись их
#define KEY1 0x41BED02F            //кнопка Up меню
#define KEY3 0x41BE609F            //кнопка Down возврата 
#define KEY6 0x41BE40BF            //уменьшение значения Left
#define KEY7 0x41BEB04F            //увеличение значения Right

/*
byte key(){
if (results.value == 0x41BEB04F) return 5;
if (results.value == 0x41BE609F) return 4;
if (results.value == 0x41BED02F) return 3;
if (results.value == 0x41BE40BF) return 2;
if (results.value == 0x41BEC03F) return 1;
else return 0; }
*/

byte ledPin1 =7;        //Светодиод
byte ledPin2 =9;        //Светодиод

//=====Rtc_Clock*
#define DS1307_I2C_ADDRESS 0x68
byte seconds, minutes, hours, day, date, month, year;
long tmIntv = 1000;               //Интервал для обновления времени на экране каждую секунду
//long razdIntv = 500;              //Интервал для обновления ":" на экране каждые 2 секунды
long prvMlsTm = 0;                //Предыдущее показание миллисекунд для обновления показания часов
//long prvMlsRazd = 0;              //Предыдущее показание миллисекунд для обновления ":"
//long prvMlsLght = 0;              //Предыдущее показание проверки временного интервала

//=====Timer*
//    long lghtIntv = 60000;            //Интервал для проверки включения/выключения освещения аквариума, 1 минута
byte lcdStat = 0;                //Флаг подсветки Lcd если включена, то в 1
byte lghtStat1 = 0;              //Флаг освещения, Реле Dimm, если включена, то в 1 в первом таймере
byte lghtStat2 = 0;              //Флаг освещения, Реле Dimm, если включена, то в 1 во втором таймере
byte co2Stat = 0;                //Флаг Co2, Реле, если включена, то в 1
byte isLcdt = 0;                 //Флаг для обработки необходимости включить подсветку Lcd
byte isLght1 = 0;                //Флаг для обработки необходимости включить реле освещения на 1 канале в первом таймере
byte isLght2 = 0;                //Флаг для обработки необходимости включить реле освещения на 1 канале во втором таймере
byte isCo2t = 0;                 //Флаг для обработки необходимости включить реле Co2
byte isNight = 0;                //Если включаем на ночь, т.е. начальное время больше конечного

//=====Eeprom*
int hrOn_r1e;                  //переменные для хранения данных о вкл. выкл. реле1 после считывания с EEPROM
int mnOn_r1e;
int hrOff_r1e;
int mnOff_r1e;
int hrOn_r2e;                 //переменные для хранения данных о вкл. выкл. реле2 после считывания с EEPROM
int mnOn_r2e;
int hrOff_r2e;
int mnOff_r2e;
int hrOn_r3e;                 //переменные для хранения данных о вкл. выкл. реле3 CO2 после считывания с EEPROM
int mnOn_r3e;
int hrOff_r3e;
int mnOff_r3e;
int hrOn_lcde;                //переменные для хранения данных о вкл. выкл. Lcd после считывания с EEPROM
int mnOn_lcde;
int hrOff_lcde;
int mnOff_lcde;

//***********************************************************************************************************

void setup() {
  Wire.begin();
  Serial.begin(9600);
  irrecv.enableIRIn();                  //Включаем IR-сенсор
  tft.initR(INITR_BLACKTAB);   
  tft.fillScreen(ST7735_BLACK);         // Clear screen

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin1, HIGH);
  digitalWrite(ledPin2, HIGH);
}

//====================================================
//=========== Обработка RTC часов
//====================================================
void timeRtc(){
  Wire.beginTransmission(DS1307_I2C_ADDRESS);       //104 is DS3231 device address
  Wire.write(0x00);                                 //Start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);          //Request seven bytes
      if(Wire.available()) { 
    seconds = Wire.read();                           //Get second
    minutes = Wire.read();                           //Get minute
    hours   = Wire.read();                           //Get hour
    day     = Wire.read();
    date    = Wire.read();
    month   = Wire.read();                          //Get month
    year    = Wire.read();
       
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111));  //Convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111));
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111));      //Convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111));     //Convert BCD to decimal  1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111));   //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
   tft.setCursor(15,5);
     tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
     tft.setTextSize(2);
if (hours<10) {tft.print(0);tft.print(hours);} else {tft.print(hours);} 
  tft.print(":"); 
      if (minutes<10) {tft.print(0);tft.print(minutes);} else {tft.print(minutes);} 
  tft.print(":"); 
      if (seconds<10) {tft.print(0);tft.print(seconds);} else {tft.print(seconds);}
  tft.setCursor(15,25);
     tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
     tft.setTextSize(1); 
      if (date<10) {tft.print(0);tft.print(date);} else {tft.print(date);} 
 tft.print("/");
 if (month==1){tft.print ("Jan");} 
 if (month==2){tft.print ("Feb");} 
 if (month==3){tft.print ("Mar");} 
 if (month==4){tft.print ("Apr");} 
 if (month==5){tft.print ("May");} 
 if (month==6){tft.print ("Jun");} 
 if (month==7){tft.print ("Jul");} 
 if (month==8){tft.print ("Aug");} 
 if (month==9){tft.print ("Sep");} 
 if (month==10){tft.print ("Oct");} 
 if (month==11){tft.print ("Nov");} 
 if (month==12){tft.print ("Dec");} 
 tft.print("/"); 
 tft.print(year+2000); 
 if (day==1){tft.print (" Sun.");} 
 if (day==2){tft.print (" Mon.");} 
 if (day==3){tft.print (" Tue.");} 
 if (day==4){tft.print (" Wed.");} 
 if (day==5){tft.print (" Thu.");} 
 if (day==6){tft.print (" Fri.");} 
 if (day==7){tft.print (" Sat.");} 
}

//====================================================
//=========== Обработка Таймеров
//====================================================
void timer(){                               //Включаем/выключаем освещение аквариума и СО2
//========== Таймер №1 
  int fullMinutes = hours * 60 + minutes;   //Переводим часы + минуты к полным минутам
  int fullMinutesOn1 = hrOn_r1e * 60 + mnOn_r1e;                //Переводим часы + минуты включения 1 реле к полным минутам
  int fullMinutesOff1 = hrOff_r1e * 60 + mnOff_r1e;             //Переводим часы + минуты выключения 1 реле к полным минутам
  int fullMinutesOn2 = hrOn_r2e * 60 + mnOn_r2e;                //Переводим часы + минуты выключения 2 реле к полным минутам
  int fullMinutesOff2 = hrOff_r2e * 60 + mnOff_r2e;             //Переводим часы + минуты выключения 2 реле к полным минутам
      if (fullMinutesOn1 > fullMinutesOff1) {isNight = 1;}        //Если ночное время
    if (isNight == 0) {                          //Если день
    if (fullMinutes >= fullMinutesOn1 && fullMinutes < fullMinutesOff1) {isLght1 = 1;}        //Проверяем интервал
   else {isLght1 = 0;}                           //Если необходимо включить свет
  } else {                                       //Если ночь
      if(fullMinutes - fullMinutesOn1 >= 0) {isLght1 = 1;}        //Если больше или равно верхнему значению, то необходимо включить свет
   else {                                        //Если необходимо включить свет
      if(fullMinutes < fullMinutesOff1) {isLght1 = 1;}            //Если меньше нижнего значения, то необходимо включить свет
   else {isLght1 = 0;}                           //Если необходимо включить свет
    }
  }  
    if((isLght1 == 1) && (lghtStat1 == 0)){      //Если свет еще не включен и выставлен флаг необходимости включить
    digitalWrite(ledPin1, LOW); lghtStat1 = 1;
    } else {
      lghtStat1 = 0;

}
//========== Таймер №2
      if (fullMinutesOn2 > fullMinutesOff2) {isNight = 1;}        //Если ночное время
    if (isNight == 0) {                          //Если день
    if (fullMinutes >= fullMinutesOn2 && fullMinutes < fullMinutesOff2) {isLght2 = 1;}        //Проверяем интервал
   else {isLght2 = 0;}                           //Если необходимо включить свет
  } else {                                       //Если ночь
      if(fullMinutes - fullMinutesOn2 >= 0) {isLght2 = 1;}        //Если больше или равно верхнему значению, то необходимо включить свет
   else {                                        //Если необходимо включить свет
      if(fullMinutes < fullMinutesOff2) {isLght2 = 1;}            //Если меньше нижнего значения, то необходимо включить свет
   else {isLght2 = 0;}                           //Если необходимо включить свет
    }
  }  
    if((isLght2 == 1) && (lghtStat2 == 0)){      //Если свет еще не включен и выставлен флаг необходимости включить
  digitalWrite(ledPin1, LOW); lghtStat2 = 1;
      } else {
      lghtStat2 = 0;
}
    tft.setTextSize(1);
    tft.setTextColor(ST7735_WHITE, ST7735_BLACK);
    tft.setCursor(50, 140); 
    tft.print(fullMinutesOn1/60);
    tft.print(" ");
    tft.print(fullMinutesOff1%60);
    tft.setCursor(50, 150); 
    tft.print(fullMinutesOn2/60);
    tft.print(" ");
    tft.print(fullMinutesOff2%60);
}

void eEPROMread() {
    hrOn_r1e = EEPROM.read(1);
    mnOn_r1e = EEPROM.read(2);
    hrOff_r1e = EEPROM.read(3); 
    mnOff_r1e = EEPROM.read(4);
    hrOn_r2e = EEPROM.read(5);
    mnOn_r2e = EEPROM.read(6);
    hrOff_r2e = EEPROM.read(7); 
    mnOff_r2e = EEPROM.read(8);
    hrOn_r3e = EEPROM.read(9);
    mnOn_r3e = EEPROM.read(10);
    hrOff_r3e = EEPROM.read(11); 
    mnOff_r3e = EEPROM.read(12);
    hrOn_lcde = EEPROM.read(13);   
    mnOn_lcde = EEPROM.read(14);
    hrOff_lcde = EEPROM.read(15); 
    mnOff_lcde = EEPROM.read(16);
}    
//***********************************************************************************************************

void setOnOff(){    
  byte pos = 0;   

  setHorClockOn = EEPROM.read(win*4+1);    //Считываем записанные значения таймеров
  setMinClockOn = EEPROM.read(win*4+2);    //Адрес определяется как номер таймера*4+четыре ячейки
  setHorClockOff = EEPROM.read(win*4+3);
  setMinClockOff = EEPROM.read(win*4+4);
    
//    lcd.clear();
//    lcd.blink();
tft.fillScreen(ST7735_BLACK); // Clear screen

    while(key() != 1) {//Крутим цикл пока не будет Setup
//    if (irrecv.decode(&results)){
    byte KEY = key(); // читаем состояние кнопок
//    Serial.println(key(),DEC); delay(500);
      delay(200); //Если убрать, не работает подсветка уст.позиции
//    lcd.setCursor(1, 1);
     tft.setCursor(5,75);
     tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
     tft.setTextSize(1);
    tft.print("set to save");
    tft.setCursor(5, 55);
    tft.print(win+1,DEC);    //Печатаем номер прогр.таймера.
    tft.setCursor(35, 55);     // выводим инфу
     if (setHorClockOn < 10) tft.print("0");
    tft.print(setHorClockOn,DEC);
    tft.print(":");
     if (setMinClockOn < 10) tft.print("0"); 
    tft.print(setMinClockOn,DEC);  
    tft.print(" ");     
     if (setHorClockOff < 10) tft.print("0");
    tft.print(setHorClockOff,DEC);
    tft.print(":");
     if (setMinClockOff < 10) tft.print("0");
    tft.print(setMinClockOff,DEC); 
    
    tft.setCursor(pos, 0); // устанавливаем курсор согласно позиции
    
    if (KEY == 5 && pos < 11) pos += 3; // крутим позицию право-лево
    else if (KEY == 2 && pos > 3) pos -= 3;
    
    else if (pos == 3 && KEY == 3) setHorClockOn++; // крутим значения
    else if (pos == 3 && KEY == 4) setHorClockOn--;
    else if (pos == 6 && KEY == 3) setMinClockOn++;
    else if (pos == 6 && KEY == 4) setMinClockOn--;    
    else if (pos == 9 && KEY == 3) setHorClockOff++;
    else if (pos == 9 && KEY == 4) setHorClockOff--;    
    else if (pos == 12 && KEY == 3) setMinClockOff++;
    else if (pos == 12 && KEY == 4) setMinClockOff--;    
    
    if (setHorClockOn > 23) setHorClockOn = 0;  //Ограничиваем значения
    else if (setMinClockOn > 59) setMinClockOn = 0;
    else if (setHorClockOff > 23) setHorClockOff = 0;
    else if (setMinClockOff > 59) setMinClockOff = 0;
// irrecv.resume(); }   
  }// конец цикла
//   lcd.noBlink(); 
//   lcd.clear();
tft.fillScreen(ST7735_BLACK); // Clear screen

   EEPROM.write(win*4+1, setHorClockOn);
   EEPROM.write(win*4+2, setMinClockOn); //Записываем значения
   EEPROM.write(win*4+3, setHorClockOff);
   EEPROM.write(win*4+4, setMinClockOff);

   tft.print("     Saved");
//   delay(1500);
}

//***********************************************************************************************************

void menu(){
    //Массив с наименованиями для экрана
  char menuTxt[5][15] = {"set Timer-1 >>", "set Timer-2 >>","set menu-3 >>","set menu-4 >>","set menu-5 >>"};
  byte pos = 0;
  byte KEY;
  while(1) {//Бесконечный цикл
//  if (irrecv.decode(&results)){
      KEY=0;
      if (temp[1]<millis()) KEY = key(); //Если прошел интервал, читаем код
//      Serial.println(key(),DEC); delay(500);
    tft.setCursor(5,55);
    tft.print(pos+1);  //Печатаем номер.
    tft.print(". ");
    tft.print(menuTxt[pos]); //Печатаем название
    // Уменьшить увеличить + блокировка кнопки
    if (KEY == 3 && pos > 0) {pos--; temp[1]=millis()+50;}
    if (KEY == 4 && pos < 4) {pos++; temp[1]=millis()+50;}
    
    win=pos; //Переменная номера таймера
    
    // Здесь переходим на подменю. Если останется как сейчас, то достаточно
    // if (KEY == 5) setOnOff();
    // Сейчас можно перейти на разные подменю.
    if (KEY == 5 && pos == 0) setOnOff();
    if (KEY == 5 && pos == 1) setOnOff();
    if (KEY == 5 && pos == 2) setOnOff();
    if (KEY == 5 && pos == 3) setOnOff();
    if (KEY == 5 && pos == 4) setOnOff();
    //Выход из меню с проверкой и установкой блокировки от возврата
    if (KEY ==1 && temp[0]<millis())        
       { 
         temp[0]=millis()+200;
tft.fillScreen(ST7735_BLACK); // Clear screen
         break;} 
//   irrecv.resume(); }         
  }
} 

//************************************************************

void keyM(){
//  tft.fillScreen(ST7735_BLACK); // Clear screen
  byte KEY=key();            //ВХОД В МЕНЮ и проверка блокировки от возврата.Принимаем код клавиши
  if (KEY==1 && temp[0]<millis()) {
        temp[0]=millis()+2000;
        menu(); }            //Если setup идем в меню
}

byte key(){
  if (irrecv.decode(&results))
  {irrecv.resume();}
  Serial.println(results.value,HEX);
  if (results.value == 0x41BEB04F)  return 5;
  if (results.value == 0x41BE609F)  return 4;
  if (results.value == 0x41BED02F)  return 3;
  if (results.value == 0x41BE40BF)  return 2;
  if (results.value == 0x41BEC03F)  return 1;
  else  return 0; 
}
//************************************************************

void loop() {
  eEPROMread();
  timeRtc();
  keyM();
}

Почти 22 кб собака в таком виде, Значит сечас разберусь с обновлениями экрана, также нужно флажок типа (нужен\ненужен таймер) придумать и время автоматического выхода из меню, основной то цикл неработает и ничего невыполняется, даже кнопки :) хороший урок для меня.

Thorn
Offline
Зарегистрирован: 07.11.2014

Я понял почему постоянно обновляется экранчик подсказал принт

byte key(){
if (irrecv.decode(&results))
{irrecv.resume();}
Serial.println(results.value,HEX);

несмотря на то, что нажата однажды кнопка setup ОН её возвращает ПОТСОЯННО пока нежмакнеш что иное, вот...

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

Я понял почему постоянно обновляется экранчик подсказал принт

byte key(){
if (irrecv.decode(&results))
{irrecv.resume();}
Serial.println(results.value,HEX);

несмотря на то, что нажата однажды кнопка setup ОН её возвращает ПОТСОЯННО пока нежмакнеш что иное, вот...

Т.Е фактически получается как кнопка с фиксацией. Хоть палец убран, она все равно нажата?

bwn
Онлайн
Зарегистрирован: 25.08.2014

Тяк, начну критиковать сверху вниз.

1. стр.30-31 Можем сделать вход в меню по Setup, а запись значений и выход  по Enter. Тогда исчезает проблема нажатой клавиши и автовозврат.

2. стр71-87 Бессмысленно кушают ресурсы. Эти значения уже существуют в конкретных ячейках EPROM, а самое главное до перезагрузки они будут старыми, как ни меняй их в меню. Правильнее  a=EEPROM.read(x)*60. x можно указывать как прямо, так и косвенно по типу ка win в меню.

3. стр221-238 - пункт.2

4. стр.308 Если убираете ее, то тогда и предыдущую, все равно ничего не увидите.

5. стр.344 и 357. Если делаем как п.1, то эту логику можно всю выбросить.

6. Флажок нужности таймера по идее лишний, если время вкл.=время откл. таймер не нужен. Это условие и проверяйте.

7. Возврату в loop я боюсь вам препятствует 344 строка. Вы за 0,2 секунды просто не успеваете среагировать. У меня выход был четкий. Или читаем п.1.

Вроде все сказал.

 

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

Т.Е фактически получается как кнопка с фиксацией. Хоть палец убран, она все равно нажата?

Мдя... чуток отходил от кода... понедельник всёже :). Все верное таке ощёщение что кнопка с фиксацией несмотря на IR... счас зашел в menu - дале в set Timer-1 (он же set menu1) по вашему старому и чт овы думаете блинк я невижу, однако курсок сразу ушёл на минуты выкл (они-жеЕПРОМ(4)) и елси я нажимаю(up или sown то значения сами меняются в ту или иную сторону). 

Теперь перечитываю вашу критику к коду.....

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

Тяк, начну критиковать сверху вниз.

1. стр.30-31 Можем сделать вход в меню по Setup, а запись значений и выход  по Enter. Тогда исчезает проблема нажатой клавиши и автовозврат.

Можно, кнопок в пульте сами знаете, это не физические манстырить, тут определил и готово. Хотя вариант с 5-ю кнопками тоже ничего такой, очень классный вышел. Просто я когда на if-ах писать пробовал то имеено о 6-т кнопках и думал влево\вправо|вверх\вниз|вход в меню|принятие значения и выход - так и думал.

bwn пишет:

2. стр71-87 Бессмысленно кушают ресурсы. Эти значения уже существуют в конкретных ячейках EPROM, а самое главное до перезагрузки они будут старыми, как ни меняй их в меню. Правильнее  a=EEPROM.read(x)*60. x можно указывать как прямо, так и косвенно по типу ка win в меню.

Это я видимо по аналогии из какого то кода и его работы с ЕПРОМ брал. Счас понимаю что слишком длинно получилось и занимается каждый байт, И да формула полных минут не просто *60 а ещё и прибавляем сами МИНУТЫ тоесть chas*60+min

3. стр221-238 - пункт.2

4. стр.308 Если убираете ее, то тогда и предыдущую, все равно ничего не увидите.

bwn пишет:

5. стр.344 и 357. Если делаем как п.1, то эту логику можно всю выбросить.

Попробую сам описать, неполучится спрошу, ок? НО после того как сейчашнее меню будет нормуль отрабатывать и нажатия и обновления экранчика. :)

bwn пишет:

6. Флажок нужности таймера по идее лишний, если время вкл.=время откл. таймер не нужен. Это условие и проверяйте.

Я так понял проверки именно в функции таймера будет? Там и проверять.

7. Возврату в loop я боюсь вам препятствует 344 строка. Вы за 0,2 секунды просто не успеваете среагировать. У меня выход был четкий. Или читаем п.1.

Вроде все сказал.

[/quote]

Вот вроде все и понял, как теперь побороть "Удержание" кнопки, которая и неудерживается. 

bwn
Онлайн
Зарегистрирован: 25.08.2014
	//====================================================
249	//========== Обработка IR-кнопок, ручное управление реле и диммером
250	//====================================================
251	void ir_manual_key(){
252	  if (irrecv.decode(&results)){      //Если пришел пакет и этот пакет не FF сохраняем правильный пакет в переменную
253	    if (results.value != 0xFFFFFFFF){ //Если пришел FF, соответственно пропускаем.
254	      val = results.value;            //Сверяем значение из переменной val.. если пришла команда повтора (пакет с FF)   
255	  }                                   //в переменной останется прошлый, правильный, пакет и код выполнится повторно.

 

Посмотрел по вашему коду, такая конструкция работает без resume - в чем назначение этой команды?

P.S.погорячился, оно у вас в 302 строке.

bwn
Онлайн
Зарегистрирован: 25.08.2014

А давайте из чистой злобы, так попробуем


byte key(){
  
  if (irrecv.decode(&results))
  {irrecv.resume();}
  Serial.println(results.value,HEX);
  if (results.value == 0x41BEB04F) results.value=0; return 5;
  if (results.value == 0x41BE609F) results.value=0; return 4;
  if (results.value == 0x41BED02F) results.value=0; return 3;
  if (results.value == 0x41BE40BF) results.value=0; return 2;
  if (results.value == 0x41BEC03F) results.value=0; return 1;
  else  results.value=0; return 0; 
}

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Похоже я избавился от "зажатой" кнопки так:

byte key(){
  if (irrecv.decode(&results)){
  irrecv.resume();
  if (results.value == 0x41BEB04F)  return 5;
  if (results.value == 0x41BE609F)  return 4;
  if (results.value == 0x41BED02F)  return 3;
  if (results.value == 0x41BE40BF)  return 2;
  if (results.value == 0x41BEC03F)  return 1;
  else  return 0; 
}
}

Однако теперь перестали работать имеено рабоать (в serial они возвращаются) но ни поменять время ни позицию нельзя.

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

А давайте из чистой злобы, так попробуем




byte key(){
  
  if (irrecv.decode(&results))
  {irrecv.resume();}
  Serial.println(results.value,HEX);
  if (results.value == 0x41BEB04F) results.value=0; return 5;
  if (results.value == 0x41BE609F) results.value=0; return 4;
  if (results.value == 0x41BED02F) results.value=0; return 3;
  if (results.value == 0x41BE40BF) results.value=0; return 2;
  if (results.value == 0x41BEC03F) results.value=0; return 1;
  else  results.value=0; return 0; 
}

 

сначчаал вам написал свой вариант потмо попробовал ваш, синтакси ругается

389: error: 'else' without a previous 'if' 

Thorn
Offline
Зарегистрирован: 07.11.2014

Thorn пишет:

Похоже я избавился от "зажатой" кнопки так:





byte key(){
  if (irrecv.decode(&results)){
  irrecv.resume();
  if (results.value == 0x41BEB04F)  return 5;
  if (results.value == 0x41BE609F)  return 4;
  if (results.value == 0x41BED02F)  return 3;
  if (results.value == 0x41BE40BF)  return 2;
  if (results.value == 0x41BEC03F)  return 1;
  else  return 0; 
}
}

Однако теперь перестали работать именно работать (в serial они возвращаются) но ни поменять время ни позицию нельзя.

Срабатывания на нажатия ОЧЕНЬ чёткие, даже сначала и неповерил - ранее какая то замыленность, то среагирует то нет, а тут чётко, обновляется корректно всё и вход и выход и сохранение... ПОПРАВИТЬ параметры нельзя - ну несмех ли..

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:



	//====================================================
249	//========== Обработка IR-кнопок, ручное управление реле и диммером
250	//====================================================
251	void ir_manual_key(){
252	  if (irrecv.decode(&results)){      //Если пришел пакет и этот пакет не FF сохраняем правильный пакет в переменную
253	    if (results.value != 0xFFFFFFFF){ //Если пришел FF, соответственно пропускаем.
254	      val = results.value;            //Сверяем значение из переменной val.. если пришла команда повтора (пакет с FF)   
255	  }                                   //в переменной останется прошлый, правильный, пакет и код выполнится повторно.

 

Посмотрел по вашему коду, такая конструкция работает без resume - в чем назначение этой команды?

P.S.погорячился, оно у вас в 302 строке.

Да это код ШИКАРНО обрабатывает именно"удержание" кнопки, очень классно и точно обрабатывет на диммировании, вот бы его и прикрутить в устновку времени - чтобы нежмакать минуты каждый раз, а нажал и держиш...

bwn
Онлайн
Зарегистрирован: 25.08.2014

А если так?

byte key(){
  
  if (irrecv.decode(&results))
  {irrecv.resume();}
  val=results.value;
  results.value=0;
  Serial.println(val,HEX);
  if (val == 0x41BEB04F) return 5;
  if (val == 0x41BE609F) return 4;
  if (val == 0x41BED02F) return 3;
  if (val == 0x41BE40BF) return 2;
  if (val == 0x41BEC03F) return 1;
  else return 0; 
}

По val я возможно погорячился, посмотрите что она в HEX возвращает.

bwn
Онлайн
Зарегистрирован: 25.08.2014

Thorn пишет:

bwn пишет:



	//====================================================
249	//========== Обработка IR-кнопок, ручное управление реле и диммером
250	//====================================================
251	void ir_manual_key(){
252	  if (irrecv.decode(&results)){      //Если пришел пакет и этот пакет не FF сохраняем правильный пакет в переменную
253	    if (results.value != 0xFFFFFFFF){ //Если пришел FF, соответственно пропускаем.
254	      val = results.value;            //Сверяем значение из переменной val.. если пришла команда повтора (пакет с FF)   
255	  }                                   //в переменной останется прошлый, правильный, пакет и код выполнится повторно.

 

Посмотрел по вашему коду, такая конструкция работает без resume - в чем назначение этой команды?

P.S.погорячился, оно у вас в 302 строке.

Да это код ШИКАРНО обрабатывает именно"удержание" кнопки, очень классно и точно обрабатывет на диммировании, вот бы его и прикрутить в устновку времени - чтобы нежмакать минуты каждый раз, а нажал и держиш...

По нормальному, на мех.кнопках это и происходит с интервалом в 0,3 секунды.

Thorn
Offline
Зарегистрирован: 07.11.2014

Почти ка ки в моем варианте, все корректно обрабатывается пока ненужно параметры поменять времени (минут и часов).

Однако в моем варианет если нет нажатия то нет и возврата в вашем случае если нет нажатия возвращается "0" если еть то HEX адрес кнопки с межеванием "0" (я так понял это и есть return 0)

Жаль но мой предлженный  ни ваш неизменят параметра. внутри setmenu-1

Thorn
Offline
Зарегистрирован: 07.11.2014

bwn пишет:

По нормальному, на мех.кнопках это и происходит с интервалом в 0,3 секунды.

Понимаю, только я пульт выбрал непотому чт олень кнопи манстырить было а по другим причинам. ВО первых мобильность некая, далее кнопки у кадого СВОИ кто то так ктото эдак ктото вообще потнциометромих пользует (переменными резиорами, где поворот часов/24 а минут на /60). А пульт у каждого, взяли наш с вами код, подставили СВОИ HEX-кнопки и всё. Ну и само собой у меня контроллер это маааленькая чать в светильнике акариума и довольно высоко вот лазать туда жмакать хоть и нечасто но надо. Да и вообще IR - же намного интереснее, выже сами видите уже :)

Thorn
Offline
Зарегистрирован: 07.11.2014

у категорически непонмаю ничего КАК могут возвращаться НАЖАТЫЕ кнопки и НИЧЕГО неделать? Есч ораз промониторил serial.Print всё нажимается, а изменения нет.

bwn
Онлайн
Зарегистрирован: 25.08.2014

Так я и не могу понять почему не так. Сейчас выходит: если клавиша нажата, key() возвращает что то от 1 до 5. Если отпустили, идет 0. То есть полностью соответствует мех.клавишам. При этом первый экран меню работает корректно или нет?

bwn
Онлайн
Зарегистрирован: 25.08.2014

Так как насчет первого экрана, где выбираем таймер?