КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Создаём и скачиваем файлы из внутенней памяти Piranha ESP32

Общие сведения:

В этом проекте мы настроим Piranha ESP32 на подключение к существующей точке доступа WiFi, запустим Web-сервер ESP32, создадим файл во встроенной памяти при помощи файловой системы SPIFFS, а при подключении к локальному Web-сайту по имени piranha-logger.local можно будет скачать файл, в который с периодичностью в десять секунд записываются текущие millis().

Для работы данного скетча внутренняя память Piranha ESP32 должна быть отформатирована. Для этого либо воспользуйтесь утилитой загрузки файлов на Piranha ESP32, либо раскоменнтируйте строку SPIFFS.format() в функции setup().

  • Процедуру форматирования необходимо выполнить только один раз.
  • При использовании любого метода все файлы, загруженные вами или созданные скетчем ранее, будут удалены.
  • Если процедуру форматирования не убрать из скетча и не загрузить новую версию скетча в плату, то память будет очищаться при каждом включении или перезагрузке микроконтроллера.
  • Процедура format() занимает относительно долгое время, будьте терпеливы.

Создание файлов

В этом примере файл перезаписывается каждый раз. Для записи с сохранением предыдущих показаний измените способ открытия файла с "w" на "a"SPIFFS.open("/logger.txt", "w") на SPIFFS.open("/logger.txt", "a")).

Данный подход, например, можно использовать для ведения журнала показаний датчиков за небольшой промежуток времени. Стоит помнить, что памяти, доступной для файловой системы, 1 МБ. Если нужно вести длительные наблюдения показаний, стоит воспользоваться записью файлов на внешний носитель (например на SD-карту).

Скачивание файлов

В данном примере создаётся локальный Web-сайт, доступ к которому можно получить по ссылке http://piranha-logger.local. Сайт генерируется кодом скетча и выводит список файлов, хранящихся во внутренней памяти, на указанный выше локальный сайт. Доступ по имени возможен благодаря серверу mDNS (Multicast DNS), библиотеку которого мы используем в скетче. Если по каким-то причинам mDNS не работает в локальной сети - то сайт может быть доступен по адресу, который выводиться в последовательный порт сразу после подключения к точке WiFi.

Видео:

редактируется ...

Нам понадобится:

Подключение:

Скетчи проекта:

Скетч с перезаписью файла. В скетче необходимо указать Ваши данные для Вашей точки доступа WiFi.

// Подключаем библиотеки
#include 
#include 
#include 
#include 

// Определяем интервал записи в файл
const unsigned long INTERVAL = 10000;
unsigned long write_millis = 0;

// Определяем название и пароль точки доступа
const char* ssid = "название_WiFi"; // Это поле нужно заполнить необходимыми данными
const char* password = "пароль_WiFi"; // Это поле нужно заполнить необходимыми данными

// Определяем имя сервера в сети
const char* host = "piranha-logger";

// Создаём объект Веб-сервера
WebServer server(80);

// Функция обработки клиента
void handleClient()
{
    // Выводим содержимое корневого каталога как Веб-страницу
    listRootToHtml();
}

// Функция чтения файла
bool handleFileRead(String path)
{
    // Открываем файл для чтения по указанному пути
    File file = SPIFFS.open(path, "r");

    // Если файл не удалось открыть
    if (!file) {
        Serial.println("Ошибка. Файл не существует.");

        // Отвечаем клиенту ошибкой
        server.send(404, "text/plain", "FileNotFound");

        // Возвращаемся из функции
        return false;
    }

    // Отдаём клиенту содержимое файла
    server.streamFile(file, "text/html");
    // Закрываем файл
    file.close();
    // Возвращаемся из функции
    return true;
}

// Функция вывода списка файлов в HTML страницу
void listRootToHtml()
{
    // Открываем корневой файл
    File root = SPIFFS.open("/");

    // Если не получилось открыть
    if (!root) {
        // Выводим ошибку
        Serial.println("error");
        // Возвращаемся из функции
        return;
    }

    // Создаём строку для конкатенации
    String html = "";

    // Если корневой файл - каталог
    if (root.isDirectory()) {

        // Открываем следующий файл
        File file = root.openNextFile();

        // Входим в цикл, если файл существует
        /* После прохода данного цикла должна
         * получиться страница вида:
         * 
         * 

* имя_первого_файла

*

* имя_второго_файла

* ..... *

* имя_N-файла

* */ while (file) { // Записываем имя файла String name = file.name(); // Удаляем первый символ ("/"); name.remove(0, 1); // Конкатенируем строку html += "

"; html += name; html += "

"; // Открываем следующий файл file = root.openNextFile(); } html += ""; } // Отравляем страницу клиенту server.send(200, "text/html", html); } void setup() { // Форматируем внутренную память (нужно выполнить только один раз) // SPIFFS.format(); // Инициируем объект файловой системы SPIFFS.begin(); Serial.begin(115200); Serial.println(); Serial.println("Подключаемся к WiFi"); // Инициируем точку доступа WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(100); } // Записываем IP-адрес IPAddress myIP = WiFi.localIP(); // Инициируем Multicast DNS MDNS.begin(host); // Выводим IP-адрес Веб-сервера Serial.print("IP-адрес: "); Serial.println(myIP); // Функция, выполняемая при подключении к клиента корневому каталогу server.on("/", HTTP_GET, handleClient); // Функция, которая будет выполнена, если файл не найден server.onNotFound([]() { // Если по указанному пути файл не найден... if (!handleFileRead(server.uri())) { // Отвечаем клиенту ошибкой 404 server.send(404, "text/plain", "FILE NOT FOUND"); } }); // Инициируем сервер server.begin(); Serial.println("Сервер запущен."); } void loop() { // Библиотечная функция обработки клиента server.handleClient(); // Если прошёл интервал ожидания if (millis() - write_millis > INTERVAL) { // Записываем текущие millis write_millis = millis(); // Создаём файл с абсолютным путём File file = SPIFFS.open("/logger.txt", "w"); // Если файл не получилось создать if (!file) // Выводим сообщение Serial.println("error creating file"); // Иначе else // Выводим текущие millis в файл file.println(write_millis); file.flush(); file.close(); } // Даём процессору переключиться на другие задачи delay(2); }

Скетч с добавлением в файл и записью показаний с текущим реальным временем

// Подключаем библиотеки
#include 
#include 
#include 
#include 
#include "time.h"

// Определяем интервал записи в файл
const unsigned long INTERVAL = 10000;
unsigned long write_millis = 0;

// Определяем название и пароль точки доступа
const char* ssid = "название_WiFi"; // Это поле нужно заполнить необходимыми данными
const char* password = "пароль_WiFi"; // Это поле нужно заполнить необходимыми данными

// Определяем сервер времени
const char* ntpServer = "pool.ntp.org";

// Определяем имя сервера в сети
const char* host = "piranha-logger";

// Создаём объект Веб-сервера
WebServer server(80);

// Функция обработки клиента
void handleClient()
{
    // Выводим содержимое корневого каталога как Веб-страницу
    listRootToHtml();
}

// Функция чтения файла
bool handleFileRead(String path)
{
    // Открываем файл для чтения по указанному пути
    File file = SPIFFS.open(path, "r");

    // Если файл не удалось открыть
    if (!file) {
        Serial.println("Ошибка. Файл не существует.");

        // Отвечаем клиенту ошибкой
        server.send(404, "text/plain", "FileNotFound");

        // Возвращаемся из функции
        return false;
    }

    // Отдаём клиенту содержимое файла
    server.streamFile(file, "text/html");
    // Закрываем файл
    file.close();
    // Возвращаемся из функции
    return true;
}

// Функция вывода списка файлов в HTML страницу
void listRootToHtml()
{
    // Открываем корневой файл
    File root = SPIFFS.open("/");

    // Если не получилось открыть
    if (!root) {
        // Выводим ошибку
        Serial.println("error");
        // Возвращаемся из функции
        return;
    }

    // Создаём строку для конкатенации
    String html = "";

    // Если корневой файл - каталог
    if (root.isDirectory()) {

        // Открываем следующий файл
        File file = root.openNextFile();

        // Входим в цикл, если файл существует
        /* После прохода данного цикла должна
         * получиться страница вида:
         * 
         * 

* имя_первого_файла

*

* имя_второго_файла

* ..... *

* имя_N-файла

* */ while (file) { // Записываем имя файла String name = file.name(); // Удаляем первый символ ("/"); name.remove(0, 1); // Конкатенируем строку html += "

"; html += name; html += "

"; // Открываем следующий файл file = root.openNextFile(); } html += ""; } // Отравляем страницу клиенту server.send(200, "text/html", html); } void setup() { // Форматируем внутренную память (нужно выполнить только один раз) // SPIFFS.format(); // Инициируем объект файловой системы SPIFFS.begin(); Serial.begin(115200); Serial.println(); Serial.println("Подключаемся к WiFi"); // Инициируем точку доступа WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(100); } // Записываем IP-адрес IPAddress myIP = WiFi.localIP(); // Инициируем Multicast DNS MDNS.begin(host); // Выводим IP-адрес Веб-сервера Serial.print("IP-адрес: "); Serial.println(myIP); // Конфигурируем время configTime(3600*3, 0, ntpServer); // Функция, выполняемая при подключении к клиента корневому каталогу server.on("/", HTTP_GET, handleClient); // Функция, которая будет выполнена, если файл не найден server.onNotFound([]() { // Если по указанному пути файл не найден... if (!handleFileRead(server.uri())) { // Отвечаем клиенту ошибкой 404 server.send(404, "text/plain", "FILE NOT FOUND"); } }); // Инициируем сервер server.begin(); Serial.println("Сервер запущен."); } void loop() { // Библиотечная функция обработки клиента server.handleClient(); // Если прошёл интервал ожидания if (millis() - write_millis > INTERVAL) { // Записываем текушее время struct tm timeinfo; getLocalTime(&timeinfo); // Записываем текущие millis write_millis = millis(); // Создаём файл с абсолютным путём File file = SPIFFS.open("/logger.txt", "a"); // Если файл не получилось создать if (!file) // Выводим сообщение Serial.println("error creating file"); // Иначе else // Выводим текущее время в файл file.print(&timeinfo, "%B %d %Y %H:%M:%S,"); // Выводим текущие millis в файл file.println(write_millis); file.flush(); file.close(); } // Даём процессору переключиться на другие задачи delay(2); }

Ссылки




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями