ESP8266 - Nextion OTA

ESP8266, ESP32 chipek és az ESP-xx modulok. Programozási nyelvek, trükkök, hardware tippek.
Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 1031
Csatlakozott: 2009. február 28. szombat, 7:00

ESP8266 - Nextion OTA

Hozzászólás Szerző: SanyiSay »

Már régóta keresgélem hogy lehetne nextion-t frissíteni wifin keresztül.
Találtam egy megoldást, de az egy külső szerverről tölti le a fájlt ha jól értettem, szóval nekem az teljesen kínai egyenlőre.
http://support.iteadstudio.com/support/ ... rl_locale=
Aztán találtam a Nextion Arduino Lib ben egy NexUpload.h részt ahol Arduinohoz kötött SD kártyáról tudja frissíteni a Nextiont.
https://github.com/itead/ITEADLIB_Ardui ... r/examples
Na ebből lett az én megoldásom, hogy ESP FS fájlrendszerébe feltöltöm a Nextion.tft fájlt ESP-n futtatott FTP szerverre, és onnan töltöm át nextionra Soft Serial-on keresztül.
Hát nem egy tipikus OTA de működik. Persze ESP flash kiosztásból kell hozzá a 4M(3M SPIFFS) mert kb 1 megás maga a nextion.tft fájl.
Kódot még nem mellékelek mert igen kezdetleges,de ha valakit érdekel akkor felteszem, vagy ha ennél van jobb megoldás az is érdekelne.
Szerintem az lenne az optimális, ha böngészőből kiválasztva a fájlt, feltöltené a Nextionra, de ez már ízlés kérdése.

A feltöltési protokol:
https://www.itead.cc/blog/nextion-hmi-upload-protocol
DaeMonSHome
Újonc
Újonc
Hozzászólások: 2
Csatlakozott: 2017. augusztus 25. péntek, 8:39

Re: ESP8266 - Nextion OTA

Hozzászólás Szerző: DaeMonSHome »

Szia,

Engem érdekelne.
Éppen akuális a téma.

Jó lenne egy olyan megoldás, amit esp oldalon egy sima weblapról, file kiválasztással feltölt-majd átküldi a nextion-ra.
Meddig jutottál, forrás tekintetében nagyon kiváncsi vagyok.

Köszönettel
D
Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 1031
Csatlakozott: 2009. február 28. szombat, 7:00

Re: ESP8266 - Nextion OTA

Hozzászólás Szerző: SanyiSay »

Téma már nem is annyira aktuális, de még dereng valami. :)
Cél az volt hogy hasonlóan a weboldalon keresztüli ESP OTA frissítéshez, csak kiválasztok egy fájlt és frissítem vele a nextiont, nincs fájl mentés az esp-re. Elvileg az ESPAsyncWebServer erre alkalmas is lenne.
https://github.com/me-no-dev/ESPAsyncWebServer
Na eddig nem jutottam el.

Ami megy hogy az ESP fájlrendszerén tárolt .tft fájlt feltölti Nextionra SW serialon keresztül.
https://github.com/plerup/espsoftwareserial

Hogy hogy kerül oda a fájl annak több módja is van.
FTP szervert futtatsz az ESP-n.
Itt az első hozzászólásban van FTP szerver és kliens megoldás.
viewtopic.php?f=46&t=1849

Vagy ahogy a minta kódomban is az ESP_AsyncFSBrowser (ami integrálva van a fent említett szerverbe) segítségével töltöd fel.
Én szeretem mert weboldalon kapok egy "fájlkezelőt" és egyben szerkesztőt is. Nem kell minden config fájl módosításhoz külön html menü oldalt generálni. Elég csak txt álományba belepiszkálni.

Minta kód nem egy kiforrott termék (kicsit ollózott, kicsit belepiszkált típusú), igazából csak teszt szinten foglalkoztam vele, így nagy tapasztalatom nincs róla, de működik.
Amolyan irányadónak elmegy.
Bitang lassan tölti fel Nextionra azzal is lehetne még kezdeni valamit.
Feltöltés után újra kell indítani a nextiont.

Aztán itt jön a kérdés hogy neked ebből a sok mindenből, amiből végül összeállt a kód, mennyi az ismerős és mennyi a sötét folt? :)

Kód: Egész kijelölése

#include <ESP8266WiFi.h>
#include <FS.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFSEditor.h>
#include <SoftwareSerial.h>

SoftwareSerial _SoftSerial(5, 4, false, 64); 

AsyncWebServer server(80);

const char* ssid = "-----";
const char* password = "----------";

//***************************************************
bool SayshouldReboot = false;   // reboot kapcsoló
bool Nextion_up = false;        // Nextion OTA kapcsoló

// Nextion felé menő üzenetek ürítése
byte ter[3] = { 0xff, 0xff, 0xff };

uint32_t FileSize;
File nextionFile;

void uploadTftFile() {
	uint8_t c;
	uint16_t send_timer = 0;
	uint16_t last_send_num = 0;
	send_timer = FileSize / 4096 + 1;
	last_send_num = FileSize % 4096; //osztás utáni maradék kiszámítása
	int sending_byte = 0;

	Serial.printf("send_timer -> %d ......\n", send_timer);
	Serial.printf("last_send_num -> %d ......\n", last_send_num);

	while (send_timer) {
		if (send_timer == 1) {
			for (uint16_t j = 1; j <= 4096; j++) {
				yield();
				if (j <= last_send_num) {
					c = nextionFile.read();
					_SoftSerial.write(c);
					sending_byte += 1;
				} else {
					break;
				}
			}
		} else {
			for (uint16_t i = 1; i <= 32; i++) {
				yield();
				char ct[128];
				nextionFile.readBytes(ct, 128);
				//_SoftSerial.write(&ct[0], 128);
				_SoftSerial.write(ct, 128);
				sending_byte += 128;
			}
			Serial.printf("sending_byte -> %d ......\n", sending_byte);
			delay(250);
		}
		--send_timer;
	}
	Serial.printf("sending_byte -> %d ......\n", sending_byte);
}

void Nextion_Update() {
	// fájl megnyitása elküldése nextionnak
	nextionFile = SPIFFS.open("/xxxxx.tft", "r");
	if (!nextionFile) {
		Serial.println("Failed to open config file");
		return;
	}

	// get available data size
	FileSize = nextionFile.size();
	Serial.println(FileSize);

	// read up to 128 byte
	_SoftSerial.flush();   
	Serial.println("Contacting Nextion...");
	_SoftSerial.printf("%sconnect%s", ter, ter);
	delay(500);
	_SoftSerial.printf("whmi-wri %u,115200,0", FileSize);

	_SoftSerial.write(ter, 3);
	delay(500);
	Serial.print("Starting UPload...\n");

	int poz = int(FileSize / 128);
	int poz2 = FileSize - poz * 128;
	Serial.print("filesize ");
	Serial.println(FileSize);
	Serial.print("poz ");
	Serial.println(poz);
	Serial.print("poz2 ");
	Serial.println(poz2);

	uploadTftFile();
	nextionFile.close();
}

void setup() {
	//***************************************************
	// serial port aktiválása
	Serial.begin(115200);
	_SoftSerial.begin(115200);

	Serial.println(); //soremelés a boot üzenet után
	//***************************************************
	// előző wifi beállítások törlése újjak beállítása
	WiFi.softAPdisconnect(true);
	WiFi.mode(WIFI_STA);
	WiFi.setAutoConnect(true);
	WiFi.begin(ssid, password);

	WiFi.config( { 192, 168, x, x }, { 192, 168, x, x }, { 255, 255, 255, 0 }, { 192, 168, x, x });

	//***************************************************
	// STA mód routerhez csatlakozási kísérlet
	byte b = 0;
	while (WiFi.status() != WL_CONNECTED) {
		delay(500);
		Serial.print(".");
		b++;
		if (b > 10) {
			Serial.println(F("Sikertelen STA csatlakozás"));
			break;
		}
	}

	if (WiFi.status() == WL_CONNECTED) {
		Serial.print("\nSikeres Wifi kapcsolat\nDHCP IP: ");
		Serial.println(WiFi.localIP());
	}

	//***************************************************
	// fájlrendszer aktiválása
	SPIFFS.begin();

	//***************************************************
	// FS Editor aktiválása
	server.addHandler(new SPIFFSEditor());

	//***************************************************
	// Fájlrendszerből is keressen html oldalakat
	// kezdőoldal beállítása
	server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm");

	//***************************************************
	// weboldalról ESP Firmware frissítése
	server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request) {
			request->send(200, "text/html", "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update' ><input type='submit' value='Update' ></form>");
		});

	server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request) {
		SayshouldReboot = !Update.hasError();
		AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", SayshouldReboot?"OK":"FAIL");
		response->addHeader("Connection", "close");
		request->send(response);
	}, [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
		if(!index) {
			//Serial.printf("Update Start: %s\n", filename.c_str());
			Update.runAsync(true);
			if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) {
				//Update.printError(Serial);
			}
		}
		if(!Update.hasError()) {
			if(Update.write(data, len) != len) {
				//Update.printError(Serial);
			}
		}
		if(final) {
			if(Update.end(true)) {
				SayshouldReboot=true;
				//Serial.printf("Update Success: %uB\n", index+len);
			} else {
				//Update.printError(Serial);
			}
		}
	});

	//***************************************************
	// weboldalról NEXTION Firmware frissítése
	server.on("/nextionup", HTTP_GET, [](AsyncWebServerRequest *request) {
		Nextion_up=true;
		request->send(200, "text/html", "OK");
	});

	//***************************************************
	// hiányzó oldal lekezelése 404 hiba
	server.onNotFound([](AsyncWebServerRequest *request) {
		request->send(404);
	});

	//***************************************************
	// szerver aktiválása
	server.begin();

}

void loop() {
	//***************************************************
	// kérésre Reboot
	if (SayshouldReboot == true) {
		delay(100);
		Serial.println("ESP Reboot kérésre");
		ESP.restart();
	}

	//***************************************************
	// kérésre Nextion frissítés
	if (Nextion_up == true) {
		delay(100);
		Serial.println("Nextion update kérésre");
		Nextion_up = false;
		Nextion_Update();
	}
}
DaeMonSHome
Újonc
Újonc
Hozzászólások: 2
Csatlakozott: 2017. augusztus 25. péntek, 8:39

Re: ESP8266 - Nextion OTA

Hozzászólás Szerző: DaeMonSHome »

koszonom, atnezem, gondolkodom.

Sebesseg ugyben tuom hogy 4k-s tombokben megy fel ,majd szunet stb - ez is lassit sokat..majd ellenorzom.

Osszessegeben attekintheto,
gondolkodom, hogyan lehetne egy olyasmi libet csinalni, mint az OTA, csak egy link-file tallozas-feltoltes.
Avatar
SanyiSay
Elektronbűvölő
Hozzászólások: 1031
Csatlakozott: 2009. február 28. szombat, 7:00

Re: ESP8266 - Nextion OTA

Hozzászólás Szerző: SanyiSay »

Maga a szerver képes fájlokat feltölteni fájlrendszerre, vagy simán fogadni is de az nekem már nagy falat volt egyenlőre.
Kicsit az asynkron megoldás miatt bonyolultabbak a megoldások ez sem segített. Azon viszont csodálkozom hogy eddig nem írta meg senki.
Válasz küldése