Raspbery Pi Pico W 2023
Nechal jsem se zlákat lákavou cenou, a pořídil na Aliexpressu dvě vývojové desky, které se tvářily jako 1:1 klon Raspbery Pi Pico W, avšak skutečnost byla poněkud jiná. Oproti originálu tento klon pro komunikaci WiFi používá MCU ESP8285 (vylepšená obdoba ESP8266), který s hlavním MCU RP2040 komunikuje pomocí UART a AT příkazů. Výhodou proti originální desce je osazený USB-C konektor.
Potíže s dokumentací
Snažil jsem se na webu najít, jak s touto deskou pracovat, a co se týká samotného programování, bez využívání WiFi, je to celkem jednoduché. Deska je prakticky 100% kompatibilní s originálním Raspbery Pi Pico bez WiFi rozšíření, s plnou podporou programování v Pythonu i v Arduino IDE. Komplikace nastávají, pokud chci najít, jak využít její trochu atypické WiFi rozšíření. Co vypadalo slibně bylo to, že je deska ohledně WiFi koncipovaná podobně jako Challenger RP2040 WiFi, a zde jsou také k dispozici nějaké rady, jak s WiFi zacházet v Arduino IDE. Nicméně po nějakém dalším pátrání se mi mezi velmi chaotickými informacemi podařilo vypátrat (na fóru o tomto klonu), že WiFi modul je u mé desky připojen jednoduše k HW portu UART0 (piny GP0, GP1), který se v IDE dá jednoduše definovat jako Serial1, a pak s ním lze naprosto jednoduše komunikovat. Jednoduchý program pro testování modemu jsem pak našel ZDE, dle něj je pak vytvořen i kód, který přikládám níže v odstavci TESTOVACÍ APLIKACE.
Přidání podpory vývojové desky do IDE
S testovací aplikací jsem ale poněkud přeskočil postup, takže se vraťme trochu zpět. Pro desky s MCU RP2040 sice lze do IDE doinstalovat podpora přímo od Arduina (nakonec i jejich originální deska Arduino Nano RP2040 Connect je založena na tomto MCU), avšak jako nejvhodnější (a nejstabilnější) je komunitou doporučována podpora od Earle F. Philhower, která má široké portfolio podporovaných desek tohoto typu i nálož příkladů kódu pro různé účely.
Upload firmware modemu
Na fóru o potížích s klonem jsem nabyl dojmu, že se autoři příspěvků potýkali s tím, že ESP8285 nereagoval na AT příkazy, a nejdřív do něj bylo nutné nahrát nějaký FW. Já jsem takové potíže ale neměl, a jakmile jsem pochopil, jak je provedené propojení mezi RP2040 a modemem s ESP8285, pomocí testovací aplikace mi modem na příkazy korektně odpovídal bez nutnosti zavádění FW (ESP již obsahovalo FW SDK V2.2.1 z dubna 2018). Pokud by však bylo z nějakého důvodu třeba zavést (např. upgradovat) jiný FW, lze k tomu využít postupu uvedeného ZDE, popř. zde či zde.
Dokumentace ohledně dostupných AT příkazů lze najít na různých místech, je zřejmě vhodné vycházet z dokumentace pro konkrétní verzi, která je v ESP8285 zavedena. Alternativy jsou v následujících odkazech:
Dokumentace Espressif / ESP32 / ESP8266 / esp AT na Github
Knihovna pro komunikaci s WiFi modemem
Pro nějakou složitější komunikaci v bezdrátové síti je vhodné do IDE doinstalovat knihovnu, která tuto komunikaci usnadní a současně do IDE přidá i nějaké příklady, z kterých lze při vlastním programování vycházet či se na nich učit. Pro tento účel je vhodná knihovna WifiEspAT.
Odkazy:
https://github.com/earlephilhower/arduino-pico/issues/475
GEMINI: raspberry pi pico w klon s esp8285 / arduino pico
TESTOVACÍ APLIKACE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
// Test komunikace RP2040 s WiFi modulem ESP8285 // Návrh pro klon Raspbery Pico W 2023 // ======================================================== void setup() { Serial.begin(9600); // UART pro komunikaci USB Serial1.begin(115200); // UART pro komunikaci s ESP8285 (WiFi modem) delay(3000); Serial.println("Inicializace spojení..."); } void loop() { if(Serial.available()>0) { char c = Serial.read(); Serial1.print(c); } if(Serial1.available()>0) { char c = Serial1.read(); Serial.print(c); } } /* --------------------------------------------------------------- Pár příkladů zadaných příkazů v sériovém monitoru vč. odpovědí --------------------------------------------------------------- AT+GMR AT version:1.6.2.0(Apr 13 2018 11:10:59) SDK version:2.2.1(6ab97e9) compile time:Sep 10 2019 17:31:08 OK (pozn: před připojením k WiFi je třeba nejdřív nastavit mód modemu) AT+CWMODE_CUR=3 OK AT+CWJAP_CUR="moje_ssid","moje_pwd" WIFI CONNECTED WIFI GOT IP OK AT+CIFSR +CIFSR:APIP,"192.168.4.1" +CIFSR:APMAC,"c6:4f:33:df:16:7b" +CIFSR:STAIP,"192.168.0.47" +CIFSR:STAMAC,"c4:4f:33:df:16:7b" OK AT+UART? +UART:115273,8,1,0,1 OK */ |
Vzorová aplikace (webserver)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
/* Výchozí kód: WiFiEsp example: WebServer Upraveno pro RP2040 Pico W-2023 A simple web server that shows the value of the analog input pins via a web page using an ESP8266 module. This sketch will print the IP address of your ESP8266 module (once connected) to the Serial monitor. From there, you can open that address in a web browser to display the web page. The web page will be automatically refreshed each 20 seconds. For more details see: https://yaab-arduino.blogspot.com/p/wifiesp.html */ #include "WiFiEsp.h" char ssid[] = "xxx"; // your network SSID (name) char pass[] = "xxxx"; // your network password int status = WL_IDLE_STATUS; // the Wifi radio's status int reqCount = 0; // number of requests received WiFiEspServer server(80); void setup() { // initialize serial for debugging Serial.begin(115200); // initialize serial for ESP module Serial1.begin(115200); // initialize ESP module WiFi.init(&Serial1); // check for the presence of the shield if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue while (true); } // attempt to connect to WiFi network while ( status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network status = WiFi.begin(ssid, pass); } Serial.println("You're connected to the network"); //delay(3000); printWifiStatus(); // start the web server on port 80 server.begin(); } void loop() { // listen for incoming clients WiFiEspClient client = server.available(); if (client) { Serial.println("New client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { Serial.println("Sending response"); // send a standard http response header // use \r\n instead of many println statements to speedup data send client.print( "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" // the connection will be closed after completion of the response "Refresh: 20\r\n" // refresh the page automatically every 20 sec "\r\n"); client.print("<!DOCTYPE HTML>\r\n"); client.print("<html>\r\n"); client.print("<h1>Hello World!</h1>\r\n"); client.print("Requests received: "); client.print(++reqCount); client.print("<br>\r\n"); // output the value of analog input pins for (int analogChannel = 0; analogChannel < 4; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } client.print("Teplota MCU: "); client.print(analogReadTemp()); client.print("°C<br>\r\n"); client.print("</html>\r\n"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(10); // close the connection: client.stop(); Serial.println("Client disconnected"); } } void printWifiStatus() { // print the SSID of the network you're attached to Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print your WiFi shield's IP address // IPAddress ip = WiFi.localIP(); Příkaz nefunguje, pokud je ponechán, program se zde kousne Serial.print("IP Address: "); Serial.println("ip"); // proměnná vložena do uvozovek // print where to go in the browser Serial.println(); Serial.print("To see this page in action, open a browser to https://"); Serial.println("ip"); // proměnná vložena do uvozovek Serial.println(); } |
