C# kód futtatása ESP32 mikrovezérlőn
Szakmai karrierem két meghatározó pontja a mikrovezérlők és a C#. Itt az ideje, hogy kombináljuk a kettőt 🙂
Tudom, vannak olyanok, akiket már a címtől kiráz a hideg. Másokban csak szimplán a „De minek?” kérdések fogalmazódnak meg, ám mielőtt megválaszolnánk a kérdést, egy pici gyorstalpalóval érdemes kezdeni.
Mikrovezérlők gyorstalpaló
A mikrovezérlők olyan mini számítógépek, amik integráltan egy chip-en belül tartalmaznak mindent, ami kell egy mikroszámítógéphez: ROM, RAM, CPU és I/O eszközök. Jellemzőjük, hogy beágyazott környezetre célirányosan fejlesztik őket. Ebből adódóan széles spektrumon mozog az alkalmazhatóságuk a képességeikkel együtt. Általánosan jellemző, hogy míg az asztali gépekben, vagy akár a telefonjainkban a memóriát GiB nagyságrendben mérjük, a tároló kapacitást meg a több száz GiB nagyságrendben, addig itt egy vezérlő ha már 1 MiB RAM-al és 8MiB belső tárolóval rendelkezik, akkor igencsak erősnek tekinthető. Ugyanez igaz a CPU órajelére is. A telefonjainkban ezt GHz nagyságrendben mérjük, itt azonban pár száz MHz nagyságrendről beszélhetünk, vagy kevesebbről.
A méltán népszerű Arduino Uno-ban használt vezérlő csupán 16MHz-es órajelen fut és 32KiB belső tárhoz 2KiB RAM párosul. A limitált hardver mégis sok mindenre képes. A hardver limitáltságából adódóan ezeket az eszközöket C vagy Assembly, esetleg limitált C++ nyelven programozzák.
Mivel limitált a hardver, mikrovezérlők esetén nem igen beszélhetünk operációs rendszerről. A futó programot firmware-nek nevezzük. Ez a firmware megvalósíthat operációs rendszer szerű feladatokat, pl. több szál egymás melletti futtatása, zárolás, stb…, de akkor sem egy teljes operációs rendszer.
De miért C# egy mikrovezérlőre?
C#-ot és egy mini .NET rendszert telepíteni akkor érdemes egy mikrovezérlőre, ha adott egy viszonylag erős vezérlő és ki szeretnénk használni a képességeit. Például ott az ESP32, amire Arduino segítségével is írhatunk kódot, de előbb-utóbb limitálni fog bennünket a nyelv, illetve több szál kezelésére lesz szükségünk, amihez vagy egy meglévő ütemezőt fordítunk a programunkba, vagy írunk egyet nulláról. Bármelyiket is válasszuk, nem kényelmes egy idő után, illetve pont az Arduino „szinte minden ott van készen” előnyét veszítjük el.
Természetesen ha csak I/O lábakat kell kapcsolgatnunk, vagy nincs bonyolult logikánk, akkor egy ESP32 és a C# is ágyúval a galambra szituáció, de ugyanez elmondható, ha MicroPython-t választunk ilyen célra.
MicroFramework, nanoFramework
A Microframework nagyjából a .NET 4-el egy időben jelent meg. Eredetileg ST mikrovezérlőkre szánták, de a moduláris felépítésének köszönhetően elméletben átpakolható volt bármilyen architektúrára, ha a használt vezérlőhöz elkészítették az absztrakciót. Gyakorlatban ez nem történt meg sosem, mivel a .NET Core került fókuszba. Ezt követően a Microframework nyílt forráskódúvá vált. Ennek a továbbfejlesztése, továbbgondolása a nanoFramework.
ESP32
Az ESP32 egy olcsó kis mikrovezérlő platform, ami kifejezetten IoT alkalmazásokhoz lett kitalálva. Bluetooth és Wi-Fi kapcsolódásra képes, hardverből tud HTTPS használatához szükséges titkosításokat és hash algoritmusokat. Ezt egy 240MHz-en futó CPU oldja meg. Tárhely tekintetében 4 vagy 8MiB Flash szokott rendelkezésre állni.
Maga az ESP32 modulként kapható. Ezt a modult kell egy környezetbe építeni. A modul kivitel oka a Wi-Fi és Bluetooth antennákhoz kapcsolódó szabványok és előírások. Millió egy gyártó készít erre a modulra épülő vezérlőlapokat.
A cikk írásához egy NodeMcu-hoz hasonló ESP32 lapot használtam, amit még a Pandémia előtt ~3000Ft-ért vásároltam az eBay-en, de ahogy nézem, a chiphiány nem igen érintette az árakat.
Vágjunk bele!
Ahhoz, hogy érdemben foglalkozni tudjunk a nanoFramework-kel, szükségünk lesz egy támogatott vezérlőre, egy USB kábelre, Visual Studio 2022-re és .NET 6-ra. A nanoFramework működéséhez egy minimális CLR firmware-t kell feltöltenünk a kiválasztott lapunkra.
Ennek kapcsán megjegyezném, hogy az ESP32 lapon található USB port nem valódi USB port, csupán egy USB – Serial (RS232) átalakító. Így a firmware feltöltéséhez tudnunk kell a soros port számát, illetve szükségünk lesz egy illesztőprogramra is. Ha szerencsénk van, akkor a Windows rendelkezik vele, vagy Update-ről be tudja szerezni. Rosszabb esetben azonban nekünk kell letölteni a gyártó weboldaláról. Szerencsére az eszközkezelő ad némi támpontot.
Jelen cikk írásához használt ESP32 modulon egy Silicon Labs által gyártott CP210x van, amihez az illesztőt a gyártó oldaláról könnyen be tudtam szerezni. Ha mindent jól csináltunk telepítés után, akkor az eszközkezelőben egy újabb soros portnak kellene felbukkannia.
Ezt követően szükségünk lesz egy Powershell vagy cmd ablakra, amiben az alábbi parancs kiadásával le tudjuk tölteni a firmware feltöltéséhez szükséges programozót:
dotnet tool install -g nanoff
Ha ez települt, akkor feltölthetjük a firmware-t. Az én esetemben ehhez az alábbi parancsot kellett kiadnom:
nanoff --platform esp32 --serialport COM3 --update --preview
A parancs kiadása azonban kevés lesz. Ugyanis az ESP32 lapok többsége kód fogadására csak akkor képes, ha a BOOT jelzésű gomb lenyomva tartása mellett a RESET gomb megnyomásával újraindítjuk a mikrovezérlőt, ami ilyenkor bootloader üzemmódba vált és fogadja a kódot.
Ha minden jól megy, akkor valami ilyesmi kimenetet kellene kapnunk egy idő után:
.NET nanoFramework Firmware Flasher v2.0.9+947a088d7c
Copyright (C) 2019 .NET Foundation and nanoFramework project contributors
Using COM3 @ 1500000 baud to connect to ESP32.
Reading details from chip...
OK
Connected to:
ESP32 (ESP32-D0WDQ6 (revision 1))
Features WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Flash size 4MB GD25Q32 from GIGADEVICE (manufacturer 0x200 device 0x16406)
PSRAM: not available
Crystal 40MHz
MAC B4:E6:2D:86:54:1D
No target name was provided! Using 'ESP32_REV0' based on the device characteristics.
Trying to find ESP32_REV0 in development repository...OK
Downloading firmware package...OK
Extracting ESP32_REV0-1.7.4-preview.1.zip...OK
Updating to 1.7.4-preview.1
Erasing flash...
OK
Flashing firmware...
Wrote 24192 bytes (15088 compressed) at 0x00001000 in 0.4 seconds (effective 468.5 kbit/s)...
Hash of data verified.
Wrote 1070592 bytes (704819 compressed) at 0x00010000 in 10.8 seconds (effective 791.5 kbit/s)...
Hash of data verified.
Wrote 3072 bytes (136 compressed) at 0x00008000 in 0.2 seconds (effective 113.2 kbit/s)...
Hash of data verified.
OK
A firmware feltöltés után jöhet a Visual Studio, amihez telepítenünk kell egy bővítményt, hogy ténylegesen tudjunk kódot fordítani a nanoFramework-re. A kiegészítő a Visual Studio Marketplace-ről ingyenesen beszerezhető .NET nanoFramework Extension néven.
A kiegészítő telepítése után tudunk nanoFramework projektet létrehozni.
Hello, World!
Az előkészületek után belevághatunk a mikrovezérlős helló világ program elkészítésébe. A „Create a new project” ablakban válasszuk a Blank Application (nanoFramework) opciót.
A projekt létrejötte után első utunk a NuGet csomagkezelőbe kell, hogy vezessen, mivel a nanoFramework minden komponense NuGet csomag formájában van terjesztve. A LED villogtatásához a nanoFramework.System.Device.Gpio
csomagra lesz szükségünk. Ennek a telepítése után az Updates fülön jelöljük be az „Include prerelease” opciót, majd frissítsünk minden csomagot a legújabbra.
Ha ezt elmulasztjuk, akkor a feltöltés biztos sikertelen lesz, mivel a firmware-t a --preview
opcióval telepítettük, ami a legfrissebbet jelenti. A legfrissebbre pedig azért van szükségünk, mert a korábbi „stabil” firmware annyira stabil, hogy feltölteni az esetek többségében nem hajlandó.
Ha ezen túl vagyunk, akkor meg is írhatjuk az LED villogtató programunkat. Ehhez egy LED-et kellene az eszköz valamelyik kimenetére kötnünk, de használhatjuk a panelen találhatót is. Ez ESP32 lapok esetén vagy a 2-es vagy a 4-es GPIO lábra van kötve. Az én panelem esetén ez a 2-es lábon volt található. A villogtató kód:
using System.Device.Gpio;
using System.Diagnostics;
using System.Threading;
namespace NFApp1
{
public class Program
{
private static GpioController _gpio;
public static void Main()
{
Debug.WriteLine("Hello from nanoFramework!");
_gpio = new GpioController();
var led = _gpio.OpenPin(2, PinMode.Output);
led.Write(PinValue.Low);
while (true)
{
led.Toggle();
Thread.Sleep(250);
}
}
}
}
A GpioController
a GPIO vezérlésért felelős. Ennek példányosítása után az OpenPin
metódussal tudunk ténylegesen egy I/O lábat megszólítani. Az első paraméter a port száma, a második paraméter pedig az I/O típusa. Jelen esetben ez kimenet lesz.
A Write
metódussal tudunk egy értéket írni a kimenetre, amit kezdetben kikapcsolt állapotról indítunk, majd a végtelen ciklusban a Toggle()
metódussal megfordítjuk a kimenet állapotát és ezt követően a Thread
osztály Sleep
metódusával várakozunk 250ms-ot.
A kód megírása után jöhet a kód fordítása és feltöltése. Fordítani ugyanúgy tudunk, mint egy normál framework alkalmazás esetén. Feltöltéshez pedig a Device Explorer-re lesz először szükségünk. Ezt a nanoFramewrok kiegészítője hozza magával a Visual Studio-ba és az „Other Windows” menüben találjuk meg.
Itt fel kellene bukkannia az eszközünknek. Ha kiválasztottuk az eszközt, akkor a „Solution explorer”-be navigáljunk át és a projekten válasszuk a Deploy lehetőséget.
A feltöltés itt is egy kis időt vesz igénybe, de ha minden jól ment, akkor az Output ablakban azt kellene látnunk, hogy sikerrel járt a folyamat. Ezt követően laptól függően szükségünk lehet a RESET gomb megnyomására az eszközön, ezt követően a LED villogni kezd.
Ha a programot az eszköztárról elérhető debug módban indítjuk, akkor valódi hardveres hibakeresést és debug lehetőséget kapunk. Ez viszont tényleg nem a leggyorsabb futást fogja eredményezni, cserébe viszont a „Debug output” ablakban látni fogjuk a „Hello from nanoFramework!” üzenetet is, amint futni kezd a programunk.
Hibaelhárítás
- Ha a feltöltés nem sikerül, akkor esetleg próbáljunk ki egy másik kábelt. Rengeteg kábelből kispórolják az anyagot, ami feszültségesést eredményez a fogadó oldalon. Ez pedig kommunikációs hibákban nyilvánul meg.
- Ha a LED nem villog, akkor valószínűleg nem a megfelelő GPIO portot adtuk meg, de az is lehet, hogy nem indítottuk újra a lapot.
Összegzés és további olvasnivalók
A nanoFramework kiválóan alkalmas komplex firmware fejlesztésre, ha van hozzá megfelelő hardverünk.
További olvasnivalónak a nanoFramework dokumentációját és a minta forráskódjaik GIT tárolóját érdemes nézegetni, a használt mikrovezérlő dokumentációja mellett. Ha esetlegesen nagyon új a mikrovezérlős téma, akkor ajánlom a korábbi könyvemet, a Programozható elektronikákat. Ebből véleményem szerint egész jól meg lehet tanulni mindent, amit érdemes tudni a mikrovezérlőkről.
Mezősi Norbert
2022.02.12. @ 10:10
Nagyon örülök a témának, remélem lesz rá érdeklődés, és lesz folytatása.
Jaskó László
2022.02.18. @ 09:12
Van egy egész dobozom tele mindenféle hülyeséggel, mini OLED display-től elkezdve Arduino-kig minden. Azért nem foglalkoztam vele, mert tényleg semmi kedvem ArduinoIDE-ben fejlesztgetni, meg nyelvet tanulni.. de ez, hogy a fő nyelvemen (C#) tudok fejleszteni ilyesmire, meghozta a kedvem!
Magyarországról hol lehet rendelni ilyet? Esetleg egy linket dobhatnál be.
Ruzsinszki Gábor
2022.02.20. @ 11:39
A bejegyzésben ott van egy ebay link. Magyar forgalmazót nem ismerek (mindig külföldről veszek)
Jaskó László
2022.02.21. @ 14:37
Köszönöm! Amúgy találtam itthon is hosszas keresgélés után, meg is rendeltem, viszont nem tudom, szabad-e linkelni, úgyhogy csak az online bolt nevét írom le, hátha valakit érdekel és nem talál (mint én): hestore(dot)hu
Jaskó László
2022.02.23. @ 11:20
HeStore-os NodeMCU-ESP-32S-ról írnék tapasztalatot.. van a boardon két gomb, az egyik egyik BOOT feliratú (bár nálam OOT volt, lekopott a B betű mindkét számomra elküldött lapról).. ezt a gombot nem egyszer kell csak lenyomni, hanem VÉGIG NYOMVATARTANI amíg a firmware frissítő parancs lefut, ha nem így teszünk, akkor „A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.” üzenetet kapunk, és nem sikerül a flash-elés. Tehát mielőtt leütjük az ENTER-t, benyomjuk a kis boot gombot, és végig nyomvatartjuk a programozás alatt. Máshogy nem ment nekem egyik lapkával sem!
Jaskó László
2022.02.23. @ 11:31
Sőt, elnézést kérek, nem végig kell nyomvatartani, hanem így kell:
1) USB tápot adsz
2) beírod a parancsot, majd benyomod a gombot mielőtt ENTER-t ütsz.. kiíírja, hogy
Using COM3 @ 1500000 baud to connect to ESP32.
Reading details from chip…
3) elengeded a gombot, különben nem is hajlandó tovább lépni.. kiolvassa a chip adatait:
Connected to:
ESP32 (ESP32-D0WDQ6-V3 (revision 3))
Features WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Flash size 4MB unknown from (manufacturer 0x104 device 0x16406)
PSRAM: not available
Crystal 40MHz
MAC 30:C6:F7:29:59:B8
No target name was provided! Using ‘ESP32_REV3’ based on the device characteristics.
Trying to find ESP32_REV3 in development repository…OK
Extracting ESP32_REV3-1.7.4-preview.59.zip…OK
Updating to 1.7.4-preview.59
Erasing flash…
4) itt benyomod gyorsan a BOOT gombot újra.. kíírja, hogy
OK
Flashing firmware…
5) itt megint gyorsan benyomod a BOOT gombot, kiiírja, hogy:
Flashing firmware…
Wrote 23712 bytes (14951 compressed) at 0x00001000 in 0.3 seconds (effective 758.7 kbit/s)…
Hash of data verified.
Wrote 1026272 bytes (673705 compressed) at 0x00010000 in 8.1 seconds (effective 1008.5 kbit/s)…
Hash of data verified.
Wrote 3072 bytes (136 compressed) at 0x00008000 in 0.1 seconds (effective 312.9 kbit/s)…
Hash of data verified.
OK
6) kész vagy.
Én jól megszívtam mire rájöttem a menetére, nektek már nem kell, csak kövessétek pontosan a leírásom! Úgy tűnik, ez a NodeMCU nem marad boot módban, ha elengedjük a boot gombot, ezért minden egyes írási műveletnél nyomogatni kell sajnos, hogy a nano firmware flasher úgy érzékelje, hogy írható a chip.
Remélem segítettem!
Jaskó László
2022.02.23. @ 23:16
A LED villogtatás összejött.. összekapcsoltam egy kis OLED kijelzővel, de nem bírom rávenni, hogy kirajzoljon bármit is. Tud valaki segíteni? Ssd1306-os, nem találok a neten sehol példakódot, csak arduino-val.
Jaskó László
2023.03.25. @ 22:21
Elszállt több, mint egy év az utolsó hozzászólásom óta, azóta változott a keretrendszer is párszor.
A lényeg, hogy ez a parancs már nem működik helyesen, mert 1.7.x verziót akar telepíteni: nanoff –platform esp32 –serialport COM3 –update –preview
A preview-t azóta nem használják már, elavult, helyette a megfelelő parancs ugyanaz csak azon kapcsoló nélkül és a v1.8.x-et telepíti, helyesen tehát:
nanoff –platform esp32 –serialport COM3 –update