Close

Sériová komunikace a cykly

Schéma bufferu

V dnešním díle splním sliby, které jsem v posledních článcích dal. Ukážeme si, jak může Arduino komunikovat přes sériovou linku s jinými zařízeními a deskami Arduino a vysvětlíme si, jak fungují cykly.

 

Sériová komunikace

Ve článku Základní struktury jazyka Wiring jsme si popsali, jak sériová komunikace funguje. Neřekli jsme si ale, k čemu se dá využít. Pokud chceme od Arduina získávat nějaké hodnoty, nebo mu je posílat, přichází na řadu právě sériová komunikace. Pracujeme-li například na projektu meteostanice, určitě se hodí získané hodnoty nějakým způsobem zpracovat. Nejlepší je posílat je do PC a tam je v nejjednodušším případě zobrazovat jako text, nebo je pomocí dalších programů zpracovávat. Poté přijde na řadu právě sériová komunikace. Ta je také důležitým nástrojem při ladění programů. Když nám něco nefunguje a my nevíme proč, může být užitečné si nechat vypisovat hodnotu proměnné, nebo určitý text pouze v podmínce, takže máme kontrolu nad tím, jaká část kódu se právě provádí. Dá se také využít při komunikaci Arduina a dalších zařízení (jiné Arduino, moduly atd.). K tomu slouží piny popsané Rx a Tx (u UNO odpovídají pinům 0 a 1). Všechny funkce využívající sériovou komunikaci obsahují slovo Serial. My si představíme pár nejužitečnějších z těchto funkcí.

K již zmíněnému čtení informací v textové podobě na PC se používá tzv. Serial monitor. Ikonu pro jeho spuštění nalezneme v IDE v horním panelu s ikonami úplně vpravo (ikona s lupou). Po spuštění Serial monitoru musíme ještě nastavit rychlost komunikace pomocí rolovací nabídky v pravé dolní části. Ukažme si nyní, jak může Arduino komunikovat s PC právě přes sériovou linku a Serial monitor.

Poznámka: Větší desky (Mega, Due…) mají k dispozici více kanálů pro sériovou komunikaci a připojení dalších zařízení. Piny se pak jmenují: Rx1, Tx1, Rx2, Tx2… Jejich použití je popsáno zde. S počítačem ale komunikuje pouze jedna základní linka.

 

Zahájení komunikace – Serial.begin()

Tato funkce se používá k zahájení sériové komunikace. Do závorek se píše parametr rychlosti této komunikace, který odpovídá počtu přenosů za sekundu. Při komunikaci s PC ale tato rychlost není pouze na našem výběru. Může mít jen několik vyhrazených hodnot (300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 a 115200). Nejčastěji se používá hodnota 9600. Funkce Serial.begin() se většinou volá v části setup.

void setup(){
  Serial.begin(9600);
  
  Serial2.begin(9600); //pro Arduina s více sériovými linkami
}

 

Odeslání dat – Serial.print() a Serial.println()

Tyto funkce slouží k odeslání hodnoty z Arduina do PC, nebo jiného zařízení. Liší se od sebe tím, že funkce Serial.print() posílá data stále na jednom řádku. Funkce Serial.println() vždy na konci odeslaných dat přidá znak pro zalomení řádku. Rozdíl mezi těmito dvěma funkcemi můžete vidět na následujících příkladech.

//ukázka funkce Serial.print();
void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.print("abc ");
  delay(500);
}
//ukázka Serial.println();
void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.println("abc ");
  delay(500);
}

Při pohledu na použití těchto funkcí je jasné, že obě mají jeden povinný parametr, kterým je odesílaná hodnota. V praxi fungují tak, že se odesílá ASCII kód odesílaných znaků, který se poté v PC patřičně interpretuje. V ASCII tabulce znaků má malé ‚a‘ v desítkové soustavě hodnotu 97. Při volání funkce Serial.print(‚a‘) se tedy odesílá číslo 97 a až v PC dojde k jeho překladu. Serial.print() a Serial.println() mají ale ještě jeden nepovinný parametr. Ten může udávat buď typ odesílaných dat (v jaké soustavě se číslo ve výpisu zobrazí – DEC = desítková, OCT = osmičková, HEX = šestnáctková a BIN = dvojková), nebo počet desetinných míst (což je použitelné u datového typu float). Pokud u typu float neuvedeme počet desetinných míst, automaticky se odesílají pouze dvě místa. Pokud je to potřeba, čísla se zaokrouhlí.

Poznámka: O číselných soustavách si můžete více přečíst na české Wikipedii

//použití jednoho parametru
Serial.print(97); //vypíše: 97 
Serial.print(2.123456); //vypíše: 2.12
Serial.print('a'); //vypíše: "a"
Serial.print("ABCDEFGHIJ"); //vypíše: "ABCDEFGHIJ"

//použití nepovinného operátoru pro typ dat
Serial.print(97, DEC); //vrátí: 97
Serial.print(97, BIN); //vrátí: 1100001 (což je 97 ve dvojkové soustavě)
Serial.print(97, OCT); //vrátí: 141 (=97 v osmičkové soustavě)
Serial.print(97, HEX); //vrátí: 61 (=97 v šestnáctkové soustavě)

//použití nepovinného operátoru pro délku čísel
Serial.print(4.56789, 0); //vrátí: 5
Serial.print(4.56789, 1); //vrátí: 4.6
Serial.print(4.56789, 3); //vrátí: 4.568

Před chvílí jsem zmínil, že i znaky jsou přenášeny jako číslo, které jim odpovídá v ASCII tabulce znaků. Dá se s nimi tedy pracovat stejně, jako s čísly. Následující kód přenáší znak ‚a‘, kterému odpovídá hodnota 97 v různých soustavách.

Serial.print('a', DEC); //vrátí: 97
Serial.print('a', BIN); //vrátí: 1100001 
Serial.print('a', OCT); //vrátí: 141
Serial.print('a', HEX); //vrátí: 61

 

Čtení dat – Serial.available() a Serial.read()

Odesílání dat z Arduina již máme za sebou. Nyní se podíváme na možnosti čtení informací, které do Arduina posílá PC, nebo jiné zařízení. Nejdříve si musíme říci o tom, jak vlastně posílání dat vypadá na nejnižší úrovni. Když do Arduina přijdou informace po sériové lince, nezpracovávají se hned, ale jsou uchovány v „zásobníku“ (anglicky buffer). Ten dokáže uchovat až 64 bytů. Čtení poté probíhá tak, že se vezme první byte z bufferu, zpracuje se procesorem, jeho místo se uvolní a uchované byty se posunou dopředu. Poté se vezme další byte, zpracuje se atd.

Schéma bufferu

Buffer

Když chceme Arduinu odeslat nějakou hodnotu, nejjednodušším způsobem je napsat ji do textového pole v horní části Serial monitoru. Jelikož se odesílá ASCII hodnota znaků, má každý znak (i čísla) vlastní byte paměti.

Funkce Serial.available() a Serial.read() jsem dal dohromady, protože spolu souvisí a využívají se obě najednou. Jako první přichází na řadu funkce Serial.available(). Ta vrátí počet bytů, dostupných v bufferu. Poté dojde na funkci Serial.read(), která vezme první byte z bufferu a přečte ho. Zároveň dojde k vyjmutí bytu z bufferu, což se projeví snížením hodnoty Serial.available() při dalším čtení. Při spuštění následujícího skriptu a odeslání řetězce „AHOJ“ z PC do Arduina budou v bufferu obsazené 4 byty (za každý znak jeden). Všimněme si, že při vícenásobném odeslání řetězce se počet bytů v bufferu zvětšuje, protože stále nedošlo ke zpracování předchozích dat.

void setup(){
  Serial.begin(9600);
  Serial.println("Komunikace zahajena");
}

void loop(){
  Serial.print("V bufferu je nyni: ");
  Serial.print(Serial.available());
  Serial.println(" bytu.");
  delay(1000);
}

A nyní si ukažme použití funkce Serial.read(). V tomto příkladu čte Arduino byte po bytu buffer a vypisuje přijaté hodnoty zpět po sériové lince.

char prijato;

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

void loop() {
  if (Serial.available() > 0) {
    prijato = Serial.read();           
    Serial.print("Prijato: ");
    Serial.println(prijato);
  }
}

 

Ukončení komunikace – Serial.end()

Tato funkce se v praxi moc často nepoužívá. Při jejím volání ale dojde k ukončení sériové komunikace. Nepotřebuje žádný parametr.

Serial.end();

Serial1.end(); //u větších desek s více sériovými linkami

Poznámka: Existuje ještě řada dalších funkcí, které pracují se sériovou linkou. My jsme si představili ty nejzákladnější. Popis zbylých funkcí naleznete v jejich dokumentaci.

 

Cykly

Jistě si vzpomenete, že jsme se v minulých dílech dostali do situace, kdy jsme museli psát prakticky stejnou věc stále dokola, jen s menší obměnou (většinou to byla změna čísla). Pokud se při programování stane, že se nám něco pořád opakuje, přicházejí na řadu cykly. Existují tři druhy cyklů. Ty si teď popíšeme a vysvětlíme si rozdíly mezi nimi. Než se ale pustíme do vysvětlování, ukážeme si složené operátory, které se v cyklech (a nejen tam) často používají.

 

Složené operátory

Anglicky nazývané compound operators jsou operátory, které nám usnadní práci. Zkracují totiž zápis operací, kdy upravujeme hodnotu pouze jedné proměnné. Popišme si je na příkladech.

//sčítání
x = x + 2; //zvětšili jsme hodnotu x o 2
x += 2; //dosáhneme stejného výsledku s kratším zápisem

//odčítání
x = x - y; //od x odečteme hodnotu y a výsledek zapíšeme do x
x -= y; //výsledek je stejný

//na stejném principu funguje i násobení a dělení
x *= 20;
x /= 30;

Speciálním druhem těchto operátorů jsou x++ a x–. Ty použijeme tehdy, když chceme hodnotu proměnné snížit, nebo zvýšit pouze o 1.

x = 10;
x++; //x má nyní hodnotu 11
x--;
x--; //teď už má hodnotu 9

 

Cyklus while()

Všechny příkazy v cyklu se provádí, dokud je podmínka pravdivá. Za zmínku stojí, že program kontroluje platnost podmínky vždy na začátku cyklu, pokud je nepravdivá, cyklus skončí. Vyjádřeno slovy: „Pokud je podmínka pravdivá, udělej tohle a vrať se na začátek. Pokud není, skonči“. Cyklus while() se tedy nemusí provést vůbec. Používá se následující syntaxe:

while(podmínka){
	příkazy...
}

Příklad 1. – ukázka cyklu

boolean x = true;

void setup() {
  Serial.begin(9600);
  while(x){
    Serial.println("OPAKUJI");
    x = false; //cyklus se tedy provede jednou
  } 
}

void loop() {
  
}

Příklad 2. – výpis všech čísel od 0 do 99

byte x = 0;

void setup() {
  Serial.begin(9600);
  while(x < 100){
    Serial.println(x);
    x++;
  } 
}

void loop() {
  
}

 

Cyklus do…while()

Cyklus do..while() se od while() liší pouze v tom, že se podmínky kontrolují až na konci. Dříve tedy dojde k provedení příkladů a poté až ke kontrole podmínek. Slovně: „Udělej něco, a když platí podmínky, vrať se na začátek. Jinak skonči.“ V praxi to tedy znamená, že se tento cyklus provede minimálně jednou. Syntaxe je následující:

do{
    příkazy...
}while (podmínky); //<--všimněme si, že je zde na konci cyklu středník

Příklad 1. – ukázka cyklu

boolean x = true;

void setup() {
  Serial.begin(9600);
  do{
    Serial.println("OPAKUJI");
    x = false; //cyklus se také provede pouze jednou
  } while(x);
}

void loop() {
  
}

Příklad 2. – počítání od 0 do 99

byte x = 0;
 
void setup() {
  Serial.begin(9600);
  do{
    Serial.println(x);
    x++;
  }while(x < 100);
}
 
void loop() {
  
}

 

Cyklus for()

Tento cyklus se používá asi nejčastěji. Jedná se většinou o případy, kdy známe počet opakování cyklu. Také se od ostatních cyklů liší tím, že potřebuje mít pro svoji funkci vlastní proměnnou, která hlídá počet opakování.

for(inicializace proměnné a nastavení hodnoty; podmínka; operace prováděné při každém opakování){
	příkazy...
}

Příklad 1. – výpis čísel od 0 do 99

void setup() {
  Serial.begin(9600);
  for(int i = 0; i < 100; i++){
    Serial.println(i);
  } 
}
 
void loop() {
  
}

 

Příklad

V tomto díle si vytvoříme hada z pěti LED diod (počet je však volitelný) a ukážeme si, jak se dá cyklus for využít v praxi. Budeme potřebovat:

  1. Desku Arduino
  2. PC
  3. Nepájivé kontaktní pole s vodiči
  4. 5x 330 ohm resistor
  5. 5x LED diodu
byte led[] = {2,3,4,5,6}; //piny s LED diodami
byte pocet = 5; //počet diod
int rychlost = 1000; //jakou prodlevu mají jednotlivá; bliknutí

void setup() {
  for(int i = 0; i < pocet; i++){
    pinMode(led[i], OUTPUT); //nastavení pinů
  }
}
 
void loop() {
  for(int i = 0; i < pocet; i++){
    digitalWrite(led[i], HIGH);
    delay(rychlost/2);
    digitalWrite(led[i], LOW);
    delay(rychlost/2);
  }
}

V případě jakýchkoliv dotazů či nejasností se na mě neváhejte obrátit v komentářích.

Zbyšek Voda

27 Comments on “Sériová komunikace a cykly

Tominy
2.7.2017 at 13:49

Zdravím,
mám arduino nano připojené na něm mám 2x čidlo vlhkosti půdy. Mám napsán program kdy mi měří každé čidlo zvlášt a dle hodnoty píše Sucho, Mokro, Vlhko. Chtěl bych výppis který se mi zobrazuje na ser. lince zobrazovat na oled display I2C 1306 128×64 bohužel vůbec nevím jak napsat tento kód aby mi psalo to co se píše na ser.lince.

Zbyšek Voda
7.7.2017 at 20:45

Dobrý den, zkuste váš problém trochu rozvést na našem fóru. Třeba chybí informace o tom, jaká čidla používáte. Také prosím připojte aktuální kód.

STaRDuST
18.5.2017 at 15:29

Dobrý den. Chtěl bych se zeptat jak rozdělím program ve smyčce (void loop)? Dělám program jakoby simulaci bomby. Mám tam piezo buzzer udělaný tak aby tikal a mám k tomu RGB LEDpásky. Rozblikal jsem led pásky roztikal jsem piezo ale potřebuju aby to tikalo v průběhu celého programu přesně po sekundě jako sekundová ručička hodin nezávisle na tom co v loopu ještě probíhá dál. Tohle je můj zdrojový kód jak udělám to aby piezo tón tikal po sekundě i v případě že celkový průběh smyčky je delší než sekunda? Díky za pomoc

#define REDPIN 4
#define GREENPIN 3
#define BLUEPIN 2

#define FADESPEED 1
int piezoPin = 7;
int time1 = 1000;

void setup() {
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);

}

void loop() {
int r, g, b;

tone(piezoPin, 2, 500);
delay(time1);

for (r = 0; r 0; b–) {
analogWrite(BLUEPIN, b);
delay(FADESPEED);
}

for (g = 0; g 0; r–) {
analogWrite(REDPIN, r);
delay(FADESPEED);
}

for (b = 0; b 0; g–) {
analogWrite(GREENPIN, g);
delay(FADESPEED);
}
}

STaRDuST
18.5.2017 at 15:35

A ještě bych potřeboval udělat to že blikají barvy a tiká piezo a po půl minutě se to začne celé zrychlovat i blikání i tikání jako simulace blížícího se výbuchu a na konci tón + svítí červená a potom přijde výbuch (nějaký tón) pak bude dejme tomu 20s pauza a program začne odznovu. Byl bych moc vděčný kdyby mi takto někdo ten můj kór upravil případně poslal jiný. Klidně stačí v blikání střídat základní barvy červená, zelená a modrá v tom tikání po sekundě. Po půl minutě (až napočítá do 30ti) začne zrychlovat i blikání i tikání a na konci 10 sekund tón a svítí červená a potom tón a osvětlení zhasne (případně se rozsvítí žlutá) počká 20s a pak začne program znovu. Dělám to pro děti na Den otevřených dveří u nás. Děkuji

Zbyšek Voda
18.5.2017 at 16:02

viz moje předchozí reakce, jen budete postupně zkracovat dobu čekání.

Zbyšek Voda
18.5.2017 at 16:01

K tomuto se používá místo delay, které opravdu na nějaký čas zastaví běh programu, funkce millis(), popřípadě micros().
Tyto funkce vracejí hodnotu v ms/us od začátku běhu programu.

Algoritmus je naznačený třeba zde: https://bastlirna.hwkitchen.cz/arduino-zaklady-blikani-bez-funkce-delay/

Mirosku
24.2.2017 at 13:15

Ahoj, nevedeli by ste mi ppradiť? Mám Wemos D1 a pri správne nastavenej rýchlosti mi pri tomto kóde:
void setup() {
Serial.begin(9600);
Serial.println(„Ahoj, tu je Arduino“);
}
void loop() {
}
vypisuje do serialmonitoru nezmyselné znaky.
2DOz4`lMEŘ<B8Cü(ˇ˝©± tu je Arduino
Rýchlosť mám nastavenú správne.
Mám ešte niečo iné nastaviť alebo kde môže byť zrada?

Zbyšek Voda
24.2.2017 at 13:37

Zkuste po Seriál.begin dát nějaký krátký delay. Možná se nestačí nastartovat sériová linka a vy už něco posilate.

Mirosku
24.2.2017 at 13:44

Nepomohlo, ale všimol som si že už samotný Serial.bigin, iný riadok už v kóde nieje, vypíše tie nezmysly.

mat
12.1.2017 at 19:57

Nedaří se použít Cyklus while()

Dobrý den,
začínám si hrát s arduinem a snažím se testovat části kódu, které chci použít v připravovaném projektu ovládání okenních rolet.
Úspěšně jsem vyzkoušel hodiny s obvodem 3231 a knihovnou DS3231.h. Data z hodin bych rád použil také pro časování vysílače 433MHz (už také odzkoušen), který ovládá rolety. Tam musím opakovaně zadávat příkaz pro vyslání kódu po určitou dobu. Například pro úplné zatažení zhruba 16s. Snažil jsem se použít while, ale zatím neúspěšně. Po rúzných nezdarech vzniknul tento pokusný program s ladicími tisky(zatím neřeším přechod 59s>00s):

// pouziva se RX8025 pripojeny na I2C
int cas=0; //proměnná pro čas, kdy má končit cykl
int dobajizdy=5; //proměnná pro dobu trvání cyklu

#include //knihovna I2C
#include „DS3231.h“ //knihovna hodinoveho modulu

DS3231 hodiny; //objekt hodiny
.
.
.
void setup ()
{
Serial.begin(57600);
Wire.begin();
hodiny.begin();
}

void loop ()
{
DateTime now = hodiny.now(); //precte aktualni cas
.
.//v tomto miste pouze tisknu kompletni datum a cas
.
cas=now.second()+dobajizdy; //cas, kdy ma cyklus koncit

while (now.second()<cas)
{
DateTime now = hodiny.now(); //načte aktuální čas
Serial.print(now.second()); //vytiskne aktuální sekundy
Serial.print(':');
Serial.println(cas); //vytiskne sekundy, kdy má cykl končit
if (now.second()<cas)
{
Serial.println('<'); //pokud je aktuální čas menší než konečný, vytiskne ‚); //pokud je aktuální čas větší než konečný, vytiskne >
}

delay (500);
}
Serial.println(‚X‘); //po skončení cyklu vytiskne X
delay (5000);

}

Bohužel cyklus neskončí, přestože podle tisku nabývá podmínka všechny možnosti.
Část výpisu:

7:11
<
8:11
<
8:11
<
9:11
<
9:11
<
10:11
<
10:11

12:11
>
13:11
>
13:11
>
14:11
>

Zbyšek Voda
17.1.2017 at 11:26

Dobrý den, podařilo se vám problém nějak vyřešit?
Když se na to tak koukám, tak by cyklus měl normálně skončit. Nebude ale spíš problém v tom, že po skončení cyklu a dokončení funkce loop se loop spouští znovu a podmínky opět platí?

Asi budete muset přidat proměnnou, která bude informovat o stavu rolety -> po jejím zatažení se nastaví třeba na 1 a vy budete vědět, že už ji znovu zatahovat nemáte. Obdobně při vytažení se nastaví na 0, abyste věděl, že už ji nemáte vytahovat.

Pokud to nepomůže, tak prosím pošlete celý zdrojový kód a také větší část výpisu, ať z toho něco můžu vyčíst 🙂

Situaci byste si ulehčil, kdybyste na časování použil Arduino funkci millis(). Pak by část kódu pro zatažení rolety vypadala například takto:

long stopTime = millis() + dobajizdy;
while(millis() < stopTime){     zatahuj(); }

Robert
7.10.2016 at 12:54

Dobrý den , prosil bych o pomoc, jsme začátečník a potřebuji to do školy, je to jen základ.

Vytvořte program pro ovládání čtyř LED,které se budou postupně z jedné strany rozsvěcovat podle stoupajícího napětí na analogovém vstupu. Např. pro napětí menší než 1V nesvítí žádná LED, pro napětí 1 až 2 V svítí 1 LED, pro 2-3V svítí 2 LED, pro 3-4 V svítí 3LED a pro více než 4 V svítí 4 LED

Děkuju

Zbyšek Voda
7.10.2016 at 16:39

Dobrý den. Nasměruji vás.
Napětí můžete zjišťovat funkcí analogRead(), led rozsvěcet funkcí digitalWrite() a rozhodování jestli má nebo nemá led svítit můžete udělat pomocí podmínky if, ve které budete zkoumat hodnotu naměřenou funkcí analogRead() 🙂 ke všemu zmíněnému najdete informace tady na webu.

Petr
10.8.2016 at 17:17

Dobrý den, potřebuji odesílat z ATTINY85 = Digispark napětí načtené z AIN do serialmonitoru klasického Arduino IDE, kterým to i programuji. To u tohoto malého CPU nějak nejde přímo, údajně to jde nepřímo, nějakou SW berličkou. Chtěl bych použít pouze tu moji původní sestavu, žádné další HW a dráty. Můžete prosím pomoci? Můj SW má pouze několik řádků, místa moc nezabere.
Děkuji.
Petr

Zbyšek Voda
12.8.2016 at 12:16

Dobrý den.
Něco k této problematice naleznete zde a zde.

Petr
12.8.2016 at 14:25

Zdravím,
aha, tak to vše jsem samozřejmě pročetl, a mnoho dalšího, ale to mi nic nepomohlo.
Petr

Adam Blažek
9.7.2016 at 9:11

Dobrý den,
pěkný článek. Měl bych ale dotaz ohledně odesílání dat přes sériovou linku, řeším problém kdy odesílat více hodnot, např teplotu, tlak, atd a nevím jak na druhé straně identifikovat odeslané hodnoty. Nemáte nějaký nápad popřípadě kód pro inspiraci?
Děkuji, Adam Blažek.

Zbyšek Voda
11.7.2016 at 8:23

Dobrý den.
Můžete si například čísla ve zprávě oddělit pomocí dvojtečky a jednotlivé zprávy začínat středníkem.
Pak budete čekat na středník, po kterém budete vědět, že bude následovat několik informací oddělených dvojtečkou. K načtení těchto čísel se dá použít například funkcí parseInt() a parseFloat(), které načítají čísla, dokud se neobjeví jiný znak, než číslice (v našem případě dvojtečka). Pokud na druhé straně není Arduino, ale PC, určitě budou existovat obdobné funkce.

Jarmil
30.4.2016 at 11:42

Dobrý den měl bych opět jeden dotaz , nevím jak to udělat abych například obdržel hodnotu z analogového vstupu, zapsal ji do pole a potom opět vypsal z pole kod co mám nefunguje prosím mohl by jste mi poradit?

for (i=0; i<20; i =i+1) {
data = analogRead(A0);
digitalWrite(pole[i],data); // zde by se to mělo zapsat
delay(300);}

for (y=0; y < 20; y=y+1) {
led = (pole[y]); // zde vyčíst
if (led 100) {digitalWrite (13,LOW) ; }

Díky

Zbyšek Voda
2.5.2016 at 20:35

Dobrý den, musíte kód trochu poupravit

for (i=0; i<20; i =i+1) {
pole[i] = analogRead(A0);
delay(300);
}

for (y=0; y < 20; y=y+1) { if(pole[y] > 100){
led = HIGH;
}
else{
led = LOW;
}
digitalWrite (13,led);
}

Karel Jurkovič
25.3.2015 at 9:45

Ahoj – velice užitečný článek, díky za něj…
Mám však dotaz – ohledně kódování ?
V jakém kódování to arduino posílá po seriové lince pryč ? – co když potřebuji přenášet české znaky… ? Dá se zjistit typ kódové stránky, kterou arduino tedy používá, příp. ji změnit (např. na LATIN2) ?
Díky za info.

Zbyšek Voda
25.3.2015 at 16:03

Ahoj,
to je popravdě věc, kterou jsem nikdy nepotřeboval, takže o ní moc nevím.

Co jsem se ale dočetl je, že jak editor, tak sériová linka podporují UTF-8, čili i české znaky. Ve stejném článku ale píší, že monitor sériové linky ještě utf-8 nepodporuje.

Když si nechám vypsat pomocí Serial.write() všechny znaky s hodnotou od 0 do 255, tak se všechny české znaky zobrazí dobře. Když ale pošlu Serial.println(„ěščřžýáíé“), vrátí mi to ěščřžýáíé. Myslel jsem, že je to jen chyba serial monitoru, ale vypisují to i další dva sériové monitory.

Nenapadá mě tedy zatím jiná cesta, než přes výpis znaku pomocí jeho hodnoty.

Ještě by mohla pomoci tato diskuse.

Karel Jurkovič
20.4.2015 at 9:20

Ahoj díky za info,
nechal jsem si vypsat všechny znaky a ano – jsou tam všechny české písmena, dá se to posílat pomocí čísel odpovídající jednotlivým znakům (pro zájemce např. :
Serial.write(158);
Serial.write(154);
Serial.write(232);
Serial.write(248);
Serial.write(13);
:

…toto funguje a po seriové lince se soubory přenesou korektně…
KJ

Karel Čtvrtý
14.10.2015 at 14:05

To co píšete poukazuje na to, že Arduino IDE používá UTF-8, zatím co SerialMonitor používá nějaké 1bytové kódování, jste-li na Widlích, bude to nejspíš Windows-1250, protože to při vypisování znaků s kódy 0–255 napsalo české znaky (tzn. musí to být 1B kódování s českými znaky: Win1250 nebo Latin2) a při zobrazování těch znakových konstant se zobrazí místo správného znaku 2 znaky, tzn. 1 znak musel být 2bytový a interpretuje se přes 1B tabulku. Snad je to srozumitelné :-).

Karel Čtvrtý
14.10.2015 at 13:58

Arduino nepoužívá žádnou znakovou sadu, protože nemá žádný systém ani displej na kterém by musel binární informaci zobrazovat/reprezentovat znakem. Arduino prostě počítá jen s čísly.

Jaká „čísla“ (znaky) napíšeš do kódu (do znakových konstant a řetězců), taková „čísla“ (znaky) ti bude posílat zpět po seriové lince nebo do displeje. Až ten displej nebo seriový monitor (terminál) se pokusí ta čísla zobrazit a tedy přepsat podle nějaké znakové tabulky. Záleží teda pouze a jen na tom, jakou znakovou sadu si nastavíš v seriovém monitoru nebo jakou znakovou sadu používá připojený displej.

Ctirad Nešpor
4.1.2015 at 18:39

Mám dotaz, co když potřebuji přečíst data z PC delší než je buffer (64 bytů)? Potřebuji přenést informaci asi délce 128 bytů a po 63 to skončí.

Děkuji

Zbyšek Voda
4.1.2015 at 18:52

Pokud nejste programem schopný zajistit, aby byly informace uložené v bufferu dostatečně rychle odebírány a uvolnily tak místo dalším příchozím (tento postup není na kontrolu úplně nejvhodnější), musíte jít trochu jinou cestou. Řešil bych to asi tak, že bych vždy odeslal jen 64 bytů a po tom, co by Arduino všechny přečetlo, by do PC odeslalo nějaký response (stačí třeba poslat znak 1, nebo tak něco). Počítač pak budě vědět, že už může poslat dalších 64 bytů.

Snad bude rada užitečná 🙂

Napsat komentář