PC - ARDUINO ovládání vstupů a výstupů

Odpovědět
tosik
Příspěvky: 90
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od tosik » 18 úno 2020, 10:45

Jasně, neuvedl jsem to... Předpokládejme, že budou chodit hodnoty K1 - K9 (celý řetězec K1|P1|12|35|1|53|2|1), ten už umím rozkouskovat a odstranit "|", použil jsem dataKulozeni[0][1], vytisknu na sériovém monitoru, vše OK.

Kód: Vybrat vše

10:30:21.442 -> Přijatý řetězec: K1|P1|12|35|1|53|2|1
10:30:21.489 -> Kanal: K
10:30:21.489 -> číslo: 1
10:30:21.542 -> Program: P
10:30:21.542 -> číslo: 1
10:30:21.542 -> Hodina: 12
10:30:21.542 -> Minuta: 35
10:30:21.542 -> FadeDIM: 1
10:30:21.542 -> DIM: 53
10:30:21.589 -> Režim kanálu: 2
10:30:21.589 -> Typ kanálu: 1
10:30:21.642 -> Součet: 0
10:30:21.642 -> --------------------------
Vypadá to v pořádku, jenže se mi nedaří ten znak uložený do dataKulozeni[0][1] převést na číslo (viz. součet, sčítám dvě první jedničky). Přikládám kód, je zatím neučesaný, jak zkouším různé věci pro zpracování... Prostě bych potřeboval, abych ty přijaté znaky, které se mi po průchodu sériovou linkou změnily na znaky, vrátili zase zpátky na čísla. A ještě jeden dotaz. Proč nemůžu použít proměnnou např. dataKulozeni[0] ve switch (mám to zakomentované)? Já bych to vlastně ani nepotřeboval (to K1 nebo P1) převádět na číslo, je to v podstatě jen ukazatel, nebudu s ním provádět matematické operace (ale naučit se to chci), ale nedaří se mi ani ho využít v tom switch. Při pokusu o kompilaci IDE píše:

"switch quantity not an integer".

To můžu vstupní proměnnou použít jen celočíselnou u switch? Když ji změním na celočíselnou, tak zase řve case:

"conversion from pointer type 'const char (*)[3]' to arithmetic type 'int' in a constant expression".


Kód: Vybrat vše

// testovací řetězec
//P1|K1|12|35|1|53|2|1

char prijatyRetezec[23]; //P1|K1|hh|mm|FD|DI|RE|TY
int citac;
char* item;
String dataKulozeni[8];
void setup() {
  Serial.begin(9600);
}

void loop() {
citac = 0;
while (Serial.available() > 0)
 { 
   prijatyRetezec[citac] = Serial.read();
   delay(10);  
   if (prijatyRetezec[citac] == '\0') break;
   citac++;
 }
 prijatyRetezec[citac] = '\0'; 
 // ------------------------ 
 if (citac > 0) {       
    
    Serial.print("Přijatý řetězec: ");
    Serial.println(prijatyRetezec);
int x = 0; 
  item = strtok(prijatyRetezec,"|");
  while(item != NULL)
  {
    dataKulozeni[x] = item;
    item = strtok(NULL, "|"); 
    x++;   
   }
//int test0 = dataKulozeni[0].toInt();
   int test1 = dataKulozeni[0][1];
   test1 = atoi(test1);
   int test2 = dataKulozeni[1][1];
   test2 = atoi(test2);
//   int test = test0 + test1 + test2; 
   Serial.print("Kanal: ");
   Serial.println(dataKulozeni[0][0]);
   Serial.print("číslo: ");
   Serial.println(dataKulozeni[0][1]);
   Serial.print("Program: ");
   Serial.println(dataKulozeni[1][0]);
   Serial.print("číslo: ");
   Serial.println(dataKulozeni[1][1]);
   Serial.print("Hodina: ");
   Serial.println(dataKulozeni[2]);
   Serial.print("Minuta: ");
   Serial.println(dataKulozeni[3]);
   Serial.print("FadeDIM: ");
   Serial.println(dataKulozeni[4]);
   Serial.print("DIM: ");
   Serial.println(dataKulozeni[5]);
   Serial.print("Režim kanálu: ");
   Serial.println(dataKulozeni[6]);
   Serial.print("Typ kanálu: ");
   Serial.println(dataKulozeni[7]);
   Serial.print("Součet: ");
   Serial.println(test1 + test2);
   Serial.println("--------------------------");
   if (dataKulozeni[0] == "K1") (Serial.println("test0 má K1"));
/*   switch (dataKulozeni[0]) {
      case "K1":
        Serial.println("Kanál K1");
        switch (dataKulozeni[1] == "P1") {
            case(1):
              Serial.println("Program P1");
        break;
        }
   break;
   }*/
}
}

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od KamilV » 18 úno 2020, 13:28

Tady:

Kód: Vybrat vše

int test1 = dataKulozeni[0][1];
test1 = atoi(test1);
zjednodušeně říkáš, že:
int = char (resp. ASCII hodnota znaku)
int = atoi(int)

místo toho, abys rovnou řekl, že:
int = atoi(char)

Kód: Vybrat vše

int test1 = atoi(dataKulozeni[0][1]);
Switch umí pracovat s int nebo char, Ty mu předhazuješ string.

tosik
Příspěvky: 90
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od tosik » 18 úno 2020, 14:51

Ta první zkomolenina vznikla, když jsem laboroval s toInt a atoi, tak jsem si to zkoušel načítat a měnit typ postupně, už to používám zkráceně, jak píšeš ty, ale stejně mi to nedává, to co potřebuji. Proženu tím jedno, pak druhé, sečtu to a výsledek na serialu je 0. Proč?

Kód: Vybrat vše

// testovací řetězec
//P1|K1|12|35|1|53|2|1


char prijatyRetezec[23]; //P1|K1|hh|mm|FD|DI|RE|TY
int citac;
char* item;
String dataKulozeni[8];
void setup() {
  Serial.begin(9600);
}

void loop() {
citac = 0;
while (Serial.available() > 0)
 { 
   prijatyRetezec[citac] = Serial.read();
   delay(10);  
   if (prijatyRetezec[citac] == '\0') break;
   citac++;
 }
 prijatyRetezec[citac] = '\0'; 
 // ------------------------ 
 if (citac > 0) {       
    
    Serial.print("Přijatý řetězec: ");
    Serial.println(prijatyRetezec);
int x = 0; 
  item = strtok(prijatyRetezec,"|");
  while(item != NULL)
  {
    dataKulozeni[x] = item;
    item = strtok(NULL, "|"); 
    x++;   
   }
   int test0 = atoi(dataKulozeni[0][1]);
   int test1 = atoi(dataKulozeni[1][1]);
   int test = test0 + test1; 
   
   Serial.print("Kanal (dataKulozeni[0][0]): ");
   Serial.println(dataKulozeni[0][0]);
   
   Serial.print("číslo (dataKulozeni[0][1]): ");
   Serial.println(dataKulozeni[0][1]);
   
   Serial.print("Program (dataKulozeni[1][0]): ");
   Serial.println(dataKulozeni[1][0]);
   
   Serial.print("číslo (dataKulozeni[1][1]): ");
   Serial.println(dataKulozeni[1][1]);

   Serial.print("test0: ");
   Serial.println(test0);

   Serial.print("test1: ");
   Serial.println(test1);
   
   Serial.print("Součet test0 + test1:");
   Serial.println(test);
   
   
   Serial.println("*********************************************");
   }
}
Po serialu pošlu testovací řetězec v úvodu kódu a dostanu tento výpis:

Kód: Vybrat vše

14:46:03.626 -> Přijatý řetězec: P1|K1|12|35|1|53|2|1
14:46:03.673 -> Kanal (dataKulozeni[0][0]): P
14:46:03.726 -> číslo (dataKulozeni[0][1]): 1
14:46:03.726 -> Program (dataKulozeni[1][0]): K
14:46:03.773 -> číslo (dataKulozeni[1][1]): 1
14:46:03.827 -> test0: 0
14:46:03.827 -> test1: 0
14:46:03.827 -> Součet test0 + test1:0
14:46:03.827 -> *********************************************

Co dělám špatně, že testy obsahují 0 a tím pádem jejich součet je 0?

Díky za osvětlení toho switch, teď mi je to jasné... :-D

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od KamilV » 18 úno 2020, 15:22

No jasně, ono mu tam chybí \0.
Takže bych zkusil buď:

Kód: Vybrat vše

int test0 = dataKulozeni[0][1] - '0';
nebo

Kód: Vybrat vše

char tmp[] = '0';
tmp[0] =dataKulozeni[0][1];
int test0 = atoi(tmp);

tosik
Příspěvky: 90
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od tosik » 18 úno 2020, 16:44

Hurá!!!! Varianta č.1 funguje.... Konečně. Díky moc. Ta druhá varianta vypadá taky zajímavě. Probíhá v ní to, že se za K dosadí 0? Takže na pozici [0] bude 0 (místo K1 bude 01)? Tu první se ani nesnažím pochopit.... :-D

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od KamilV » 18 úno 2020, 21:27

Varianta č. 1 využívá toho, že každý char je nějaký ASCII int. Čísla jsou v ASCII za sebou, počínaje nulou.
Mám tedy nějaký char znak, resp. jeho ASCII hodnotu, odečtu od něj ASCII hodnotu nuly a tím rozdílem dostanu "vzdálenost od nuly v ASCII tabulce". Čili samotné číslo.

Varianta č. 2 pracuje s tím, že atoi vyžaduje v parametru celý char řetězec, tedy pole znaků končící \0.
Když mu vyďobneš jen dataKulozeni[0][1], tak mu tam \0 chybí, takže to asi nepřetypuje dobře a vrátí 0.
Když si uděláš chat tmp[] = '0';
tak obsahuje tmp[0] = 0; tmp[1] = \0;
Nultou pozici přeplácneš požadovaným, např. "2", takže pak máš tmp[0] = 2; tmp[1] = \0;
To jde to atoi() a vrátí 2.

tosik
Příspěvky: 90
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od tosik » 19 úno 2020, 10:30

No tak teď už tomu aspoň trochu rozumím. Takže tím se při odečtení jakéhokoliv jiného prvního znaku vlastně dostanu na začátek požadované sady znaků (třeba abecedy apod.) a pak můžu pracovat s následujícími znaky, že? Vychytané... :-)
To Le-Ze
Potřeboval bych nastavit TComboBox v Lazarusu. Umím do něj nasoukat položky seznamu, ale jak uělám více sloupců jsem v žádném návodu nenašel.
Např.:
0 rozsvěcování skokově
1 rozsvěcování plynule

Potřebuji to číslo (na pořadí na tom řádku mi nezáleží, třeba by ani ta hodnota nemusela být vidět) a ten text je vlastně jen nápověda. A kdyby někdo věděl o nějakých stránkách s dobrým návodem pro začátečníky s Lazarusem, nebo nějakou pdf publikaci, tak prosím dejte to sem. V češtině ideál, ale nějak přelouskám i tu angličtinu... :-D

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od KamilV » 19 úno 2020, 10:49

Nevím, jak v Pascalu, ale +- to bude podobná komponenta jako v C++.
Sloupce neumí, musel by sis to dozarovnat mezerami a nastavit nějaký monospace font, třeba Courier.

IMHO to číslo v textu nepotřebuješ, pro uživatele nech jen skokově / plynule a až budeš sestavovat string pro Serial, sáhneš si na: ComboBox.ItemIndex

Dokumentace třeba zde: https://wiki.freepascal.org/Main_Page, CZ nemá, ale SK ano...

tosik
Příspěvky: 90
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od tosik » 19 úno 2020, 17:49

To sice jde, ale vyskytnou se mi dva problémy. Když nevyberu (omylem) žádnou z položek, nechám ji tak, jak je po spuštění programu, uloží se mi prázdná hodnota a dál to pak tvoří nesmysly.
A když potřebuji přeskočit nějaké hodnoty (nechávám si rezervu pro případné další možnosti), tak mi index moc nepasuje...
0 skok
1 plynule
9 deaktivovat

Lze aspoň nastavit nějaký default index? Nějak se k tomu nemůžu dopátrat...

KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: PC - ARDUINO ovládání vstupů a výstupů

Příspěvek od KamilV » 19 úno 2020, 19:15

Ad 1. problém: podívej se do Properties té komponenty, většinou se dá někde zapnout, že ComboBox bude mít vždy nějakou volbu vybranou, tzn. vykreslí se s vybranou první položkou a uživatel může max. překliknout na jinou.

Ad 2. problém: při sestavování stringu na Serial můžeš mít "převodní tabulku":
array[0] = 0;
array[1] = 1;
array[2] = 9;

Tedy:
array[ItemIndex] = stav;

Odpovědět

Kdo je online

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