Říkáš si, že poslat si nějaký text do sériové konzole (Arduino IDE, YAT, Putty) je jednoduché a není možné, aby tam něco nefungovalo? Nebo komunikovat s čidlem přes UART? No, v tomto článku upozorníme na nejčastější chyby a problémy – ať je to špatná rychlost, přehozené piny nebo například to, jak si vypsat data z vývojové desky, která nemá USB-UART převodník na desce nebo jak se pro komunikaci používá ten nativní v ESP32-C3.
Mezi nejčastější důvody, proč „jak to, že mi to nic nepíše do terminálu?“ nebo „proč to čidlo přes UART nefunguje?“ patří například:
Špatně nastavená rychlost.
Komunikace s počítačem: V začátcích Arduino se ve výchozím nastavení používalo 9600 Bd. To byla i výchozí rychlost třeba pro ESP8266. S příchodem ESP32 a novějších Arduino desek byla poptávka po rychlejším přenosu dat a tak vzniklo nepsané pravidlo, že vyšší rychlost bude 115200. No jo! Ale ty starší vzorové kódy už nikdo neupravil. A tak v některých kódech můžeš najít Serial.begin(9600), jinde Serial.begin(115200) a samozřejmě se najdou i ti, co používají něco jiného. Pokud bys potřeboval externí USB-UART převodník, tak máme.
Komunikace s čidlem: Každé čidlo může mít jinou přenosovou rychlost – 9600, 19200, 38400 nebo i 115200. Je to na čidle, proto použij ověřené knihovny se vzorovými kódy a přelouskej datasheet 🙂 U čidel i kontroluj správný typ paketu – počet bitů, parita, počet stop bitů.
Prohozené RX a TX: Zatímco u I2C se připojuje SDA na SDA a SCL na SCL, u UART to tak není.
RX jednoho zařízení se připojí na TX druhého, a TX prvního zařízení se připojí na RX druhého.
K tomu se váže i to, aby napěťové úrovně obou čipů byly stejné – nejčastěji tedy 3.3 nebo 5V.
Pokud nejsou, můžeš použít převodník.
(Ne)Definované piny: RX a TX piny vývojových desek respektive čipů jsou zpravidla jasně daná a nelze je měnit.
V Arduino IDE jsou výchozí(programovací) UARTy běžně v knihovnách vývojových desek už definovány a není potřeba je nějak explicitně určit/měnit/upravovat. Opačný případ je, pokud v nějakém projektu s ESP32/Arduino Uno/atd je potřeba použít druhý UART, který není výchozím, nebo používáš nějakou neobvyklou desku s neobvyklým zapojením (to bývá velmi zřídka).
Pak je potřeba zkontrolovat dokumentaci k desce a zjistit, kde a jak jsou zapojeny.
V případě potřeby druhého UARTu se volí mezi možností použít hardwarovým (pokud jej čip podporuje) nebo softwarovým.
Definování softwarové verze UART záleží na dané knihovně pro daný kontrolér, podívej se na její vzorové příklady.
U hardwarového UARTu je pak nutné použít následující kód (čip musí mít více hardwarových UARTů).
#include <HardwareSerial.h>
HardwareSerial HW_Serial1(1);
HW_Serial1.begin(115200, SERIAL_8N1, XX, YY); // 115200 – rychlost; SERIAL_8N1 – typ paketu; XX je číslo pinu pro RX a YY je číslo pinu pro TX – katalogový list výrobce.
HW_Serial1.println(„HW UART“); // odeslání dat přes HW UART
Praktický příklad můžeš vidět níže, deska s ESP32 má dva fyzické UARTy 0 a 2. V nastavení Arduino IDE by měl být ve výchozím nastavení definován U0 – UART0 (TX – IO1, RX – IO3) – ten je určen pro nahrávání kódu. U2/UART2 pak TX – IO17 a RX – IO16 – ten můžeš použít při komunikaci s nějaký čidlem, například.
UART2 definujeme sami, tedy:
#include <HardwareSerial.h>
HardwareSerial HW_Serial(0);
void setup() {
HW_Serial.begin(115200, SERIAL_8N1, 16, 17); // 115200 – rychlost; SERIAL_8N1 – typ paketu; 16 je číslo pinu pro RX a 17 je číslo pinu pro TX.
}
void loop() {
HW_Serial.println(„test“);
delay(1000);
}
Více zařízení využívá stejný UART: Na jeden UART by měly být připojeny dvě zařízení (například programátor a čidlo by používalo UART0).
Jsou případy, kdy jeden – hlavní – posílá příkazy a ostatní – vedlejší – je jen poslouchají a už nedopovídají, aby nedošlo ke kolizi – to je ale specifický případ, který tu nebudeme detailněji popisovat.
Deska používá nativní/vestavěné USB: A dostáváme se k bodu, který nás přiměl sepsat tento článek 🙂 Naše deska LaskaKit ESP32-DEVKit má vestavěný USB-UART převodník jako programátor přímo na desce. Ten je připojený na piny, které jsou výchozí pro UART a Arduino IDE to ví. V Arduino IDE tedy stačí definovat UART jako
Serial.begin(115200);
a kompilovat jako ESP32 DEV Module to je všechno. Arduino ví, kam je UART připojený a automaticky provede správnou inicializaci a všechno funguje. UART je totiž připojený do USB-UART převodníku na desce.
Máme ale i desky (LaskaKit ESP32-C3-LPKit a LaskaKit microESP), které jsme chtěli co nejmenší, a tam by další čip (USB-UART převodník) a součástky okolo něj, zabíraly mnoho místa a tak jsme využili nativní/vestavěný USB, který se používá (může používat) i pro programování a zároveň pro posílání dat (tváří se jako COM port – Seriový port)
Desku kompilujeme jako ESP32-C3 DEV Module, ale použití Serial.begin(xxxx) už má pravidla -> viz níže.
Tak jak?
Nastavení: Používáme (v době psaní článku) poslední verzi ESP knihovny 3.0.4 – oproti starší 2.0.xy doznala několik významných změn a mezi nimi je i použití Serial.
Pro verzi ESP knihovny 3.0.x, platí:
Pokud je Tools -> USB CDC On Boot ZAKÁZANÝ potom Serial znamená výstup na UART (piny na hřebínku – nutnost použít externí USB-UART převodník).
V případě, že Tools -> je USB CDC On Boot POVOLENÝ potom Serial znamená výstup na nativní USB (USB konektor). A tady může nastat komplikace pokud používáš „čekaní na inicializaci USB“, tedy:
while(!Serial);
Pokud máš USB CDC On Boot POVOLENÝ, ale desku nepřipojíš do počítače, zůstane program čekat v této smyčce.
Bastlíři si běžně nechávají vypisovat data na Serial Monitor aniž by měli desku připojenou do počítače (připojí se jen když je potřeba) – to je přesně moment, kdy může vzniknout problém.
Desky s ESP32-C3 kompilujeme jako ESP32-C3 DEV Module (nastavení Arduino IDE).
Povolíme v nastavení možnost „USB CDC On Boot“
Když je USB CDC On Boot POVOLENÝ, pak vypisuje přes nativní USB (COM port)
Serial.begin(xxxx);
ale pokud je USB CDC On Boot ZAKÁZANÝ, pak Serial vypisuje na UART (máme vývody na hřebínku).
Zároveň v kódu nepoužíváme while(!Serial); protože by ESP32 bez připojení k počítači zůstal v této podmínce viset navždy.
Vzorový kód pro práci s nativním USB a komunikací s počítačem (COM port)
void setup() {
Serial.begin(115200);
Serial.println(„ESP32-C3 USB-CDC USBSerial test“);
}
void loop() {
Serial.println(„LaskaKit“);
delay(2000);
/* Pokud chces uspat cip*/
//Serial.flush();
//esp_sleep_enable_timer_wakeup(PocetSekund * 1000000);
//esp_deep_sleep_start();
}
Pro ESP knihovny 2.0.xy se používá příkaz USBSerial.begin().
Doufáme, že ti tento článek přinesl očekávané informace. Budeme rádi, když nám tu necháš nějaký další nápad 🙂