IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 13:03

Výpis položek z pole const char * na e-ink displej pomocí příkazu:

display.print(array[i]);        // Nezobrazí požadovaný text pole
display.print(array[0]);        // Při zadání indexu "natvrdo" výpis funguje

Zkusil jsem: Data uložena ve tvaru:

const char* array[] = {
  "Sunka Bohemia",
  "Cesn syrova pomazanka",
  "Hermelin", "Smetana",
  "Pazitka",
  "Hovezi bujon tekuty"
};
Displ_Y = 5;
for (int i = p; i < 6; i++) {
      display.setTextColor(EPD_BLACK);
      display.setCursor(0, Displ_Y);
      display.print(array[1]);  // Text se nevypíše pokud změním na potřebné array[i]
      Displ_Y =  Displ_Y + 20;
    }

Chci docílit: Vypisovat texty v uloženém poli na e-ink displej. Jde o program pro Arduino.

Jak příkaz upravit,případně použít jiný, přetypovat data či texty uložit jinak ?

Poznámka: k dotazu jsem přidal "dlouhý zdroják" Print.cpp, který používá funkce display.print nevím ale, jestli se u dotazu zobrazí (či jak to udělat).

 
Odpovědět
9.4.2022 13:03
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 13:12

Přidávám parametry funkce display.print Příspěvek nelze bohužel editovat.

 
Nahoru Odpovědět
9.4.2022 13:12
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 13:13

Sorry správně se to vypisuje takto:

 
Nahoru Odpovědět
9.4.2022 13:13
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:9.4.2022 14:10

Použij write() namísto print().

display.write(array[i]);
Nahoru Odpovědět
9.4.2022 14:10
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 20:24
display.write(array[i]);

Nic na obrazovku nevypíše, jen bílá obrazovka a černý čtverec

display.write(*array[i]);

Vypíše jen první znak

Problém je asi v tom, že funkce display.print má typ const char (hvězdička)str a já mám texty uložené v const char(hvězdička) array[]

 
Nahoru Odpovědět
9.4.2022 20:24
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:9.4.2022 21:11

To zda máš řetězce uložené v poli nebo ne je jedno.

deklarace parametru

const char *str

jasně říká, že argument funkce je ukazatel na konstantní řetězec, tedy řetězec, který se nebude měnit. Což ty ani měnit nemůžeš, jelikož řetězce jsou uloženy v tabulce řetězců a ty znáš pouze jejich adresy.

Spíše to vypadá, že knihovna kterou používáš není schopna pracovat s řetězci.

Použij místo print() funkci println().

Nahoru Odpovědět
9.4.2022 21:11
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 21:58

println() vyzkouším

Přišel jsem ale na to, že funguje:

display.write(array[i], sizeof(array[i]));

vypíše to ale jen první 4 znaky. Jakým příkazem určit počet bytů v aktuální položce pole ? Musí to být hodnota typu size_t

 
Nahoru Odpovědět
9.4.2022 21:58
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:9.4.2022 22:24

4 znaky to vypíše proto, že prvkem pole je ukazatel a ten má velikost 4 byty. Pro určení délky řetězce použij funkci strlen() z knihovny string.h.

Př.

#include <stdio.h>
#include <string.h>

int main(void) {
        char* foods[] = {
           "Sunka Bohemia",
           "Cesn syrova pomazanka",
           "Hermelin",
           "Smetana",
           "Pazitka",
           "Hovezi bujon tekuty"
        };

        size_t len = sizeof(foods) / sizeof(foods[0]);

        for (size_t i = 0; i < len; i++) printf("%zu %s\n", strlen(foods[i]), foods[i]);

        return 0;
}

Tedy ve tvém případě by to mohlo vypadat takto:

display.write(array[i], strlen(array[i]));

Což by značilo, že write() je přetížená metoda, kde jeden prototyp by mohl mít dva parametry. Kde jako první argument se předává ukazatel (ve tvém případě ukazatel na začátek pole) a druhý argument je počet vypisovaných znaků (počet znaků tedy délku řetězce získáš pomocí již zmiňované funkce strlen()). Někde ale musíš přecházet na nový řádek, aby si zobrazil data na novém řádku displeje.

Editováno 9.4.2022 22:25
Nahoru Odpovědět
9.4.2022 22:24
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:9.4.2022 22:48

Ještě by mělo fungovat:

int n = 0;
while (*(array[i]+n) != 0x00){
  display.write(*array[i]+n);
  n++;
}

Jen přesně nevím, jak mám načíst byte z paměti aktuálního textu pomocí pointru a zjistit, zda již nejsem na konci (0x00)

Když vyhodím cyklus, nechám jen write a zadám např. n = 3, správně se vypisují 4 písmena textu v array.

 
Nahoru Odpovědět
9.4.2022 22:48
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:9.4.2022 22:52

Ano, toto bude fungovat rovněž. Je to způsob, kde vypisuješ postupně jednotlivé znaky dokud nenarazíš na nul.

Vztah mezi indexací a ukazatelovou aritmetikou je:

a[i] ~ *(a+i)
Nahoru Odpovědět
9.4.2022 22:52
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:9.4.2022 23:01

Takto vypíšeš celé pole po jednotlivých znacích pomocí ukazatelové aritemtiky:

for (size_t i = 0; i < len; i++) {
        for (char* p = foods[i]; *p; p++) putchar(*p);
        putchar('\n');
}
Nahoru Odpovědět
9.4.2022 23:01
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Petan
Člen
Avatar
Odpovídá na Caster
Petan:10.4.2022 9:42

Prvni priklad musi fungovat,ale co je p vfor (int i = p; i < 6; i++) { musi tam byt for (int i = 0; i < 6; i++) {

 
Nahoru Odpovědět
10.4.2022 9:42
Avatar
Caster
Člen
Avatar
Caster:10.4.2022 20:57

Nejschůdnější asi bude použít:

display.write(array[i], sizeof(array[i]));

což ale vypíše jen 4 první znaky.

int x = strlen(array[i]);
display.write(array[i], strlen(array[i]));
Serial1.printf("%d", x);

nefunguje, udělá to jen bílý a černý displej viz obrázek výše. Na sériové lince 1 je ale správně vypsána délka "Cesn syrova pomazanka" 21 znaků viz obrázek z logického analyzátoru. Problém je asi ve funkci print, která očekává jiný typ dat.

Příkaz display.write(a­rray[i], strlen(array[i])); je definován pomocí:

using write
// In Adafruit_GFX
public: using Print::write

v souboru Adafruit_GFX.h je pak:

using Print::write;
#if ARDUINO >= 100
  virtual size_t write(uint8_t);
#else
  virtual void write(uint8_t);
#endif

a v Print.h pak:

#ifndef Print_h
#define Print_h

#include <inttypes.h>
#include <stdio.h> // for size_t
#include <stdarg.h> // for printf
#define PRINTF_BUF 80

#include "WString.h"
#include "Printable.h"

#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2

class Print
{
  private:
    int write_error;
    size_t printNumber(unsigned long, uint8_t);
    size_t printFloat(double, uint8_t);
  protected:
    void setWriteError(int err = 1) { write_error = err; }
  public:
    Print() : write_error(0) {}

    int getWriteError() { return write_error; }
    void clearWriteError() { setWriteError(0); }

    virtual size_t write(uint8_t) = 0;
    size_t write(const char *str) {
      if (str == NULL) return 0;
      return write((const uint8_t *)str, strlen(str));
    }
    virtual size_t write(const uint8_t *buffer, size_t size);
    size_t write(const char *buffer, size_t size) {
      return write((const uint8_t *)buffer, size);
    }

    // default to zero, meaning "a single write may block"
    // should be overriden by subclasses with buffering
    virtual int availableForWrite() { return 0; }

    size_t print(const __FlashStringHelper *);
    size_t print(const String &);
    size_t print(const char[]);
    size_t print(char);
    size_t print(unsigned char, int = DEC);
    size_t print(int, int = DEC);
    size_t print(unsigned int, int = DEC);
    size_t print(long, int = DEC);
    size_t print(unsigned long, int = DEC);
    size_t print(double, int = 2);
    size_t print(const Printable&);

    size_t println(const __FlashStringHelper *);
    size_t println(const String &s);
    size_t println(const char[]);
    size_t println(char);
    size_t println(unsigned char, int = DEC);
    size_t println(int, int = DEC);
    size_t println(unsigned int, int = DEC);
    size_t println(long, int = DEC);
    size_t println(unsigned long, int = DEC);
    size_t println(double, int = 2);
    size_t println(const Printable&);
    size_t println(void);

    size_t printf(const char[], ...);

    virtual void flush() { /* Empty implementation for backward compatibility */ }
};

#endif
display.printf("%2d", dny[i]);

funguje správně. Funkce je definována v Print.cpp:

size_t Print::printf(const char format[], ...)
{
  size_t r;
  char buf[PRINTF_BUF];
  va_list ap;
  va_start(ap, format);
  r = vsnprintf(buf, sizeof(buf), format, ap);
  write(buf);
  va_end(ap);
  return r;
}

Celé Print.cpp je tady (možná by šlo použít příkaz pro tisk textu jídla funkci odtud:

#include <math.h>
#include "Arduino.h"

#include "Print.h"

// Public Methods //////////////////////////////////////////////////////////////

/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
  size_t n = 0;
  while (size--) {
    if (write(*buffer++)) n++;
    else break;
  }
  return n;
}

size_t Print::print(const __FlashStringHelper *ifsh)
{
  return print(reinterpret_cast<const char *>(ifsh));
}

size_t Print::print(const String &s)
{
  return write(s.c_str(), s.length());
}

size_t Print::print(const char str[])
{
  return write(str);
}

size_t Print::print(char c)
{
  return write(c);
}

size_t Print::print(unsigned char b, int base)
{
  return print((unsigned long) b, base);
}

size_t Print::print(int n, int base)
{
  return print((long) n, base);
}

size_t Print::print(unsigned int n, int base)
{
  return print((unsigned long) n, base);
}

size_t Print::print(long n, int base)
{
  if (base == 0) {
    return write(n);
  } else if (base == 10) {
    if (n < 0) {
      int t = print('-');
      n = -n;
      return printNumber(n, 10) + t;
    }
    return printNumber(n, 10);
  } else {
    return printNumber(n, base);
  }
}

size_t Print::print(unsigned long n, int base)
{
  if (base == 0) return write(n);
  else return printNumber(n, base);
}

size_t Print::print(double n, int digits)
{
  return printFloat(n, digits);
}

size_t Print::println(const __FlashStringHelper *ifsh)
{
  size_t n = print(ifsh);
  n += println();
  return n;
}

size_t Print::print(const Printable& x)
{
  return x.printTo(*this);
}

size_t Print::println(void)
{
  return write("\r\n");
}

size_t Print::println(const String &s)
{
  size_t n = print(s);
  n += println();
  return n;
}

size_t Print::println(const char c[])
{
  size_t n = print(c);
  n += println();
  return n;
}

size_t Print::println(char c)
{
  size_t n = print(c);
  n += println();
  return n;
}

size_t Print::println(unsigned char b, int base)
{
  size_t n = print(b, base);
  n += println();
  return n;
}

size_t Print::println(int num, int base)
{
  size_t n = print(num, base);
  n += println();
  return n;
}

size_t Print::println(unsigned int num, int base)
{
  size_t n = print(num, base);
  n += println();
  return n;
}

size_t Print::println(long num, int base)
{
  size_t n = print(num, base);
  n += println();
  return n;
}

size_t Print::println(unsigned long num, int base)
{
  size_t n = print(num, base);
  n += println();
  return n;
}

size_t Print::println(double num, int digits)
{
  size_t n = print(num, digits);
  n += println();
  return n;
}

size_t Print::println(const Printable& x)
{
  size_t n = print(x);
  n += println();
  return n;
}

size_t Print::printf(const char format[], ...)
{
  size_t r;
  char buf[PRINTF_BUF];
  va_list ap;
  va_start(ap, format);
  r = vsnprintf(buf, sizeof(buf), format, ap);
  write(buf);
  va_end(ap);
  return r;
}

// Private Methods /////////////////////////////////////////////////////////////

size_t Print::printNumber(unsigned long n, uint8_t base)
{
  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
  char *str = &buf[sizeof(buf) - 1];

  *str = '\0';

  // prevent crash if called with base == 1
  if (base < 2) base = 10;

  do {
    char c = n % base;
    n /= base;

    *--str = c < 10 ? c + '0' : c + 'A' - 10;
  } while(n);

  return write(str);
}

size_t Print::printFloat(double number, uint8_t digits)
{
  size_t n = 0;

  if (isnan(number)) return print("nan");
  if (isinf(number)) return print("inf");
  if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
  if (number <-4294967040.0) return print ("ovf");  // constant determined empirically

  // Handle negative numbers
  if (number < 0.0)
  {
     n += print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;

  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  n += print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0) {
    n += print(".");
  }

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    unsigned int toPrint = (unsigned int)remainder;
    n += print(toPrint);
    remainder -= toPrint;
  }

  return n;
}
 
Nahoru Odpovědět
10.4.2022 20:57
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:10.4.2022 21:25

Vypiš pole takto:

for (size_t i = 0; i < len; i++) {
        for (char* p = foods[i]; *p; p++) display.write(*p);
        display.write('\n');
}
Nahoru Odpovědět
10.4.2022 21:25
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:10.4.2022 22:53

Dal jsem to do stávající cyklu pro výpis položek pole, ale hlásí mi to chybu viz screenshot. Místo proměnné p, kterou už používám, jsem zvolit proměnnou "x".

for (char* x = array[i]; *x; x++) display.write(*x);

variable x
Type: char *

// In loop
char *x = <recovery - expr>(array[i])
Cannot initialize a variable of type 'char *' with an lvalue of type 'const char *'clang(init_con­version_failed)

Při překladu program hlásí:
\Arduino\xiao_sle­epRtc\xiao_sle­epRtc.ino:108:29: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
for (char* x = array[i]; *x; x++) display.write(*x);

pole array[i] je podtrženo

 
Nahoru Odpovědět
10.4.2022 22:53
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:10.4.2022 23:08

Přidej klíčové slovo const před deklaraci pointeru v inicializační části.

Nahoru Odpovědět
10.4.2022 23:08
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Odpovídá na DarkCoder
Caster:10.4.2022 23:57
for (const char* x = array[i]; *x; x++) {
       display.print(*x);
     }

In Print: public: size_t print(char)
netiskne

když ale použiji:

display.print("+");

vypíše všechny položky správně vč. jejich délky, jen jen samozřejmě místo textu stále "+"
In Print: public: size_t print(const char[])

display.write(*x);

netiskne
In Adafruit_GFX: public: virtual size_t write(uint8_t)

display.write("+");

vypíše všechny položky správně vč. jejich délky, jen jen samozřejmě místo textu stále "+"
In Adafruit_GFX: public: using Print::write

 
Nahoru Odpovědět
10.4.2022 23:57
Avatar
Caster
Člen
Avatar
Caster:11.4.2022 0:48

Tohle už alespoň začalo něco vypisovat:

display.write(reinterpret_cast<char *>(*x));

In Adafruit_GFX: public: using Print::write

viz obrázek

 
Nahoru Odpovědět
11.4.2022 0:48
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.4.2022 13:47

Arduino si zřejmě s ukazately moc netyká.. Tak jinak

Máme následující:

char* foods[] = {
           "Sunka Bohemia",
           "Cesn syrova pomazanka",
           "Hermelin",
           "Smetana",
           "Pazitka",
           "Hovezi bujon tekuty"
};

size_t len = sizeof(foods) / sizeof(foods[0]);

Zajímají mě výstupy u následujících úryvků kódu:

for (size_t i = 0; i < len; i++) {
        display.setCursor(0, i);
        display.print(strlen(foods[i]));
}
for (size_t i = 0, l = 0; i < len; i++) {
        display.setCursor(0, i);
        l = strlen(foods[i]);
        display.print(l);
}

Očekávám 13 21 8 7 7 19, každé číslo na samostatném řádku

display.print(foods[2]);
display.println(foods[2]);
display.write(foods[2], 21);
display.write(foods[2], strlen(foods[2]));
size_t z = strlen(foods[2]);
display.write(foods[2], z);

Výsledky mě zajímají i na serial.

Nahoru Odpovědět
11.4.2022 13:47
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.4.2022 14:38

Co se uz nekdo nekdy ptal na audirino, tak rikal, ze pouziva nejakou vlastni zjednodusenou verzi c++. Takze, zrada ciha uplne vsude a je treba najit kod pro ten stroj :)

https://www.arduino.cc/…ypes/string/

char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3",
                     "This is string 4", "This is string 5", "This is string 6"
                    };

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 6; i++) {
    Serial.println(myStrings[i]);
    delay(500);
  }
}
 
Nahoru Odpovědět
11.4.2022 14:38
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.4.2022 14:43
char *foods[] = {
           "Sunka Bohemia",
           "Cesn syrova pomazanka",
           "Hermelin",
           "Smetana",
           "Pazitka",
           "Hovezi bujon tekuty"
};

void setup() {
  Serial.begin(9600);
}

void loop() {
  int i_start = 0
  int i_end = 6
  for (int i = i_start; i < i_end; i++) {
    Serial.println(myStrings[i]);
    delay(500);
  }
}
 
Nahoru Odpovědět
11.4.2022 14:43
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.4.2022 14:46

Jinak, uz prvne jsem si toho vsiml, ale proc tam mas p?

for (int i = p; i < 6; i++) { // i = 0 ne?
for (int i = 0; i < 6; i++) {
 
Nahoru Odpovědět
11.4.2022 14:46
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Peter Mlich
DarkCoder:11.4.2022 14:59

Takze, zrada ciha uplne vsude a je treba najit kod pro ten stroj :)

Také jsem toho názoru podle toho co vidím 😀. Fórum plné podobných dotazů. Stále vznikají různé hybridy a pak to tak dopadá. C se drží na topu stále, je osvědčené a to už je tu 50 let! Vše nej k narozeninám!

Na tuto stránku jsem také narazil, na seriálu by neměl být problém, zajímají mě především výstupy na LCD. Tak uvidíme s Caster přijde.

Nahoru Odpovědět
11.4.2022 14:59
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Peter Mlich
DarkCoder:11.4.2022 15:04

To p tam představuje posun v poli. Záznamy, u kterých vypršela doba expirace zůstávají navrchu a aby se přeskočily, je třeba posouvat pozici na první vypisovány záznam. Již jsme to řešili v předchozí diskuzi. Samozřejmě tato verze je pouze provizorní, neboť záznamy zůstávají v poli a velmi rychle se to pole zaplní. Pro začátek to ale stačí.

Nahoru Odpovědět
11.4.2022 15:04
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:11.4.2022 17:37

@DarkCoder

for (size_t i = 0; i < len; i++) {
    display.setCursor(0, Displ_Y);
    display.print(strlen(food[i]));
    Displ_Y = Displ_Y + 20;
  }

Vypíše čísla 13 21 8 7 7 a 19 na samostatném řádku

for (size_t i = 0; i < len; i++) {
    display.setCursor(0, Displ_Y);
    l = strlen(foods[i]);
    display.print(l);
    Displ_Y = Displ_Y + 20;
  }

Vypíše čísla 13 21 8 7 7 a 19 na samostatném řádku

display.print(foods[2]);

Vypíše na displej "Hermelin" dtt na seriovou linku

display.println(foods[2]);

Vypíše na displej "Hermelin" dtt na seriovou linku (vidím i CR, LF)

display.write(foods[2], 21);

Vypíše na displej v jednom řádku "Hermelin Smetana Pazi" dtto na seriovou linku

display.write(foods[2], strlen(foods[2]));

Vypíše na displej "Hermelin" dtto na seriovou linku

size_t z = strlen(foods[2]);
display.write(foods[2], z);

Vypíše na displej "Hermelin" dtto na seriovou linku

Obrázek z mého stolu, testování (Arduino XIAO, e-ink displej a logický analyzátor LA104) ;-)

 
Nahoru Odpovědět
11.4.2022 17:37
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.4.2022 19:33

Skvělé! Výsledky přesně takové jaké jsem očekával.

Teď mě zajímá toto:

for (size_t i = 0, Displ_Y = 5; i < len; i++) {
    display.setCursor(0, Displ_Y);
    display.print(foods[i]));
    Displ_Y += 20;
}
Nahoru Odpovědět
11.4.2022 19:33
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.4.2022 20:01

Popřípadě po zjednodušení:

for (size_t i = 0; i < len; i++) {
    display.setCursor(0, 20 * i + 5);
    display.print(foods[i]));
}
Nahoru Odpovědět
11.4.2022 20:01
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:11.4.2022 21:59

@DarkCoder
Super, fungují obě dvě verze. Problém byl asi tedy v tom, že jsem měl proměnnou "i" dříve definovánu jako int. Pomohlo ji definovat jako size_t i když přesně nevím, jako je v tom rozdíl od int.

Ve finále jsem tam přidal i tisk počtu dnů:

for (size_t i = 0; i < len; i++) {
    display.setCursor(0, 20 * i + 5);
    display.printf("%2d", dny[i]);
    display.setCursor(36, 20 * i + 5);
    display.print(foods[i]);
    Displ_Y += 20; // Bude se používat pro vypisování expirovaných potravin, výpis musí začít odshora displeje
}

Fakt moc oceňuji skvělou pomoc DarkCodera, někdy zajdem na pivo ;-).

P.S. Zjistil jsem, že má na funkčnost výpisu i vliv zadání x pozice začátku výpisu. Pro danou velikost písma to vypadá, že je písmo široké 5 + 1 (mezera) bod. Když jsem chtěl vypisovat foods od x pozice 18 (tj. za pevnou délkou čísla přidat 1 mezeru), text se překrýval, pro 32 se vůbec nic nezobrazilo (není násobek 6ti ?) a teď mi tam funguje 36 (násobek šířky písmena 6 * 6 ? mezera mezi počtem dnů a začátkem foods ale vůbec neodpovídá. To už je ale prkotina. Displej má rozlišení 296 x 128 bodů.

Obrázek výpisu jen foods a druhý včetně dnů do expirace

Editováno 11.4.2022 22:02
Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět
11.4.2022 21:59
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.4.2022 23:04

No vida, hned to vypadá veseleji když jsme se zdárně dopidili k výsledku. A barvy nebudou? Červená pro potraviny po expiraci.. 😀

V typu iterační proměnné to nebude, takže jaká kouzla si tam dělal víš jen ty. 😊 int je znaménková proměnná o velikosti 16 resp. 32 bitů. Size_t je beznamenková proměnná veliká minimálně 16 bitů a velká tak, aby bylo možné pracovat s objekty maximální velikosti. Bývá používaná právě jako iterační proměnná pro indexaci polí a je návratovou hodnotou funkce strlen() a operátoru sizeof. Ve 32b prostředí odpovídá typu unsigned long int a v 64b prostředí odpovídá unsigned long long int.

Jinak zdaleka ještě aplikace není hotová. Je třeba doplnit přidávání potravin, řazení, mazání záznamů po expiraci a mnoho dalšího. Ale jako základy jsou celkem dobré.

To nejpodstatnější je, že si se zase zase něčemu novému přiučil a mně se třeba jednou budou tvé zkušenosti s arduinem hodit. 😊

Pivo, to je nějaký nový datový typ? 😀

Nahoru Odpovědět
11.4.2022 23:04
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:11.4.2022 23:56

Když Ti to teď funguje, ověř mi ještě jednou tento způsob výpisu:

for (size_t i = 0; i < len; i++) {
        display.setCursor(0, 20 * i + 5);
        for (const char* prec = foods[i]; *prec; prec++) display.write(*prec);
}
Editováno 11.4.2022 23:59
Nahoru Odpovědět
11.4.2022 23:56
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Caster:12.4.2022 9:25

Vyzkoušel a funguje také úplně v pohodě ;-)

Ve finální verzi programu mám RTC wakeup alarm každý den v 6:00, kdy se aktualizuje expirace potravin a displej, než přejde Arduino zpět do režimu spánku.

Červený výpis jídla pak:

if (dny[i] < 0) {
  display.setTextColor(EPD_RED);
}

Zčásti mám již navržen plošný spoj na který přiletuji Arduino a posadím e-Ink displej. Pro napájení asi použiji malou knoflíkovou baterii Zinc-Air A675 a Boost Up měnič na 3.3V

3D krabičku navrhnu ve FreeCADu. Představu mám takovou, že nyní po nákupu sundám displej z lednice a texty do něj nahraju přes USB pomocí Arduino IDE. V druhé fázi dokončím program v Android studiu a texty se po jejich nadiktování do mobilu přenesou pomocí Bluetooth do Arduina, kam přidám BT modul.

 
Nahoru Odpovědět
12.4.2022 9:25
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:12.4.2022 10:58

Skvělé, že i způsob pomocí ukazatelové aritmetiky funguje. :-) Použij verzi, jaká se ti líbí..

Ve finální verzi tedy budou dvě jednotky (mobilní aplikace a arduino).

V arduinu bude uložen soubor s databází (potravina a její expirační doba), pojede si svým vlastním životem, kdy pouze v 6:00 ráno si provede aktualizaci expirace potravin, aktualizuje výpis na e-displeji a ponoří se do řežimu spánku. Zde je jedno vylepšení, expirační doba. Čas do expirace bylo lepší aby se počítalo tak, že arduino si při spuštění zjistí aktuální čas a provede rozdíly časů, čímž získá dobu, za jakou dojde u potraviny k vypršení expirační doby. Je to lepší řešení nežli odečet -1.

Vše ostatní, přidávání potraviny, ubírání potravin, třídění databáze a další úkony, by bylo na straně mobilní aplikace. Z té pouze pomocí bluetooth se přenese aktuální databázi do arduina. To znamená, že pomocí mobilní aplikace je třeba po změně databáze probudit arduino, nahrát novou databázi a znovu jej uspat. Ač je to už pouze ssw záležitost, bude to možná ještě více zajímavější než operace na straně arduina. :-)

Každopádně to celé, jak to popisuješ, vypadá skvěle a jsem zvědav na hotovou verzi. :-)

a veškeré úpravy databáze se budou provádět na straně mobilní aplikace (přidávání a ubírání potravin, třídění).

Nahoru Odpovědět
12.4.2022 10:58
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Caster
Člen
Avatar
Odpovídá na DarkCoder
Caster:12.4.2022 11:57

Aktuální čas si program při nahrátí do Arduina načte z Windows. Přesnost RTC v MCU SAMD21G18 Arduino XIAO je v pohodě pro probuzení jednou za den.

myRtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

Budu se snažit, aby projekt vypadal profesionálně, stejně jako můj první, měření napětí autobaterie (ATtiny202 a Sigfox).

 
Nahoru Odpovědět
12.4.2022 11:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 33 zpráv z 33.