esp/arduino Kommunikation optimieren?

Hallo zusammen.

Ich versuche grade meinen DUE mit dem ESP zu verheiraten… funzt auch aber irgendwie ist mir die übertragung zu lahm?

meine code fragmente:

DUE:

//esp8266 communication
if (Serial2.available() > 0) {    // is a character available?
  rx_byte2 = Serial2.read();       // get the character

  if (rx_byte2 != '\n') {
    // a character of the string was received
    rx_str2 += rx_byte2;
  }
  else {
    // end of string
    //DPRINT("empfange: ");
    //DPRINTLN(rx_str2);

    if (rx_str2 == "reset") {
    }

    else if (rx_str2 == "sensors") {

      char espresponsebuff[58];
      double ddhthum = (double) DHTHum;
      double ddhttemp = (double) DHTTemp;
      double ddstemp = (double) DSTemp0;



      sprintf(espresponsebuff, "sensors:%5.2f,%5.2f,%5.2f,%04d,%02d,%02d,%02d,%02d,%02d,%04d\n", ddstemp, ddhttemp, ddhthum, analogRead(ldr), hour(), minute(), second(),day(), month(), year());


      Serial2.write(espresponsebuff);

      
      //DPRINTLN("antworte esp...");
      //Serial2.write("sensors:20.88,22.80,44.80,0000\n");
    }
    else {
      //DPRINTLN("unbekannter befehl");

    }
    rx_str2 = "";                // clear the string for reuse
  }
} // end: if (Serial.available() > 0)

zeit zwischen anfragen ist:

1sekunde

zeit zwischen anfrage und antwort ist:

0.736sekunden

zeit für übertragung der antwort ist

4.363500 ms

der teil “Sensors:” in anfrage und antwort kann ich noch durch “s” z.b. ersetzen und mir so 7 zeichen sparen

was lässt sich da noch optimieren um das ganze schneller zu machen?

esp:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <SoftwareSerial.h>

char rx_byte = 0;
String rx_str = "";
#define INTERVAL 500 // in msec
long temp_time;

String DueDhttemp;
String DueDhthum;
String DueDstemp;
String DueLDR;
String DueTimeSec;
String DueTimeMin;
String DueTimeHour;
String DueDateDay;
String DueDateMonth;
String DueDateYear;


SoftwareSerial swSer(4, 5, false, 256);

ESP8266WebServer server(80);
const char* ssid = "1";
const char* password = "1";
String webSite, javaScript, XML;

void buildWebsite() {
  buildJavascript();
  webSite = "<!DOCTYPE HTML>\n";
  webSite += javaScript;
  webSite += "<BODY onload='process()'>\n";
  webSite += "
This is the ESP website ...
\n";
  webSite += "Runtime = <A id='runtime'></A>
\n";
  webSite += "DHTTEMP = <A id='DHTTEMP'></A>
\n";
  webSite += "DHTHUM = <A id='DHTHUM'></A>
\n";
  webSite += "DSTEMP = <A id='DSTEMP'></A>
\n";
  webSite += "LDR = <A id='LDR'></A>

\n";

  webSite += "DUE Time = <A id='DUETIME'></A>
\n";
  webSite += "DUE DATE = <A id='DUEDATE'></A>
\n";

  webSite += "</BODY>\n";
  webSite += "</HTML>\n";
}


void buildJavascript() {
  javaScript = "<SCRIPT>\n";
  javaScript += "var xmlHttp=createXmlHttpObject();\n";

  javaScript += "function createXmlHttpObject(){\n";
  javaScript += " if(window.XMLHttpRequest){\n";
  javaScript += "    xmlHttp=new XMLHttpRequest();\n";
  javaScript += " }else{\n";
  javaScript += "    xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');\n";
  javaScript += " }\n";
  javaScript += " return xmlHttp;\n";
  javaScript += "}\n";

  javaScript += "function process(){\n";
  javaScript += " if(xmlHttp.readyState==0 || xmlHttp.readyState==4){\n";
  javaScript += "   xmlHttp.open('GET','xml',true);\n";
  javaScript += "   xmlHttp.onreadystatechange=handleServerResponse;\n"; // no brackets?????
  javaScript += "   xmlHttp.send(null);\n";
  javaScript += " }\n";
  javaScript += " setTimeout('process()',1000);\n";
  javaScript += "}\n";

  javaScript += "function handleServerResponse(){\n";
  javaScript += " if(xmlHttp.readyState==4 && xmlHttp.status==200){\n";
  javaScript += "   xmlResponse=xmlHttp.responseXML;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('response');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('runtime').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responsedhttemp');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('DHTTEMP').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responsedhthum');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('DHTHUM').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responsedstemp');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('DSTEMP').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responseldr');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('LDR').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responsetime');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('DUETIME').innerHTML=message;\n";

  javaScript += "   xmldoc = xmlResponse.getElementsByTagName('responsedate');\n";
  javaScript += "   message = xmldoc[0].firstChild.nodeValue;\n";
  javaScript += "   document.getElementById('DUEDATE').innerHTML=message;\n";

  javaScript += " }\n";
  javaScript += "}\n";
  javaScript += "</SCRIPT>\n";
}

void buildXML() {
  XML = "<?xml version='1.0'?>";

  XML += "<Sensors>";

  XML += "<response>";
  XML += millis2time();
  XML += "</response>";


  XML += "<responsedhttemp>";
  XML += DueDhttemp;
  XML += "</responsedhttemp>";

  XML += "<responsedhthum>";
  XML += DueDhthum;
  XML += "</responsedhthum>";

  XML += "<responsedstemp>";
  XML += DueDstemp;
  XML += "</responsedstemp>";

  XML += "<responseldr>";
  XML += DueLDR;
  XML += "</responseldr>";

  XML += "<responsetime>";
  XML += DueTimeHour;
  XML += ":";
  XML += DueTimeMin;
  XML += ":";
  XML += DueTimeSec;
  XML += "</responsetime>";

  XML += "<responsedate>";
  XML += DueDateDay;
  XML += ":";
  XML += DueDateMonth;
  XML += ":";
  XML += DueDateYear;
  XML += "</responsedate>";

  XML += "</Sensors>";

}

String millis2time() {
  String Time = "";
  unsigned long ss;
  byte mm, hh;
  ss = millis() / 1000;
  hh = ss / 3600;
  mm = (ss - hh * 3600) / 60;
  ss = (ss - hh * 3600) - mm * 60;
  if (hh < 10)Time += "0";
  Time += (String)hh + ":";
  if (mm < 10)Time += "0";
  Time += (String)mm + ":";
  if (ss < 10)Time += "0";
  Time += (String)ss;
  return Time;
}

void handleWebsite() {
  buildWebsite();
  server.send(200, "text/html", webSite);
}

void handleXML() {
  long time = millis();
  if (time > temp_time + INTERVAL) {
    swSer.write("sensors\n");
    temp_time = millis();
  }

  buildXML();
  server.send(200, "text/xml", XML);
}

void setup() {
  Serial.begin(115200);
  swSer.begin(115200);
  Serial.println("\nSerial started");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)delay(500);
  WiFi.mode(WIFI_STA);
  Serial.println("\n\nBOOTING ESP8266 ...");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("Station IP address: ");
  Serial.println(WiFi.localIP());
  server.on("/", handleWebsite);
  server.on("/xml", handleXML);
  server.begin();
}

void loop() {
  server.handleClient();

  read_arduino();
}

void read_arduino() {

  if (swSer.available() > 0) {    // is a character available?
    rx_byte = swSer.read();       // get the character

    if (rx_byte != '\n') {
      // a character of the string was received
      rx_str += rx_byte;
    }
    else {
      // Serial.print("empfange von DUE: ");
      //Serial.println(rx_str);
      //sensors:20.88,22.80,44.80,0000

      if (rx_str.startsWith("sensors:", 0))
      {
        // Serial.println(rx_str);
        rx_str.remove(0, 8);
        // Serial.println(rx_str);

        DueDhttemp = "";
        DueDhthum = "";
        DueDstemp = "";
        DueLDR = "";
        DueTimeSec = "";
        DueTimeMin = "";
        DueTimeHour = "";
        DueDateDay = "";
        DueDateMonth = "";
        DueDateYear = "";

        int Index1 = rx_str.indexOf(',');
        int Index2 = rx_str.indexOf(',', Index1 + 1);
        int Index3 = rx_str.indexOf(',', Index2 + 1);
        int Index4 = rx_str.indexOf(',', Index3 + 1);
        int Index5 = rx_str.indexOf(',', Index4 + 1);
        int Index6 = rx_str.indexOf(',', Index5 + 1);
        int Index7 = rx_str.indexOf(',', Index6 + 1);
        int Index8 = rx_str.indexOf(',', Index7 + 1);
        int Index9 = rx_str.indexOf(',', Index8 + 1);
        int Index10 = rx_str.indexOf(',', Index9 + 1);
        int Index11 = rx_str.indexOf(',', Index10 + 1);


        DueDstemp = rx_str.substring(Index10 + 1, Index11);
        DueDhttemp = rx_str.substring(Index1 + 1, Index2);
        DueDhthum = rx_str.substring(Index2 + 1, Index3);
        DueLDR = rx_str.substring(Index3 + 1, Index4);
        DueTimeHour = rx_str.substring(Index4 + 1, Index5);
        DueTimeMin = rx_str.substring(Index5 + 1, Index6);
        DueTimeSec = rx_str.substring(Index6 + 1, Index7);
        DueDateDay = rx_str.substring(Index7 + 1, Index8);
        DueDateMonth = rx_str.substring(Index8 + 1, Index9);
        DueDateYear = rx_str.substring(Index9 + 1, Index10);

      }
      rx_str = "";                // clear the string for reuse


    }
  } // end: if (Serial.available() > 0)

}

Warum nimmst Du nicht I2C? Ein Beispiel mit UNO/NANO habe ich hier gepostet.

Gruß Tommy

i2c geht doch nur in eine richtung oder? bzw frage senden und antwort erhalten... ich will mich aber in beide richtungen unterhalten also auch mal von DUE zum ESP ohne das der ESP mich danach gefragt hat

mpl1337:
i2c geht doch nur in eine richtung oder? bzw frage senden und antwort erhalten... ich will mich aber in beide richtungen unterhalten also auch mal von DUE zum ESP ohne das der ESP mich danach gefragt hat

Das kannst du doch per Interrupt lösen.

Ja, das ist es. Man könnte aber noch eine Statusleitung hinzu nehmen, womit der Slave dem Master sagt: Frag mich mal was ich Dir zu sagen habe.

Du kannst auch übers Netzwerk gehen (2 UDP-Server), das ist auch bidirektional.

Gruß Tommy

Ich hab mich mit dem thema i2c schon beschäftigt gehabt aber habs nicht richtig zum laufen bekommen hatte öfters mal nen eingefroreren DUE oder ESP...

Tommy56:
Du kannst auch übers Netzwerk gehen (2 UDP-Server), das ist auch bidirektional.

Gruß Tommy

dafür müsste ich dem DUE nen LAN anschluss erst verpassen oder?

ich hab schon nen LCD und ne SD card am SPI hängen... wenn da noch nen Netzwerkcontroller mit drangeht befürchte ich böses :smiley:

Vom SPI her sollte es funktionieren aber die Ethernet-Module sollen einen Prinzipfehler haben, wodurch sie nicht in den hochohmigen Zudtand gehen, wenn sie desektiert sind. Da gab es mal einen Thread hier im Forum dazu. Evtl. weiß einer der Mitleser noch, welcher das war.

Also ich habe bei kurzen Entfernungen ( < 30 cm) noch nie Probleme mit I2C gehabt.

Gruß Tommy

mpl1337:
Ich hab mich mit dem thema i2c schon beschäftigt gehabt aber habs nicht richtig zum laufen bekommen hatte öfters mal nen eingefroreren DUE oder ESP...

Beim DUE habe ich keine Erfahrung mit I2C, aber Uno, Nano, Pro Mini und ATtiny macihen das alle problemlos.
Der Skietch muss natürlich sauberi aufebaut sein, dann klappt es auch mit I2C.
Und auf kurzer Distanz erst recht.

Ja i2c ansich funzt am DUE auch ohne probleme mit Sensoren.. das problem war ich... ich hatte irgendwo nen fehler drin und konnte diesen nicht lokalisieren.. bzw konnte ich schon lokalisieren aber wusste nicht warum das passiert bzw wusste nicht was ich dagegen machen kann

jetzt läuft das ganze seit 2 wochen stabil per UART nur ein wenig lahm...

Auch auf dem NodeMCU (ESP8266-12E) läuft I2C problemlos.

Gruß Tommy

mpl1337:
jetzt läuft das ganze seit 2 wochen stabil per UART nur ein wenig lahm...

Was du mit "lahm" meinst, würde mich mal interessieren.
Ich verwende eine serielle Verbindung zwischen einem Uno und einem Atmega328 zur Übertragung von Schaltbefehlen und da geht es schnell.
Ich kann es schlecht in Millisekunden ausdrücken, aber gefühlt wird die Anweisung im Atmega328 direkt nach dem Drücken der Taste am Uno ausgeführt.