Serieller Plotter im Web anzeigen

Hallo,
ich habe den NodeMCU ESP8266 Mikrocontroller und wollte mal fragen, ob es möglich ist den Seriellen Plotter der mir momentan Werte eines Sensors liefert über das Internet ausgeben zu lassen.
Also den Controller mit dem Internet verbinden hab ich schon und ich kann da auch einen Text ausgeben. Aber wie geht das mit dem Serial Plot? Im Prinzip sollte es so aussehen wie hier: Arduino - Web Serial Plotter - Arduino Project Hub
Nur eben angepasst an meinen Controller.
Vielen Dank im voraus für eure Hilfe.

Hallo,

ich hab sowas mal mit HTML code basierend auf einer svg Grafik gemacht. Ist aber ziemlich aufwendig. Ich denke da gibts bessere Lösungen.

Hast Du Dich schon mal bei fips umgesehen.

Heinz

Hallo Heinz, nein hab ich noch nicht. Da schau ich auch mal nach.
Ich habe gerade ein Beispiel Code in der Arduino IDE gefunden- Er war zu finden unter Beispiele->ESP8266WebServer->Graph

#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>

#if defined USE_SPIFFS
#include <FS.h>
FS* fileSystem = &SPIFFS;
SPIFFSConfig fileSystemConfig = SPIFFSConfig();
#elif defined USE_LITTLEFS
#include <LittleFS.h>
FS* fileSystem = &LittleFS;
LittleFSConfig fileSystemConfig = LittleFSConfig();
#elif defined USE_SDFS
#include <SDFS.h>
FS* fileSystem = &SDFS;
SDFSConfig fileSystemConfig = SDFSConfig();
// fileSystemConfig.setCSPin(chipSelectPin);
#else
#error Please select a filesystem first by uncommenting one of the "#define USE_xxx" lines at the beginning of the sketch.
#endif


#define DBG_OUTPUT_PORT Serial

#ifndef STASSID
#define STASSID "xxx"
#define STAPSK  "xxx"
#endif

// Indicate which digital I/Os should be displayed on the chart.
// From GPIO16 to GPIO0, a '1' means the corresponding GPIO will be shown
// e.g. 0b11111000000111111
unsigned int gpioMask;

const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "graph";

ESP8266WebServer server(80);

static const char TEXT_PLAIN[] PROGMEM = "text/plain";
static const char FS_INIT_ERROR[] PROGMEM = "FS INIT ERROR";
static const char FILE_NOT_FOUND[] PROGMEM = "FileNotFound";

////////////////////////////////
// Utils to return HTTP codes

void replyOK() {
  server.send(200, FPSTR(TEXT_PLAIN), "");
}

void replyOKWithMsg(String msg) {
  server.send(200, FPSTR(TEXT_PLAIN), msg);
}

void replyNotFound(String msg) {
  server.send(404, FPSTR(TEXT_PLAIN), msg);
}

void replyBadRequest(String msg) {
  DBG_OUTPUT_PORT.println(msg);
  server.send(400, FPSTR(TEXT_PLAIN), msg + "\r\n");
}

void replyServerError(String msg) {
  DBG_OUTPUT_PORT.println(msg);
  server.send(500, FPSTR(TEXT_PLAIN), msg + "\r\n");
}

////////////////////////////////
// Request handlers

/*
   Read the given file from the filesystem and stream it back to the client
*/
bool handleFileRead(String path) {
  DBG_OUTPUT_PORT.println(String("handleFileRead: ") + path);

  if (path.endsWith("/")) {
    path += "index.htm";
  }

  String contentType = mime::getContentType(path);

  if (!fileSystem->exists(path)) {
    // File not found, try gzip version
    path = path + ".gz";
  }
  if (fileSystem->exists(path)) {
    File file = fileSystem->open(path, "r");
    if (server.streamFile(file, contentType) != file.size()) {
      DBG_OUTPUT_PORT.println("Sent less data than expected!");
    }
    file.close();
    return true;
  }

  return false;
}


/*
   The "Not Found" handler catches all URI not explicitely declared in code
   First try to find and return the requested file from the filesystem,
   and if it fails, return a 404 page with debug information
*/
void handleNotFound() {
  String uri = ESP8266WebServer::urlDecode(server.uri()); // required to read paths with blanks

  if (handleFileRead(uri)) {
    return;
  }

  // Dump debug data
  String message;
  message.reserve(100);
  message = F("Error: File not found\n\nURI: ");
  message += uri;
  message += F("\nMethod: ");
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += F("\nArguments: ");
  message += server.args();
  message += '\n';
  for (uint8_t i = 0; i < server.args(); i++) {
    message += F(" NAME:");
    message += server.argName(i);
    message += F("\n VALUE:");
    message += server.arg(i);
    message += '\n';
  }
  message += "path=";
  message += server.arg("path");
  message += '\n';
  DBG_OUTPUT_PORT.print(message);

  return replyNotFound(message);
}
  
void setup(void) {
  ////////////////////////////////
  // SERIAL INIT
  DBG_OUTPUT_PORT.begin(115200);
  DBG_OUTPUT_PORT.setDebugOutput(true);
  DBG_OUTPUT_PORT.print('\n');

  ////////////////////////////////
  // FILESYSTEM INIT

  fileSystemConfig.setAutoFormat(false);
  fileSystem->setConfig(fileSystemConfig);
  bool fsOK = fileSystem->begin();
  DBG_OUTPUT_PORT.println(fsOK ? F("Filesystem initialized.") : F("Filesystem init failed!"));

  ////////////////////////////////
  // PIN INIT
  pinMode(4, INPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(15, OUTPUT);

  ////////////////////////////////
  // WI-FI INIT
  DBG_OUTPUT_PORT.printf("Connecting to %s\n", ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    DBG_OUTPUT_PORT.print(".");
  }
  DBG_OUTPUT_PORT.println("");
  DBG_OUTPUT_PORT.print(F("Connected! IP address: "));
  DBG_OUTPUT_PORT.println(WiFi.localIP());

  ////////////////////////////////
  // MDNS INIT
  if (MDNS.begin(host)) {
    MDNS.addService("http", "tcp", 80);
    DBG_OUTPUT_PORT.print(F("Open http://"));
    DBG_OUTPUT_PORT.print(host);
    DBG_OUTPUT_PORT.println(F(".local to open the graph page"));
  }

  ////////////////////////////////
  // WEB SERVER INIT

  //get heap status, analog input value and all GPIO statuses in one json call
  server.on("/espData", HTTP_GET, []() {
    String json;
    json.reserve(88);
    json = "{\"time\":";
    json += millis();
    json += ", \"heap\":";
    json += ESP.getFreeHeap();
    json += ", \"analog\":";
    json += analogRead(A0);
    json += ", \"gpioMask\":";
    json += gpioMask;
    json += ", \"gpioData\":";
    json += (uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16));
    json += "}";
    server.send(200, "text/json", json);
  });

  // Default handler for all URIs not defined above
  // Use it to read files from filesystem
  server.onNotFound(handleNotFound);


  // Start server
  server.begin();
  DBG_OUTPUT_PORT.println("HTTP server started");

  DBG_OUTPUT_PORT.println("Please pull GPIO4 low (e.g. press button) to switch output mode:");
  DBG_OUTPUT_PORT.println(" 0 (OFF):    outputs are off and hidden from chart");
  DBG_OUTPUT_PORT.println(" 1 (AUTO):   outputs are rotated automatically every second");
  DBG_OUTPUT_PORT.println(" 2 (MANUAL): outputs can be toggled from the web page");

}

// Return default GPIO mask, that is all I/Os except SD card ones
unsigned int defaultMask() {
  unsigned int mask = 0b11111111111111111;
  for (auto pin = 0; pin <= 16; pin++) {
    if (isFlashInterfacePin(pin)) {
      mask &= ~(1 << pin);
    }
  }
  return mask;
}

int rgbMode = 1; // 0=off - 1=auto - 2=manual
int rgbValue = 0;
esp8266::polledTimeout::periodicMs timeToChange(1000);
bool modeChangeRequested = false;

void loop(void) {
  server.handleClient();
  MDNS.update();

  if (digitalRead(4) == 0) {
    // button pressed
    modeChangeRequested = true;
  }

  // see if one second has passed since last change, otherwise stop here
  if (!timeToChange) {
    return;
  }

  // see if a mode change was requested
  if (modeChangeRequested) {
    // increment mode (reset after 2)
    rgbMode++;
    if (rgbMode > 2) {
      rgbMode = 0;
    }

    modeChangeRequested = false;
  }

  // act according to mode
  switch (rgbMode) {
    case 0: // off
      gpioMask = defaultMask();
      gpioMask &= ~(1 << 12); // Hide GPIO 12
      gpioMask &= ~(1 << 13); // Hide GPIO 13
      gpioMask &= ~(1 << 15); // Hide GPIO 15

      // reset outputs
      digitalWrite(12, 0);
      digitalWrite(13, 0);
      digitalWrite(15, 0);
      break;

    case 1: // auto
      gpioMask = defaultMask();

      // increment value (reset after 7)
      rgbValue++;
      if (rgbValue > 7) {
        rgbValue = 0;
      }

      // output new values
      digitalWrite(12, rgbValue & 0b001);
      digitalWrite(13, rgbValue & 0b010);
      digitalWrite(15, rgbValue & 0b100);
      break;

    case 2: // manual
      gpioMask = defaultMask();

      // keep outputs unchanged
      break;
  }
}

ich bin leider ein Anfänger und kann da nicht viel mit anfangen-Außer wie ich den Webserver starte.
Kann man den obigen Code denn mit folgendem modifizieren, damit diese werte online angezeigt werden?

//===================================================================================NodeMCU Sensor Serial Plotter
//----------------------------------------Variable Declaration
const int Sensor = A0; 
const int LED= D4; 
int Threshold = 650; 
int Signal; //--> holds the incoming raw data.
//----------------------------------------

//--------------------------------------------------------------------------------void setup
void setup() {
  Serial.begin(9600); //--> Set's up Serial Communication at certain speed.
  pinMode(LED,OUTPUT); //--> Set LED_3 PIN as Output.
}
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------void loop
void loop() {
  Signal = analogRead(Sensor); //--> Read the Sensors's value. Assign this value to the "Signal" variable.

  Serial.println(Signal); //--> Send the Signal value to Serial Plotter.

  if(Signal < Threshold){ //--> If the signal is above "600"(Threshold), then "turn-on" Arduino's on-Board LED.
    digitalWrite(LED,HIGH);
  } else {
    digitalWrite(LED ,LOW); //--> Else, the sigal must be below "600", so "turn-off" this LED.
  }

  delay(10);
}

also mit einer Bibliotek ala Highchart.com sollte das doch auch am ESP zu schaffen sein einen Graph in einem Webbrowser anzeigen zu lassen.

Oder eben ein SVG ... kommt halt drauf an wie viele Graphen / wie viele Werte auf X ... kann eigentlich auch händisch nicht SOOO kompliziert sein, oder unterschätze ich das jetzt?

noiasca:
also mit einer Bibliotek ala Highchart.com sollte das doch auch am ESP zu schaffen sein einen Graph in einem Webbrowser anzeigen zu lassen.

Oder eben ein SVG ... kommt halt drauf an wie viele Graphen / wie viele Werte auf X ... kann eigentlich auch händisch nicht SOOO kompliziert sein, oder unterschätze ich das jetzt?

Ich glaub eher, dass du mich überschätzt :sweat_smile: Ich bin leider noch blutiger Anfänger und bekomme das alleine nicht hin-muss ich aber :smiley:
Und es soll eigentlich nur dieser eine Graph sein, der bei dem 2. Code ausgegeben wird.

Hallo,

ich habe mich zu dem Thema Messwerte auf Web Seite grafisch anzeigen mal auf die Suche begeben und verschiedenes gefunden. Das auf https://www.chartjs.org/. fand ich ganz gut. Da gibts auch reichlich Beispiele und eine ganz gute Doku.

Letztlich war mir auch wichtig das die Lib auf dem Brauser laüft und auch gehostete wird. Damit ist das dann auch mobil auf dem Handy ohne zusätzliche Installation möglich.

Heinz

Alles klar,
vielen Dank für eure Hilfe!