Jednoduché memu - I2C displej 20x4 + rotační enkodér

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
johnyhol
Příspěvky: 33
Registrován: 07 pro 2017, 21:17
Reputation: 0

Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od johnyhol » 07 bře 2021, 16:40

Ahoj všichni,
měl bych dotaz, jestli někdo z Vás nemá jednoduché funkční menu k nastavení šesti různých hodnot (položek). V podstatě by se jednalo o hlavní nabídku šesti položek a po stisknutí enkodéru na konkrétní položce by se zobrazila podnabídka s nastavením parametru (času). Čas by se nastavoval otáčením a potvrzovalo by se stisknutím enkodéru. Zkoušel jsem hledat ale nic co by mi vyhovovalo jsem bohužel nenašel. Pouze nějaké demo menu s různými nastaveními, ale to bylo dost složité. Přiložil jsem obrázek aktuálního zobrazení na displeji a potom ještě požadovaný vzhled menu.
Aktuální zobrazení na displeji během provozu
Aktuální zobrazení na displeji během provozu
Požadované menu
Požadované menu
Jedná se o:
  • Arduino Mega
    4x relé
    Ethernet modul
    I2C Displej 20x4
    Rotační enkodér
Tady ještě můj kód:

Kód: Vybrat vše

// REGULACE PELETKOVEHO KOTLE 2.0
// author Johnyhol
// v 14_11_2020

// changelog


// definice poruch
// bit  funkce
// 0    prehrati kotle pri zapalovani
// 1    ztrata plamene pri horeni
// 2    volne
// 3    volne
// 4    volne
// 5    volne
// 6    volne
// 7    volne

// knihovna watchdogu
#include <avr/wdt.h>
// knihovna displeje
#include <LiquidCrystal_I2C.h>
#include <UIPEthernet.h>
#include <CayenneMQTTEthernet.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "6c40f970-f7a9-11e6-9728-67156ca35db4";
char password[] = "6ef9aaf21f1b0782b8e6a854ebe6f88f3aa0370d";
char clientID[] = "1311d2b0-2208-11eb-8779-7d56e82df461";

//#define VIRTUAL_CHANNEL 1

// nastaveni pinu displeje
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);

#define davkovaniPelet 13 // davkovani pelet snek
#define spirala 12 // zapalovaci spirala
#define ventilator 11 // ventilator
#define alarm 14 // signalizace poruchy
#define kotlovyTermostat 2 // kotlovy termostat
#define fotobunka 55 // fotobunka pro kontrolu plamene DI55 = A1 pro arduino MEGA
#define trimr1 56 // nastaveni doby zapaleni  DI56 = A2 pro arduino MEGA
#define tlacitkoKvitance 3 // pin tlacitka kvitance poruchy
//pin DI54 = A0 -> rezervace pro tlacitka displeje
//pin D13 -> rezervace pro Ethernet Schield
//pin D12 -> rezervace pro Ethernet Schield
//pin D11 -> rezervace pro Ethernet Schield
//pin D10 -> rezervace pro Ethernet Schield + pro podsviceni displeje
//pin D4 -> rezervace pro SD kartu + pro displej
//pin D1 -> rezervace pro seriovou linku
//pin D0 -> rezervace pro seriovou linku

int smycka1 = 0; // pomocna smycka - zapaleni
int smycka1max = 720; // max.pomocne smycky - ted jiz nastavitelne trimrem na A2 60-720s
int smycka2 = 0; // pomocna smycka - udrzeni horeni
int smycka2max = 2; // max.pomocne smycky
int smycka3 = 0; // pomocna smycka - pocet pokusu o zapaleni
int smycka3max = 2; // max.pomocne smycky
int smycka4 = 0; // pomocna smycka - davkovani zapalne davky pelet
int smycka4max = 110; // max.pomocne smycky
int smycka5 = 0; // pomocna smycka - rozhoreni
int smycka5max = 40; // max.pomocne smycky
int smycka6 = 0; // pomocna smycka - dohoreni
int smycka6max = 840; // max.pomocne smycky
byte porucha = 0; // promenna pro zaznam poruchy
 int ldr = 1; // analogovy pin kde je pripojen fotorezistor
int ldr_value = 0; // promenna pro zaznam hodnot z fotorezistoru
boolean cayenne_zapnuto; // promenna pro stav sepnuti Cayenne
boolean kotlovy_zapnut; // promenna pro stav sepnuti kotloveho termostatu
boolean cayenne_zapnuto_display; // promenna pro zobrazeni sepnuti Cayenne

void setup() {
  Serial.begin(9600); // nastav seriovou komunikaci na rychlost 9600 bd 
  Serial.println("Nastavuji vstupy/vystupy"); // ladici seriova komunikace
  Cayenne.begin(username, password, clientID);
  lcd.init(); // inicializace LCD
  lcd.backlight(); // zapnutí podsvícení
  lcd.print("NAST. VSTUPY/VYSTUPY"); // zobrazeni na displeji
  lcd.setCursor(0, 3); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("VYPINAM VSECHNY RELE"); // zobrazeni na displeji
  delay (2000);
  pinMode(davkovaniPelet, OUTPUT);
  pinMode(spirala, OUTPUT);
  pinMode(ventilator, OUTPUT);
  pinMode(alarm, OUTPUT);
  pinMode(kotlovyTermostat, INPUT);
  pinMode(fotobunka, INPUT);
  pinMode(trimr1, INPUT);
  pinMode(tlacitkoKvitance, INPUT);
  
  vypniVse(); // vsechno vypni
        
        wdt_enable(WDTO_8S); // nastav watchdog na 8s
}

void loop() {
        wdt_reset(); // resetuj watchdog
        Cayenne.loop();
        ldr_value = analogRead(ldr); // čte hodnoty LDR
  Serial.print("HODNOTA FOTOBUNKY = ");
  Serial.println(ldr_value); // zobrazí hodnoty LDR na seriove lince
  Serial.println("Cekam na sepnuti termostatu ..."); // ladici seriova komunikace
  smycka1max = map(analogRead(trimr1), 0, 1024, 60, 720); // nastaveni doby zapaleni trimrem na A2
  if (digitalRead(kotlovyTermostat) == HIGH){
      kotlovy_zapnut = true;
      lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(" -TERMOSTAT ZAPNUT- "); // zobrazeni na displeji
    }
    else {
    kotlovy_zapnut = false;
    lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
    lcd.print(" -TERMOSTAT VYPNUT- "); // zobrazeni na displeji
    }
  
  if (cayenne_zapnuto == true && kotlovy_zapnut == true){  // cayenne a kotlovy termostat je zapnuty
          Serial.println("Kotlovy termostat zapnut"); // ladici seriova komunikace
          //lcd.clear();
          //lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
          //lcd.print(" -TERMOSTAT ZAPNUT- "); // zobrazeni na displeji
  delay (2000);
      // startovaci davka pelet
      //------------------------
      zapalovaciDavkaPelet();
      
      // proces zapaleni
      //----------------
      zapaleni();
      
      // test poruchy
      // -----------------
      //testPlamene(); 
      
      // udrzeni horeni
      //--------------
      udrzujHoreni();
      
      // dohoreni
      //---------
      //dohoreni();
      
    } else {
      Serial.println("Kotlovy/Prostorovy termostat vypnut"); // ladici seriova komunikace
      //lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      //lcd.print("                    "); // zobrazeni na displeji
      //lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      //lcd.print(" -TERMOSTAT VYPNUT- "); // zobrazeni na displeji
      lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("(VERZE FW: 14.11.20)"); // zobrazeni na displeji
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      //lcd.print("                    "); // zobrazeni na displeji
      }
  // kvitence pripadne poruchy
  //-------------------------------
  kvitancePoruchy();
 
}

void vypniVse() { // funkce: vypni vse
  Serial.println("Vypinam vsechny rele ..."); // ladici seriova komunikace
  digitalWrite(davkovaniPelet, HIGH); // vypni davkovani
  digitalWrite(spirala, HIGH); // vypni zhaveni
  digitalWrite(ventilator, HIGH); // vypni ventilator
  digitalWrite(alarm, HIGH); // vypni alarm
}

void zapalovaciDavkaPelet() { // funkce: prvotni davkovani pelet pro zapaleni
  Serial.println("Davkuji pelety pro zapaleni ... 90s"); // ladici seriova komunikace
  lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print(" -STARTOVACI DAVKA- "); // zobrazeni na displeji
  lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("   DAVKUJI PELETY   "); // zobrazeni na displeji
  lcd.setCursor(0, 3); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("  ZADNA PORUCHA...  "); // zobrazeni na displeji
  digitalWrite(davkovaniPelet, LOW); //davkuj pelety
        for (smycka4 = 0;  smycka4 < smycka4max; smycka4 ++){ // pomocna smycka - davkovani zapalne davky pelet
    delay(1000); 
          wdt_reset(); // resetuj watchdog
  Serial.print("Stav: ");
  Serial.print(smycka4); // pomocna smycka - davkovani zapalne davky pelet
  Serial.print("s/");
  Serial.print(smycka4max); // pomocna smycka - davkovani zapalne davky pelet
  Serial.println("s ");
  lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("       STAV:        "); // pomocna smycka - davkovani zapalne davky pelet
  lcd.setCursor(13, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print(smycka4); // pomocna smycka - davkovani zapalne davky pelet
  lcd.setCursor(16, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("/"); // zobrazeni na displeji
  lcd.print(smycka4max); // pomocna smycka - davkovani zapalne davky pelet
          }
  digitalWrite(davkovaniPelet, HIGH); // potom vypni davkovani
  digitalWrite(ventilator, LOW); // zapni ventilator
  digitalWrite(spirala, LOW); // zapni zhaveni
}

void zapaleni() { // funkce: zapaleni pelet
  // 2 pokusy o zapaleni
  Serial.println("Spoustim zapaleni ..."); // ladici seriova komunikace
  lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("     -ZAPALENI-     "); // zobrazeni na displeji
  for (smycka3 = 0;  smycka3 < smycka3max; smycka3 ++){ // smycka 2 pokusy o zapaleni
    for (smycka1 = 0;  smycka1 < smycka1max; smycka1 ++){ // smycka "1-10" minut zapalovani
                        wdt_reset(); // resetuj watchdog
      Serial.print("Pokus o zapaleni "); // ladici seriova komunikace
      Serial.print(smycka3); // ladici seriova komunikace - pomocna smycka - pocet pokusu o zapaleni
      Serial.print("/"); // ladici seriova komunikace
      Serial.println(smycka3max); // ladici seriova komunikace - pomocna smycka - pocet pokusu o zapaleni
      Serial.print("Stav: "); // ladici seriova komunikace
      Serial.print(smycka1); // ladici seriova komunikace - pomocna smycka - zapaleni
      Serial.print("s/"); // ladici seriova komunikace
      Serial.print(smycka1max); // ladici seriova komunikace - pomocna smycka - zapaleni
      Serial.println("s "); // ladici seriova komunikace
      lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("POKUS           "); // zobrazeni na displeji
      lcd.setCursor(6, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(smycka3); // pomocna smycka - pocet pokusu o zapaleni
      lcd.setCursor(7, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("/"); // zobrazeni na displeji
      lcd.print(smycka3max); // pomocna smycka - pocet pokusu o zapaleni
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("       STAV:        "); // pomocna smycka - davkovani zapalne davky pelet
      lcd.setCursor(13, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(smycka1); // pomocna smycka - zapaleni
      lcd.print("  "); // zobrazeni na displeji
      lcd.setCursor(16, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("/"); // zobrazeni na displeji
      lcd.print(smycka1max); // pomocna smycka - zapaleni
      ldr_value = analogRead(ldr); // čte hodnoty
      lcd.setCursor(10, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("FOTO="); // zobrazeni na displeji
      lcd.setCursor(15, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(ldr_value); // hodnota fotobuňky
                        
      if(digitalRead(kotlovyTermostat) == LOW){ // kotlovy termostat vypne
        //digitalWrite(spirala, HIGH); //vypni zhaveni
        //smycka1 = smycka1max; // ukonci smycku1 (zapaleni)
        //smycka3 = smycka3max; // ukonci smycku3 (pokusy o zapaleni)
        Serial.println("Rozepnuti termostatu ..."); // ladici seriova komunikace
                                //bitSet(porucha,0); // nastav poruchu bit c.0 na "1"
      }
      if(analogRead(fotobunka) <= 800){ // pokud fotobunka vidi plamen
        delay(2000);
        digitalWrite(spirala, HIGH); // vypni zhaveni
        smycka1 = smycka1max; // ukonci smycku1 (zapaleni)
        smycka3 = smycka3max; // ukonci smycku3 (2 pokusy o zapaleni)
        Serial.println(" hori ...");   // ladici seriova komunikace
        Serial.println("Rozhoreni ... 40s ");
        lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("    -ROZHORENI-     "); // zobrazeni na displeji
        lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("HORI...         "); // zobrazeni na displeji
        ldr_value = analogRead(ldr); // čte hodnoty LDR
        lcd.setCursor(11, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("FOTO="); // zobrazeni na displeji
        lcd.setCursor(16, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print(ldr_value); // hodnota fotobuňky
                               
      } else {
        Serial.println(" nehori ...");   // ladici seriova komunikace 
      }
      delay(1000);
    }
                for (smycka5 = 0;  smycka5 < smycka5max; smycka5 ++){ // smycka rozhoreni
            delay(1000); 
                  wdt_reset(); // resetuj watchdog
        Serial.print("Stav: ");
        Serial.print(smycka5); // pomocna smycka - rozhoreni
        Serial.print("s/");
        Serial.print(smycka5max); // pomocna smycka - rozhoreni
        Serial.println("s ");
        lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("       STAV:        "); // pomocna smycka - davkovani zapalne davky pelet
        lcd.setCursor(13, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print(smycka5); // pomocna smycka - rozhoreni
        lcd.setCursor(16, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("/"); // zobrazeni na displeji
        lcd.print(smycka5max); // pomocna smycka - rozhoreni
        ldr_value = analogRead(ldr); // čte hodnoty 
        lcd.setCursor(11, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("FOTO="); // zobrazeni na displeji
        lcd.setCursor(16, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print(ldr_value); // hodnota fotobuňky
                }
    //delay(5000); // cekej 5s
  }
}

void udrzujHoreni() { // funkce: udrzeni horeni
  ldr_value = analogRead(ldr); // čte hodnoty LDR
  Serial.print("HODNOTA FOTOBUNKY = ");
  Serial.println(ldr_value); // zobrazí hodnoty LDR na seriove lince
  Serial.println("Udrzeni horeni ..."); // ladici seriova komunikace
  for (smycka2 = 0;  smycka2 < smycka2max; smycka2 ++){ // pomocna smycka - udrzeni horeni
                    wdt_reset(); // resetuj watchdog
        smycka2 = 0; // vynuluj smycku
    if(digitalRead(kotlovyTermostat) == HIGH){ // kotlovy termostat je zapnuty
      if (cayenne_zapnuto_display = true){      
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(" -CAYENNE ZAPNUTO-  "); // zobrazeni na displeji
      }
        else{
         lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
         lcd.print(" -CAYENNE VYPNUTO-  "); // zobrazeni na displeji 
        }      
    
      if(analogRead(fotobunka) <= 1000){ // pokud fotobunka vidi plamen
        Serial.println("Test plamene ... hori"); // ladici seriova komunikace
        Serial.println("Davkuji pelety ... ");
        lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("     -DAVKOVANI-    "); // zobrazeni na displeji
        ldr_value = analogRead(ldr); // čte hodnoty 
        lcd.setCursor(11, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("FOTO="); // zobrazeni na displeji
        lcd.setCursor(16, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print(ldr_value); // hodnota fotobuňky
        digitalWrite(davkovaniPelet, LOW); // davkuj pelety
        delay(4000); // pockej 4s
        wdt_reset(); // resetuj watchdog
        delay(4000); // pockej 4s
        wdt_reset(); // resetuj watchdog
        Serial.println("Pauza ... ");
        lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("      -HORENI-      "); // zobrazeni na displeji
        ldr_value = analogRead(ldr); // čte hodnoty 
        lcd.setCursor(11, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print("FOTO="); // zobrazeni na displeji
        lcd.setCursor(16, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
        lcd.print(ldr_value); // hodnota fotobuňky
        digitalWrite(davkovaniPelet, HIGH); //vypni davkovani
        delay(5000); // pockej 5s
        wdt_reset(); // resetuj watchdog
        delay(5000); // pockej 5s
        wdt_reset(); // resetuj watchdog
      } else {
        delay(2000); // pocekej jeste 1s a zkus to znovu
        if(analogRead(fotobunka) >= 1020){  //pokud fotobunka nevidi plamen 1020
                                Serial.println("Test plamene ... porucha"); // ladici seriova komunikace
                                lcd.setCursor(0, 3); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
                                lcd.print("!!!NEHORI-PORUCHA!!!"); // zobrazeni na displeji
  //delay (500);
                                smycka2 = smycka2max; // ukonci smycku
                    //porucha = 1; // nastav poruchu
                                bitSet(porucha,1); // nastav poruchu bit c.1 na "1"
                                digitalWrite(alarm, LOW); // zapni alarm
        }
      }
    } else {
      smycka2 = smycka2max; // ukonci smycku
      dohoreni();
    }  
  }
}

void dohoreni() { // funkce: dohoreni
  Serial.println("Dohoreni ... 840s "); // ladici seriova komunikace
  lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("     -DOHORENI-     "); // zobrazeni na displeji
  digitalWrite(davkovaniPelet, HIGH); // vypni davkovani pelet
  digitalWrite(spirala, HIGH); // vypni zhaveni - pro jistotu
          for (smycka6 = 0;  smycka6 < smycka6max; smycka6 ++){ // pomocna smycka - dohoreni
            if(analogRead(fotobunka) >= 1020){  //pokud fotobunka nevidi plamen
                                lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
                                lcd.print("NEHORI...       "); // zobrazeni na displeji
            }
  Serial.print("Stav: ");
  Serial.print(smycka6); // pomocna smycka - dohoreni
  Serial.print("s/");
  Serial.print(smycka6max); // pomocna smycka - dohoreni
  Serial.println("s ");
  lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("       STAV:        "); // pomocna smycka - davkovani zapalne davky pelet
  lcd.setCursor(13, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print(smycka6); // pomocna smycka - dohoreni
  lcd.print("  "); // zobrazeni na displeji
  lcd.setCursor(16, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("/"); // zobrazeni na displeji
  lcd.print(smycka6max); // pomocna smycka - dohoreni
  ldr_value = analogRead(ldr); // čte hodnoty 
  lcd.setCursor(11, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print("FOTO="); // zobrazeni na displeji
  lcd.setCursor(16, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
  lcd.print(ldr_value); // hodnota fotobuňky
     delay(1000); 
          wdt_reset(); // resetuj watchdog
        }
  digitalWrite(ventilator, HIGH); // vypni ventilator
  if (cayenne_zapnuto_display = true){      
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(" -CAYENNE ZAPNUTO-  "); // zobrazeni na displeji
      }
        else{
         lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
         lcd.print(" -CAYENNE VYPNUTO-  "); // zobrazeni na displeji 
        }      
  
}

void kvitancePoruchy() { // funkce: kvitance poruchy
    if(porucha > 0 ){ // kdyz je porucha aktivni
        Serial.println("Kvitance poruchy ..."); // ladici seriova komunikace
    // vypni vse
    vypniVse();
    while (digitalRead(tlacitkoKvitance) == LOW) { // zapni alarm a cekej na stisk tlacitka
      digitalWrite(alarm, LOW); // zapni alarm
      Serial.println("Porucha ... cekam na kvitanci"); // ladici seriova komunikace
      lcd.setCursor(0, 0); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(" -CEKAM NA KVITACI- "); // zobrazeni na displeji
      lcd.setCursor(0, 1); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("  STISKNI TLACITKO  "); // zobrazeni na displeji
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print("     NA PANELU      "); // zobrazeni na displeji
                          wdt_reset(); // resetuj watchdog
    }
    Serial.println("Porucha kvitovana ..."); // ladici seriova komunikace
    digitalWrite(alarm, HIGH); // vypni alarm
    porucha = 0; // vynuluj poruchu
  } else {  // jinak 
    Serial.println("Zadna porucha  ..."); // ladici seriova komunikace
    //lcd.clear();
    lcd.setCursor(0, 3); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
    lcd.print("  ZADNA PORUCHA...  "); // zobrazeni na displeji
    digitalWrite(alarm, HIGH); // vypni alarm
}
}

//CAYENNE_IN(VIRTUAL_CHANNEL)
CAYENNE_IN_DEFAULT()
{
  // Write value to turn the relay switch on or off. This code assumes you wire your relay as normally open.
 if (getValue.asInt() == 1) {
      cayenne_zapnuto = true;
      cayenne_zapnuto_display = true;
      lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
      lcd.print(" -CAYENNE ZAPNUTO-  "); // zobrazeni na displeji
    }
  else {
    cayenne_zapnuto = false;
    lcd.setCursor(0, 2); // (1 znak => sloupec,druhy znak => radek, prvni radek je 0)
    lcd.print(" -CAYENNE VYPNUTO-  "); // zobrazeni na displeji
    }
 }

 CAYENNE_OUT_DEFAULT()
{
  if (digitalRead(kotlovyTermostat) == HIGH){ 
  Cayenne.virtualWrite(2, 1, "digital_sensor", "d");
  }
  else{
  Cayenne.virtualWrite(2, 0, "digital_sensor", "d"); 
  }
  // Some examples of other functions you can use to send data.
  //Cayenne.celsiusWrite(1, 22.0);
  //Cayenne.luxWrite(2, 700);
  //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
}
Díky moc!

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od pavel1tu » 07 bře 2021, 17:22

Tak opravdu jednoduché menu je v projektu "Hodiny" v hotových projektech, jak jsem již mnohokráte přiznal, rád ho používám. Jen je s tlačítky.

Ale k displejům tohoto typu je dost hotových menu, jako knihovny, myslím že i s rotačním enkoderem. Jen se mi to nechce hledat.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

johnyhol
Příspěvky: 33
Registrován: 07 pro 2017, 21:17
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od johnyhol » 07 bře 2021, 20:28

Hm, tak to nevím, to mi asi moc nepomůže. Přesto díky za reakci. Zkusím ještě pohledat.

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od martinius96 » 07 bře 2021, 20:53

Mám to v dosť robustnom projekte s ukladaním do EEPROM atď..., tak ti napíšem skôr nápovedu, ako to ľahko urobiť...
Zobral som tento test sketch:
https://navody.dratek.cz/navody-k-produ ... y-040.html

Obmedzil som jednoduchými if podmienkami pohyb vľavo a vpravo tak, aby som mal napríklad hodnoty enkódera 0 až 2 (aby mi to nepretieklo za).
Hodnota pozície enkódera 0 (zobrazí sa i po spustení Arduina) je MENU 1, hodnota 1 je MENU 2, hodnota 2 MENU 3. Vždy otočenie enkódera o krok pripočíta, respektíve odpočíta 1 k hodnote pozície. Vždy pri zmene (otočení enkóderu vypíšem to menu na displej). Používam switch() s cases 0 1 2 pre tieto menu (ten switch spustím až pri otočení enkódera, keď to zaznamená pohyb). Teda ak je enkóder bez pohnutia, nič sa neprekresluje.

Výpis menu po otočení enkóderom podľa hodnoty pozície
Obrázek
Následne ak si zvolím konkrétnu možnosť stlačením integrovaného tlačidla enkódera, prepnem sa do samostatného režimu (režim 0 môžu byť tie hlavné menu) (Režim 1 bude po zvolení MENU 1 napríklad nastavenie hodnoty ANALOG pinu, Režim 2 môže byť nastavenie teploty, Režim 3 Ďalšie. Mám tam staticky (pri zvolení režimu vypísaný len nadpis, názov), napríklad: Zmena ANALOG na druhý riadok si vypíšem aktuálnu hodnotu premennej, ktorú chcem meniť.. Otáčaním enkódera budem túto hodnotu meniť (rovnaký fragment kódu ako pri prechode menu predtým, budem však meniť hodnotu premennej a nie poziceEnkod ako pri prechode v hlavnou menu). Vždy si vypíšem hodnotu na displej pre tú premennú pri jej zmene (po otočení enkódera do + alebo do -), môžem tam obmedziť tiež rozsah tých hodnôt, napríklad od 0 po 1023, jednoduché if else.. if premenná < 0, premenná = 0; if premenná >1023, premenná =1023; Po stlačení tlačidla enkódera sa hodnota uloží, ja používam do EEPROM. Následne sa prepnem opäť do režimu 0 (aby som videl a mohol prezerať všetky hlavné menu, kde si môžem vybrať znovu čo chcem konfigurovať) + ešte pred tým prechodom si môžem vypísať že, hodnota ABCD sa uložila a má hodnotu XXX...

Napríklad na tých priložených obrázkoch mám konfiguráciu času, kedy si volím čas hry (na hodnote 0 sa mi vypíše NEKONECNO, ak točím do vyšších pozícii, tak X hodín... následne to viem použiť v programe, samostatným menu si spustím hru :) )
Obrázek
Obrázek

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od pavel1tu » 08 bře 2021, 17:17

No, právě že těch menu je hodně, já většinou vycházel z tohoto, ale jen u složitějších menu.
https://github.com/Jomelo/LCDMenuLib

Ale je nutná úprava na encoder, ten bohužel nepoužívám.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

johnyhol
Příspěvky: 33
Registrován: 07 pro 2017, 21:17
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od johnyhol » 10 bře 2021, 08:34

Pánové díky moc za reakce, koukám že to nebude až tak jednoduchý jak jsem si myslel. Jsem pořád ještě začátečník a tak v tom docela plavu, proto jsem si myslel, že bych vzal nějaký hotový funkční sketch kde by byl zahrnutý I2C displej 20x4 a ovládalo by se to rotačním enkodérem. Já bych pouze upravil počet a názvy položek menu a podnabídek. Jenže takový sketch jsem nikde nenašel, vždy je tam něco jinak (třeba tam není enkodér, nebo je tam jiná skladba menu, je to zbytečně složitý-moc úrovní atd.) a s tím si já neporadím.

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od ondraN » 10 bře 2021, 09:17

No tak začni s něčím jednodušším a pomalu svoji úroveň zvedni :mrgreen: Vždyť o tom to je. Pokud se tomu nechceš věnovat a potřebuješ jenom něco specifického, je nejlepší to poptat jako zakázku.

johnyhol
Příspěvky: 33
Registrován: 07 pro 2017, 21:17
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od johnyhol » 10 bře 2021, 09:49

Mám rozdělaných nebo hotových cca. 20 projektů, od jednoduchých po složitější jako tento. Začínal jsem s blikáním LEDky atd. až jsem si sestrojil online meteo stanici a další. Tento projekt taky začínal pouze na UNU se 4x relé a pak jsem přešel na MEGA s displejem 16x2, potom na 20x4 a ethernet modul + napojení na Cayenne. No a další krok je právě to menu s enkodérem pro nastavení hodnot, které zatím upravuju v kódu připojením notebooku a to se mi moc nelíbí. Takže se tomu chci věnovat, ale jsou věci na který prostě (zatím) nestačím. (a možná je budu muset poptat na zakázku - to bych ale chtěl nechat jako poslední možnost, spíš bych se to chtěl naučit)

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od ondraN » 10 bře 2021, 10:00

Pokud se to chceš naučit, nesmíš na to tak hopem. Že něco nezvládneš, je jen ukazatelem, že jsi si dal laťku příliš vysoko. Zkus si udělat jiný projekt, kde budeš řešit jen to menu s enkodérem, hezky jen jednu úroveň, pak dvě, tři ... No a pak se vrať zase k rozdělanému pprojektu a uvidíš, že to už bude v pohodě. A pokud se nechceš stát lepičem cizích kódů, tak to zku řešit tak, že se do cizích kódů jen podíváš, ale nic nebudeš kopírovat do svého. Prostě je jen pochopit a pak podle pochopeného algoritmu udělat svůj.

johnyhol
Příspěvky: 33
Registrován: 07 pro 2017, 21:17
Reputation: 0

Re: Jednoduché memu - I2C displej 20x4 + rotační enkodér

Příspěvek od johnyhol » 10 bře 2021, 11:09

Přesně takto to chci řešit, zkusit si to na nečisto jak píšeš (jednoduchý menu s enkodérem), ale potřeboval bych se právě podívat na nějaký jednoduchý příklad ze kterýho bych mohl vycházet a na něm se to naučit. Ten jsem bohužel zatím nenašel, všechno jsou to hotový na mě složitý projekty, kde se moc neorientuju.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 8 hostů