Страница 37 из 51
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 8:23 pm
serghei
Alex писал(а): Вс июн 18, 2017 5:38 pm
Arduino Mega Server для ESP32 с SD картой памяти..
... поскольку в драйверах не реализован сервер и обновление прошивки по воздуху, то этого функционала нет и в АМС
Уже есть. Реализовано:
1. Загрузка файлов по воздуху
2. Обновление прошивки по воздуху
3. Редактирование страниц в браузере с сохранением результата " на лету" без перезагрузки сервера
В скетч добавляем вкладку HTTP с текстом
Код: Выделить всё
/*
Modul HTTP for ESP_32
part of Arduino Mega Server project
*/
#ifdef HTTP_FEATURE
#include "WebServer.h"
#include "Update.h"
#define HTTP_PORT 8080
WebServer HTTP(HTTP_PORT);
File fsUploadFile;
String getContentType(String filename){
if(HTTP.hasArg("download")) return "application/octet-stream";
else 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(".csv")) return "text/plain";
else if(filename.endsWith(".cfg")) return "text/plain";
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.htm";
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SD.exists(pathWithGz) || SD.exists(path)){
if(SD.exists(pathWithGz))
path += ".gz";
File file = SD.open(path, "r");
HTTP.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void handleFileUpload() {
if(HTTP.uri() != "/edit") return;
HTTPUpload& upload = HTTP.upload();
if(upload.status == UPLOAD_FILE_START){
String filename = upload.filename;
if(!filename.startsWith("/")) filename = "/"+filename;
fsUploadFile = SD.open(filename, "w");
filename = String();
} else if(upload.status == UPLOAD_FILE_WRITE){
if(fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize);
} else if(upload.status == UPLOAD_FILE_END){
if(fsUploadFile)
fsUploadFile.close();
}
} // handleFileUpload()
void handleFileDelete() {
if(HTTP.args() == 0) return HTTP.send(500, "text/plain", "BAD ARGS");
String path = HTTP.arg(0);
if(path == "/")
return HTTP.send(500, "text/plain", "BAD PATH");
if(!SD.exists(path))
return HTTP.send(404, "text/plain", "FileNotFound");
SD.remove(path);
HTTP.send(200, "text/plain", "");
path = String();
} // handleFileDelete()
void handleFileCreate() {
if(HTTP.args() == 0)
return HTTP.send(500, "text/plain", "BAD ARGS");
String path = HTTP.arg(0);
if(path == "/")
return HTTP.send(500, "text/plain", "BAD PATH");
if(SD.exists(path))
return HTTP.send(500, "text/plain", "FILE EXISTS");
File file = SD.open(path, "w");
if(file)
file.close();
else
return HTTP.send(500, "text/plain", "CREATE FAILED");
HTTP.send(200, "text/plain", "");
path = String();
} // handleFileCreate();
void handleFileList() {
if(!HTTP.hasArg("dir")) {HTTP.send(500, "text/plain", "BAD ARGS"); return;}
String path = HTTP.arg("dir");
if(path != "/" && !SD.exists((char *)path.c_str())) {HTTP.send(500, "text/plain", "BAD PATH"); return;}
File dir = SD.open((char *)path.c_str());
path = String();
if(!dir.isDirectory()){
dir.close();
HTTP.send(500, "text/plain", "BAD DIR");
return;
}
dir.rewindDirectory();
HTTP.setContentLength(CONTENT_LENGTH_UNKNOWN);
HTTP.send(200, "text/json", "");
HTTP.sendContent("[");
for (int cnt = 0; true; ++cnt) {
File entry = dir.openNextFile();
if (!entry)
break;
String output;
if (cnt > 0)
output = ',';
output += "{\"type\":\"";
output += (entry.isDirectory()) ? "dir" : "file";
output += "\",\"name\":\"";
output += String(entry.name()).substring(1);
output += "\"";
output += "}";
HTTP.sendContent(output);
entry.close();
Serial.println(output);//============== вывод в сериал
}
HTTP.sendContent("]");
dir.close();
} // handleFileList()
String Fail = "<!DOCTYPE html><html><head><meta http-equiv='Content-type' content='text/html; charset=utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'></head><style>body{background:#FFA07A;}</style><body><h3>Firmware update:</h3><h2>  FAIL</h2><h3>  Restart ESP</h3></body></html>";
String Ok = "<!DOCTYPE html><html><head><meta http-equiv='Content-type' content='text/html; charset=utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><meta http-equiv='refresh' content='15;update.htm'></head><style>body{background:#E0EEE0;}</style><body><h3>Firmware update:</h3><h2>  OK!</h2></body></html>";
void updateInit() {
HTTP.on("/update", HTTP_POST, [](){
HTTP.sendHeader("Connection", "close");
HTTP.send(200, "text/html", (Update.hasError()) ? Fail : Ok);
delay(500);//=================================
ESP.restart();
},[](){
HTTPUpload& upload = HTTP.upload();
if(upload.status == UPLOAD_FILE_START){
uint32_t maxSketchSpace = 0x140000;
if(!Update.begin(maxSketchSpace)){
Update.printError(Serial);
}
} else if(upload.status == UPLOAD_FILE_WRITE){
if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
Update.printError(Serial);
}
} else if(upload.status == UPLOAD_FILE_END){
if(Update.end(true)){
Serial.printf("Update Success: %u B\nDownload time: %d sec.\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
yield();
});
} // updateInit()
void initHttp() {
HTTP.on("/list", HTTP_GET, handleFileList);
HTTP.on("/edit", HTTP_GET, []() { if (!handleFileRead("edit.htm")) HTTP.send(404, "text/plain", "FileNotFound"); });
HTTP.on("/edit", HTTP_PUT, handleFileCreate);
HTTP.on("/edit", HTTP_DELETE, handleFileDelete);
HTTP.on("/edit", HTTP_POST, []() { HTTP.send(200, "text/plain", ""); }, handleFileUpload);
HTTP.onNotFound([]() { if (!handleFileRead(HTTP.uri())) HTTP.send(404, "text/plain", "FileNotFound"); });
updateInit();
HTTP.begin();
timeStamp();
printValue("HTTP port", String(HTTP_PORT));
moduleHTTP = ENABLE;
started(F("Http"), true);
} // initHttp()
void httpWork() {
HTTP.handleClient();
}
#endif // HTTP_FEATURE
Не забываем про инициализацию
Код: Выделить всё
#define HTTP_FEATURE
----------------------------
byte moduleHTTP = NOT_COMPILLED;
----------------------------
#ifdef HTTP_FEATURE
initHttp();
#endif
--------------------------
#ifdef HTTP_FEATURE
httpWork();
#endif
-------------------------
На карту памяти добавляем файлы ( с заменой)
Вложение SD_edit.zip больше недоступно
Необходимая библиотека
Работа с обновлением по воздуху ничем не отличается от подобного c ESP8266.
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 8:46 pm
serghei
Проверяем в монитор-порту ,что новый модуль стартанул
- Module SD...
Init: OK
Type: SDSC
Size: 942 MB
Check: ........................................
.........
Files: 495
Total: 13436222 B
Empty: 3
Index: found
===========
Module NTP...
Server: 37.247.53.178
Port: 123
===========
Module Time...
Provider: network
NTP request: OK
===========
2018-05-04 19:44:56 Module Server... started
2018-05-04 19:44:56 Module Upload... started
2018-05-04 19:44:56 Module Send... started
2018-05-04 19:44:56 2018-05-04 19:44:56 Found 4 devices
2018-05-04 19:44:57 #0: 40 26 27 42 7 0 0 151 tempSTR
2018-05-04 19:44:57 #1: 40 67 255 28 7 0 0 171 tempHOM
2018-05-04 19:44:57 #2: 40 239 16 29 7 0 0 176 tempWRM
2018-05-04 19:44:57 #3: 29 187 48 10 0 0 0 163 tempB2
2018-05-04 19:44:57 Module Temp... started
2018-05-04 19:44:57 Module Keys... started
2018-05-04 19:44:57 Module DHT... started
2018-05-04 19:44:57 Module BME... started
2018-05-04 19:44:57 Module Electro... started
2018-05-04 19:44:57 Module TLog... started
2018-05-04 19:44:57 HTTP port: 8080 // порт 8080
2018-05-04 19:44:57 Module Http... started // старт модуля
GLOBAL Init DONE (34s)
AMS WORK
2018-05-04 19:44:57 : 112064 (39%) 112064
2018-05-04 19:44:57 tempSTR: 22.62
2018-05-04 19:44:57 tempHOM: 33.38
2018-05-04 19:44:57 tempWRM: 36.00
2018-05-04 19:44:57 tempB2: ID problem or not present
*** workCount ***
2018-05-04 19:44:57 count1: (0)39017.11 (1)19558.94
2018-05-04 19:44:58 count2: (0)39017.11 (1)19558.94
2018-05-04 19:44:58 count3: (0)39017.11 (1)19558.94
2018-05-04 19:44:58 count4: (0)39017.11 (1)19558.94
2018-05-04 19:44:58 count5: (0)39017.11 (1)19558.94
*** workCount ***
Открываем страницу IP:8080/edit.htm и видим картину
Вложение Editor.jpg больше недоступно
Для загрузки прошивки - IP:8080/update.htm Выбираем предварительно скомпилированый .bin файл и жмем волшебную кнопку
Вложение Update.jpg больше недоступно
После успешной загрузки увидим картинку

- Editor.jpg (352.25 КБ) 4412 просмотров
Замечания после суток теста. Так как библиотека молодая , наблюдается сильная задержка при загрузке файлов.
Файл 160 000 КБ закачался за неполные 5 часов. Жертв нет.
Остался вопрос - что проверялось? Похоже моя WiFi сеть тоже.
Вывод : файл неограниченного в пределах разумного размера можно смело грузить "по воздуху" - то есть прошивать.
Прошивка за 30 секунд.
В результате экспериментов кто то поломал файловую систему на карте - была FAT16 , стала FAT. При этом карта виделась и работала , а файлы не сохранялись.Пришлось переформатировать.
НЕ РАБОТАЕТ С ХРОМОМ! Винда 10. Пользуйтесь FF.
PS Код придумал НЕ я ! Я только озвучиваю !!!!
PSS Ну вот НЕ правильно работает форум - теряются вложения. Это вообще тихий ужос !!! куда делись картинки??????
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 8:51 pm
serghei
Вложения

- EDIT.jpg (269.1 КБ) 4409 просмотров
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 8:52 pm
serghei
Еще

- 32_update.jpg (104.97 КБ) 4408 просмотров
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 9:40 pm
serghei
Не , ну это не серьёзно! Файлы на карту. Добавить с заменой файла.
Re: Arduino Mega Server для ESP32
Добавлено: Пт май 04, 2018 9:43 pm
serghei
Re: Arduino Mega Server для ESP32
Добавлено: Сб июн 16, 2018 12:10 am
serghei
Alex писал(а): Пн июн 11, 2018 8:18 amУ вас уже много полезных наработок — было бы неплохо, если бы вы их оформляли в виде статей тут или даже на своём сайте.
Сайта у меня нет , к сожалению. Всё, чего я достиг за два года въезжания в тему AMS - это благодаря пяти великим программистам на этом форуме , без преувеличения.
Но не ожЫданно столкнулся с проблемой на ESP32 - подключил Мажерика на Апельсине ( привет
Alexsis_76..............)
Мега , Дуя и ESP8266 влетели без проблем. ESP32 стала отправлять Гет запросы сама себе........ То есть к Алисе конектится , А в модуле "Send" наблюдаю картину маслом ))
Код: Выделить всё
void sendHttpRequest(byte ip[], int port, WiFiClient cl) {
String s = "";
if (cl.connect(ip, port)) {
timeStamp();
Serial.print(F("Host "));
//Serial.print(stringIp(SELF_IP));// вставляет свой IP и Алиса его НЕ видит !!
Serial.print(stringIp(MAJOR_IP));// Заменил и всё ОК-еюшки ))
Serial.print(F(" "));
Serial.println(buf);
s += String(buf);
s += '\n';
s += "Host: ";
// s += stringIp(SELF_IP);
s += stringIp(MAJOR_IP);// тут тоже самое
s += '\n';
cl.println(s);
delay(100);
cl.stop();
} else {
timeStamp();
Serial.print(F("Host "));
// Serial.print(stringIp(SELF_IP));// а так отправляет сама себе !!!!!
Serial.print(stringIp(MAJOR_IP));// и тута то же
Serial.print(F(" not connected ("));
Serial.print(buf);
Serial.println(F(")"));
}
}
Но это еще пол-беды. На Апельсине с последним образом от
Immortal не захотела нормально работать ( то есть свойство V = 1 в упор не видит ) . Вспомнил про древние версии МД и о ч Ю до! - Всё взлетело с полпинка! ( правда это на винде ))
С учетом всех предыдущих мыслей я теперь в диком шоке. Это что бы достигнуть уровня AMS-Pro надо ещё сильно попотеть!

- ESP32.jpg (190.73 КБ) 4112 просмотров
Re: Arduino Mega Server для ESP32
Добавлено: Чт июн 21, 2018 9:03 am
alexsis_76
serghei тебе удалось добиться двухядерности?
Re: Arduino Mega Server для ESP32
Добавлено: Чт июн 21, 2018 11:49 am
serghei
У меня конкретно это реализовано только в Веб-радио. Но звуковой процессор запустил только на 8266. Плату пришлось всю перепаивать. К 32 пока не подключал.
Вообще по правильному весь AMS для ESP32 надо переписывать для работы с RTOS. Единственную правильную реализацию под мою плату видел только у
Olmoro ( он и автор платы )). Посмотри его сайт.
У меня получилось от туда забрать только реконнект к сети. Критерием правильного кода будет отсутствие вкладки Таймеры. А сама структура скетча - это ОДНА вкладка .ino и куча хедеров. Начало выглядит так
Код: Выделить всё
/*
* U32maxi
* Ol.Moro
* 2018.05.10
* IDE: ARDUINO 1.8.5
* Arduino core for the ESP32 09.03.2018 https://github.com/espressif/arduino-esp32
* Complete Project Details http://randomnerdtutorials.com
* http://microsin.net/programming/arm/freertos-part1.html
*/
#include "pcb.h" // Choose pcb here
#include "server.h"
#include "temp.h"
#include "fsm.h"
#include "irms.h"
#include <WiFi.h>
// Replace with your network credentials
const char* ssid = "************";
const char* password = "********";
int fire = 1; // X5-2
void setup()
{
// initialize serial port
Serial.begin(115200);
// initialize temp sensors
initTemp();
initFsm();
initFsm();
// initServer();
// initialize tasks
xTaskCreate( initServTask, "InitServer", 5000, NULL, 1, NULL );
xTaskCreate( servTask, "Server", 10000, NULL, 1, NULL );
xTaskCreate( tempTask, "Dallas", 5000, NULL, 1, NULL );
xTaskCreate( fsmTask, "FSM Test", 5000, NULL, 1, NULL );
xTaskCreate( irmsTask, "Irms", 5000, NULL, 1, NULL );
xTaskCreate( reconnectTask, "Reconnect", 5000, NULL, 1, NULL );
}
void loop()
{
fire = checkFire();
vTaskDelay( 200 / portTICK_PERIOD_MS );
}
void servTask( void * parameter )
{
while(1)
{
workServer();
vTaskDelay( 50 / portTICK_PERIOD_MS );
}
vTaskDelete( NULL );
}
void tempTask( void * parameter )
{
while(1)
{
workTemp();
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
vTaskDelete( NULL );
}
void fsmTask( void * parameter )
{
while(1)
{
workFsm();
}
vTaskDelete( NULL );
}
void irmsTask( void * parameter )
{
while(1)
{
workIrms();
vTaskDelay( 500 / portTICK_PERIOD_MS );
}
vTaskDelete(NULL);
}
void reconnectTask( void * parameter )
{
while(1)
{
if (WiFi.status() != WL_CONNECTED )
{
WiFi.reconnect();
}
vTaskDelay( 30000 / portTICK_PERIOD_MS );
}
vTaskDelete(NULL);
}
void initServTask( void * parameter )
{
while(1)
{
initServer();
vTaskDelay( 5000 / portTICK_PERIOD_MS );
}
vTaskDelete(NULL);
}
И уже после этого можно замахнуться на двухядерность. В моём понимании на одном ядре работает сервер , а на другом все датчики. А может я и не прав.
Re: Arduino Mega Server для ESP32
Добавлено: Чт июн 21, 2018 12:07 pm
alexsis_76
тут применение нашлось для его двухъядерности.