Výběr barvy

Cuore
Příspěvky: 8
Registrován: 24 bře 2018, 19:26
Reputation: 0

Výběr barvy

Příspěvek od Cuore » 24 bře 2018, 19:54

Ahoj,
potřeboval bych pár návrhů, jak by se dalo řešit výběr barvy pro RGB LED pomocí tlačítek a displeje. Má představa je taková, že si v menu nastavení budu listovat mezi předdefinovanými barvami (modrá, bílá atd.) a jejím potvrzením se barva nastaví. Tzn. že na displeji bude zobrazovaná např. červená a v kódu pro diodu bude zapsáno R = 255, G = 0,B = 0. Tady pro náhled celý kód:

Kód: Vybrat vše

#include <LiquidCrystal.h>
#include <IRremote.h>       
#include <EEPROM.h>             

#define ANALOG_SENSOR_PIN  A0 
#define Prodleva_Zap 50
#define Prodleva_A0 1500
#define Prodleva_Vyp 5000
#define Prodleva_Dis 3000
#define Prodleva_Res 30000
#define HTPiStav 0
#define HTPiPozadavek 1
#define NasPozadavek 2
#define LightBerryStav 3
#define LightBerryPozadavek 4 
#define Navigace 5 

unsigned long aktualMillis;            //aktualni cas
unsigned long predchoziMillis = 0;
unsigned long PosledniCteniA0 = 0;
unsigned long CasZmenyZap = 0;         // promenna pro ulozeni casu zmeny stavu tlacitka
unsigned long CasZmenyVyp = 0;         // promenna pro ulozeni casu zmeny stavu tlacitka
unsigned long CasZmenyRes = 0;         // promenna pro ulozeni casu pro restart HTPi
unsigned long CasZmenyDis = 0;         // promenna pro ulozeni casu pro zmeni obrazovky
unsigned long interval;
unsigned long readingTime;             // cas posledniho cteni
unsigned long readingUpdate;           // cas posledniho stisku tlacitka
unsigned long mimoradnaUdalost;
unsigned long ENTER;
unsigned long VLEVO;
unsigned long VPRAVO;
unsigned long NAHORU;
unsigned long DOLU;
const long timeoutUpdate = 60000;
char barva[10] = "";
char barva1[10] = "cervena";
char barva2[10] = "zelena";
char barva3[10] = "modra";
char barva4[10] = "bila";
char barva5[10] = "fialova";
char barva6[10] = "zluta";

bool MinulyStavZap = 1;                // priznak predchoziho stavu tlacitka (1 .. stisknuto)
bool MinulyStavVyp = 1;                // priznak predchoziho stavu tlacitka (1 .. stisknuto)
bool MinulyStavRes = 1;                // priznak predchoziho stavu komunikace
bool zmenaObrazovka = true;            // zmena obrazovky
boolean udalost = true;
boolean displayUpdate = true;          // nastaveni zda se ma aktualizovat displej
byte mode = 0;                         // nastaveni modu rozbrazeni a ceteni

const int LED_HTPi = 2;
const int LED_Arduino = 3;
const int LED_G = 4;
const int LED_O = 5;
const int LED_R = 6;
const int RGB_B = 11;
const int RGB_G = 12;
const int RGB_R = 13;
const int RasPi_PW = 22;
const int RasPi_G = 23;
const int RasPi_O = 24;
const int RasPi_R = 25;
const int RasPi_NAS = 26;
const int RasPi_Vyp = 27;
const int RasPi_Res = 28;
const int RasPi_Rez = 29;
const int HTPi = 30;
const int LED_grabber = 31;
const int Rez1 = 32;
const int Rez2 = 33;
const int rs = 34;
const int en = 35;
const int d4 = 36;
const int d5 = 37;
const int d6 = 38;
const int d7 = 39;
const int IrLED = 40;
const int SW = 41;
const int LB_Rez1 = 50;
const int LB_Rez2 = 51;
const int LB_Rez3 = 52;
const int LB_Rez4 = 53;
const int timeout = 500;
const int timeoutButton = 400;

int  LightAnalogValue;
int jas = 255, jasB = 255, jasG = 255, jasR = 255, jasW = 240, jasMax, jasMin;
int LED_AH;
int LED_A;
int LED_H;                             
int krok = 1; 
int obrazovka = 0;   
int obrazovkaMax = 5;
int vyberBarvy = 0;
     
LiquidCrystal LCD(rs, en, d4, d5, d6, d7);
IRrecv irrecv(IrLED);
decode_results results;

// sipka nahoru
byte newChar1[8] = {
  0b00100,
  0b01110,
  0b10101,
  0b00100,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

// sipka dolu
byte newChar2[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b10101,
  0b01110,
  0b00100
};

// sipka vpravo
byte newChar3[8] = {
  B00000,
  B00100,
  B00010,
  B11111,
  B00010,
  B00100,
  B00000,
  B00000
};
 
// sipka vlevo
byte newChar4[8] = {
  B00000,
  B00100,
  B01000,
  B11111,
  B01000,
  B00100,
  B00000,
  B00000
};

void stav1()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("    Stav HTPi   ");
  LCD.setCursor(0, 1);           
  if (digitalRead(RasPi_PW) == HIGH) LCD.print("HTPi je vypnuto");
  else if (digitalRead(RasPi_PW) == LOW) LCD.print("HTPi je zapnuto");
  else LCD.print("  neznamy stav  ");
}

void stav2()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("Stav LightBerry");
  LCD.setCursor(0, 1);           
  if (LB_Rez1 == LOW) LCD.print("rezerva");         
  else if (LB_Rez2 == LOW) LCD.print("rezerva"); 
  else LCD.print("  neznamy stav  ");
}

void pozadavek1()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print(" Pozadavek HTPi ");
  LCD.setCursor(0, 1);           
  if (RasPi_Vyp == LOW) LCD.print("vypni HTPi");
  else if (RasPi_Res == LOW) LCD.print("restartuj HTPi");
  else if (RasPi_Rez == LOW) LCD.print("rezerva");
  else LCD.print("zadny pozadavek");
}

void pozadavek2()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("  Pozadavek NAS ");
  LCD.setCursor(0, 1);           
  if (digitalRead(RasPi_NAS) == LOW && digitalRead(RasPi_PW) == LOW) LCD.print("pripojit disky");      
  else if (digitalRead(RasPi_NAS) == 1 && digitalRead(RasPi_PW) == LOW) LCD.print("odpojit disky");
  else LCD.print("zadny pozadavek");
}

void pozadavek3()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("Poz. LightBerry");
  LCD.setCursor(0, 1);           
  if (LB_Rez3 == LOW) LCD.print("rezerva");
  else if (LB_Rez4 == LOW) LCD.print("rezerva");
  else LCD.print("zadny pozadavek");
}

void navigace()
{
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("Pohyb v menu");
  LCD.setCursor(0, 1);           
  LCD.write((uint8_t)1);                                   
  LCD.setCursor(2, 1);
  LCD.print("OK");
  LCD.setCursor (5, 1);                                   
  LCD.write((uint8_t)0);
  LCD.setCursor (7, 1);                                   
  LCD.write((uint8_t)2);
  LCD.setCursor (9, 1);                                   
  LCD.write((uint8_t)3);
}

void setup() {
  
 Serial.begin(9600);
 irrecv.enableIRIn();                  // zacatek cteni pinu v seriovem monitoru
  
 LCD.createChar(0, newChar3);          // sipka vpravo
 LCD.createChar(1, newChar4);          // sipka vlevo
 LCD.createChar(2, newChar1);          // sipka nahoru
 LCD.createChar(3, newChar2);          // sipka dolu
 
//  **KONFIGURACE PRO DISPLAY 16x2** 
  LCD.begin(16, 2);                    // pocet radu a znaku u LCD
  analogWrite(LED_Arduino, 255);
  LCD.clear();
  LCD.setCursor(0, 0);           
  LCD.print("     HTPi v2    ");
  LCD.setCursor(0, 1);         
  LCD.print("inicializace...."); 
  delay(2000);
  
    if (EEPROM.read(0) > 254 || EEPROM.read(1) < 0)            // kdyz nejsou hodnoty v povolenem rozsahu
       {
    EEPROM.update(0, 254);                                     // nastav minimalni hodnotu rozsahu
    EEPROM.update(1, 180);                                     // nastav maximalni hodnotu rozsahu
       }
    if (EEPROM.read(2) < 0 && EEPROM.read(2) > 200)           // kdyz nejsou hodnoty v povolenem rozsahu
       {
    EEPROM.update(2, 80);                                      // nastav minimalni hodnotu rozsahu
       }
  
 pinMode(IrLED, INPUT_PULLUP);         // vstup od IRLED
 pinMode(RasPi_PW, INPUT_PULLUP);      // zpetna vazba od RasPi seplo samodrz
 pinMode(RasPi_G, INPUT_PULLUP);       // zpetna vazba od RasPi rozsvit zelenou
 pinMode(RasPi_O, INPUT_PULLUP);       // zpetna vazba od RasPi rozsvit oranzovou
 pinMode(RasPi_R, INPUT_PULLUP);       // zpetna vazba od RasPi rozsvit cervenou
 pinMode(SW, INPUT_PULLUP);            // SW tlacitko
 pinMode(LB_Rez1, INPUT_PULLUP);       // lightberry rezerva
 pinMode(LB_Rez2, INPUT_PULLUP);       // lightberry rezerva
 pinMode(LB_Rez3, OUTPUT);             // lightberry rezerva
 pinMode(LB_Rez4, OUTPUT);             // lightberry rezerva
 pinMode(LED_HTPi, OUTPUT);            // podsvetleni pro display HTPi
 pinMode(LED_Arduino, OUTPUT);         // podsvetleni pro display Arduino
 pinMode(LED_G, OUTPUT);               // zelena diody 
 pinMode(LED_O, OUTPUT);               // oranzova dioda
 pinMode(LED_R, OUTPUT);               // cervena dioda
 pinMode(RGB_B, OUTPUT);               // modra dioda
 pinMode(RGB_G, OUTPUT);               // zelena dioda
 pinMode(RGB_R, OUTPUT);               // cervena dioda
 pinMode(RasPi_NAS, OUTPUT);           // pozadavek na pripojeni NAS   
 pinMode(RasPi_Vyp, OUTPUT);           // pozadavek na vypnuti
 pinMode(RasPi_Res, OUTPUT);           // pozadavek na restart
 pinMode(RasPi_Rez, OUTPUT);           // pozadavek rezerva
 pinMode(HTPi, OUTPUT);                // napajeni pro HTPi    
 pinMode(LED_grabber, OUTPUT);         // napajeni LED pasku
 pinMode(Rez1, OUTPUT);                // napajeni SSR
 pinMode(Rez2, OUTPUT);                // napajeni SSR
 
 digitalWrite(RGB_B, HIGH);            // Zhasni B
 digitalWrite(RGB_G, HIGH);            // Zhasni G
 digitalWrite(RGB_R, HIGH);            // Zhasni R
 digitalWrite(RasPi_NAS, HIGH);        // nuluj komunikaci s RasPi
 digitalWrite(RasPi_Vyp, HIGH);        // nuluj komunikaci s RasPi 
 digitalWrite(RasPi_Res, HIGH);        // nuluj komunikaci s RasPi   
 digitalWrite(RasPi_Rez, HIGH);        // nuluj komunikaci s RasPi 
 digitalWrite(LB_Rez3, HIGH);          // nuluj komunikaci s Lightberry 
 digitalWrite(LB_Rez4, HIGH);          // nuluj komunikaci s Lightberry
 jasMin = EEPROM.read(0);
 jasMax = EEPROM.read(1);
 interval = EEPROM.read(2);
}

void loop() { 

  aktualMillis = millis();

 if (mode == 0)                                                // kdyz je mod 0 zobrazeni cteni napeti
    {                                                          // kazdych 200 milisekund (timeout) precteme data
if(aktualMillis - CasZmenyDis > Prodleva_Dis)              
  {
    CasZmenyDis = aktualMillis;
    obrazovka++;
    if (obrazovka > obrazovkaMax) obrazovka = 0;  
    zmenaObrazovka = true;
  }
    if (zmenaObrazovka)
  {
    zmenaObrazovka = false;
    switch(obrazovka)
    {
    case HTPiStav:
      stav1();
      break;
    case HTPiPozadavek:
      pozadavek1();
      break;
    case NasPozadavek:
      pozadavek2();
      break;
    case LightBerryStav:
      stav2();
      break;
    case LightBerryPozadavek:
      pozadavek3();
      break;
      case Navigace:
      navigace();
      break;
    }
  }   
    if (displayUpdate == true)                                 // zkontrolujeme zda je na disleji pozadovany text (true = neni)
       {
      displayUpdate = false; 
       
    if ((unsigned long)(millis() - readingTime) >= timeout )  // cekame na uplynuti timeout
       {
        
      readingTime = millis();                                  // nastavime novy cas pro pristi zpracovani

       } 
       LCD.clear();
       LCD.setCursor(0, 0);           
       LCD.print("****HTPi v2****");
       LCD.setCursor(0, 1);         
       LCD.print("navrat do smycky"); 
       }
    }  
  else if (mode == 1 && displayUpdate == true)                 // zobrazeni minimalni nastavene hodnoty
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("LED tlacitko:");                              // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print("pulzace");                                    // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
      LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
      LCD.write((uint8_t)0);
          }  
  else if (mode == 11 && displayUpdate == true)                // zobrazeni minimalni nastavene hodnoty
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Min. hodnota:");                              // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(EEPROM.read(0));                               // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
      LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
      LCD.write((uint8_t)0);
          }
  else if (mode == 12 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Max. hodnota:");                              // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(EEPROM.read(1));                               // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
      LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
      LCD.write((uint8_t)0);
          }
  else if (mode == 13 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Rychlost:");                                  // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(EEPROM.read(2));                               // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
      LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
      LCD.write((uint8_t)0);
          }
  else if (mode == 14 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Barva:");                                     // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(EEPROM.read(3));                               // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
          }
  else if (mode == 111)                                         // zobrazeni nastaveni min hodnoty
          {
    if (displayUpdate) 
       {  
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Nastav Min.");                                // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (8, 1);                                    // nastavime pozici kurzoru na 9 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(10, 1);
      LCD.print("OK");
      LCD.setCursor(13, 1);
      LCD.write((uint8_t)2);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(15, 1);
      LCD.write((uint8_t)3);                                   // zobrazime text pro zobrazeni hodnoty
                                                               // tyto dva radky zajisti zobrazeni hodnot pri opakovanem stisknuti vyber
      LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(EEPROM.read(0));                               // zobrazime text pro zobrazeni hodnoty
    }
      LCD.setCursor (4, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(jasMin);                                       // zobrazime text pro zobrazeni hodnoty
          }
  else if (mode == 121)                                        // zobrazeni nastaveni max hodnoty
          {
    if (displayUpdate) 
       {
     displayUpdate = false;
     LCD.clear();                                              // vycistime displej
     LCD.setCursor (0, 0);                                     // nastavime pozici kurzoru na 1 misto 1 radku
     LCD.print("Nastav Max.");                                 // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor (8, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
     LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(10, 1);
     LCD.print("OK");
     LCD.setCursor(13, 1);
     LCD.write((uint8_t)2);                                   // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(15, 1);
     LCD.write((uint8_t)3);
                                                               // tyto dva radky zajisti zobrazeni hodnot pri opakovanem stisknuti vyber
     LCD.setCursor (0, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(EEPROM.read(1));                                // zobrazime text pro zobrazeni hodnoty
       }
     LCD.setCursor (4, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(jasMax);                                        // zobrazime text pro zobrazeni hodnoty
       }
  else if (mode == 131)                                        // zobrazeni nastaveni max hodnoty
          {
    if (displayUpdate) 
       {
     displayUpdate = false;
     LCD.clear();                                              // vycistime displej
     LCD.setCursor (0, 0);                                     // nastavime pozici kurzoru na 1 misto 1 radku
     LCD.print("Nastav Rychlost");                             // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor (8, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
     LCD.write((uint8_t)1);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(10, 1);
     LCD.print("OK");
     LCD.setCursor(13, 1);
     LCD.write((uint8_t)2);                                   // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(15, 1);
     LCD.write((uint8_t)3);
                                                               // tyto dva radky zajisti zobrazeni hodnot pri opakovanem stisknuti vyber
     LCD.setCursor (0, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(EEPROM.read(2));                                // zobrazime text pro zobrazeni hodnoty
       }
     LCD.setCursor (4, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(interval);                                      // zobrazime text pro zobrazeni hodnoty
       }
  else if (mode == 141)                                        // zobrazeni nastaveni max hodnoty
          {
    if (displayUpdate) 
       {
     displayUpdate = false;
     LCD.clear();                                              // vycistime displej
     LCD.setCursor (0, 0);                                     // nastavime pozici kurzoru na 1 misto 1 radku
     LCD.print("Nastav Barvu");                                // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor (8, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
     LCD.write((uint8_t)1);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(10, 1); 
     LCD.print("OK");
     LCD.setCursor(13, 1);
     LCD.write((uint8_t)2);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(15, 1);
     LCD.write((uint8_t)3);
       }
     LCD.setCursor (0, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(TextFromEEPROM(50,10));                         // zobrazime text pro zobrazeni hodnoty
       }
  else if (mode == 2 && displayUpdate == true)                 // zobrazeni pro ulozeni tovatniho nastaveni
          {
      displayUpdate = false;
      LCD.clear();                                             // vycistime displej
      LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print("Tovarni nastav.");                            // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
      LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(12, 1);
      LCD.print("OK");
      LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
      LCD.write((uint8_t)0);
          }
  else if (mode == 3 && displayUpdate == true)                 // zobrazeni pro ulozeni tovatniho nastaveni
          {
      displayUpdate = false;
      LCD.clear();
      LCD.setCursor(0, 0);           
      LCD.print("****HTPi v2****");
      LCD.setCursor(0, 1);         
      LCD.print("stiknuto SW"); 
          }
// ** PRACUJEME S TLACITKEM VPRAVO ** 
 
  if (!digitalRead(VPRAVO))                                            // kdyz je stisknuto tlacitko vpravo
     {
    if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
     {
      VPRAVO = 0;
      readingTime = millis();                                          // nastavime novy cas pro povoleni dalsiho cteni
      readingUpdate = millis();                                        // nastav novou prodlevu pro kontrolu necinnosti
      displayUpdate = true;                                            // povol aktualizaci displeje
      if (mode == 0) mode = 1;
      else if (mode == 1) mode = 2;
      else if (mode == 2) mode = 0;
      else if (mode == 11) mode = 12;
      else if (mode == 12) mode = 13;
      else if (mode == 13) mode = 14;
     }
     }

  // ** PRACUJEME S TLACITKEM VLEVO ** 
  
  if (!digitalRead(VLEVO))                                             // kdyz je stisknuto tlacitko vlevo
     {
    if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
     {
      VLEVO = 0;
      readingTime = millis();                                          // nastavime novy cas pro povoleni dalsiho cteni
      readingUpdate = millis();                                        // nastav novou prodlevu pro kontrolu necinnosti
      displayUpdate = true;                                            // povol aktualizaci displeje
      if (mode == 0) mode = 2;
      else if (mode == 2) mode = 1;
      else if (mode == 1) mode = 0;
      else if (mode == 11) mode = 1;
      else if (mode == 12) mode = 11;
      else if (mode == 13) mode = 12;
      else if (mode == 14) mode = 13;
      else if (mode == 111) mode = 11;
      else if (mode == 121) mode = 12;
      else if (mode == 131) mode = 13;
      else if (mode == 141) mode = 14;
     }
     }
  
  // ** PRACUJEME S TLACITKEM NAHORU ** 
   if (mode != 0)                                                      // kdyz neni mod 0 kontroluj tlacitko nahoru a cas nastaveni
      {
    if (!digitalRead(NAHORU))                                          // kdyz je stisknuto tlacitko nahoru
       {
    if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
       {
      NAHORU = 0;
      readingTime = millis();                                          // nastavime novy cas pro povoleni dalsiho cteni
      readingUpdate = millis();                                        // nastav novou prodlevu pro kontrolu necinnosti
      displayUpdate = true;                                            // povol aktualizaci displeje
      if (mode == 111 && jasMin < 255) jasMin++;
      else if (mode == 121 && jasMax < 238) jasMax++;
      else if (mode == 131 && interval < 200) interval = interval + 10;
      else if (mode == 141) TextToEEPROM(50,10,barva);
       }
       }
      }

// ** PRACUJEME S TLACITKEM DOLU ** 
   if (mode != 0)                                                      // kdyz neni mod 0 kontroluj tlacitko dolu a cas nastaveni
      {
    if (!digitalRead(DOLU))                                            // kdyz je stisknuto tlacitko dolu
       {
    if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
       {
      DOLU = 0;
      readingTime = millis();                                          // nastavime novy cas pro povoleni dalsiho cteni
      readingUpdate = millis();                                        // nastav novou prodlevu pro kontrolu necinnosti
      displayUpdate = true;                                            // povol aktualizaci displeje
      if (mode == 111 && jasMin > 242) jasMin--;
      else if (mode == 121 && jasMax > 0) jasMax--;
      else if (mode == 131 && interval > 0) interval = interval - 10;
       }
       }
      }

// ** PRACUJEME S TLACITKEM SW **
if (!digitalRead(SW) && udalost == 1)                                   // kdyz je stisknuto tlacitko SW
   {  
      displayUpdate = true;
      mode = 3;
   }

// ** PRACUJEME S VYPNUTIM **
if (!digitalRead(SW) && udalost == 1)                                   // kdyz je pozadavek na vypnuti
   {    
      displayUpdate = true;
      mode = 3;
   }
       if (udalost == 0)
          {
       if ((unsigned long)(millis() - mimoradnaUdalost) >= 2000)       // kdyz uplynul cas necinnosti vrat se na mode 0
          {
      mimoradnaUdalost = millis();
      displayUpdate = true;                                            // povol aktualizaci displeje
      mode = 0;
      udalost = 1;
          }
          }
      
// ** PRACUJEME S TLACITKEM OK ** 

  if (mode != 0)                                                       // kdyz neni mod 0 kontroluj tlacitko enter a cas nastaveni
     {
    if ((unsigned long)(millis() - readingUpdate) >= timeoutUpdate)    // kdyz uplynul cas necinnosti vrat se na mode 0
       {
      displayUpdate = true;                                            // povol aktualizaci displeje
      mode = 0;
       }
    if (!digitalRead(ENTER))                                           // kdyz je stisknuto tlacitko vyber
       {
      if ((unsigned long)(millis() - readingTime) >= timeoutButton)    // kdyz uplynula doba blokovani tlacitka
         {
        ENTER = 0; 
        readingTime = millis();                                        // nastavime novy cas pro povoleni dalsiho cteni
        readingUpdate = millis();                                      // nastav novou prodlevu pro kontrolu necinnosti
        displayUpdate = true;                                          // povol aktualizaci displeje
        if (mode == 1) mode = 11;
        else if (mode == 11) mode = 111;
        else if (mode == 12) mode = 121;
        else if (mode == 13) mode = 131;
        else if (mode == 2)
        { 

// ** PRACUJEME S MODY ** 

          mode = 0;
          EEPROM.update(0, 254);                                      // tovarni hodnota rozsahu
          EEPROM.update(1, 180);                                      // tovarni hodnota rozsahu
          EEPROM.update(2, 80);                                       // tovarni hodnota rozsahu
        }
        else if (mode == 111) 
        {
          mode = 11;
 if (jasMin < 255 && jasMin >= 242 && jasMin != EEPROM.read(0)) EEPROM.update(0, jasMin);           // uloz minimalni hodnotu rozsahu
          else {                                                                                   // jinak zobraz chybu
            LCD.clear();                                                                           // vycistime displej
            LCD.setCursor (0, 0);                                                                  // nastavime pozici kurzoru na 1 misto 1 radku
            LCD.print("Chyba min.");                                                               // zobrazime text pro zobrazeni hodnoty
            delay(2000);
               }
        }
          else if (mode == 121) 
               {
            mode = 12;
            if (jasMax > 0 && jasMax <= 238 && jasMax != EEPROM.read(1)) EEPROM.update(1, jasMax); // uloz maximalni hodnotu rozsahu
                     else {
            LCD.clear();                                                                           // vycistime displej
            LCD.setCursor (0, 0);                                                                  // nastavime pozici kurzoru na 1 misto 1 radku
            LCD.print("Chyba max.");                                                               // zobrazime text pro zobrazeni hodnoty
            delay(2000);
                          }
               }
           else if (mode == 131) 
               {
            mode = 13;
            if (interval > 0 && interval < 200 && interval != EEPROM.read(2)) EEPROM.update(2, interval); // uloz maximalni hodnotu rozsahu
                     else {
            LCD.clear();                                                                                  // vycistime displej
            LCD.setCursor (0, 0);                                                                         // nastavime pozici kurzoru na 1 misto 1 radku
            LCD.print("Chyba rychlost.");                                                                 // zobrazime text pro zobrazeni hodnoty
            delay(2000);
                          }
               }
           else if (mode == 141) 
               {
            mode = 14;
            switch(vyberBarvy){
            case 0:
             barva[10] = barva1;
            break;
            case 1:
             barva[10] = barva2;
            break;
            case 2:
             barva[10] = barva3;
            break;
            case 3:
             barva[10] = barva4;
            break;
            case 4:
             barva[10] = barva5;
            break;
            case 5:
            barva[10] = barva6;
            break;
                             }
               }
         }
      }
      if (mode == 3) udalost = 0;
    }

//  **RIZENI PODSVICENI DISPLAYU** 

LightAnalogValue = analogRead(ANALOG_SENSOR_PIN);                                     // cteni voltu z analogoveho vstupu
    if(aktualMillis - PosledniCteniA0 > Prodleva_A0) 
    {
            PosledniCteniA0 = aktualMillis;                                           // v tento cas jsem provedl posledni akci
            LED_AH = map(LightAnalogValue, 0, 1023.0, 255, 0);                        // zapis hodnoty podsvitu
            LED_A = constrain(255,5, max(5, abs(LED_AH)));
            LED_H = LED_A / 2.35;
    }  

  // **ZAPNUTI HTPi POMOCÍ TLACITKA** 
if ((digitalRead(SW) == LOW) && (digitalRead(RasPi_PW) == HIGH))                      // jeli stisknuto tlacitko a nemam info o sepnute samodrzi HTPi
   {  
          if (MinulyStavZap == 1 && millis() - CasZmenyZap > Prodleva_Zap)            // neni-li nastaven priznak tlacitko je stisknuto a uplynul-li vetsi cas od zmeny stavu tlacitka nez je PRODLEVA     
             {                                                
      MinulyStavZap = 0;                                                              // nastav priznak tlacitko stisknuto
    digitalWrite(HTPi, HIGH);
    digitalWrite(LED_grabber, HIGH);                        
    digitalWrite(RasPi_Vyp, HIGH);                                                    // nuluj komunikaci s RasPi 
    digitalWrite(RasPi_Res, HIGH);                                                    // nuluj komunikaci s RasPi 
    digitalWrite(RasPi_NAS, LOW);                                                     // dej požadavek na připojení NAS
    analogWrite(LED_HTPi, LED_H);
    analogWrite(LED_Arduino, LED_A); 
             }
   }
  else                                                                                // neni-li stisknuto tlacitko
   {
    CasZmenyZap = millis();                                                           // zapamatuj si posledni cas, kdy bylo nestisknuto
    MinulyStavZap = 1;                                                                // nuluj priznak, tlacitko stisknuto
   }

  // **TVRDE VYPNUTI HTPi POMOCI TLACITKA (PODRZENI TLACITKA > 5s)** 
if (digitalRead(SW) == LOW)                                                           // jeli stisknuto tlacitko dele nez 5s
   {  
          if (MinulyStavVyp == 1 && millis() - CasZmenyVyp > Prodleva_Vyp)            // neni-li nastaven priznak tlacitko je stisknuto a uplynul-li vetsi cas od zmeny stavu tlacitka nez je PRODLEVA     
             {                                                
      MinulyStavVyp = 0;                                                              // nastav priznak tlacitko stisknuto
    digitalWrite(HTPi, LOW);
    digitalWrite(LED_grabber, LOW);
    digitalWrite(RasPi_NAS, HIGH);                                                    // dej pozadavek na odpojeni NAS
    analogWrite(LED_HTPi, 0);
    analogWrite(LED_Arduino, 0);
    digitalWrite(RasPi_Vyp, LOW);
             }
   }
  else                                                                                // neni-li stisknuto tlacitko
   {
    CasZmenyVyp = millis();                                                           // zapamatuj si posledni cas, kdy bylo nestisknuto
    MinulyStavVyp = 1;                                                                // nuluj priznak, tlacitko stisknuto
   }

  // **VYPNUTI HTPi POMOCI TLACITKA** 
if ((digitalRead(SW) == LOW) && (digitalRead(RasPi_PW) == LOW))                       // jeli stisknuto tlacitko a HTPi ma seplou samodrz
   {  
    digitalWrite(HTPi, LOW);                                                          // vypni napajeni HTPi
    digitalWrite(LED_grabber, LOW);                                                   // vypni napajeni LED diod
    digitalWrite(RasPi_NAS, HIGH);                                                    // dej pozadavek na odpojeni NAS
    analogWrite(LED_HTPi, 0);                                                         // vypni dislay HTPi
    analogWrite(LED_Arduino, 0);                                                      // vypni diplay Arduino
    digitalWrite(RasPi_Vyp, LOW);                                                     // posli pozadavek na vypnuti HTPi
   }

  // **BLIKANI LED POKUD JE HTPi V POHOTOVOSTI**
if (digitalRead(RasPi_PW) == HIGH && digitalRead(HTPi) == LOW)
   {
  if (aktualMillis - predchoziMillis > interval)
     {
        predchoziMillis = aktualMillis;
        
       // puvodni blikani cervnou led 
       // if (jasR == 255) jasR = 254;
       // else jasR = 255;
       // analogWrite(RGB_R, jasR);
       
      analogWrite(RGB_R, jasW);
      analogWrite(RGB_G, jasW);
      analogWrite(RGB_B, jasW);
      
    jasW = jasW - krok;
  
    if (jasW == jasMax || jasW == jasMin) 
    {
           krok = -krok;
    }
     }
    analogWrite(LED_G, 0);
    analogWrite(LED_O, 0);
    analogWrite(LED_R, 0);
    analogWrite(LED_HTPi, 0);           // vypni dislay HTPi
    alogWrite(LED_Arduino, 0);          // vypni diplay Arduino
    digitalWrite(RasPi_NAS, HIGH);        // nuluj komunikaci s RasPi
    digitalWrite(RasPi_Vyp, HIGH);        // nuluj komunikaci s RasPi 
    digitalWrite(RasPi_Res, HIGH);        // nuluj komunikaci s RasPi   
    digitalWrite(RasPi_Rez, HIGH);        // nuluj komunikaci s RasPi
   } 
   
  // **PREPIS DIOD PRO TEPLOTU DLE PAZADAVKU HTPi**
    if (digitalRead(RasPi_G) == LOW) analogWrite(LED_G, 10);
    else digitalWrite(LED_G, LOW);
    if (digitalRead(RasPi_O) == LOW) analogWrite(LED_O, 10);
    else digitalWrite(LED_O, LOW);
    if (digitalRead(RasPi_R) == LOW) analogWrite(LED_R, 2);
    else digitalWrite(LED_R, LOW);  
    
 // **RIZENI DIOD**      
if (digitalRead(RasPi_PW) == LOW && digitalRead(HTPi) == HIGH) 
    {
      digitalWrite(RGB_G, HIGH);
      analogWrite(RGB_B, jas);
      analogWrite(LED_HTPi, LED_H);
      analogWrite(LED_Arduino, LED_A);
    }
    
// **RESTART HTPi**
if (digitalRead(RasPi_PW) == HIGH && digitalRead(HTPi) == HIGH)                       // restart HTPi
   { 
              if (MinulyStavRes == 1 && millis() - CasZmenyRes > Prodleva_Res)            
             {                                                
      MinulyStavRes = 0;
    digitalWrite(HTPi, LOW);                                                          // vypni napajeni HTPi
    digitalWrite(LED_grabber, LOW);                                                   // vypni napajeni LED diod
    digitalWrite(RasPi_NAS, HIGH);                                                    // dej pozadavek na odpojeni NAS
    digitalWrite(RasPi_Res, HIGH);                                                    // nuluj komunikaci s RasPi
    digitalWrite(RasPi_Vyp, HIGH);                                                    // nuluj komunikaci s Raspi
    analogWrite(LED_HTPi, 0);                                                         // vypni dislay HTPi
    analogWrite(LED_Arduino, 0);                                                      // vypni diplay Arduino
    analogWrite(LED_G, 0);
    analogWrite(LED_O, 0);
    analogWrite(LED_R, 0);
    digitalWrite(RGB_G, HIGH);
    digitalWrite(RGB_B, HIGH);
    }
    analogWrite(RGB_R, 255);
    analogWrite(RGB_G, 0);
    analogWrite(RGB_B, 255);
    analogWrite(LED_HTPi, LED_H);
    analogWrite(LED_Arduino, LED_A);
    digitalWrite(RasPi_Res, HIGH);
    }
   else                                                                                 // neni-li stisknuto tlacitko
    {
    CasZmenyRes = millis();                                                             // zapamatuj si posledni cas, kdy bylo nestisknuto
    MinulyStavRes = 1;                                                                  // nuluj priznak, tlacitko stisknuto
    }

    // **VYPNITI HTPi**
    if (digitalRead(RasPi_PW) == LOW && digitalRead(HTPi) == LOW) analogWrite(RGB_R, 0), analogWrite(RGB_B, 255); // vypnuti HTPi
    
  // **ODCHYT TLACITKA Z DALKOVEHO OVLADACE** 
  if (irrecv.decode(&results)) {
int DO = results.value;
      if (DO == 13033)                                                                   // pokud je stisknuto zelene tlacitko na TV a zatim neprobehla akce spusteni RasPi
      {
      digitalWrite(HTPi, HIGH);                                                          // sepni napajeni pro RasPi
      digitalWrite(LED_grabber, HIGH);
      digitalWrite(RasPi_NAS, LOW);                                                      // dej požadavek na připojení NAS
      digitalWrite(RasPi_Vyp, HIGH);                                                     // nuluj komunikaci s RasPi 
      digitalWrite(RasPi_Res, HIGH);                                                     // nuluj komunikaci s RasPi 
      analogWrite(LED_HTPi, LED_H);
      analogWrite(LED_Arduino, LED_A);                                                                        
      }  
      if (DO == 21225)                                                                   // pokud je stisknuto cervene tlacitko na TV a zatim neprobehla akce spusteni RasPi
      {
      digitalWrite(HTPi, HIGH);                                                          // sepni napajeni pro RasPi
      digitalWrite(RasPi_NAS, HIGH);                                                     // dej požadavek na odpojeni NAS
      digitalWrite(RasPi_Vyp, HIGH);                                                     // nuluj komunikaci s RasPi 
      digitalWrite(RasPi_Res, HIGH);                                                     // nuluj komunikaci s RasPi 
      analogWrite(LED_HTPi, LED_H);
      analogWrite(LED_Arduino, LED_A);                                                                        
      }  
      if (DO == 29417)                                                                   // pokud je stisknuto zlute tlacitko na TV vypni RasPi
      {
      digitalWrite(HTPi, LOW);                                                           // vypni napajeni HTPi
      digitalWrite(LED_grabber, LOW);                                                    // vypni napajeni LED diod
      digitalWrite(RasPi_NAS, HIGH);                                                     // dej pozadavek na odpojeni NAS
      analogWrite(LED_HTPi, 0);                                                          // vypni dislay HTPi
      analogWrite(LED_Arduino, 0);                                                       // vypni diplay Arduino
      digitalWrite(RasPi_Vyp, LOW);                                                      // posli pozadavek na vypnuti HTPi 
      digitalWrite(RasPi_NAS, HIGH);                                                     // nuluj komunikaci s RasPi
      digitalWrite(RasPi_Res, HIGH);                                                     // nuluj komunikaci s RasPi                                                                       
      }      
      if (DO == 4841)                                                                    // pokud je stisknuto modre tlacitko na TV restartuj RasPi
      {
      digitalWrite(RasPi_Res, LOW);                                                      // posli pozadavek na restart HTPi 
      digitalWrite(RasPi_Vyp, HIGH);                                                     // nuluj komunikaci s RasPi                                                                    
      } 
      if (DO == 765)                                                                   
      {
      ENTER = 1;                                                                         // stisknuto tlacitko OK                                                                  
      }  
      if (DO == -15811)                                                               
      {
      VPRAVO = 1;                                                                        // stisknuto tlacitko vpravo                                                                 
      }    
      if (DO == 8925)                                                                
      {
      VLEVO = 1;                                                                         // stisknuto tlacitko vlevo                                                                
      } 
      if (DO == 25245)                                                               
      {
      NAHORU = 1;                                                                        // stisknuto tlacitko nahoru                                                             
      }    
      if (DO == -22441)                                                                
      {
      DOLU = 1;                                                                          // stisknuto tlacitko dolu                                                                
      }                                        
   Serial.println(DO, DEC);                                                              // prepis HEX na seriovy monitor
   irrecv.resume();                                                                      // Cti dalsi hodnotu
 }
   
}
void TextToEEPROM(int adresa, int maxVelikost, String text)
{
  for (int i = 0;i < text.length();i++)
  {
  EEPROM.write(adresa + i, (byte)text[i]);
  }
  for (int i = text.length();i < maxVelikost;i++)
  {
  EEPROM.write(adresa + i, ' ');
  }  
}
 
String TextFromEEPROM(int adresa, int maxVelikost)
{
  String TextFromEEPROM = "";
  for (int i = 0;i < maxVelikost;i++)
  {
  char znak = (char)EEPROM.read(adresa + i);
  TextFromEEPROM = TextFromEEPROM + znak;  
  }
  while (TextFromEEPROM[TextFromEEPROM.length() - 1] == ' ')
    {  
      TextFromEEPROM = TextFromEEPROM.substring(0,TextFromEEPROM.length() - 1);
    }
  return  TextFromEEPROM;
}
za návrhy díky

Uživatelský avatar
gilhad
Příspěvky: 786
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Výběr barvy

Příspěvek od gilhad » 25 bře 2018, 13:17

Promiň, nečetl jsem celý ten kód, natož, abych si ho zkompiloval a spustil, ale jestli to chápu správně, máš 4 tlačítka (nahoru, dolů, doleva, doprava) a LCD (asi tak 2x16?) a chceš si nastavit RGB diody na nějaké barvy.

Já bych to asi řešil sérií menu, kde se šipkou doleva vracíš o úroveň výš (Escape), nahoru/dolu volí položky v menu a doprava slouží jako Enter (tedy výběr další úrovně menu,(pokud je), nebo odsouhlasení položky.

Po několika základních menu (Stav, výběr, co chci nastavit a tak) by se člověk dostal k volbě příslušné LED (pokud jich má být víc, pokud má být jen jedna, tak tak se jde rovnou na volbu barvy) a po jejím zvolení , k volbě barvy LED.

Menu pro volbu barvy bych viděl tak, že doleva ukončí volbu, aniž by barvu změnilo, nahoru/dolu bude procházet jména předdefinovaných barev (červená, zelená, modrá, ...) přičemž toto menu bude cyklické, tedy z první položky nahoru se jde na poslední a z poslední dolu se jde na první. Bylo by hezké rovnou při přechodu na další barvu tu příslušnou LED rozsvítit tou aktuální barvou, aby člověk viděl, co vlastně zrovna vybírá. když dá šipku doprava, barva se uloží na trvalo, (a já bych rovnou vyskočil o úroveň výš, když je vybráno) a když dá šipku doleva, tak se barva neuloží, menu se opustí a LED se rozsvítí svou původní předdefinovanou barvou.

Navíc bych mezi ty barvy dal i položku "vlastní", šipkou doprava by se šlo do dalšího podmenu, kde by byla na prvním řádku složka (červená/modrá/zelená) a na druhém hodnota (0-255), přičemž šipkami nahoru/dolů by se ta hodnota měnila nahoru/dolu (v daném rozsahu nebo cyklicky), šipka doprava by ji (dočasně) potvrdila a přešla na další složku (červená->zelená->modrá -> uložit barvu?) pokud by na uložit barvu dal šipku doprava (OK), tak by se barva uložila, pokud by dal nahoru/dolu, cyklus by se opakoval s dočasně vybranýma hodnotama jako defaultníma a pokud by dal doleva, tak by se vrátil do menu s přednastavenýma barvama. Tím, jak by se při každé změně tak LEDka přizpůsobila, by bylo snadné vybrat správný odstín.

Obdobně by šlo nastavovat i rychlost pulzování a případné další parametry.

V podstatě by to asi šlo zjednodušit přepsáním na dvě dvě hlavní funkce pro menu, kde jedna by dělala klasický výběr z pole textů a druhá by dělala nastavení numerické hodnoty a tyto funkce volat opakovaně na další a další podmenu, přičemž návratový kód by byl buď číslo vybrané položky, nebo označení, že k výběru nedošlo (Escape, asi -1) (Případně pokud by bylo potřeba návrat o víc úrovní, tak -2, -3 .. volající funkce by toto číslo vždy zvedla o jedna, dokud by nedostala nulu a tak by věděla, že to má skončit u ní, nebo pokud by to nevypadlo postupně ze všech vnořených volání těch funkcí a neodchytila to hlavní smyčka jako nějakou závažnější chybu)

dost by se dalo inspirovat například tady: http://www.microvga.com/docs je to sice pro výrazně grafičtější rozhraní, ale ta myšlenka menu je IMHO povedená a snadno adaptovatelná http://www.microvga.com/MicroVGA-arduino.zip (ui.c/runmenu a examples/menu/menu.pde)

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

Re: Výběr barvy

Příspěvek od pavel1tu » 25 bře 2018, 14:32

Nechápu co očekáváš za návrhy :-)

- projekt nemohu vyzkoušet, nemám potřebný HW
- jak se píše o příspěvek výše vymysly si menu, aby ti to vyhovovalo, nadefinuj si barvy (já u akvaria definuji různou peplotu světla do proměnné typu pole - využívám jen 5 teplot)
- v menu jsem se ustálil na 5 tlačítkách (mám znakový displej se 4 řádky) doleva/doprava je skákání v menu, dol je vstup do podmenu, nahoru odchod z podmenu, enter aktivace položky v menu - osobně zatím nezvládám nějaké nastavování hodnot a ani to nepotřebuji.

Je to spíše o tobě, aby ti to vyhovovalo, místní guru programátoři tě pak nakopnou správným směrem až ti to nebude fungovat.
Za mne - já jsem tupec na programování - menu jsem vymýšlel jen na 3 položkách, ladil jsem ho asi 3 měsíce až jsem byl spokojen že to nikamnezabloudí, teď jen přidávám další podmenu atd. - menu (funkci jak funguje a vzhled) jsem obšlehl z netu, z projektu který mi vyhovoval :-) , samotné odladil a pak ho vložil do mého projektu.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Cuore
Příspěvky: 8
Registrován: 24 bře 2018, 19:26
Reputation: 0

Re: Výběr barvy

Příspěvek od Cuore » 25 bře 2018, 16:33

Díky za postřehy, menu mám hotový a pohyb v menu je pomocí IR ovladače, kde jsem si dal pomocí šipek vlevo/vpravo možnost vstup a procházení položek menu. Tlačítkem OK vstup do podmenu a šipkama nahoru/dolu změna parametrů. Šipkou doleva se vyskočí bez uložení a tlačítkem OK se položka ukládá. Parametry dále ukládám do EEPROM jako ochranu před ztrátou dat při vypnutí napájení. Už mám zmáknuto nastavení /min/max limitů při blikání a jeho rychlost. Barvy jsem pochopil, že se musí uložit do proměnné char[] tu jsem zvládl uložit a vyčíst z EEPROM a vypsat na displeji. Ale co netuším jak udělat je to, jak vybrat jednotlivé barvy. Začal jsem tím, že jsem vytvořil pro každou barvu proměnnou char barva1[] = modrá, char barva2[] = zelená, atd., ale už netuším jak je pak při listování šipkou nahoru/dolu tyto proměnné přepisoval do jedné hlavní char barva[], která by byla zobrazovaná na displeji a následně přepsaná při potvrzení do EEPROM. Po pravdě ani netuším jestli je tento postup správný a jaké jsou možnosti. Na netu k tomu nic není, tam se spíš řeší posílání po sériové lince.

Uživatelský avatar
gilhad
Příspěvky: 786
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Výběr barvy

Příspěvek od gilhad » 25 bře 2018, 21:22

Je bych byl s ukladanim do EEPROM docela střídmý, ona má sice velký, ale omezený počet zápisů, takže pokud tam něco ukládat, tak až když je to úplně hotové (tedy když mám vybrané všechny tři barevné složky a odsouhlasené). Naopak číst se může kolikrát chceš. (ale to tam vlastně máš)

(Teď jsem si to celé stáhnul a začínám to trochu procházet, takhle na fóru je to dost nepřehledné. Musím pochválit štábní kulturu a komentáře, ale vidím tam několik problémů:
  • 600+ řádků v loop() a žádné funkce (dobře čtení a zápis EEPROM tam jsou) je docela dost na přehlednost.
  • spousta věcí se ti tam opakuje skoro doslovně - vytáhnul bych je do funkcí a tím by se to výrazně zpřehlednilo i zkrátilo

Kód: Vybrat vše

 
 void loop(){
 // ....
       else if (mode == 12 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
              {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print("Max. hodnota:");                              // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(EEPROM.read(1));                               // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(12, 1);
          LCD.print("OK");
          LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)0);
              }
      else if (mode == 13 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
              {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print("Rychlost:");                                  // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(EEPROM.read(2));                               // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(12, 1);
          LCD.print("OK");
          LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)0);
              }
      else if (mode == 14 && displayUpdate == true)                // zobrazeni maximalni nastavene hodnoty
              {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print("Barva:");                                     // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(EEPROM.read(3));                               // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(12, 1);
          LCD.print("OK");
              }
// ...
} //end loop()
vs.

Kód: Vybrat vše

 void loop(){
 // ....
      else if (mode == 12 && displayUpdate == true)  { ZobrazMenu("Max. hodnota:", EEPROM.read(1)); }
      else if (mode == 13 && displayUpdate == true)  { ZobrazMenu("Rychlost:", EEPROM.read(2)); }
      else if (mode == 14 && displayUpdate == true)  { ZobrazMenu("Barva:", EEPROM.read(3)); }
// ...
} //end loop()

void   ZobrazMenu(char *nazev, byte hodnota)   {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print(nazev);                                     // zobrazime nazev
          LCD.setCursor (0, 1);                                    // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(hodnota);                               // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(12, 1);
          LCD.print("OK");
          }

(a s trochou práce (a pár dalšíma proměnnýma pro pozici, pokud se nedá spočítat) by takto šlo upravit většina toho zobrazování.)
  • LCD.print / LCD.write přesunuje kurzor, takže je možná jednodušší místo posouvání kurzorem ty hodnoty vypsat za sebou oddělené mezerama

Kód: Vybrat vše

          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(12, 1);
          LCD.print("OK");
          LCD.setCursor (15, 1);                                   // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)0);
vs.

Kód: Vybrat vše

          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)1);                                   // zobrazime text pro zobrazeni hodnoty
          LCD.print(" OK ");                                        // mezera před a za OK
          LCD.write((uint8_t)0);
eventuálně využít toho, že umíme zapsat do řetězce i znakové konstanty (až na nulu, která slouží jako konec řetězce)

Kód: Vybrat vše

          LCD.setCursor (10, 1);                                   // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.print("\1 OK ");                                        // šipka a mezera před a za OK
          LCD.write((uint8_t)0);
  • Barvy bych uložil do pole řetězců (indexovaného od nuly, jak je v C++ a tedy i Wiringu zvykem), spousta věcí by se zjednodušila

Kód: Vybrat vše

    char barva[10] = "";
    char barva1[10] = "cervena";
    char barva2[10] = "zelena";
    char barva3[10] = "modra";
    char barva4[10] = "bila";
    char barva5[10] = "fialova";
    char barva6[10] = "zluta";
    // ...
     LCD.print(TextFromEEPROM(50,10)); 
     // ...
     else if (mode == 141) TextToEEPROM(50,10,barva);
     // ...
                    switch(vyberBarvy){
                case 0:
                 barva[10] = barva1;
                break;
                case 1:
                 barva[10] = barva2;
                break;
                case 2:
                 barva[10] = barva3;
                break;
                case 3:
                 barva[10] = barva4;
                break;
                case 4:
                 barva[10] = barva5;
                break;
                case 5:
                barva[10] = barva6;
                break;
                                 }
//...
void TextToEEPROM( 
// ... az konec souboru

vs.

Kód: Vybrat vše

    byte barva = 0;	// 0=cervena, 1=zelena, ...
    char barvy[][10] = {"cervena","zelena","modra","bila","fialova","zluta"};
    // ...
    barva=EEPROM.read(50);
     LCD.print(barvy[barva]); 
     // ...
     else if (mode == 141) EEPROM.update(50,barva);
     // ...
                    barva=vyberBarvy
//...
// void TextToEEPROM( // zbytecne, smazat :)
// ... az konec souboru
(A mozna bych do EEPROM ukladal i RGB slozky barvy, pokud bych jich chtel vic a mit to konzistentni mezi verzemi programu s ruznym poctem barev)
  • Ruzne nazvy pro promennou a funkci, ktera s ni pracuje

Kód: Vybrat vše

   
    String TextFromEEPROM(int adresa, int maxVelikost)
    {
      String TextFromEEPROM = "";
      for (int i = 0;i < maxVelikost;i++)
      {   
      char znak = (char)EEPROM.read(adresa + i);
      TextFromEEPROM = TextFromEEPROM + znak; // a tady to TextFromEEPROM je String, nebo adresa teto funkce ??
  • Rozlisovat promennou obsahujici cislo pinu a promennou, kam si ukladam hodnotu

Kód: Vybrat vše

    // ** PRACUJEME S TLACITKEM DOLU **  DOLU ma hodnotu 0 nebo 1
       if (mode != 0)                                                      // kdyz neni mod 0 kontroluj tlacitko dolu a cas nastaveni
          {
        if (!digitalRead(DOLU))                                            // kdyz je pin digital 0(RX) nebo 1(TX) LOW (čili čteme HW Serial?)
           {
        if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
           {
          DOLU = 0;	// nastavíme další čtení z pinu 0 (RX)
 
tohle asi fungovat nebude tak, jak očekáváš

Cuore
Příspěvky: 8
Registrován: 24 bře 2018, 19:26
Reputation: 0

Re: Výběr barvy

Příspěvek od Cuore » 27 bře 2018, 22:35

No tak teď netuším, kde začít :) . Takže od začátku, pokusím se vytvořit pro stejné menu funkce.
Ty pole řetězců atd. hlavně jejich vytváření a čtení hlavně pokud je proměnná text, je pro mě španělská vesnice. Takže doufám, že co si nahodil je nějak funkční, abych to nahrál a dělal experimenty jak se to chová a funguje.
Tu práci s EEPROM jak se ptáš jsem vytáhnul tady https://arduino8.webnode.cz/news/lekce- ... -a-eeprom/ Vstup a výstup z toho funguje, co to dělá uvnitř opravdu netuším, nějak jsem to zatím neřešil.
K tlačítkům můžu jenom říct, že vyčítám z IR ovladače, pro tlačítko DOLU tady

Kód: Vybrat vše

      if (DO == -22441)                                                                
      {
      DOLU = 1;    // stisknuto tlacitko dolu                                                                
      }
Vypadá to, že to funguje jak má, všechny menu a nastavení jsou funkční a chovají se podle očekávání. Jen jsem se zatím zastavil na práci s tím textem :? Takže si něco přečtu o funkcích a vše se pokusím zjednodušit. To určitě zvládnu a k těm barvám

Kód: Vybrat vše

 byte barva = 0;	// 0=cervena, 1=zelena, ...proměnné barva
    char barvy[][10] = {"cervena","zelena","modra","bila","fialova","zluta"};
    // ...
    barva=EEPROM.read(50);
     LCD.print(barvy[barva]); 
     // ...
     else if (mode == 141) EEPROM.update(50,barva);
     // ...
                    barva=vyberBarvy
Na začátku definuješ byte, kde se ukládá ke každé barvě číslo. V druhém řádku je pole s barvou. Pořadí barev v poli a byte spolu koresponduje? Následně se do proměnné barva načte z EEPROM číslo předvolené barvy, kterou jsem si jako uživatel vybral a tu pak pošlu na displej. Jelikož ty dvě proměnné korespondují tak se vypíše např. zelená pokud mám v EEPROM číslo 1. Poslední řádek je způsob nastavení barvy, kde pomocí nahoru/dolu budu měnit čísla v proměnné vyberBarvy, kterou zapíšu do proměnné barva. Nenech se zmást a celý tento odstavec ber jako jedno velkou otázku, jestli jsem to pochopil správně. Pokud ano, tak nevidím uložení barvy do EEPROM, to by mělo být v pohodě, jen uložím následně vybraný obsah proměnné barva do EEPROM. Ale co mi není jasné je ten výběr nové barvy. Pokud budu listovat v menu mezi barvama, tak tohle

Kód: Vybrat vše

else if (mode == 141)                                        // zobrazeni nastaveni max hodnoty
          {
    if (displayUpdate) 
       {
     displayUpdate = false;
     LCD.clear();                                              // vycistime displej
     LCD.setCursor (0, 0);                                     // nastavime pozici kurzoru na 1 misto 1 radku
     LCD.print("Nastav Barvu");                                // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor (8, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
     LCD.write((uint8_t)1);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(10, 1); 
     LCD.print("OK");
     LCD.setCursor(13, 1);
     LCD.write((uint8_t)2);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(15, 1);
     LCD.write((uint8_t)3);
       }
     LCD.setCursor (0, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(TextFromEEPROM(50,10));                         // zobrazime text pro zobrazeni hodnoty
       }
upravím takhle

Kód: Vybrat vše

else if (mode == 141)                                        // zobrazeni nastaveni max hodnoty
          {
    if (displayUpdate) 
       {
     displayUpdate = false;
     LCD.clear();                                              // vycistime displej
     LCD.setCursor (0, 0);                                     // nastavime pozici kurzoru na 1 misto 1 radku
     LCD.print("Nastav Barvu");                                // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor (8, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
     LCD.write((uint8_t)1);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(10, 1); 
     LCD.print("OK");
     LCD.setCursor(13, 1);
     LCD.write((uint8_t)2);                                    // zobrazime text pro zobrazeni hodnoty
     LCD.setCursor(15, 1);
     LCD.write((uint8_t)3);
       }
     LCD.setCursor (0, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
     LCD.print(barvy[barva]);                                // zobrazime text pro zobrazeni hodnoty
       }
a takhle to snad bude makat :roll: doufám....
Zítra si to otestuji a začnu zjednodušovat. Zatím díky.

Uživatelský avatar
gilhad
Příspěvky: 786
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Výběr barvy

Příspěvek od gilhad » 28 bře 2018, 02:58

No tak teď netuším, kde začít :) . Takže od začátku,
Vím, že nic nevím je dobrý začátek :) (Teda, přiznat si, že o problematice, se kterou se dá hrát roky nevím všechno)

Taky doufám, že to funkční je, ale netestoval jsem to v překladači, sem tam můžu mít překlepy a tak, šlo mi spíš o myšlenku.

To pole řetězců je prostě pole (indexuje se to od nuly, každá položka má nějaký obsah, s kterým se dá něco dělat), kde (čistě náhodou) ty položky nejsou třeba čísla, ale naopak to jsou opět pole a to tak, že pole znaků (čili vlastně řetězce a navíc díky té inicializaci ukončené vždy znakem '\0' což je konec řetězce, takže se to dál nevypisuje, i když to nevyplní všech 10 vyhrazených míst pro znaky (teda vyplní je to nulama, ale to už funkce pro práci s řetězci - jako je třeba println() - nezajímá, tak daleko se už nedostanou))

EEPROM je Elektronicky Erasovatelná(mazatelná) Programovatelná(zapisovatelná) ReadOnlyMemory (paměť jen pro čtení). Zní to hrozně (je za tím spousta elektronické magie a tak) a lépe je si o tom najít nějaký výklad, podstatné je, že
  • dá se z toho číst po bytech jako z normální paměti (akorát jak je to na Atmega328 udělané, tak je na to potřeba jiná strojová instrukce a Arduino to zabalilo do EEPROM.read(adresa) )
  • Dá se do toho nějak i zapsat byte, jen to není vůbec jednoduché a rychlé, protože se to místo musí zvláštním způsobem nejdřív vymazat a potom tam teprve jde zapsat nová hodnota a ten chip tímto trpí a zvládne jen omezený počet přepsání. Navíc během mazání ani zápisu nesmí vypadnout či výrazně zakolísat napájecí napětí, jinak se to může skutečně pokazit. V Arduinu je to úhledně zabalené do funkce EEPROM.write(adresa,hodnota)
  • Když se to udělá takto a nic se nepokazí, tak tam ta hodnota zůstane i po vypnutí, stejně jako tam i po vypnutí zůstane i ten nahraný program a po dalším zapnutí se zase dá přečíst (jako se ten program zase spustí)
Proto se běžně proměnné - které mají přečkat restart, či vypnutí a zapnutí - ukládají do EEPROM a proto se taky nejdřív kontroluje, jestli tam už ta hodnotá náhodou není (čti neliší se ta nová od té minulé), protože pokud tam ta hodnota už je, tak ji nechceme zapisovat, "ošoupávat" si to paměťové políčko mazáním a zápisem a navíc riskovat, že někdo vypne proud a my o to políčko (i hodnotu v něm) nadobro přijdeme a budeme muset přepisovat program, aby používal jiné.

Pokud ti to vyčítání tlačítka z IR ovladače funguje, tak je to fajn, co ti určitě nefunguje správně je to, že se pak pokoušíš použít tu hodnotu toho tlačítka jako hodnotu pinu pro digitalRead(číslo_pinu), protože tam místo čísla nějakého pinu dáváš hodnotu toho DO, což je nula nebo jedna a pin číslo nula je Sériový vstup a pin číslo jedna je sériový výstup a to určitě není něco, co by jsi chtěl číst, natož takovýmto způsobem.

K těm barvám:
  • (tady se lišíme) Na začátku definuju byte (jménem barva), kde se ukládá číslo zvolené barvy. Když zvolím červenou, uložím si do barva číslo nula, když zvolím zelenou, uložím si tam číslo jedna, když zvolím modrou, uložím si tam číslo dva.
  • (tady to sedí) V druhém řádku je pole s barvou. (teda pole se jmény barev, jak je chci vypisovat, ale ano, je to tak)
  • Pořadí barev v poli a byte spolu koresponduje? (Ano, rozhodně, tak je to míněno. nultá položka pole 'barvy', čili barvy[0] je řetězec "cervena". Pokud chci mít vybranou cervenou dam do bytu 'barva' hodnotu nula a pak nemusím pro LCD.print dělat nic složitého, ale prostě nechám vypsat řádek pole 'barvy', který odpovídá hodnotě bytu 'barva' takto jednoduše: LCD.print(barvy[barva]); pro nulu se vypíše cervena, pro jedničku zelena a tak dál
Pochopil jsi to správně a věřím, že se ti to povede poupravovat k tvé libosti.

Ono se skutečně vyplatí si dát trochu práce s tím zjednodušováním, pokud se tím výrazné zvýší čitelnost a zmenší počet opakování stejného, či podobného kódu. Protože se v tom pak líp vyznáš i za týden, i za rok, nebo pět a pokud budeš chtít něco upravit, tak to upravíš na jednom místě a nestane se ti, že to musíš upravovat na deseti místech a z toho na jednom na to zapomeneš, nebo uděláš nějakou chybu a pak se to najednou začne chovat podivně, ale jen občas - což se ladí a opravuje mnohem hůř, než když uděláš chybu v tom jednom místě, kde se dělají všechny menu a pak něco nechodí ve všech menu - na to přijdeš hned a taky víš, kde jsi to měnil a kde to teda opravit.

---
V těch příkladech jsem v podstatě dělal to samé co ty, jenom na podstatně míň řádků a přehlednějším stylem.

Až na ten poslední / ** PRACUJEME S TLACITKEM DOLU ** kde jsem nechal tvůj kód jak byl, ale napsal jsem vlastní komentáře, co to doopravdy dělá. Nemyslím, že to, co to doopravdy dělá je to, co chceš, aby to dělalo, aspoň podle okolní logiky a tvých komentářů.

Myslím, že jsi chtěl spíš něco jako

Kód: Vybrat vše

   
    // ** PRACUJEME S TLACITKEM DOLU ** 
       if (mode != 0)                                                      // kdyz neni mod 0 kontroluj tlacitko dolu a cas nastaveni
          {
        if (DOLU==1)  // kdyz IR reklo, ze je je stisknuto tlacitko dolu ((irrecv.decode nastavilo do results.value hodnotu -22441 a ja si teda nastavil DOLU na jedna
           {
        if ((unsigned long)(millis() - readingTime) >= timeoutButton)      // kdyz uplynula doba blokovani tlacitka
           {
          DOLU = 0; // ... tak si nastavim hodnotu DOLU na nula, ze to uz neblokuju a nepovazuju za stisknute
          // a neco udelam podle mode s jasama nebo intervalama
   
A samozrejme i pro ostatni tlacitka (NAHORU, VLEVO ...).
Porovnej si, ze tady ctes promennou DOLU, kterou sam nastavujes podle IR prijimace, zatimco u tlacitka SW ctes hodnotu na pinu 41 (cili napeti na nozicce arduina) a podivej se, cim se ti DOLU od SW lisi (a je spravne, ze se lisi) - SW je 41 a to je nozicka arduina mega a kdyz chci znat napeti na ni, tak pouziju digitalRead(SW), zatimco DOLU je "nejake moje cislo, co si pamatuju" stejne jako treba "barva", nebo "mode" a u "mode" te (spravne) ani nenapadlo volat digitaRead, protoze tomu zadna nozicka neodpovida a zadne napeti tam cist nejde.
---
az si to pozjednodusujes a bude ti to porad chodit stejne (dobry test, ze jsi to zjednodusovani udelal spravne), tak pak ma cenu zacit vymyslete dalsi triky s tim menu na barvy, protoze uz budes vedet, ze se to da udelat jednoduse a prehledne a jen porad volat dokola a najednou bude vsechno mnohem jednodussi.

(a u funkci muzes mit i vic parametru a podle jejich nastaveni se rozhodnout, co presne funkce udela, takze se da jednou funci resit nejen nekolik uplne stejnych menu, ale i nekolik docela podobnych, kdyz ji reknes o jakou variantu jde. Takze od zbezneho pohledu se asi cela ta sekce od 'else if mode == 1' po 'else if mode == 3' da zjednodusit na radu ifu a volani jedne funkce s ruznymi parametry)

(a doporucuju si neco precist o polich, je to velice uzitecna vec)

To s tim ukladanim RGB do EEPROM misto barvy jsem myslel tak, az se v nejake z dalsich verzi rozhodnes tam mit vic barev, nebo nechat uzivatele nastavovat si barvy vlastni, tak bude lepsi mit ulozene 255,0,0 (3 byty) misto "cervena" a pak to "cervena" prevadet na 255,0,0. Protoze pokud bude chtit uzivatel ruzovou, nebudes muset menit program a jednoduse se tam ulozi treba 200,100,100, nebo 210,120,97 nebo libovolny jiny odstin, co se mu zalibi. Ale to je az pro nejakou dalsi verzi, az dokoncis to zjednodusovani a budes to mit zase funkcni a prehledne.

Jo a doporucuju si ukladat jednotlive verze, clovek snadno udela chybu a je lepsi ji moct vratit zpatky. Ja pouzivam GIT jako verzovaci system a nemuzu si ho vynachvalit (a ze jsem jich uz prosel celkem dost). (Jo a samozrejme je zdarma a open source a otestovany soucasnou praci tisicu programatoru po celem svete na projektech jako je linuxove jakdro, webovy server, Arduino a tak podobne, pritom perfektne chodi i na 6 let starem Atomu a nejspis by chodil slusne i na 486 procesoru z dob, kdy o arduinu nesnili ani jeho tvurci)

https://git-scm.com/book/cs/v2

(neco takoveho by mel mit KAZDY, kdo to mysli s programovanim alespon trochu vazneji nez "musim si napsat ukol do programovani na zitra do skoly, chodit to nemusi, hlavne kdyz odevzdam aspon neco" )

Cuore
Příspěvky: 8
Registrován: 24 bře 2018, 19:26
Reputation: 0

Re: Výběr barvy

Příspěvek od Cuore » 28 bře 2018, 11:06

Děkuji za vyčerpávající odpověď. Už jsem to s tím tlačítkem konečně pochopil :? digitalRead se přeci používá na přístup k pinům a ne k vyčtení hodnoty z proměnné :oops: jsem to ale pitoma. Takže se vrhnu na zjednodušení a pak to sem nahodím jak jsem pokročil. Jen pro představu co vyvádím
Obrázek
Je to stavba multimediálního PC postaveném na RaspberryPi 3B, kde jsem integroval 2x GB switche, routerboard 433AH, HDMI grabber pro řízení LED pásku za TV. Arduino je tam z důvodu neschopnosti raspberry se zapnou a vypnout. Nechtěl jsem, aby nepřetržitě běželo a tím přišel u výhody HDMI CEC, kdy si při zapnutí přepne na sebe výstup TV a vypnutí buď TV vypne, nebo přepne na předchozí vstup. No a když už tam Arduino je, tak jsem si řekl, proč neřídit podsvětlení displejů, ovládat diod, jelikož zvládne větší proudovou zátěž apod. Arduino dělá prostě ten hlavní mozek HTPi a bude most mezi uživatelem a HTPi. Raspberry se stará pouze o openelec, komunikaci s NAS a s Arduinem si vyměňuje 8bitů základních informací o jeho stavu. Druhé raspberry je pro řízení LED diod za TV a časem jako tvheadend backend pro stream DVBT do LAN. S Arduinem si bude vyměňovat 4bity. Co se týče programování, tak jsem programátor průmyslové automatizace a tam je toho spoustu jinak. Zatím zvládám obstojně bash, kde jsem si napsal kompletně backend pro NAS, postavený opět na raspberry a Raspbianu. K tomu mám dva frontendy jeden co běží na raspberry HTPi a připojuje si kompletní uložiště a druhý pro klasické PC s grafickým GUI kde si vybírám jaký disk z uložiště chci připojit /filmy/seriály/filmy3D. Takže Arduino byla spíš nouze/kompenzace nedostatků raspberry no a jeho chování a jazyk mě docela dostal :)

Uživatelský avatar
gilhad
Příspěvky: 786
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Výběr barvy

Příspěvek od gilhad » 28 bře 2018, 13:32

Sice nechápu zcela přesně o co jde, ale moc se mi to líbí :)

(A "programátor průmyslové automatizace" v kombinaci "začínám s Arduinem" toho taky hodně vysvětluje - já jsem zaměřený na práci s databázemi, pořádně jsem začínal na Borland Pascal 5.0 prošel řadou jazyků, teď nejvíc Python/bash/Django a dělám kompletní SW systém pro řízení hudby a reklam pro několik velkých řetězců a s Arduinem jsem tak nějak začal asi ?předloni?. RPi taky mám v síti několik desítek, běží mi na nich Gentoo.

Prozradím ti sladké tajemství - celý slavný Arduino jazyk je normální C++ pro AVR, vybavené knihovnou Wiring (kde jsou všechny ty zabalující funkce jako digitalRead() a EEPROM.write() a #define HIGH 0x1 , aby se to tvářilo jako "jednoduché a bezpečné prostředí pro začátečníky, co se nechtějí učit tak složité věci jako programování". IDE pak z *.ino vybere definice všech funkcí a udělá z nich klasickou hlavičku *.h a přidá #include pro systémové knihovny. V hardware/arduino/avr/cores/arduino/ najdeš všechny ty známé Arduino věci napsané v Céčku. A samozřejmě můžeš použít cokoli z normálního Céčka kde se ti zachce a klidně přistupovat k těm pinům a časovačům přímo a řídit se datasheetem k atmega328p, případně to libovolně kombinovat s klasickým Arduino kódem.)

Stejně jako můžeš používat normální *.cpp *.h knihovny pro funkce a definice a tak. (ne, že by to byl ideální start pro práci s Arduinem, ale až se ti to bude hodit, tak věz, že to bezproblémů funguje).

Já osobně bych spís viděl RPi na úrovni mozku a Arduino na úrovni míchy, která toho tolik nevymyslí, ale zato dobře ovládá periferie a automatizmy na úrovni dýchání, srdce a převádění "uchopím sklenici" na pohyby konkrétních svalů a jejich skupin. Tím se taky mozek nezatěžuje, ten myslí na to, co bude k obědu a kde to ulovit :)

Já zrovna stavím univerzální měřák/detektor na chipy 74HCxxx, protože objednávám z číny a čert jim věř, co přesně dodají - chci si postavit něco takovéhoto https://www.youtube.com/watch?v=HyznrdD ... 5dvjafglHU (jen trochu vylepšené) a to těch čipů požere dost. Zatím mám třetí iteraci prototypu (takže to vypadá, jak to vypadá, hlavně že funguje) na měření a teď píšu firmware (část *.cpp a *.h generuju pythonem z textové databáze testů) http://download.gilhad.cz/2018.03.26-74HCxxx/ Obrázek Obrázek Obrázek
)

Mimochodem, nechceš někdy přijít na http://robodoupe.cz/ ? Mohlo by se ti tam taky líbit :D

Cuore
Příspěvky: 8
Registrován: 24 bře 2018, 19:26
Reputation: 0

Re: Výběr barvy

Příspěvek od Cuore » 28 bře 2018, 20:07

Jo tak tady zase nerozumím řeči tvého kmene já :D Sice trochu vím o co ti jde, ale tohle je ještě na hony vzdáleno mým znalostem.
Tak v zjednodušování jsem prozatím pokročil takhle, založil jsem nové funkce

Kód: Vybrat vše

void   ZobrazMenu0(char *nazev0, char *nazev1, byte nav1, char *nav2, byte nav3, byte poz0, byte poz1, byte poz2, byte poz3)  
      {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print(nazev0);                                        // zobrazime nazev
          LCD.setCursor (poz0, 1);                                 // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(nazev1);                                      // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz1, 1);                                 // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)nav1);                                // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(poz2, 1);                                  // nastavime pozici kurzoru na 13 misto 2 radku
          LCD.print(nav2);                                         // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz3, 1);                                 // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)nav3);                                // zobrazime text pro zobrazeni hodnoty
      }
void   ZobrazMenu1(char *nazev, byte hodnota, byte nav1, char *nav2, byte nav3, byte poz0, byte poz1, byte poz2, byte poz3)  
      {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print(nazev);                                        // zobrazime nazev
          LCD.setCursor (poz0, 1);                                 // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(hodnota);                                      // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz1, 1);                                 // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)nav1);                                // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(poz2, 1);                                  // nastavime pozici kurzoru na 13 misto 2 radku
          LCD.print(nav2);                                         // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz3, 1);                                 // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)nav3);                                // zobrazime text pro zobrazeni hodnoty
      }
void   ZobrazMenu2(char *nazev0, char nazev1, byte hodnota, byte nav1, char *nav2, byte nav3, byte poz0, byte poz1, byte poz2, byte poz3)  
      {
          displayUpdate = false;
          LCD.clear();                                             // vycistime displej
          LCD.setCursor (0, 0);                                    // nastavime pozici kurzoru na 1 misto 1 radku
          LCD.print(nazev0);                                       // zobrazime nazev
          LCD.setCursor (poz0, 1);                                 // nastavime pozici kurzoru na 1 misto 2 radku
          LCD.print(nazev1[hodnota]);                              // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz1, 1);                                 // nastavime pozici kurzoru na 11 misto 2 radku
          LCD.write((uint8_t)nav1);                                // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor(poz2, 1);                                  // nastavime pozici kurzoru na 13 misto 2 radku
          LCD.print(nav2);                                         // zobrazime text pro zobrazeni hodnoty
          LCD.setCursor (poz3, 1);                                 // nastavime pozici kurzoru na 16 misto 2 radku
          LCD.write((uint8_t)nav3);                                // zobrazime text pro zobrazeni hodnoty
      }
void   ZobrazMenu3(char *nazev, byte hodnota0, byte hodnota1, byte nav1, char *nav2, byte nav3, byte nav4, byte poz0, byte poz1, byte poz2, byte poz3, byte poz4,  byte poz5) 
      {
if (displayUpdate) 
       {  
      displayUpdate = false;
      LCD.clear();                                                 // vycistime displej
      LCD.setCursor (0, 0);                                        // nastavime pozici kurzoru na 1 misto 1 radku
      LCD.print(nazev);                                            // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor (poz0, 1);                                     // nastavime pozici kurzoru na 9 misto 2 radku
      LCD.write((uint8_t)nav1);                                    // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(poz1, 1);
      LCD.print(nav2);
      LCD.setCursor(poz2, 1);
      LCD.write((uint8_t)nav3);                                    // zobrazime text pro zobrazeni hodnoty
      LCD.setCursor(poz3, 1);
      LCD.write((uint8_t)nav4);                                    // zobrazime text pro zobrazeni hodnoty
                                                                   // tyto dva radky zajisti zobrazeni hodnot pri opakovanem stisknuti vyber
      LCD.setCursor (poz4, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(hodnota0);                                         // zobrazime text pro zobrazeni hodnoty
       }
      LCD.setCursor (poz5, 1);                                     // nastavime pozici kurzoru na 1 misto 2 radku
      LCD.print(hodnota1); 
      }

a v loop() je

Kód: Vybrat vše

 //  **MENU** 
  else if (mode == 1 && displayUpdate == true)  { ZobrazMenu0("LED tlacitko:", "pluzace", 1, "OK", 0, 0, 10, 12, 15); }
 
  else if (mode == 11 && displayUpdate == true) { ZobrazMenu1("Min. hodnota:", EEPROM.read(0), 1, "OK", 0, 0, 10, 12, 15); }

  else if (mode == 12 && displayUpdate == true) { ZobrazMenu1("Max. hodnota:", EEPROM.read(1), 1, "OK", 0, 0, 10, 12, 15); }

  else if (mode == 13 && displayUpdate == true) { ZobrazMenu1("Rychlost:", EEPROM.read(2), 1, "OK", 0, 0, 10, 12, 15); }

  else if (mode == 14 && displayUpdate == true) { ZobrazMenu2("Barva:", barvy, barva, 1, "OK", "", 0, 10, 12, ""); }
 
  else if (mode == 111) { ZobrazMenu3("Nastav Min.", EEPROM.read(0), jasMin, 1, "OK", 2, 3, 8, 10, 13, 15, 0, 4); }

  else if (mode == 121) { ZobrazMenu3("Nastav Max.", EEPROM.read(1), jasMax, 1, "OK", 2, 3, 8, 10, 13, 15, 0, 4); }

  else if (mode == 131) { ZobrazMenu3("Nastav Rychlost", EEPROM.read(2), interval, 1, "OK", 2, 3, 8, 10, 13, 15, 0, 4); }

  else if (mode == 141) { ZobrazMenu3("Nastav Barvu", barvy, EEPROM.read(3), barva, 1, "OK", 2, 3, 8, 10, 13, 15, 0, 4); }

  else if (mode == 2 && displayUpdate == true)  { ZobrazMenu0("Tovarni nastav.", "", 1, "OK", 0, "", 10, 12, 15); }
menu je funkční jako před úpravou, zápasím jak na položky menu s barvou což je mode 14 a 141 aby se dala barva nastavit jak jsem naznačil v loop(). Ale to se podá, jdu si něco nastudovat.

Odpovědět

Kdo je online

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