Go Down

Topic: Arduino GSM shield http Get Verbindung (Read 4261 times) previous topic - next topic

BigBang

Hallo zusammen,

ich versuche verzweifelt eine funktionierende http Get Verbindung aufzubauen.
Klappt auch, wenn da nicht die falsche Antwort vom Server wäre. 404 / 302 usw.

Ich habe das Arduino uno R3 mit dem GSM Shield
GSM Karte ist von Aldi, also eplus. APN usw scheinen zu stimmen.
Kann auch einen Get an eine Domain machen, kommt nur nicht an.

http://www.open-electronics.org/arduino-gsm-shield/

Aus dem debugging geht leider nichts hervor:
booting device...
DB:ELSE
DB:ELSE
DB:ELSE
DB:CORRECT BR
Serial connection = READY
DB:STARTING NEW CONNECTION
DB:APN OK
DB:CONNECTION OK
DB:ASSIGNED AN IP
GPRS connection = ATTACHED
10.XX.XX.XX
DB:RECVD CMD
DB:OK TCP
DB:>
DB:SENT
DB:NOT CONN
DB:NOT CONN
DB:RECVD CMD
DB:OK TCP
DB:>
DB:SENT

Selbst das Demo Skript liefert bei google einen Fehler.
Gibt da einen Trick? Hat das schon jemals jemand hinbekommen?

Bin für jeden Tip dankbar.

Gruß,
Marko

mkl0815

Poste doch mal Dein Programm, das macht es etwas leichter Dein Problem zu analysieren.
Ist das evtl. ein DNS Problem? Versuchmal einfach auf eine IP-Adresse, statt eines Domainnamens zuzugreifen. Evtl. klappt ja nur die Namensauflösung nicht.
Also statt auf "http://google.de" mal nur auf "http://173.194.69.94" zugreifen. Evtl. klappt das ja schon.
Mario.

BigBang

Hallo Mario,

der get direkt auf eine IP funktioniert problemlos.

Ich denke auch, dass es ein DNS Problem ist.
Allerdings glaube ich nicht, dass es an den Hostern liegt, denn die DNS Auflösung funktioniert nirgens.
Ich dachte eher daran, dass der Header fehlerhaft ist, der gesendet wird.

Ich habe es mit Domains von einigen Hostern versucht, alle verhalten sich in etwa gleich.
Nur die Rückgabewerte der Fehlermeldung variieren.


mkl0815

Dann poste doch mal das Programm, dann sehen wie weiter.

BigBang

ok
hat etwas gedauert
musste den Rechner neu aufsetzen


#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"

InetGSM inet;

char msg[20];
int numdata;
char inSerial[50];
int i=0;
boolean started=false;

void setup()
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true; 
  }
  else Serial.println("\nstatus=IDLE");
 
  if(started){
    //GPRS attach, put in order APN, username and password.
    //If no needed auth let them blank.
    if (gsm.attachGPRS("internet.eplus.de", "eplus", "internet"))
      Serial.println("status=ATTACHED");
    else Serial.println("status=ERROR");
    delay(1000);
   
    //Read IP address.
    gsm.SimpleWrite("AT+CIFSR");
    delay(5000);
    //Read until serial buffer is empty.
    gsm.WhileSimpleRead();
 
    //TCP Client GET, send a GET request to the server and save the reply.
    numdata=inet.httpGET("www.google.de", 80, "/", msg, 50);
    //Print the results.
    Serial.println("\nNumber of data received:");
    Serial.println(numdata); 
    Serial.println("\nData received:");
    Serial.println(msg);
  }
};

void loop()
{
  //Read for new byte on serial hardware,
  //and write them on NewSoftSerial.
  serialhwread();
  //Read for new byte on NewSoftSerial.
  serialswread();
};

void serialhwread(){
  i=0;
  if (Serial.available() > 0){           
    while (Serial.available() > 0) {
      inSerial=(Serial.read());
      delay(10);
      i++;     
    }
   
    inSerial='\0';
    if(!strcmp(inSerial,"/END")){
      Serial.println("_");
      inSerial[0]=0x1a;
      inSerial[1]='\0';
      gsm.SimpleWrite(inSerial);
    }
    //Send a saved AT command using serial port.
    if(!strcmp(inSerial,"TEST")){
      gsm.SendATCmdWaitResp("ATE0", 500, 50, "OK", 5);
             
      Serial.println("SIGNAL QUALITY"); 
      gsm.SimpleWrite("AT+CSQ");

    }
   
    //Read last message saved.
    if(!strcmp(inSerial,"MSG")){
      Serial.println(msg);
    }
   
    else{
      Serial.println(inSerial);
      gsm.SimpleWrite(inSerial);
    }   
   
    inSerial[0]='\0';
  }
}

void serialswread(){
  gsm.SimpleRead();
}





DEBUG Rückgabe:
------------------------
GSM Shield testing.
DB:ELSE
DB:ELSE
DB:ELSE
DB:CORRECT BR

status=READY
DB:STARTING NEW CONNECTION
DB:APN OK
DB:CONNECTION OK
DB:ASSIGNED AN IP
status=ATTACHED

10.151.210.62
DB:RECVD CMD
DB:OK TCP
DB:>
DB:SENT

Number of data received:
49

Data received:
HTTP/1.0 302 Found
1
e/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=abf8f714c5e52192:FF=0:TM=1334859529:LM=1334859529:S=B2iPNgj00qPq4Bhg; expires=Sat, 19-Apr-2014 18:18:49 GMT; path=/; domain=.google.com
Set-Cookie: NID=58=QabGqO48aErMwsk3wzLPxnj785EDuKH0Ne9NOiyJA7XHjVxXzMlTHo027hs3fM3Mp3A1k6XJpkQJWJSbgRd_IbbU96pQr7gHyj6_xukVZA6ThpMp36ersNTmNxe-FWCE; expires=Fri, 19-Oct-2012 18:18:49 GMT; path=/; domain=.google.com; HttpOnly
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Date: Thu, 19 Apr 2012 18:18:49 GMT
Server: gws
Content-Length: 218
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.de/">here</A>.
</BODY></HTML>

CLOSED

---------------------------


unten sieht man recht gut, dass er mit dem DNS nicht klar kommt

Gruß,
Marko

mkl0815

Ich hab den Code mal in die passenden Tags gepackt, sonst kann das ja keiner lesen.
Code: [Select]

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"

InetGSM inet;

char msg[20];
int numdata;
char inSerial[50];
int i=0;
boolean started=false;

void setup()
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true;
  }
  else Serial.println("\nstatus=IDLE");

  if(started){
    //GPRS attach, put in order APN, username and password.
    //If no needed auth let them blank.
    if (gsm.attachGPRS("internet.eplus.de", "eplus", "internet"))
      Serial.println("status=ATTACHED");
    else Serial.println("status=ERROR");
    delay(1000);
   
    //Read IP address.
    gsm.SimpleWrite("AT+CIFSR");
    delay(5000);
    //Read until serial buffer is empty.
    gsm.WhileSimpleRead();

    //TCP Client GET, send a GET request to the server and save the reply.
    numdata=inet.httpGET("www.google.de", 80, "/", msg, 50);
    //Print the results.
    Serial.println("\nNumber of data received:");
    Serial.println(numdata);
    Serial.println("\nData received:");
    Serial.println(msg);
  }
};

void loop()
{
  //Read for new byte on serial hardware,
  //and write them on NewSoftSerial.
  serialhwread();
  //Read for new byte on NewSoftSerial.
  serialswread();
};

void serialhwread(){
  i=0;
  if (Serial.available() > 0){           
    while (Serial.available() > 0) {
      inSerial=(Serial.read());
      delay(10);
      i++;     
    }
   
    inSerial='\0';
    if(!strcmp(inSerial,"/END")){
      Serial.println("_");
      inSerial[0]=0x1a;
      inSerial[1]='\0';
      gsm.SimpleWrite(inSerial);
    }
    //Send a saved AT command using serial port.
    if(!strcmp(inSerial,"TEST")){
      gsm.SendATCmdWaitResp("ATE0", 500, 50, "OK", 5);
             
      Serial.println("SIGNAL QUALITY");
      gsm.SimpleWrite("AT+CSQ");

    }
   
    //Read last message saved.
    if(!strcmp(inSerial,"MSG")){
      Serial.println(msg);
    }
   
    else{
      Serial.println(inSerial);
      gsm.SimpleWrite(inSerial);
    }   
   
    inSerial[0]='\0';
  }
}

void serialswread(){
  gsm.SimpleRead();
}

mkl0815

Mehrere Sachen in Deinem Code fallen mir auf.

1.) Du definierst ein Array char msg[20], übergibst aber beim Aufruf "numdata=inet.httpGET("www.google.de", 80, "/", msg, 50);" eine Puffergröße von 50 Bytes, statt der 20 Bytes des Arrays. Damit überschreibt die Funktion alle 30 Bytes hinter dem Array im Speicher. Das kann zu sehr spannenden Ergebnissen führen.

2.) Die Ausgabe der empfangenen Zeichen ist deutlich mehr als 50 Zeichen, von welchem Code werden die denn ausgegeben?

3.) Warum sollte das Programm mit DNS nicht klar kommen? Du bekommst eine Antwort vom Google-Webserver, also klappt DNS doch, sonst würde gar nix zurück kommen. Die Antwort ist ein HTTP 302 Redirect auf http://www.google.de. Das passiert z.B.  auch wenn man einen HTTP-Request per telnet simuliert:
Quote

telnet www.google.de 80
Trying 209.85.147.94...
Connected to www-cctld.l.google.com.
Escape character is '^]'.
GET /   HTTP/1.0

HTTP/1.0 302 Found
Location: http://www.google.de/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=be4d6a2fb8e1fc75:FF=0:TM=1334861125:LM=1334861125:S=lkBvT9ZrB0NjYAxk; expires=Sat, 19-Apr-2014 18:45:25 GMT; path=/; domain=.google.com
Set-Cookie: NID=58=to_a07wmRSi1obtjhkconKlD46PR7rgfSwy1T4kgZVbztkFfyPWgozoACZ1fvEh5GzrZ9s8sBewpmsbGGK5PcV6RQp8Cowl-C6y4aQao16a6CdLXU_DTxlaLjBbIz3hc; expires=Fri, 19-Oct-2012 18:45:25 GMT; path=/; domain=.google.com; HttpOnly
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Date: Thu, 19 Apr 2012 18:45:25 GMT
Server: gws
Content-Length: 218
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.de/">here</A>.
</BODY></HTML>

Das passiert deshalb, weil beim HTTP-Request der Parameter "Host: www.google.de" nicht mitgesendet wird. Damit anwortet Google mit dem Redirect. Was bei Deinem Beispiel fehlt ist ein Teil vom HTTP-Header, da bei Dir nach 20 Zeichen Schluss ist. Mach mal den msg[] Puffer deutlich größer und übergib bei inet.httpGET() die Größe die der Puffer hat.
Mario.

mkl0815

Ich habe mir gerade mal den Code der aktuellen Version der GSM-Lib angesehen. Beim httpGet() wird der "Host:" Parameter mitgesendet. Welche Version der Lib setzt Du ein? Evtl. fehlt das ja bei Deiner Version.

BigBang

Ja. mit den 20/50 Bytes hast Du wohl recht.

in der verwendeten GSM-lib wird http 1.1 verwendet. Ist vom 21/01/2012
allerdings fehlt dort das keep alive, welches die verbindung aufrecht erhält.
Ohne keep beendet der Server meines wissen die Verbindung nach der ersten Antwort

richtiger wäre es dorch so:

  gsm.SimpleWrite("GET ");
  gsm.SimpleWrite(path);
  gsm.SimpleWrite(" HTTP/1.1\nHost: ");
  gsm.SimpleWrite(server);
  gsm.SimpleWrite("\r\n");
  gsm.SimpleWrite("User-Agent: Arduino");
  gsm.SimpleWrite("\r\n");
  gsm.SimpleWrite("Connection: keep-alive");
  gsm.SimpleWrite("\r\n");
  gsm.SimpleWrite(end_c);


BigBang

so.
habe noch ein wenig herumgespielt.

habe es auch so weit geschafft, dass der get korrekt beantwortet wird:


Code: [Select]
status=READY
DB:STARTING NEW CONNECTION
DB:APN OK
DB:CONNECTION OK
DB:ASSIGNED AN IP
status=ATTACHED

10.142.212.153
DB:RECVD CMD
DB:OK TCP
DB:>
DB:SENT
--------------
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accep
--------------


Allerdings war es dafür notwendig die Daten direkt bei InetGSM::httpGET einzutragen.

Code: [Select]
int InetGSM::httpGET(const char* server, int port, const char* path, char* result, int resultlength)
{
  boolean connected=false;
  int n_of_at=0;
  int length_write;
  char end_c[2];
  end_c[0]=0x1a;
  end_c[1]='\0';

  /*
  Status = ATTACHED.
  if(gsm.getStatus()!=GSM::ATTACHED)
    return 0;
  */
  while(n_of_at<3){
  if(!gsm.connectTCP(server, port)){
  #ifdef DEBUG_ON
Serial.println("DB:NOT CONN");
#endif
    n_of_at++;
  }
  else{
connected=true;
n_of_at=3;
}
  }

  if(!connected) return 0;

  gsm.SimpleWrite("GET /test HTTP/1.1\nHost: google.de");
  gsm.SimpleWrite("\n\r");
  gsm.SimpleWrite(end_c);

/*
  gsm.SimpleWrite("GET ");
  gsm.SimpleWrite(path);
  gsm.SimpleWrite(" HTTP/1.1\nHost: ");
  gsm.SimpleWrite(server);
  gsm.SimpleWrite("\n");
  gsm.SimpleWrite("User-Agent: Arduino");
  gsm.SimpleWrite("\n\r");
  gsm.SimpleWrite(end_c);
*/


allerdings stoppt das debugging, wenn ich die Angaben in der eigendlichen Datei hinterlege:

Code: [Select]
    //Read IP address.
    gsm.SimpleWrite("AT+CIFSR");
    delay(5000);
    //Read until serial buffer is empty.
    gsm.WhileSimpleRead();
 
    GetHttpReq:
    numdata=inet.httpGET("google.de", 80, "/blablahust/12343423432", msg, 50);
    if(numdata < 1)
      { delay(1000);
        goto GetHttpReq;
      }
    else
      { Serial.println("--------------");
        Serial.println(msg);
        Serial.println("--------------");
        delay(1000);
        goto GetHttpReq;
      }



ich habe nirgens gefunden, wo man bytegröße der Variablen einstellen kann.
das Debugging stopt immer bei "/blablahust/12343423432"

trage ich das direkt inder inetGSM.cpp ein, gibt es keine Probleme.

mkl0815

Das ist in der Tat ein seltsames Verhalten.
Ich hatte mir folgende Lib heruntergeladen:
http://code.google.com/p/gsm-shield-arduino/downloads/detail?name=GSM_Shield_GPRS_Ver_3_08_%28IDE100%29.zip&can=2&q=
Das ist Version 3.08 für die IDE 1.0 vom 15.03.2012. Also ziemlich aktuell.
Evtl. probierst Du es mal mit der.

BigBang

Habe einmal die Version von Dir benutzt.
Gleicher Effekt.

Ich habe es aber noch ein wenig getestet.
Die Übertragung scheitert immer dann, wenn man Variablen mit übertragen will.

zB: /index.html?id=1234
inet.httpGET("testdomain.de", 80, "/index.html?id=1234", msg, 50);

Muss man solche Zeichen irgendwie maskieren?

mkl0815

Das würde mich wundern. Ich hab mich mal ein wenig durch den Code geklickt. Am Ende landet das "gsm.SimpleWrite(path);" bei einem _cell.print(char*). Und dieses _cell ist eine Instanz von SoftSerial. Außerdem ist es komisch, das es klappt, wenn Du den String direkt in den Lib-Code schreibst.
Die inet.httpGET() Methode definiert path und server als const char*, also auch nix ungewöhnliches.
Wie gesagt, sehr seltsam. Versuch mal ein par Debugausgaben mit dem übergebenen String "server" an verschiedenen Stellen der Lib auszugeben, evtl. kommst Du so weiter.

Morpheus

Hallo zusammen
Kann mir hier eventuell einer helfen wie ich eine Fern Überwachung zusammenstellen kann?
Das ganze soll wie folgt ablaufen:  Ein Taster wird betätigt und ein Alam wird per SMS zu einem Handy mit dem Text Überwachung 1 hat ausgelöst. Zusätzlich muss die Spannungsversorgung überwacht werden das wenn die Batterie leer ist ein Alam gesendet wird Batterie Lehr Von Überwachung 1 dann müsste mir über eine Diode angezeigt werden ob der empfang gegeben ist am Aufstellung Ort. Kann mir da vielleicht jemand helfen wie das umgesetzt werden kann?
MfG Morpheus

IBES1410

Hallo zusammen,

ich habe ein Problem...

Ich versuche verzweifelt mit meinem GSM-Shield 3 Zahlenwerte in eine sql Datenbank zu schreiben.
Der sketch für das Ethernetshield funktioniert. Nun will ich das mit dem GSM versuchen, und scheitere jedesmal.

Hat jemand vieleicht einen Beispielsketch für mich?


Danke schonmal!!

Go Up