INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Funktionsaufruf mit String bei WLAN CC3000 will nicht
19.06.2015, 11:45
Beitrag #1
Funktionsaufruf mit String bei WLAN CC3000 will nicht
Hallo Ihr Profis,

seit ein paar Tagen quäle ich mich mit einem kleinen aber feinen Problem. Ich bin sehr neu in C und Arduino, habe aber ein kleines Basiswissen durch Perl-Skript und allgemeine Ausbildung.

Hintergrund:
Ich frage auf einem Webserver einige Sensorwerte ab. Dazu nutze ich das WLAN-Modul CC3000. Diese Werte will ich später auf einem kleinen Display anzeigen.
Das WLAn-Modul und die Abfrage ist bereits geklärt. Ich habe in einer Variablen einen Sensorwert. Die Anzeige kommt später.

Ich habe die Web-Abfrage in eine Funktion gepackt. Dabei nutze ich fast nur den Orig-Code der CC3000 Beispiele.

Was geht nicht:
Ich will drei Sensoren (somit drei Webseiten) aufrufen. Dazu soll die Funktion verwendet werden und als Return der gemessene Wert. Ich will also 3x die Funktion aufrufen und dabei jeweils die Webseite übergeben. Die drei Werte stehen entweder in einer #define oder Variablen. Das sieht dann so aus:
Code-Auszug.
Code:
...
// Adresse des Temperatursensors Garten
#define temp_garten   "/config/xmlapi/state.cgi?datapoint_id=5129"

// Adresse des Feuchtesensors Garten
#define feucht_garten "/config/xmlapi/state.cgi?datapoint_id=5129"

// Adresse des Temperatursensors Schuppen
#define temp_schuppen "/config/xmlapi/state.cgi?datapoint_id=4081"

void loop(void)
{
// Hole Sensordaten und zeige diese an
String temp_garten_wert = SensorAbfrage(temp_garten);
// 2. und 3. Funktionsaufruf folgen dann, wenn es ginge..

//... TODO: hier kommt dann noch die Anzeige usw.
  delay(3000);
  Serial.println("\nNaechster Lauf");  //nur zum Debugging - Serial.Begin(9600) ist im Orig-Code enthalten.
}
//Funktionen
String SensorAbfrage(String x)
{
  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(x);                    //hier ist das Problem
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE);    www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  }
Das Problem scheint in der Zeile www.fastrprint(x); zu liegen.
Mache ich aus dem (x) ein (temp_garten) und greife somit auf die #define Variable zurück (also besser der Kompiler ersetzt die Werte) geht es. Aber dann kann ich die Funktion nicht mehr nutzen.
Ich habe auch versucht, anstelle von #define eine Variable zu Deklarieren und zu Initialisieren: String temp_garten "... meine adresse...". Immer das Gleiche, der Kompiler arbeitet nicht.

Die Fehlermeldung:
WebClient.ino: In function 'String SensorAbfrage(String)':
WebClient.ino:151:21: error: no matching function for call to 'Adafruit_CC3000_Client::fastrprint(String&)'
WebClient.ino:151:21: note: candidates are:
In file included from WebClient.ino:14:0:
X:\Eigene Dokumente\Arduino\libraries\Adafruit_CC3000/Adafruit_CC3000.h:102:10: note: size_t Adafruit_CC3000_Client::fastrprint(const char*)
size_t fastrprint(const char *str);


Die Zeile 151 ist genau die Zeile mit dem www.fastrprint(x);

Ich hatte Versuchscode erstellt, bei dem die String-Übergabe in eine Funktion rein und raus klappt:
Code:
#define x "wert3"

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Programm beginnt");
}

void loop() {
  String neuwert2 = string_test(x);
  Serial.println("Funktion: " + neuwert2);
  delay(3000);
}

String string_test(String a){
  String b=a;
  return b;
}
Die Fehlermeldung zeigt ja einen Hinweis auf die Adafruit_CC3000.h Datei.
Was ich nicht verstehe, ist, warum der Zugriff auf eine #define klappt, aber nicht auf einen String, der Übergeben wird.

Was benötigt bloss dieser http://www.fastrprint() Befehl.. Huh

Testweise hatte ich auch erfolglos den Funktionsaufruf direkt gemacht:
Code:
String temp_garten_wert = SensorAbfrage("/config/xmlapi/state.cgi?datapoint_id=5129");

Wahrscheinlich für Euch Profis total einfach, weil man hier ein * oder sonst was wieder einsetzen muss. Confused Aber ich habe es nicht herausgefunden. Ich bin über jeden Tipp dankbar.

Viele Grüße,
Gardino
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.06.2015, 11:57
Beitrag #2
RE: Funktionsaufruf mit String bei WLAN CC3000 will nicht
Hi,
versuch mal das hier:
Code:
www.fastrprint(x.c_str());
...oder
Code:
www.fastrprint(x->c_str());
Eins von beiden muesste funktionieren.
Siehe auch http://www.arduino.cc/en/pmwiki.php?n=Re...ringObject.
Gruss,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.06.2015, 18:26
Beitrag #3
RE: Funktionsaufruf mit String bei WLAN CC3000 will nicht
Das ging ja schnell. Ich habe es gleich ausprobiert. Mit
Code:
www.fastrprint(x.c_str());
Ging es sofort....

... und nun stürzt nach zwei Loop Läufen der Atmega328 (Uno) ab.
Evtl. liegt es ja an meinen ganzen Serial.print Befehlen. Nun versuche ich auch mit Serial.print(F(text)) das Problem zu lösen - aber dafür wird nicht mehr Kompiliert. Der Compiler bleibt einfach nach 10% (laut Balken) stehen. Toll.

Die Basisroutine mit all den Serial.print() Befehlen läuft aber. D. h., es gibt kein Aufhänger - nichts. Auch mit Aufruf als Funktion. Einzig - die Rückgabe ist jetzt vorhanden.

Kann denn der c_str() hier was machen? Laut Beschreibung ist dieser Befehl ja mit Vorsicht zu genießen. Aber die #define Variable wird ja nicht angefasst. Warum scheint also mein Atmega hier aus dem RAM zu laufen?

Gruss,
Gardino
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
20.06.2015, 19:04 (Dieser Beitrag wurde zuletzt bearbeitet: 20.06.2015 19:23 von Gardino.)
Beitrag #4
RE: Funktionsaufruf mit String bei WLAN CC3000 will nicht
Jetzt geht es. Ich habe einfach noch einmal alles nach und nach eingetippt und bei jeder kleinen Änderung getestet. Nun geht's. Dodgy
Nochmals ein herzliches Danke für die schnelle Hilfe!

Ich habe bitte noch eine weitere Frage in diesem Projekt und will nicht unnötig einen weiteren Thread aufmachen. Ich hoffe das ist so in Ordnung?!

Ich habe die Ausgabe mittlerweile auf das 1.8" TFT Display (Adafruit_ST7735) umgelenkt - das eigentliche Ziel, die Infos auf diesem kleinen Display anzuzeigen.
Das geht auch eigentlich mit den normalen Variablen aus der Funktion. Z.B.:
Code:
temp_garten_wert = SensorAbfrage(temp_garten);
  tft.print(F("Temp. Garten: "));
  tft.println(temp_garten_wert);
Das geht.

Was nicht geht, sind Ausgaben direkt vom WLAN (Adafruit_CC3000) auf das Display:
Code:
...
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER);
...  
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    tft.println(F("Unable to retrieve the IP Address!\r\n"));
    return false;
  }
  else
  {
    tft.print("\nIP Addr: ");
    cc3000.printIPdotsRev(ipAddress);
..
Hier kommt nur die Ausgabe IP Addr: auf das Display.

Das Paradoxon (für mich): Nimmt man anstelle tft.print den üblichen Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);, kommt die gewünschte Info auf die Serielle Schnittstelle.

Ich habe es auch in der Funktion displayConnectionDetails mit neuer Variablen versucht:
Code:
uint32_t IPADRESSE_DISP;
IPADRESSE_DISP = cc3000.printIPdotsRev(ipAddress);
Hier kommt aber die Fehlermeldung WebClient.ino:318:20: error: void value not ignored as it ought to be
In der Variablen ipAddress muss ja was drinnen stehen: mAche ich nun ein
tft.print(ipAddress); kommt was, aber nur eine lange Zahl.

=>Kann ich also irgendwie die Ausgabe umlenken?

Wieder Danke im Voraus.


Okay... seit heute morgen eine Lösung gesucht... nichts gefunden. Und nach dem Schreiben hier eine Idee gehabt und dann das passende im Internet gefunden. Immer das Gleiche: Wenn man nach dem richtigen sucht... Sleepy

Die Lösung ist wohl, daß ich das Ganze Byteweise Ausgebe:
Code:
tft.print( (uint8_t)(ipAddress >> 24) );
tft.print(".");
tft.print( (uint8_t)(ipAddress >> 16) );
tft.print(".");
tft.print( (uint8_t)(ipAddress >> 8) );
tft.print(".");
tft.print( (uint8_t)(ipAddress) );

Binär, Hex, Dez usw. machen mir keine Probleme - nur in C muss ich das Ganze noch besser verstehen, da hier doch gerade bei (gedachten) Strings es sich anders als in Perl verhält (zumindest empfinde ich das so).

So ganz habe ich noch nicht verstanden, warum nun die Dezimalzahl kommt. Falls jemand Lust hat das mir noch zu erklären, dann bedanke ich mich im Voraus.
Zumindest war mir die Schreibweise ( (uint8_t)(ipAddress) ) nicht durch das Studieren der Beispiele erkennbar. Aber vermutlich habe ich nur nicht richtig geguckt...Confused

Ich habe es hier mal hinzugefügt, da vielleicht der Eine oder Andere das mal benötigt.

Viele Grüße,

Gardino
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
22.06.2015, 14:50
Beitrag #5
RE: Funktionsaufruf mit String bei WLAN CC3000 will nicht
(20.06.2015 19:04)Gardino schrieb:  nur in C muss ich das Ganze noch besser verstehen, da hier doch gerade bei (gedachten) Strings es sich anders als in Perl verhält (zumindest empfinde ich das so).
In C(++) steckt der Datentyp sozusagen in der Variable, nicht wie bei Perl im Operator. Wenn man nun eine Variable als uint32_t deklariert, dann ist das eine Zahl und eben kein String.

Zitat:So ganz habe ich noch nicht verstanden, warum nun die Dezimalzahl kommt.
Ich bin mir sicher, dass es vorher auch eine Dezimalzahl war. Was Du willst, ist ja was anderes. Du willst die einzelnen Bytes der 4-Byte-Zahl mit Punkten dazwischen anzeigen.

Zitat:Falls jemand Lust hat das mir noch zu erklären, dann bedanke ich mich im Voraus.
Zumindest war mir die Schreibweise ( (uint8_t)(ipAddress) ) nicht durch das Studieren der Beispiele erkennbar.
Das mit dem (uint8_t) ist meiner Meinung nach ein bisschen unsauber, aber wahrscheinlich von der Performance und dem Speicherverbrauch her gut.
Was Du damit eigentlich machst ist das:
Code:
(ipAddress >> 16) & 255
D.h. Du nimmst vom Ergebnis der Shift-Operation nur das niederwertigste Byte.

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Arduino lässt sich nicht installieren bergfrei 4 135 20.11.2016 18:34
Letzter Beitrag: bergfrei
  Arduino Mega 2560 läuft nicht Wolfgang50 6 172 13.11.2016 10:50
Letzter Beitrag: Wolfgang50
  Ardublock übertragt nicht an IDE oder UNO R3 tobi83 5 325 16.10.2016 14:07
Letzter Beitrag: Pit
  Upload funktioniert nicht Levi 5 236 22.09.2016 20:19
Letzter Beitrag: hotsystems
  ESP8266 tuts nicht sowerum 7 385 19.09.2016 21:01
Letzter Beitrag: sowerum
  If-Bedingung funktioniert nicht bei Serial1.write Datatom 6 222 16.09.2016 20:36
Letzter Beitrag: Datatom
  String zusammensetzen Mathias 13 539 01.09.2016 21:15
Letzter Beitrag: Mathias
  SD Karte wird nicht erkannt... Maxi290997 2 201 16.08.2016 14:36
Letzter Beitrag: Maxi290997
  Arduino lässt sich nicht mehr beschreiben Maxi290997 15 964 07.08.2016 11:40
Letzter Beitrag: Maxi290997
  Arduino Uno+Motor Shield+Velleman Mustercode funktionieren nicht Dubidu 8 481 20.07.2016 19:05
Letzter Beitrag: Scheams

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste