КОРЗИНА
магазина
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 <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>

// Определяем интервал записи в файл
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 = "<html><meta charset=\"UTF-8\"><body>";

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

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

        // Входим в цикл, если файл существует
        /* После прохода данного цикла должна
         * получиться страница вида:
         * <html><meta charset="UTF-8"><body>
         * <p><a href="имя_первого_файла download="имя_первого_файла">
         * имя_первого_файла</a></p>
         * <p><a href="имя_второго_файла download="имя_второго_файла">
         * имя_второго_файла</a></p>
         * .....
         * <p><a href="имя_N-фала download="имя_N-файла">
         * имя_N-файла</a></p>
         * </body></html>
         */
        while (file) {

            // Записываем имя файла
            String name = file.name();

            // Удаляем первый символ ("/");
            name.remove(0, 1);

            // Конкатенируем строку
            html += "<p><a href=\"";
            html += name;
            html += (String)"\" download=\"";
            html += name +"\">";
            html += name;
            html += "</a></p>";

            // Открываем следующий файл
            file = root.openNextFile();
        }
        html += "</body></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 <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#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 = "<html><meta charset=\"UTF-8\"><body>";

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

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

        // Входим в цикл, если файл существует
        /* После прохода данного цикла должна
         * получиться страница вида:
         * <html><meta charset="UTF-8"><body>
         * <p><a href="имя_первого_файла download="имя_первого_файла">
         * имя_первого_файла</a></p>
         * <p><a href="имя_второго_файла download="имя_второго_файла">
         * имя_второго_файла</a></p>
         * .....
         * <p><a href="имя_N-фала download="имя_N-файла">
         * имя_N-файла</a></p>
         * </body></html>
         */
        while (file) {

            // Записываем имя файла
            String name = file.name();

            // Удаляем первый символ ("/");
            name.remove(0, 1);

            // Конкатенируем строку
            html += "<p><a href=\"";
            html += name;
            html += (String)"\" download=\"";
            html += name +"\">";
            html += name;
            html += "</a></p>";

            // Открываем следующий файл
            file = root.openNextFile();
        }
        html += "</body></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);
}

Ссылки




Обсуждение

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