ESP - WeMos
Здравствуйте.
В статье описана работа с платой ESP D1 mini (она же WeMos D1 mini, она же LOLIN D1 mini) и файловой системой SPIFFS.
Вначале о разновидностях плат…
непременно ознакомьтесь
WeMos D1 (не mini)
Эта плата существует в двух ревизиях — WeMos D1 R1 и WeMos D1 R2. Различия заключаются в распиновке…
R1
R2
WeMos D1 mini
Может быть в таком исполнении…
А может быть в таком…
Есть ли на плате надпись «WeMos» или нету, не имеет значения, чипы везде стоят одни и те же.
По сути это одинаковые девайсы, разница лишь в том, что в первом вариантечип и spi-flash находятся под железкой на отдельной платке, а во втором всё распаяно на основной плате. Чип может быть esp8266 или esp8285, об этом ниже.
spi-flash она же внешняя флешь-память, это вот такая «козявочка»…
WeMos D1 mini Lite
Отличается от предыдущих отсутствием внешней spi-flash, и расположением всех компонентов на одной стороне. Установлен чип esp8285 (см.ниже).
WeMos D1 mini Pro
Как и у предыдущей платы все компоненты расположены на одной стороне, а так же есть spi-flash, керамическая антенна• Rainsun и разъём для внешней антенны.
Ещё есть вот такая D1 mini Pro (LOLIN)
У неё 16М spi-flash и интерфейс для зарядки аккумулятора.
Чипы esp8266 и esp8285
У чипа esp8266 отсутствует flash-память, поэтому применяется внешняя spi-flash (флешь-память работающая по SPI). Часть этой памяти используется для хранения прошивки, в IDE Arduino это обозначается так…
… а оставшуюся часть пользователь может использовать под свои нужды, например, хранить там файлы, которые отдаёт веб-сервер (.html, .css, .js и т.д).
Чипesp8285 отличается от предыдущего только тем, что у него есть встроенная флешь-память (1М). На платах с этим чипом spi-flash (если она есть) полностью отдана пользователю (если конечно я правильно всё понимаю).
Эта плата существует в двух ревизиях — WeMos D1 R1 и WeMos D1 R2. Различия заключаются в распиновке…
R1
R2
WeMos D1 mini
Может быть в таком исполнении…
А может быть в таком…
По сути это одинаковые девайсы, разница лишь в том, что в первом варианте
WeMos D1 mini Lite
Отличается от предыдущих отсутствием внешней spi-flash, и расположением всех компонентов на одной стороне. Установлен чип esp8285 (см.ниже).
WeMos D1 mini Pro
Как и у предыдущей платы все компоненты расположены на одной стороне, а так же есть spi-flash, керамическая антенна
Ещё есть вот такая D1 mini Pro (LOLIN)
У неё 16М spi-flash и интерфейс для зарядки аккумулятора.
Чипы esp8266 и esp8285
У чипа esp8266 отсутствует flash-память, поэтому применяется внешняя spi-flash (флешь-память работающая по SPI). Часть этой памяти используется для хранения прошивки, в IDE Arduino это обозначается так…
… а оставшуюся часть пользователь может использовать под свои нужды, например, хранить там файлы, которые отдаёт веб-сервер (.html, .css, .js и т.д).
Чип
Описание будет сделано на примере платы D1 mini
Первым делом нужно установить ядро. В IDE Arduino переходим в
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Жмём ОК и открываем менеджер плат…
Устанавливаем пакет
После установки нужно перезапустить среду.
Если у Вас такая же плата как у меня, тогда выберите
Flash Size — размер памяти на spi-флешки, который мы выделяем под пользовательские данные (в данном случае выделяем 3 мегабайта). Это то, о чём написано под спойлером в разделе «Чипы esp8266 и esp8285».
Debug port — в какой порт выводить отладочную инфу.
Debug Level — какую отладочную инфу выводить. Чтоб поглядеть что там пишется, нужно выбрать что-нибудь, загрузить скетч, открыть «Монитор порта» и нажать кнопочку Reset на плате...
В данном случае выбрано Debug port — Serial и Debug Level — CORE.
lwIP Variant — что-то связанное с размером полезного блока данных TCP-пакета (но могу и ошибаться).
VTables — смотреть здесь.
CPU Frequency — лучше оставить 80МГц, 160 может работать не стабильно.
Upload Speed — можно поставить максимальную, но у меня лучше всего загружалось на 115200.
Erase Flash…
•
•
•
На первое время установите всё как на картинке.
Пришло время загрузить традиционный
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
}
Если не прошилось, тогда есть несколько вариантов — нажать Reset или отключить/включить плату или поменять скорость или закрыть «Монитор порта» (если открыт). Что-то из этого должно помочь. У меня время от времени вываливается ошибка.
В программе, Serial — это
Для переназначения нужно после функции
Serial1 — это
Оба UART'а аппаратные.
Теперь можно протестировать работу в сети…
Web Server
#include <ESP8266WiFi.h>
const char* ssid = "istarik"; // имя вашей wifi точки доступа
const char* password = "S2fs5ds123GTs"; // пароль wifi
int val = 0;
WiFiServer server(80); // порт сервера
void setup()
{
Serial.begin(115200);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) // подключение к точке
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
server.begin(); // запуск сервера
Serial.println("Server started");
Serial.println(WiFi.localIP());
}
void loop()
{
WiFiClient client = server.available();
if (!client) // ждёт подключения клиента, пока клиент не подключится дальше этой функции дело не пойдёт
{
return;
}
Serial.println("new client");
while (!client.available()) // после подключения клиента ожидает данные
{
delay(1);
}
String req = client.readStringUntil('\r'); // читает первую строку заголовка
Serial.println(req); // печатает первую строку заголовка
client.flush(); // очищает приёмный буфер
val++;
/* отправка ответа клиенту */
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=utf-8");
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("Счётчик ");
client.print(val);
client.println("<br />");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
}
Укажите свою точку доступа и пароль.
В «Монитор порта» будет выеден адрес, присвоенный модулю…
Откройте страничку в браузере и увидите счётчик обновляющийся каждые пять секунд.
Web Client
Будем подключаться к google.com...
#include <ESP8266WiFi.h>
const char* ssid = "istarik"; // имя вашей wifi точки доступа
const char* password = "S2fs5ds123GTs"; // пароль wifi
const char* host = "google.com";
const int httpPort = 80;
void setup()
{
Serial.begin(115200);
delay(10);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) // подключение к точке
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop()
{
delay(5000);
Serial.print("Connecting to ");
Serial.println(host);
WiFiClient client;
if(!client.connect(host, httpPort)) // подключаемся к серверу
{
Serial.println("connection failed");
return;
}
// запрос к серверу
client.print(String("GET / ") + "HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
unsigned long timeout = millis();
while(client.available() == 0) // ждёт ответ от сервера
{
if(millis() - timeout > 5000) // если нет ответа в течении 5 сек, то разрывает соединение
{
Serial.println("Client Timeout");
client.stop();
return;
}
}
while(client.available()) // читает построчно ответ от сервера
{
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
}
Укажите свою точку доступа и пароль.
В «Монитор порта» будет выводиться ответ от google…
Запрос перенаправляется на https.
ESP как точка доступа
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char *ssid = "ESPap";
const char *password = "12345678";
ESP8266WebServer server(80);
// Go to http://192.168.4.1 in a web browser
void handleRoot()
{
server.send(200, "text/html", "<h1>You are connected</h1>");
}
void setup()
{
delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop()
{
server.handleClient();
}
Тут в общем-то и пояснять нечего, после загрузки скетча подключитесь к точке
В Примерах вы найдёте примеры всех возможных сетевых взаимодействий.
SPIFFS
SPIFFS (Serial Peripheral Interface Flash File System) — это файловая система на spi-флешке. Выражаясь простым языком, это «жёсткий диск», на котором можно хранить любые файлы.
Работать с файлами на флешке можно из своей программы так же как это делается на обычном компьютере, можно читать из файлов, записывать в них, создавать, удалять и переименовывать. Помимо этого можно загружать на флешку любые файлы с компьютера через IDE Arduino.
Загрузите скетч демонстрирующий работу с
/* SPIFFS.ino author stD */
#include "FS.h"
FSInfo fs_info;
Dir dir;
File f;
String str;
void setup(void)
{
Serial.begin(115200);
SPIFFS.begin(); // инициализация флешки
}
void loop(void)
{
if(Serial.available())
{
switch(Serial.read())
{
case '1': // форматирование SPIFFS
Serial.println();
Serial.println("1. Please wait 30 secs for SPIFFS to be formatted...");
SPIFFS.format();
Serial.println("SPIFFS formatted OK");
Serial.println("----------------");
break;
case '2': // SPIFFS инфа
SPIFFS.info(fs_info);
Serial.println();
Serial.println("2. SPIFFS INFO...");
Serial.print("totalBytes=");
Serial.println(fs_info.totalBytes); // размер SPIFFS
Serial.println("----------------");
Serial.print("usedBytes=");
Serial.println(fs_info.usedBytes); // количество байт, используемых файлами
Serial.println("----------------");
Serial.print("blockSize=");
Serial.println(fs_info.blockSize); // размер блока SPIFFS
Serial.println("----------------");
Serial.print("pageSize=");
Serial.println(fs_info.pageSize); // размер логической страницы SPIFFS
Serial.println("----------------");
Serial.print("maxPathLength=");
Serial.println(fs_info.maxPathLength); // макс. длина файлового имени (включая один байт для завершающего нуля)
Serial.println("----------------");
break;
case '3': // создание файла или открытие существующего для записи
Serial.println();
Serial.println("3. Creat/open file...");
f = SPIFFS.open("/myfile.txt", "w");
if(!f)
{
Serial.println("NOT сreat/open file :("); // создать/открыть файл не удалось
}
else
{
Serial.println("OK сreat/open file :)"); // файл создан/открыт
f.print("one = "); // запись строк
f.println(1);
f.print("two = ");
f.println('2');
f.print("three = ");
f.println("3 = three");
f.write('B'); // запись байта (символ B)
f.write('\n'); // запись байта (перенос строки)
f.write(0xff); // запись байта (255 в HEX-формате)
Serial.println("Write to file");
f.close(); // закрыли файл
Serial.println("Close file");
}
Serial.println("----------------");
break;
case '4': // просмотр содержимого SPIFFS
Serial.println();
Serial.println("4. View content...");
dir = SPIFFS.openDir("/");
while(dir.next())
{
Serial.println(dir.fileName());
f = dir.openFile("r");
Serial.print("Size file=");
Serial.println(f.size()); // размер файла в байтах
}
Serial.println("----------------");
break;
case '5': // чтение файла
Serial.println();
Serial.println("5. Read...");
if(SPIFFS.exists("/blabla.txt")) // проверка есть ли файл
{
Serial.println("File exists");
f = SPIFFS.open("/blabla.txt", "r");
if(f) // проверка открылся ли файл
{
Serial.println("File open");
if(f.size()) // если файл не пустой, тогда читаем
{
while(f.available())
{
str += char(f.read()); // чтение посимвольно
}
Serial.println("Content...");
Serial.println();
Serial.println(str);
}
else Serial.println("File empty");
f.close(); // закрыли файл
}
else Serial.println("File not open");
}
else Serial.println("NOT file");
Serial.println("----------------");
break;
}
for (byte i = 0; i < 3; i++)
{
Serial.read();
delay(1);
}
}
}
Откройте «монитор порта» и последовательно отправляйте цифры…
1 — отформатирует SPIFFS.
2 — покажет инфу о SPIFFS.
3 — создаст файл
4 — покажет что есть на SPIFFS.
5 — покажет содержимое файла
Все действия прокомментированы в коде.
Подробнее о SPIFFS почитайте здесь. Заодно ознакомитесь со структурой FSInfo fs_info.
Теперь нужно добавить в
После перезапуска
Чтобы загрузить файлы, нужно сделать следующее: откройте папку со скетчем (можно через меню
Папка
Теперь скопируйте или создайте в папке
Если вылезут ошибки, тогда Reset вам в помощь.
Теперь откройте «монитор порта» и отправьте цифру 4…
Вот и наш файлик —
При обращении к файлам на флешке, указывать папку
Ну и в довершение сделаем сервер, который будет отдавать файлы расположенные на флешке.
Содайте в папке
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ESP</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="mypanel">
<div class="mytext">ESP Server</div>
</div>
</body>
</html>
.mypanel {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 50px;
background:#3b4045;
border-bottom: 1px solid #e71341;
}
.mytext {
position: absolute;
top: 11px;
left: 100px;
font-size: 24px;
color: #babdb2;
}
Загрузите их в плату, а следом прошейте этот…
скетч
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <FS.h>
const char* ssid = "istarik"; // имя вашей wifi точки доступа
const char* password = "Ss32f16ys"; // пароль wifi
ESP8266WebServer server(80);
String getContentType(String filename)
{
if (filename.endsWith(".htm"))
{
return "text/html";
}
else if (filename.endsWith(".html"))
{
return "text/html";
}
else if (filename.endsWith(".css"))
{
return "text/css";
}
else if (filename.endsWith(".js"))
{
return "application/javascript";
}
else if (filename.endsWith(".png"))
{
return "image/png";
}
else if (filename.endsWith(".gif"))
{
return "image/gif";
}
else if (filename.endsWith(".jpg"))
{
return "image/jpeg";
}
else if (filename.endsWith(".ico"))
{
return "image/x-icon";
}
else if (filename.endsWith(".xml"))
{
return "text/xml";
}
else if (filename.endsWith(".pdf"))
{
return "application/x-pdf";
}
else if (filename.endsWith(".zip"))
{
return "application/x-zip";
}
else if (filename.endsWith(".gz"))
{
return "application/x-gzip";
}
return "text/plain";
}
bool handleFileRead(String path)
{
Serial.println("handleFileRead: " + path);
if(path.endsWith("/"))
{
path += "index.html";
}
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path))
{
if(SPIFFS.exists(pathWithGz))
{
path += ".gz";
}
File file = SPIFFS.open(path, "r");
server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void setup(void)
{
Serial.begin(115200);
SPIFFS.begin();
Serial.printf("Connecting to %s\n", ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
server.onNotFound([]()
{
if(!handleFileRead(server.uri()))
{
server.send(404, "text/plain", "FileNotFound");
}
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void)
{
server.handleClient();
}
Открывайте в браузере и смотрите что получилось.
Можно добавить любые файлы, .js, .png и т.д.
На этом всё.
Всем спасибо
- 0
- stD
31576
Поддержать автора
Комментарии (1)