Author Topic: Arexx Templogger -> Arduino -> Xively  (Read 20427 times)

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Arexx Templogger -> Arduino -> Xively
« on: October 16, 2013, 03:04:19 PM »
Mein zweites Projekt soll Temperatur- und Feuchtigkeitswerte von Arexx-Sensoren an Xively schicken:

Das Problem ist nun, dass es abschmiert wenn ich mehr als 1 Sensorwert an Xivley schicke.
Also habe ich es mal mit einem Switch-Konstrukt versucht. Sprich: Pro Sensorwert ein Feed an Xively schicken anstatt 6 Werte in einem. Das konnte ich dann allerdings nicht parsen: Redeclaration von XivelyDatastream.

Beispielcode der Lib:
Code: [Select]
XivelyDatastream datastreams[] = {
  XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
};

Gemäss Example würden mehrere Werte so funzen:
Code: [Select]
XivelyDatastream datastreams[] = {
  XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
  XivelyDatastream(bufferId, strlen(bufferId), DATASTREAM_BUFFER, bufferValue, bufferSize),
  XivelyDatastream(stringId, DATASTREAM_STRING)
};

Das Beispiel hat funktioniert, meine Adaption dann leider wieder nicht. (Sonderzeichen-Starwars im Serial Monitor)

Wenn ich diese Zeilen mehrmals in switch/case verwende, habe ich dieses Problem.

Obwohl bei jedem Durchgang ja nur einmal was definiert wird. Habe schon einige "vor-Deklarationen" mit leeren Werten versucht, um n den switch/cases nur noch anderen Inhalt abzufüllen. Ergab div. Fehler. Entweder nicht richtig deklariert, redeklariert oder out of scope.

Dann habe ich das ganze mal mit If-Schlaufen anstatt Switch/Case versucht. Parsen ging so, ich habe einfach vor der if-Schlaufe ein mit Beispiel-Text befülltes datastream[0] erstellt und in den If-Schlaufen jeweils [1] überschrieben. Aber im Serial Monitor wurde der Output plötzlich mit jensten Sonderzeichen gemixt (=das Problem mit mehr als einem Wert wie vorhin beschrieben).

Geht also auch nicht. Ich bin mir sicher es liegt an der Deklaration, schnalle das Programmieren aber nicht. Kann mir da jemand helfen?
Code habe ich zuhause, kann ich später noch reinstellen.

Gruss
Mario

arduinopraxis

  • freakyfriday
  • Hero Member
  • *
  • Posts: 553
  • Karma: +11/-0
  • Arduino Praxiseinstieg (4.Auflage)
    • Arduino Praxiseinstieg, 4. Auflage
Re: Arexx Templogger -> Arduino -> Xively
« Reply #1 on: October 17, 2013, 09:48:32 AM »
@Mario

Hast du schon mal das Beispiel der Xively-Library mit MultipleUploads getestet?

Ich würde im ersten Schritt die Werte manuell eintragen im Beispielsketch eintragen und so testen.

Die Deklaration deines Datenstreams muss am Anfang des Programms einmalig gemacht werden. Dabei müssen die einzelnen Strings mit den Namen der einzelnen Datenfeeds genau mit deiner Konfiguration übereinstimmen.

Im Beispiel sieht das so aus:

Code: [Select]
char sensorId[] = "sensor_reading";
char bufferId[] = "info_message";
String stringId("random_string");

Anschliessend können dann die jeweiligen Werte den einzelnen Feeds zugeordnet werden:

Code: [Select]
datastreams[0].setFloat(sensorValue);
datastreams[1].setBuffer("a message to upload");
datastreams[2].setString(stringValue);

Bei Sensoranwendungen sind vermutlich alle Werte als Float zu setzen.

Für genaue Problemanalyse musst du dein Sketch hier publizieren.

Gruss
Thomas

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #2 on: October 23, 2013, 06:28:28 PM »
Komisch, kriege nicht mehr mal das Beispiel zum Laufen. Error 403: Rate Limit: https://xively.com/dev/docs/api/communicating/usage_limits/

Kann ja nicht sein oder? Ich setze 1 Request alle 15s = 4x pro Minute Limit ist gemäss https://xively.com/pricing/ bei 25/min:

Quote
Developer Account API limit 25 API calls per minute, 3 minute moving average.

arduinopraxis

  • freakyfriday
  • Hero Member
  • *
  • Posts: 553
  • Karma: +11/-0
  • Arduino Praxiseinstieg (4.Auflage)
    • Arduino Praxiseinstieg, 4. Auflage
Re: Arexx Templogger -> Arduino -> Xively
« Reply #3 on: October 23, 2013, 08:31:02 PM »
Quote
Komisch, kriege nicht mehr mal das Beispiel zum Laufen. Error 403
Ich würde nochmals einen neuen Datenfeed einrichten und mit diesem testen oder den bisherigen Feed löschen und neu einrichten.


afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #4 on: October 24, 2013, 06:33:13 PM »
Habe ich versucht, selbes Problem.

Gibt es keine self hosted data logging apps? Das wäre mir fast am liebsten.
Habe schon viel gegoogelt aber nix gefunden :(

arduinopraxis

  • freakyfriday
  • Hero Member
  • *
  • Posts: 553
  • Karma: +11/-0
  • Arduino Praxiseinstieg (4.Auflage)
    • Arduino Praxiseinstieg, 4. Auflage
Re: Arexx Templogger -> Arduino -> Xively
« Reply #5 on: October 24, 2013, 09:55:42 PM »
Quote
Gibt es keine self hosted data logging apps? Das wäre mir fast am liebsten.

Stichwort OpenEnergyMonitor.

Schau mal hier:
http://forum.boxtec.ch/index.php/topic,2183.0.html

Gruss
Thomas

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #6 on: November 07, 2013, 07:08:39 PM »
Vielen Dank Thomas! Das ist perfekt!

Inzwischen hänge ich wieder beim Arduino. Kurz zu meinem Script: Ich habe 6 Sensoren und pro Loop lese ich die Daten eines Sensors und schicke diese zum Emoncms. Das mache ich mit einem Case-Konstrukt.
Das komische: Wenn ich 3 Sensoren schicke, also z.B. Case 4/5/6 auskommentiere, dann geht alles tadellos. Auch wenn ich Case 1/2/3 auskommentiere.
Sobald ich aber 4 Sensoren, also 4 Cases, laufen lasse, dann geht es manchmal, manchmal nicht.
Und wenn ich 5 oder alle 6 Sensoren laufen lasse, dann geht gar nichts mehr.

Das Programm loopt zwar durch und ich sehe auch ganz normal alle meine println damit ich das im Serial Ouput prüfen kann, aber im emoncms kommt nichts an...

Wenn ich die Cases umschreibe und 6 mal einfach hardcodierte Testwerte sende, dann funktioniert es!
Ich habe dann allerdings auch nie einen textfinder im Einsatz. Kann das "zuviel" für den Arduino sein?

Hier noch mein Code:

Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <TextFinder.h>


// MAC address for your Ethernet shield
byte mac[] = {
  0x90, 0x2, 0xDA, 0x0E, 0xB2, 0x12 };

EthernetClient client;
IPAddress Emoncms(80, 74, 158, 130);

//Arexx IP
IPAddress server(192,168,0,30);

EthernetClient sensorclient;
TextFinder  finder( sensorclient );

long value; // jeweiliger gemessener Wert
String stringValue; //Wert umgewandelt in String


int sensorCount = 1; // Welcher Sensor an der Reihe ist

String json1;
String json2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("void setup...");
  Serial.println();

  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }
}

void loop() {
  //Da nicht alle Sensordaten mit einem Request geschickt werden, sende Daten
  //pro Case (Sensor 1-6)
  Serial.print("sensorcount vor Programmloop: ");
  Serial.println(sensorCount);
  if (sensorCount > 6) {
    sensorCount = 1;
  }
  Serial.print("sensorcount nach korrektur:");
  Serial.println(sensorCount);



  if (sensorclient.connect(server, 80))
  {   
    Serial.println("Connect to Arexx...");
    sensorclient.println("GET /cdata.xml HTTP/1.0");
    sensorclient.println();
    Serial.println("Connected...");
  }
  else
  {
    Serial.println(" connection to Arexx failed");
  }




  switch (sensorCount) {
  case 1:
    Serial.println("Case 1:");
    //Get Data from RH17196
    if (sensorclient.connected())
    {
      finder.find("<value id=\"17196\" type=\"3\" uid=\"171963\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value, ignore dot
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");       
      stringValue = String(value);
      Serial.println(stringValue);

      json1 = "GET /input/post.json?json={Divider:1000,Humidity_OG:";     
      json2 = "}&apikey=xxx HTTP/1.0";


    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }   

    sensorclient.stop();
    sensorclient.flush();     

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush();   
    break;     
  case 2:
    Serial.println("Case 2:");
    //Get Data from T17196
    if (sensorclient.connected())
    {
      finder.find("<value id=\"17196\" type=\"1\" uid=\"171961\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");
      stringValue = String(value);
      Serial.println(stringValue);

      json1 = "GET /input/post.json?json={Divider:1000,Temp_OG:";     
      json2 = "}&apikey=xxx HTTP/1.0";   

    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }

    sensorclient.stop();
    sensorclient.flush();

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush();
    break;
  case 3:
    Serial.println("Case 3:");
    //Get Data from RH17304
    if (sensorclient.connected())
    {
      finder.find("<value id=\"17304\" type=\"3\" uid=\"173043\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");       
      stringValue = String(value);
      Serial.println(stringValue);

      json1 = "GET /input/post.json?json={Divider:1000,Humidity_EG:";     
      json2 = "}&apikey=xxx HTTP/1.0";

    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }

    sensorclient.stop();
    sensorclient.flush();   

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush();
    break;
  case 4:
    Serial.println("Case 4:");
    //Get Data from T17304
    if (sensorclient.connected())
    {
      finder.find("<value id=\"17304\" type=\"1\" uid=\"173041\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");
      stringValue = String(value);
      Serial.println(stringValue);


      json1 = "GET /input/post.json?json={Divider:1000,Temp_EG:";     
      json2 = "}&apikey=xxx HTTP/1.0";

    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }

    sensorclient.stop();
    sensorclient.flush();   

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush();
    break;
  case 5:
    Serial.println("Case 5:");
    //Get Data from RH17228
    if (sensorclient.connected())
    {
      finder.find("<value id=\"17228\" type=\"3\" uid=\"172283\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");
      stringValue = String(value);
      Serial.println(stringValue);

      json1 = "GET /input/post.json?json={Divider:1000,Humidity_OUT:";     
      json2 = "}&apikey=xxx HTTP/1.0";

    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }

    sensorclient.stop();
    sensorclient.flush();   

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush(); 
    break;
  case 6:
    Serial.println("Case 6:");
    //Get Data from T17228
    if (sensorclient.connected())
    {     
      finder.find("<value id=\"17228\" type=\"1\" uid=\"172281\" t=\"");  // seek to the Results field
      finder.find("\">"); // skip past this
      value = finder.getValue('.'); // get numeric value
      //Serial.print(value);
      Serial.println(" cdata.xml resultat");
      stringValue = String(value);
      Serial.println(stringValue);

      json1 = "GET /input/post.json?json={Divider:1000,Temp_OUT:";     
      json2 = "}&apikey=xxx HTTP/1.0"; 

    }
    else
    {
      Serial.print("cdata.xml nicht gelesen");
    }

    sensorclient.stop();
    sensorclient.flush(); 

    if (client.connect(Emoncms, 80))
    {   
      Serial.println("Connect to Emoncms...");
      Serial.println(json1+stringValue+json2);
      client.println(json1+stringValue+json2);
      client.println("HOST: emoncms.rossiworld.com");
      client.println();
      Serial.println("Connected...");
    }
    else
    {
      Serial.println(" connection to Emoncms failed");
    }
    client.stop();
    client.flush();
    break;
  }



  Serial.println("Starte Loop mit nächstem Sensor nach 5s...");


  Serial.println();
  sensorCount++;
  delay(5000);

}



pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: Arexx Templogger -> Arduino -> Xively
« Reply #7 on: November 12, 2013, 07:16:04 PM »
Nach einem schnellen Überflug über Deinen Code tippe ich auf Speichermangel. Du setzt einerseits die String-Klasse ein, die mit dynamischer Speicherverwaltung wie auf einem PC umgeht und damit den sehr beschränkten Speicher eines Arduinos (UNO: 2kB) im Nu fragmentiert hat.
Zum anderen verwendest Du das F()-Makro nicht, somit sind alle Zeichenketten (auch die konstanten) im Speicher untergebracht, welcher natürlich im Nu überläuft, was zu undefinierten Zuständen führt. Das F()-Makro kannst Du überall dort einsetzen, wo Du konstante Zeichenketten (also Strings, aber bitte nicht mit der String-Klasse verwechseln) an Methoden übergibst, die von der Print-Klasse abstammen. Bei den Standard-Bibliotheken sind das alle Methoden, die print() oder println() heissen.
Also einfach alle Aufrufe der Art:

Code: [Select]
Serial.println("Hier kommt ein konstanter String, der nichts aussagt.");
durch

Code: [Select]
Serial.println(F("Hier kommt ein konstanter String, der nichts aussagt."));
ersetzen und schon hast Du eine Menge RAM gespart.

dinoi

  • freakyfriday
  • Sr. Member
  • *
  • Posts: 441
  • Karma: +7/-0
    • Dinoi
Re: Arexx Templogger -> Arduino -> Xively
« Reply #8 on: November 13, 2013, 09:45:38 AM »
Hallo Pylon,

das ist ein guter Tipp, Danke. Ich hatte auch schon Speicherüberläufe das Problem ist man bemerkt es nicht direkt sondern das Programm macht einfach etwas undefiniertes.

Bei der neuen IDE 1.5.2 Beta wird der Speicher beim Hochladen detaillierter ausgegeben.
Wie sind Eure Erfahrungen mit dieser Information?
"Estimated memory use X bytes of X maximum bytes"

Oder gibt es noch Tricks ein Überlauf festzustellen?

Gruss Reto

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #9 on: November 14, 2013, 06:45:51 PM »
Hey pylon

Vielen Dank! Das wars!  ;D
Ich sollte wohl mal auf die IDE 1.5.2 wechseln, dann hätte ich wohl früher gemerkt in welche Richtung der Fehler geht. Trotzdem habe ich von diesem F()-Makro noch nie was gehört...hmm..

Was ist eigentlich so der "übliche" Umgang mit diesen print() und println() als Debug-Methode? Erinnert mich an meine frühesten JS-Versuche, gibts da nicht auch was mit log/terminal output oder so was?

Zudem: Ist das jetzt irgendwie "schlecht", wenn dann der Arduino im Dauerbetrieb Serial prints macht die sowieso niemand zu sehen bekommt? Jetzt läuft mein Script ja und ich könnte alle print() auskommentieren...

Gruss
Mario


dinoi

  • freakyfriday
  • Sr. Member
  • *
  • Posts: 441
  • Karma: +7/-0
    • Dinoi
Re: Arexx Templogger -> Arduino -> Xively
« Reply #10 on: November 14, 2013, 08:24:18 PM »
Hallo Mario,

alternativ zu den Serial.prints kannst Du das Atmel Studio mit Visualmicro einsetzen. Das bietet einen halben Debugger. Halb weil du vor dem übertragen die Stop Punkte definieren musst und dann nicht im Einzelschrittmodus von Befehl zu Befehl springen kannst. Du kannst dann von Stop zu Stop Punkt weiter laufen lassen und die Variablen anzeigen. Bei den Variablen ist die Funktionalität sehr durchdacht, weil er Dir den aktuellen Wert, Minimum und Maximum ausgibt. Das ganze ist schon sehr brauchbar. Einziger Nachteil die ganze Software ist relativ gross gegenüber der Arduino IDE und für den Debugger musst Du etwas Kleingeld bezahlen. Siehe meinen Post dazu:

http://forum.boxtec.ch/index.php/topic,2309.msg3049.html#msg3049

Gruss Reto

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: Arexx Templogger -> Arduino -> Xively
« Reply #11 on: November 18, 2013, 03:27:06 AM »
Was ist eigentlich so der "übliche" Umgang mit diesen print() und println() als Debug-Methode? Erinnert mich an meine frühesten JS-Versuche, gibts da nicht auch was mit log/terminal output oder so was?

"Üblich" gibt's in diesem Zusammenhang wahrscheinlich nicht. Natürlich kannst Du seriellen Output für's Debugging produzieren, häufig ist aber die Verwendung eines Pins mit einer LED dran einfacher (weil Du z.B. die serielle Schnittstelle für was anderes brauchst).

Zudem: Ist das jetzt irgendwie "schlecht", wenn dann der Arduino im Dauerbetrieb Serial prints macht die sowieso niemand zu sehen bekommt? Jetzt läuft mein Script ja und ich könnte alle print() auskommentieren...

Schlecht ist das nicht, es könnte theoretisch Dein Timing (die Ansteuerung der seriellen Schnittstelle braucht etwas Zeit, zum einen bis die Daten im Puffer sind und danach für den Interrupt der die Hardware jeweils mit dem nächsten Byte füttert) durcheinander bringen. Wenn es aber mit der seriellen Ausgabe so läuft, wie Du es Dir vorgestellt hast, kannst Du den Code problemlos drin lassen. Der Arduino gibt dann immer schön etwas über die serielle Schnittstelle aus, auch wenn dort keiner hinhört.

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #12 on: November 29, 2013, 04:30:19 PM »
Ich habe das Teil nun seit ein paar Tagen am laufen.
Er hängt sich immer alle 2.5 - 3 Tage auf und ich muss ihn resetten.

Dachte zuerst das läge an den restlichen println die ich noch drin habe, also habe ich ALLE auskommentiert. Selber Effekt: nach ca. 2.5-3 Tagen muss ich resetten.

Elegant wäre jetzt natürlich, das Problem zu lösen. Pragmatisch wäre alle 24h ein Softreset. Habe mal das da gefunden:
http://forum.arduino.cc/index.php?topic=49581.0

hmm...

EDIT: Komisch, hatte vor 4h wieder einen Aussetzer. Also weniger als 24h hat es diesmal gehalten...
« Last Edit: November 30, 2013, 02:05:35 PM by afx2000 »

afx2000

  • Newbie
  • *
  • Posts: 20
  • Karma: +0/-0
    • Meine Webseite
Re: Arexx Templogger -> Arduino -> Xively
« Reply #13 on: January 10, 2014, 04:02:48 PM »
Ich melde mich mal mit dem aktuellen Stand der Dinge.

Inzwischen habe ich den Arduino durch ein Raspberry Pi ersetzt. Hach, einfach PHP coden und fertig ;)

Der letzte Testzyklus hat 3 Wochen gedauert, dann war der Pi nicht mehr erreichbar. Komisch.
Übliche Absturzursachen gemäss Google: Netzteil oder SD-Card.

Hab also rasch die Class 10 Karte durch eine Class 4 Karte ersetzt. Läuft jetzt sein ein paar Tagen.

Gruss
Mario

 

anything