Lan Luxmeter Wert senden an Server

Hollo zusammen,

wie schon die Überschrift sagt,möchte ich den gemessenen Wert des Luxmeters an Ip und Port senden.

Hier mien code:

#include <Ethernet.h>
    #include <SPI.h>
// ----------------------- Sensor 
    #include <Wire.h>
    #include <BH1750.h>
    BH1750 lightMeter;
// ----------------------- I/O
    int LedSend = 8;                                             // Senden LED
    int LedErr  = 9;                                             // Error Led
// ----------------------- Delay Zeiten    
    const long eineSekunde = 1000;                               // Delay eine sekunde
    const long eineMinute = eineSekunde *60;                     // Delay eine Minute
    const long fuenfMinuten = eineMinute *5;                     // Delay eine Minute
    const long eineStunde = eineMinute *60;                      // Delay eine Stunde 
    const long einenTag = eineStunde *24;                        // delay einen Tag
// ----------------------- Lan Modul Einstellungen
    byte mac[] = {0xDE, 0xAD, 0xBE, 0xAF, 0xCE, 0xDD };          // Mac Adresse
    byte ip[] = {192, 168, 178, 86 };                            // Klient IP
    byte server[] = {192, 168, 178, 22 };                        // Server IP
    EthernetClient client;                                       // Klient starten
// ============================================ Setup ============================================     
void setup()
    {       
// ------------- Ausgänge deffinieren
        pinMode(LedSend, OUTPUT);                                  // Pin 8 Als Ausgang deffinieren
        pinMode(LedErr, OUTPUT);                                   // Pin 8 Als Ausgang deffinieren
// ------------- TCPIP verbindung aufbauen
        Ethernet.begin(mac, ip);                                   // Verbinden 
        Serial.begin(9600);                                        // Serialausgabe starten
        lightMeter.begin();                                        // Sensor starten
        delay(1000);                                               // Pause zum  Initialisieren
        Serial.println("Initialisieren abgeschlossen");            // Serialausgabe
    }
// ----------------------- Unterfunktion Error blink     
void ErrorBlink()
    {
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);
        delay(500);
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);
        delay(500);
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);    
    } 
// ----------------------- Unterfunktion Lux Messung     
void MessungLux()
       {
        Serial.println("Verbinde mit Server");                     // Serialausgabe 
        if (client.connect(server, 54711))                         // Prüfen ob Verbindung besteht
        {                     
        Serial.println("Verbunden");                               // Serialausgabe
        digitalWrite(LedSend, HIGH);                               // Senden LED an
        Serial.print("Sende daten an Server...");
        uint16_t lux = lightMeter.readLightLevel();                // Lux Variable
        Serial.print("Luxmessung: ");                              // Serial Ausgabe
        Serial.print(lux);                                         // Serialausgabe luxwert
        Serial.println(" lux");                                    // Serialausgabe
        client.print("LanSensor sLuxmeter=");                    // String der gesendet wird
        client.print(lux);
        client.println(); 
        client.stop();                                             // Klienten beenden
        delay(500);                                                // Senden LED Delay
        digitalWrite(LedSend, LOW) ;                               // Senden LED aus
        Serial.println("Void Luxmessung Senden Ende"); 
     } 
   }
// =========================================== Loop ==============================================
void loop()
{
        MessungLux();
        delay(eineMinute);
}

Hierbei wird die Verbindung zwar aufgebaut,der Modulname “LanSensor” gesendet, jedoch fehlt der gemessene Wert .

Am Serialmonitor geht alles wunderbar,es wird verbunden und der gemessene wert des Sensors auch angezeigt.

Senden ich jedoch den Wert als einen festen Wert,also so:

client.print("LanSensor sLuxmeter=123456");                    // String der gesendet wird
        //client.print(lux);
        client.println(); 
        client.stop();                                             // Klienten beenden

Wir der am Server empfangen und das Objekt “Luxmeter” mit dem Wert gefüllt.

Was mache ich falsch?

Besten Dank vorab,

Mfg.
haustechno

hier noch die serialausgabe:

Initialisieren abgeschlossen<\r><\n>
Verbinde mit Server<\r><\n>
Verbunden<\r><\n>
Sende daten an Server...Luxmessung: 373 lux<\r><\n>
Void Luxmessung Senden Ende

Haustechno:
Was mache ich falsch?

Vielleicht gibst Du dem client noch eine winzige Millisekunde, um die Daten aus dem Netzwerkkabel rauszubekommen, bevor Du den Client mit client.stop() abwürgst? Du kannst ja Dein nachfolgendes delay dann um 1 ms kürzen:

delay(1);               // gib dem Client eine Chance, die Daten rauszuschicken
client.stop();          // Klienten beenden
delay(499);            // Senden LED Delay

Wie sieht es denn damit aus?

Vielen dank für den Tip :grin:

Leider geht es trotzdem nicht =(

Also momentan sieht der code so aus:

void MessungLux()
       {
        Serial.println("Verbinde mit Server");                     // Serialausgabe 
        if (client.connect(server, 54711))                         // Prüfen ob Verbindung besteht
        {      
        Serial.println("Verbunden");                               // Serialausgabe
        digitalWrite(LedSend, HIGH);                               // Senden LED an
        Serial.println("Sende Daten an Server...");                // Serialausgabe
        uint16_t lux = lightMeter.readLightLevel();                // Lux Variable
        Serial.print("Luxmessung:");                               // Serial Ausgabe
        Serial.print(lux);                                         // Serialausgabe luxwert
        Serial.println(" lux");                                    // Serialausgabe
        
        String stringOne = "LanSensor sLuxmeter="; 
        String stringTwo =  String(lux);
        String stringSend = String(stringOne + stringTwo);
        Serial.println(stringOne);
        Serial.println(stringTwo);
        Serial.println(stringSend);
        
        client.println(stringSend);
        client.println();
        delay(100); 
        client.stop();                                             // Klienten beenden
        delay(500);                                                // Senden LED Delay
        digitalWrite(LedSend, LOW) ;                               // Senden LED aus
        Serial.println("Void Luxmessung Senden Ende"); 
     } 
   }

Wobei hier der Text und der messwert zu einem String zusammengefasst werden,der dann gesendet wird.

Hier der Serial Log:

Initialisieren abgeschlossen<\r><\n>
Verbinde mit Server<\r><\n>
Verbunden<\r><\n>
Sende Daten an Server...<\r><\n>
Luxmessung:70 lux<\r><\n>
LanSensor sLuxmeter=<\r><\n>
70<\r><\n>
LanSensor sLuxmeter=70<\r><\n>
Void Luxmessung Senden Ende

Die vorletzte zeile das ist der String der gesendet werden soll,laut Serial auch prima funktioniert.

Leider bekommt der server nur den ersten Buchstaben mit,nur das “L” anstatt " LanSensor sLuxmeter=70".

Hier der Server im Anhang

server.jpg

Haustechno: Leider geht es trotzdem nicht =( ...

        String stringSend = String(stringOne + stringTwo);

Das sieht voll Panne aus und sollte bei Dir ja wohl eher heißen:

        String stringSend = stringOne + stringTwo;

Die Programmierung mit "String" Objekten würde ich mir an Deiner Stelle gleich wieder komplett abgewöhnen.

Die typischen Strings unter C/C++ sind "char Arrays" (C-Strings, nullterminierte Strings). Damit sparst Du gegenüber String-Objekten RAM-Speicher, Rechenzeit, und hast jederzeit kompatible Variablen zum Aufrufen von Libraryfunktionen der AVR libc.

ok werde mich dann in die char Arrays einarbeiten :D

SO LÄUFTS

#include <SPI.h>
#include <Ethernet.h>

// ----------------------- I/O
    int LedSend = 8;                                             // Senden LED
    int LedErr  = 9;                                             // Error Led
// ----------------------- Delay Zeiten    
    const long eineSekunde = 1000;                               // Delay eine sekunde
    const long eineMinute = eineSekunde *60;                     // Delay eine Minute
    const long fuenfMinuten = eineMinute *5;                     // Delay eine Minute
    const long eineStunde = eineMinute *60;                      // Delay eine Stunde 
    const long einenTag = eineStunde *24;                        // delay einen Tag


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,178,177);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
// ------------- Ausgänge deffinieren
        pinMode(LedSend, OUTPUT);                                  // Pin 8 Als Ausgang deffinieren
        pinMode(LedErr, OUTPUT);                                   // Pin 8 Als Ausgang deffinieren
// ------------- TCPIP verbindung aufbauen

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
	  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
                  Serial.println("Verbunden");                               // Serialausgabe
                  
int sensorReading = analogRead(0);
        Serial.println("Verbinde mit Server");                     // Serialausgabe                
        Serial.println("Verbunden");                               // Serialausgabe
        digitalWrite(LedSend, HIGH);                               // Senden LED an
        Serial.print("Sende daten an Server...");
        uint16_t lux = analogRead(0);               // Lux Variable
        Serial.print("Luxmessung: ");                              // Serial Ausgabe
        Serial.print(lux);                                         // Serialausgabe luxwert
        Serial.println(" lux");                                    // Serialausgabe
        client.print("LanSensor sLuxmeter=");                    // String der gesendet wird
        client.print(lux);
        client.println(); 
        client.stop();                                             // Klienten beenden
        delay(500);                                                // Senden LED Delay
        digitalWrite(LedSend, LOW) ;                               // Senden LED aus
        Serial.println("Void Luxmessung Senden Ende");
        
            client.println("
");       
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}


void ErrorBlink()
    {
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);
        delay(500);
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);
        delay(500);
        digitalWrite(LedErr, HIGH);                                // Error LED an
        delay(500);
        digitalWrite(LedErr, LOW);    
    }

Malzeit zusammen,

also im Grunde geht alles bisher so wie ich es wollte,sogar mit LCD Ausgabe
Jetzt wollte ich wie schon " jurs " empfohlen hat,die strings in Char variablen ändern.

Kompletter Code ist im Anhang,jedoch hab ich kein Plan wie ich die strings in char strings ändere und diese dann wieder als array,also in der syntax " sText:=wert " an Port und Ip senden kann.

Hier als Beispiel aus der Funktion Temperatur:

int16_t Temperatur = dht.readTemperature()-2;           // Variable vom Sensor
// --------------------- String Temperatur erstellen        
        String stringTextTemp = "sLantemp="; 
        String stringWertTemp = String(Temperatur);
        String stringSendenTemp = stringTextTemp + stringWertTemp ;
// --------------------- Serialausgabe String Temperatur        
        Serial.print("Variable Text:");                            // Serial Ausgabe
        Serial.println(stringTextTemp);
        Serial.print("Variable Wert:");                            // Serial Ausgabe
        Serial.println(stringWertTemp);
        Serial.print("Zusammengesetzter String:");                 // Serial Ausgabe
        Serial.println(stringSendenTemp);
        delay(100);
// ------------------ Senden Temperatur an Server  
        Serial.println("Sende Daten an Server...");                // Serialausgabe
        client.println(stringSendenTemp);
        client.println();
        delay(50);                                                 // Delay zum senden
        client.stop();                                             // Klienten beenden
        Serial.println("Verbindung beendet !");                     // Serialausgabe
        delay(500);                                                // Senden LED Delay
        digitalWrite(LedSend, LOW) ;

Wie könnte da so eine Änderung aussehen?
kann mir einer einen Tip bzw. ein kurzes Beispiel geben?

Mfg.
Haustechno

Klient_Luxmessung_Temperatur_Feuchte_LCD_Senden.ino (10.8 KB)

Wieso willst du den String zusammensetzen? Das ist doch völlig unnötig! Serial oder Ethernet ist es vollkommen egal ob das in einem String/Array steht oder nicht. Das kostet nur Zeit und Speicher. Erst recht mit der grausigen String Klasse, aber auch mit Arrays ist es nicht nötig.

Wenn du eine angenehmere Syntax möchtest, leg dir das hier zu:
http://arduiniana.org/libraries/streaming/
Damit hast du bequeme Output Streams wie in C++

Dann kannst du einfach sowas machen:

client << "Temperatur:" << temp << endl;

Der Code der Hintendran rausfällt ist genau der gleiche, da nur der << Operator mit inline Funktionen überladen wird die print() aufrufen

Noch ein Tip:
Verwende überall wo du String Konstanten mit print()/println() hast das F()-Makro. Sonst landen die Strings im RAM:

Serial.print(F("String im Flash"));

Ihm geht es weniger ums Ethernet. Sein Server empfängt wohl nur strings. Ich hatte es aber auch ohne strings geschafft, keine lust jetzt XP in VM wieder installieren zum testen, hatte schon letztes mal nervenkollaps bekommen :D Vielleicht schaffts ja einer ohne mit der App zu testen.

skorpi08: Sein Server empfängt wohl nur strings.

Das ist eine sinnfreie Aussage. Die String Klasse ist letztlich eine ineffiziente Wrapper Klasse für Arrays mit einigen Zusatzfunktionen. Wenn du ein String Objekt verschickst macht Serial/Ethernet damit auch nichts anderes als mit char Arrays. Für die Ethernet Klasse macht das keinen Unterschied.

Und das hier funktioniert laut vorherigen Post:

 client.print("LanSensor sLuxmeter=");
client.print(lux);
client.println();

Wieso muss das also in einen String/ein Array? Wenn es nur um die Syntax geht und man das lieber in einer Zeile möchte, dann wie gesagt Streaming. Die SdFat Klase hat auch I/O Streams die mehr C++ Funktionalität abbilden. Die funktionieren glaube ich auch mit Ethernet, nicht nur Serial.

Haustechno, da haste es noch von einem bestätigt bekommen, funktioniert auch ohne den Strings. Hab ich doch letztes mal auch ohne Strings gemacht?! An -dem- Code kann es ja dann nicht liegen.

Abend,

@ Serenifly

Also mein Server akzeptiert halt leider nur diese Syntax:

sLanTemp=20,0

Dabei steht das "s" für Set das "Lantemp=" ist das Objekt in das der Wert geschrieben wird, hinter dem = ist dann der eigentliche Wert"20.0"

Der Server nimmt also nur den zusammengesetzten string an :

sLanTemp=20.0

Nur so und auch nicht getrennt gesendet wird es empfangen und dann in der software der Wert hinter dem = in das Objekt geschrieben-

@ skorpi08

wir haben damals nur feste Werte übermittelt keine Variablen!!!!

Also z.b. "sLantatster=an"

Jetzt wird aber ein fester Text und ein aktueller Wert gesendet,und das muss doch vorher erst zusammengesetzt werden in einen String oder nicht?

Dies ist 1 (eine) Einheit: client.print(“LanSensor sLuxmeter=”);client.print(lux);
Damit bestätigst du es, sagst also dass “der String” fertig geschrieben wurde: client.println();

Dies sind 2 Einheiten client.println(“LanSensor sLuxmeter=”);client.println(lux);

Es ist dasselbe wie wenn du über Serial anzeigen lässt, es ist mit Serial.print immer nur 1 String, solange bis kein Serial.println kommt.

ok

irgendwie stehe ich auf dem schlauch :(

Wohl zu spät Heute.......

Werde mir das nochmal da durchlesen mit der stream.lib

Vielen Dank trotzdem an euch beide ;)

Ich geh besser ins Bett :sleeping:

Mfg. haustechno

Ich kann mir sowas einfach schwer vorstellen. Der Server bekommt doch gar nicht mit wie das vom Arduino gesendet wird. Die Ethernet Klasse wird das natürlich in verschiedene Pakete aufteilen, wodurch vielleicht mehr Overhead entsteht. Aber auch das sollte den Server einen Dreck interessieren. Das läuft schließlich auf den unteren Ebenen des Übertragungsprotokolls ab. Ob das gestückelt ist, oder nicht, am Ende kommt das gleiche an.

Falls du wirklich darauf bestehst:

char buffer[30];        //muss so lange wie der maximale String + 1 sein!
snprintf_P(buffer, sizeof(buffer), PSTR("LanSensor sLuxmeter=%d"), lux);
client.println(buffer);

Warnung: das geht auf dem Arduino nicht mit float!!

float brauch er aber, zumindest 5 Stellen.

Dann kann man einen Umweg über dtostrf() nehmen:

float value = 12.34;
char floatBuffer[7];
dtostrf(value, -5, 2, floatBuffer);
char buffer[20];
snprintf_P(buffer, sizeof(buffer), PSTR("Temp=%s"), floatBuffer);
Serial.println(buffer);

5, 2 bedeutet dabei mindestens 5 Zeichen Breite (inklusive evtl. Vorzeichen und Punkt) und 2 Nachkommastellen. Das Minus macht es linksbündig (was hier wichtig ist, sonst hat man Leerzeichen nach dem = wenn die Zahl weniger Vorkommastellen hat): http://www.mikrocontroller.net/topic/86391#728740 http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

Aber ich bezweifle trotzdem dass das einen Unterschied macht. Bei dir scheint es ja auch so zu gehen