Problem mit Cosm/Ethernetshield und SHT 71 (Feuchte, Temperatursensor)

Hallo.

Ich habe folgendes Problem. Ich habe ein Arduino Ethernet. An dieses ist ein Sensirion SHT71 Temperatur und Luftfeuchtesensor angeschlossen.
Über die SHT1x Library kann ich die Daten vom Sensor wunderbar auslesen.
Und über den Cosm/Pachube Sketch auch wunderbar Daten an Cosm senden.
Wenn ich aber alles zusammen in einen Sketch packe wird alles sehr langsam und funktioniert eigentlich nicht mehr.

Ich vermute das hat vielleicht etwas mit den Zeiten, der kommunikation mit sensor und gleichzeitig mit dem Ethernetshield zu tun. Kann ich nicht die abfragen irgendwie nacheinander ausführen, also das EthernetObjekt oder das Sensorobjekt später erzeugen. Ich komme leider nicht zurecht. Vielleicht wäre jemand so nett und kann sich den Sketch mal anschauen.

Vielen Dank Martin

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


#define APIKEY         "xxxx" // COSM API
#define FEEDID         xxxxx                    // Feed ID
#define USERAGENT      "Archiv Weststraße"             // Projekt NAME
#define dataPin  5
#define clockPin 6

SHT1x sht1x(dataPin, clockPin);

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

byte gateway[] = { 192, 168, 178, 50 };

byte subnet[] = { 255, 255, 255, 0 };

IPAddress ip(192,168,178,1);

EthernetClient client;

IPAddress server(216,52,233,121);              

unsigned long lastConnectionTime = 0;            
boolean lastConnected = false;                   
const unsigned long postingInterval = 10*1000;  

void setup() {
  
  Serial.begin(9600);
 
  delay(1000);
  
  Ethernet.begin(mac, ip, gateway, subnet);
  }


void loop() {
  
  int Temperatur = sht1x.readTemperatureC();
  int Luftfeuchte = sht1x.readHumidity();
  
  String dataString = "Temperatur,";
  dataString +=Temperatur;
  dataString += "\nLuftfeuchte,";
  dataString +=Luftfeuchte;

  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    sendData(dataString);
  }
  lastConnected = client.connected();
}

void sendData(String thisData) {

  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.pachube.com");
    client.print("X-pachubeApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");
    client.println(thisData.length());
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();
    client.println(thisData);

  }
  else {

    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  lastConnectionTime = millis();
}

Was verstehst Du unter

Wenn ich aber alles zusammen in einen Sketch packe wird alles sehr langsam und funktioniert eigentlich nicht mehr.

? Wird der Wert nicht alle 10 bis 15 Sekunden erneuert? Grüße Uwe

Nein leider nicht, beim Einschalten einmal und dann nicht wieder. Hab es nicht so lange laufen lassen um zusehen ob nochmal, aber 10 min nichts. Wenn ich im Serial monitor schaue, kommt die Antwort des Servers von Cosm ganz langsam, Buchstabe für Buchstabe. Ohne die SHT abfrage ist alles ganz normal.

Ich würde das Program umstrukturieren. Das Du das Ergebnis der Clientverbindung Zeichenweise liest und das mit einem Zeichen Pro Loop-Durchlauf, wird jedesmal auch der Sensor abgefragt. Pack das Lesen auch der Verbindung mit in der sendData(), denn da gehört es hin.

Ich habe nun noch etwas geändert.
Aber Cosm bekommt nur einmal Daten nach dem Programmstart.

Danach ist ruhe.

Ich habe die Abfrage des Sensors in sendData gepackt und “if (client.available()) { char c = client.read(); Serial.print(c);” weggelassen.

Hier nochmal der Code, vielleicht hat ja jemand noch eine Idee. Dankeschön

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


#define APIKEY         "xxxxx" // COSM API
#define FEEDID         xxxxx                    // Feed ID
#define USERAGENT      "Archiv Weststraße"             // Projekt NAME
#define dataPin  8
#define clockPin 9

SHT1x sht1x(dataPin, clockPin);

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

byte gateway[] = {192,168,0,1};

byte subnet[] = {255,255,255,0};

IPAddress ip(192,168,0,180);

EthernetClient client;

IPAddress server(216,52,233,121);                // IP für api.pachube.com

unsigned long lastConnectionTime = 0;            
boolean lastConnected = false;                   
const unsigned long postingInterval = 10*1000;   // Abstand zwischen COSM aktualisierungen

void setup() {
  Serial.begin(9600);
 
  delay(1000);
  
   if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // DHCP failed, so use a fixed IP address:
    Ethernet.begin(mac, ip, gateway, subnet);
  }
}
void loop() {
  
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    sendData();
  }
  lastConnected = client.connected();
}

void sendData() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
      int Temperatur = sht1x.readTemperatureC();
      int Luftfeuchte = sht1x.readHumidity();
  
         String dataString = "Temperatur,";
         dataString +=Temperatur;
         dataString += "\nLuftfeuchte,";
         dataString +=Luftfeuchte;
         
    Serial.println("connecting...");
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.pachube.com");
    client.print("X-pachubeApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");
    client.println(dataString.length());

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.println(dataString);
  }
  else {
    // Wenn keine Verbindung zu COSM
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
  // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}
    // here's the actual content of the PUT request:
    client.println(dataString);
  }

Du rufst nie client.stop() auf (im Falle eines erfolgreichen Connects), somit wird die Verbindung wahrscheinlich aufrecht erhalten, bis ein Timeout eintritt.

Zudem scheinst Du Dich nicht für die Antwort des Servers zu interessieren. Ich würde die mal schön entgegennehmen und auf die serielle Schnittstelle ausgeben.

Zudem solltest Du die String-Klasse nicht verwenden, sie zerklüftet Dir das RAM. Und durch einen Fehler in der aktuellen IDE wird der Speicher nicht mehr richtig freigegeben, womit ein Memory-Leak eintritt. Früher oder später wird Dein Sketch also sowieso nicht mehr funktionieren, wenn Du die String-Klasse verwendest. In Deiner Anwendung ist ein snprintf() viel besser angebracht, das funktioniert auf einem char-Array.

OK danke, ich habe da nicht soviel Ahnung aber ich werde mich mal damit beschäftigen und nochmal schreiben falls ich nicht weiterkomme. Ich habe eben das Programm nur aus dem Cosm Beispiel übernommen, um 2 Datastreams, also Luftfeucht und Temperatur übergeben zu können. Ich werde das einfache nocheinmal probieren und einfach 2mal machen. Wenn ich das nicht hinbekomme probiere ich mal snprintf().

Client.stop() ist nun noch meine frage, kann das Ethernetmodul nicht immer mit dem Ziel Server verbunden bleiben ? Ich übertrage ja alle 10 s daten. Die Antwort das Servers hatte ich vorher drin, aber die habe ich rausgenommen, weil die verbindung funktioniert.

Danke schonmal

sinusblob:
Client.stop() ist nun noch meine frage, kann das Ethernetmodul nicht immer mit dem Ziel Server verbunden bleiben ? Ich übertrage ja alle 10 s daten. Die Antwort das Servers hatte ich vorher drin, aber die habe ich rausgenommen, weil die verbindung funktioniert.

Im Prinzip schon, denn laut Deinem Sketch “sprichst” Du ja HTTP/1.1 mit dem Webserver auf der anderen Seite. Allerdings müßtest Du dann auch den entsprechenden HTTP-Header “Connection: Keep-Alive” mitsenden, damit der Server auf der anderen Seite weiss, das er nicht “auflegen” soll, wenn er seine Daten geschickt hat.
Dann darfst Du aber auch kein neues "client.connect(server,80) machen, denn damit baust ja Du eine neue Verbindung zum Server auf.

Ich sehe gerade client.stop() wird in dem Script aufgerufen und zwar dann hier

if (!client.connected() && lastConnected) { Serial.println(); Serial.println("disconnecting."); client.stop(); }

Ja, aber erst, wenn der Server die Verbindung geschlossen hat. Wenn der Server, aus welchen Gründen auch immer, das nicht tut (z.B. weil die Antwort nicht abgeholt wurde), bleibt sie offen. Ich könnte mir sogar vorstellen, dass der WizNet5100 die Verbindung als offen deklariert, solange noch Bytes im Empfangsbuffer vorhanden sind, die nicht abgeholt wurden. Ein explizites client.stop() würde die einfach fort werfen, aber soweit ich das überblicke, ist das genau die gewünschte Aktion.

Leider is mir das alles zu kompliziert und mit den ganzen Funktionen und Zeiten alles zu verschachtelt.
Daher habe ich das jetzt alles rausgeworfen und das hier gemacht (siehe unten).

Jetzt funktioniert alles einwandfrei.
Wenn noch jemand einen verbesserungsvorschlag zwecks dauerhaltbarkeit (vielleicht immer mal einen Zwangsreset oder etwas ähnliches) hat, wäre ich dankbar.

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

#define APIKEY         "xxxx" // replace your Cosm api key here
#define FEEDID         xxxx // replace your feed ID
#define USERAGENT      "My Project" // user agent is the project name
#define dataPin  8
#define clockPin 9

SHT1x sht1x(dataPin, clockPin);
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte gateway[] = {192,168,0,1};
byte subnet[] = {255,255,255,0};
IPAddress ip(192,168,0,180);

EthernetClient client;
IPAddress server(216,52,233,121);      

void setup() {
    if (Ethernet.begin(mac) == 0) {
    Ethernet.begin(mac, ip, gateway, subnet);
  }
}

void loop() {
  int sensorReading = sht1x.readTemperatureC();
  int sensorReading2 = sht1x.readHumidity();
  
  if(!client.connected())  {
     if (client.connect(server, 80)) {
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.cosm.com");
    client.print("X-ApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");
    client.println(30);
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();
    client.print("Temperatur,");
    client.println(sensorReading);
    client.print("Luftfeuchte,");
    client.println(sensorReading2);
  } 
  else { 
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
  }
 client.stop();
 delay(10000);
}