OK

Při poskytování služeb nám pomáhají soubory cookie. Používáním našich služeb vyjadřujete souhlas s naším používáním souborů cookie. Více informací

Úvodní stránka » Arduino » Nextion display - VI.díl – Hodiny, stopky a Gauge

Nextion display - VI.díl – Hodiny, stopky a Gauge

Co znamená to Gauge? V překladu měřit, pro mě prostě něco jako rychloměr. Ukážeme si k čemu je tato funkce dobrá, uděláme z displeje stopky a vrátíme se k času, jak zobrazení, tak nastavení přes displej.

K tomuto dílu budeme potřebovat samotný displej a nějaké Arduino, použiji UNO.

Gauge

Gauge je funkce přímo Nextion displeje, která otáčí ručičku do stanoveného úhlu ve stupních, tedy kol dokola je 360°. Nevím proč, ale hodnota 0 je úhel 270°, chcete-li tři čtvrtě na devět. S tím je zapotřebí počítat a trochu to komplikuje práci se zobrazením hodinových ručiček.

K čemu se to dá použít? Hodinové ručičky, ale hlavně ke grafickému zobrazení jakýchkoli měřených hodnot, jako napětí, proud, rychlost, otáčky, tlak, teplota. Jenom volbou pozadí určujete jak to bude vypadat, třeba je ručička v červeném poli atd.

Hlavní výhoda této funkce je, že pokud chcete zobrazit ručičku, nemusíte v Arduinu používat poměrně složité výpočty úhlu, stačí poslat hodnotu v požadovaném rozmezí.

HMI soubor je ke stažení zde. K ukázce funkce Gauge nepotřebujeme vůbec nic. Spusťte si v Nextion editoru Debug a posouvejte.

HMI soubor je jen na ukázku a tak je velmi jednoduchý. Vytvořili jsme si posuvník, hodnoty omezili od 0 do 180 a do záložky Move touch přidali funkci hodnota posuvníku se rovná hodnotě gauge. Když to spustíte a budete posouvat posuvníkem, bude se Vám pohybovat ručička funkce Gauge. Schválně si to zkuste za pomoci připojeného potenciometru k arduinu, kde rozsah omezíte funkcí map. Už jsme si to ukazovali v minulých dílech. Jenom připomínkám, že se to nastavuje příkazem z0.val=x.

Stopky

Když si představím stopky, tak měřím alespoň na desetiny vteřiny. My si ale ukazujeme funkce, tak tyto stopky měří po 1 sekundě a pak jen pro ukázku funkcí, jsem pro Vás přidal zpomalení a zrychlení měření času.

HMI soubor je ke stažení zde.

Opět nepotřebujeme nic, vystačíme si se simulátorem. Protože čas nám měří vnitřní časovač displeje. Pro odpočítávání času, jednoduchý budík atd. Vám určitě bude stačit. Není zapotřebí s ním zatěžovat Arduino. Jinak tady je kód displeje už složitější. Každý objekt má svoji přiřazenou funkci, pro pochopení je zapotřebí to poctivě proklikat. Je tam celkem zbytečná funkce nastavení výchozích hodnot přímo na stránce, pokud ale bude tato stránka součástí většího projektu, doporučuji ji tam ponechat.

Při spuštění se nám nastaví časovač s prodlevou 1000 ms a ručička na nulu (to je zbytečná funkce). Po stisknutí tlačítka ON/OFF spustíme/vypneme časovač. Ten každých 1000 ms posune ručičku o 6 stupňů (to je jedna vteřina). Pokud stiskneme tlačítko FAST, snížíme prodlevu časovače o 100 ms, tím se zrychlí pohyb ručičky, tlačítko SLOW funguje přesně naopak.

Až na to opět na nic nezapomenout, je to opět jednoduché. Zkuste si sami přidat tlačítko pro reset ručičky na 0. Když k tomu přidáte zastavení časovače, pomůže Vám to v pochopení nejen této funkce. Podělte se s námi jak to šlo.

Hodiny

Původně jsem chtěl ručičkové, zvažoval jestli nedat digitální. Ručičkové jsou efektní a tak budou ručičkové. Také je sem dávám proto, protože budeme počítat úhly, což je způsob jak nahradit funkci Gauge. Samozřejmě by šlo hodiny udělat za pomoci této funkce, ale podívejte se jaký je to ohromný rozdíl.

HMI soubor je ke stažení zde.

//------------------------------------------------------------------
// inicializace Serial
#define nextion Serial // port pro komunikaci s displejem Nextion
//------------------------------------------------------------------
// promenne pro zobrazeni hodin na displeji
float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;    // Saved H, M, S x & y multipliers
float sdeg = 0, mdeg = 0, hdeg = 0;
uint16_t osx = 120, osy = 120, omx = 120, omy = 120, ohx = 120, ohy = 120; // Saved H, M, S x & y coords
uint16_t x0 = 0, x1 = 0, y0 = 0, y1 = 0;
uint32_t targetTime = 0;                    // for next 1 second timeout
uint8_t hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6); // Get H, M, S from compile time
boolean initial = 1;
//------------------------------------------------------------------
void setup() {
  nextion.begin(9600);   // displej nextion
  drawClock(); // nakresli hodiny
}
//------------------------------------------------------------------
void loop() {
  playClock(); // spust hodiny
}
//------------------------------------------------------------------
// nakresleni hodin
void drawClock() {
  fill_rectangle(0, 0, 240, 240, 0, "BLACK", "BLACK");
  draw_circle(120, 120, 118, "GREEN");
  draw_circle(120, 120, 110, "BLACK");
  for (int i = 0; i < 360; i += 30) {
    sx = cos((i - 90) * 0.0174532925);
    sy = sin((i - 90) * 0.0174532925);
    x0 = sx * 114 + 120;
    y0 = sy * 114 + 120;
    x1 = sx * 100 + 120;
    y1 = sy * 100 + 120;

    draw_line(x0, y0, x1, y1, "GREEN");
  }
  for (int i = 0; i < 360; i += 6) {
    sx = cos((i - 90) * 0.0174532925);
    sy = sin((i - 90) * 0.0174532925);
    x0 = sx * 102 + 120;
    y0 = sy * 102 + 120;
    draw_line(x0, y0, x0, y0, "WHITE");
    if (i == 0 || i == 180) draw_circle(x0, y0, 2, "WHITE");
    if (i == 90 || i == 270) draw_circle(x0, y0, 2, "WHITE");
  }
}
//------------------------------------------------------------------
// spusteni hodin
void playClock() {
  if (targetTime < millis()) {
    targetTime = millis() + 1000;
    ss++;
    if (ss == 60) {
      ss = 0;
      mm++;
      if (mm > 59) {
        mm = 0;
        hh++;
        if (hh > 23) {
          hh = 0;
        }
      }
    }
    sdeg = ss * 6;                
    mdeg = mm * 6 + sdeg * 0.01666667;
    hdeg = hh * 30 + mdeg * 0.0833333;
    hx = cos((hdeg - 90) * 0.0174532925);
    hy = sin((hdeg - 90) * 0.0174532925);
    mx = cos((mdeg - 90) * 0.0174532925);
    my = sin((mdeg - 90) * 0.0174532925);
    sx = cos((sdeg - 90) * 0.0174532925);
    sy = sin((sdeg - 90) * 0.0174532925);

    if (ss == 0 || initial) {
      initial = 0;
      draw_line(ohx, ohy, 120, 121, "BLACK");
      ohx = hx * 62 + 121;
      ohy = hy * 62 + 121;
      draw_line(omx, omy, 120, 121, "BLACK");
      omx = mx * 84 + 120;
      omy = my * 84 + 121;
    }
    draw_line(osx, osy, 120, 121, "BLACK");
    osx = sx * 90 + 121;
    osy = sy * 90 + 121;
    draw_line(osx, osy, 120, 121, "RED");
    draw_line(ohx, ohy, 120, 121, "WHITE");
    draw_line(omx, omy, 120, 121, "WHITE");
    draw_line(osx, osy, 120, 121, "RED");
    draw_circle(120, 121, 3, "RED");
  }
}
//------------------------------------------------------------------
// nakresleni vyplneneho obdelniku
void fill_rectangle(int x, int y, int w, int h, int out, String color, String color1) { // nakresli barevny obdelnik s okrajovou linkou
  String fill;
  if (w - (out * 2) > 0 && h - (out * 2) > 0) {
    if (out == 0) {
      fill = "fill " + String(x) + "," + String(y) + "," + String(w) + "," + String(h) + "," + color1;
    }
    else if (out > 0) {
      fill = "fill " + String(x) + "," + String(y) + "," + String(w) + "," + String(h) + "," + color;
      send_Command(fill.c_str());
      // delay(100);
      x = x - out;
      y = y - out;
      w = w - (out * 2);
      h = h - (out * 2);
      fill = "fill " + String(x) + "," + String(y) + "," + String(w) + "," + String(h) + "," + color1;
    }
    send_Command(fill.c_str());
  }
}
//------------------------------------------------------------------
// nakresleni kruhu
void draw_circle(int x, int y, int r, String color) { // nakresli linku - kruh
  String circle = "cir " + String(x) + "," + String(y) + "," + String(r) + "," + color;
  send_Command(circle.c_str());
}
//------------------------------------------------------------------
// nakresleni cary
void draw_line(int x, int y, int x2, int y2, String color) { // nakresli linku
  String line = "line " + String(x) + "," + String(y) + "," + String(x2) + "," + String(y2) + "," + color;
  send_Command(line.c_str());
}
//------------------------------------------------------------------
// odeslani dat do displeje
void send_Command(const char* cmd) { // odeslani dat do displeje
  nextion.print(cmd);
  nextion.write(0xFF);
  nextion.write(0xFF);
  nextion.write(0xFF);
}
//------------------------------------------------------------------
// funkce pro cas
static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}

Snažil jsem se to udělat tak jednoduché jak to jen šlo. Čas budeme vyčítat z časové značky nahrání programu do arduina. Sketch jsem moc nepopsal, jednak není moc co a pak když tam cokoliv změníte, nebude to fungovat. Pokud to budete chtít použít, bude potřeba program slepě okopírovat. Snad pouze pokud by jste chtěli zobrazit skutečný čas z hodinového modulu, nahradíte proměnné ss, mm a hh v úvodu funkce playClock hodnotami načtenými z hodinového modulu, které budete aktualizovat po jedné vteřině.

Závěr

Funkce gauge nabízí jednoduchou práci s ručičkou, která může ukazovat jednotlivé stavy. Snadno tak může nahradit počítání úhlů, které je použito v hodinách. Tam také vidíte jaký je to ohromný rozdíl. To mě stále fascinuje na tomto displeji. Jednoduchost jeho použití je prostě úžasná.

Příště se vrátíme opět k hodinám, ale tentokrát digitálním ve spojitosti s modulem času a ukážeme si práci s klávesnicí. Ten modul budeme nastavovat.

JB

jaroslav.bohac@arduinotech.cz

Přidat komentář

Zvýrazněné položky jsou povinné.

Přehled komentářů

  1. Diky (Zdendis, 24.3.2017 7:32:28) Odpovědět | Zobrazit odpovědi

    Výborný tutoriál už se těším na ty digitální s nastavením ... Snad už máte více času a chuti ;)

    1. Re: Diky (PavelDC, 25.3.2017 20:15:21) Odpovědět

      Máš pravdu. Takhle při sobotě už by se něco hodilo


TOP produkty

Arduino MEGA2560

Arduino MEGA2560
424 Kč s DPH

NodeMCU s ESP8266

NodeMCU s ESP8266
350 Kč s DPH

Kontakt

Ing. Petr Foltýn
Kunčice pod Ondřejníkem 814, 73913
TOPlist