Arduino Shield Verbindung bricht ab.

Hallo Zusammen,

ich habe folgendes Problem:

Ich möchte gerne, dass eine Zahl (in diesem Fall die 63) über ein PHP Skript in eine Datenbank geschrieben wird.
Diese Zahl soll jede Sekunde oder jede Zwei Sekunden übertragen werden. Später wird die Zahl natürlich variieren.
Dies funktioniert auch mit dem unten eingefügten Code, allerdings bricht die Verbindung immer nach einiger Zeit ab.
Wenn ich nur alle 10 Sekunden die Zahl 63 übertrage, dann dauert es länger bis die Übertragung abbricht und schicke ich jede Sekunde passiert dies schneller.
Um die Verbindung nach dem Abbruch wiederherzustellen muss ich dann immer das Arduino und das Shield von der Spannungsquelle trennen. Kurz warten und dann funktioniert es wieder, nur resetten funktioniert garnicht.

Es gibt ja sehr viele Beispielcodes bei dem eine Temperatur gemessen und dann diese auf eine Datenbank gespeichert wird.
Ich habe auch schon mehrere davon ausprobiert, aber ich bekomme es leider einfach nicht hin..
Bitte helft mir!

Hardware: Original Arduino UNO und Original Arduino Ethernet Shield

Beste Grüße und vielen DANK!

Julius

Arduino Code

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

byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x62, 0xAF };
char serverName[] = "dedo.bplaced.net";
char url[]     = "/webseite/SpeichernInDatenbank.php";
EthernetClient client;

void setup()
{
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) { // start ethernet using mac & IP address
    Serial.println("Failed to configure Ethernet using DHCP");  
    while(true)   // no point in carrying on, so stay in endless loop:
      ;
  }
  delay(1000); // give the Ethernet shield a second to initialize
  
}

void loop()
{    int ret = client.connect(serverName, 80);
  if (ret == 1) {
    Serial.println("connected"); //  report successful connection
    // Make an HTTP request:
   // client.println("GET /webseite/AbrufenDerDaten.php HTTP/1.0");
   // client.println("Host: dedo.bplaced.net"); 
   // client.println();

  } 
  else {
    Serial.println("connection failed, err: ");
    Serial.print(ret,DEC);
  }

   client.print("GET " + String(url));
    
    client.print("?wert=");
 
    client.print(63);
 
    client.println(" HTTP/1.1");
    Serial.println(" HTTP/1.1");
    client.print("Host: dedo.bplaced.net" );
   
    client.println();
    Serial.println();
    client.println("User-Agent: Arduino");
    Serial.println("User-Agent: Arduino");
    client.println("Connection: close");
    Serial.println("Connection: close");
    client.println();
    Serial.println();
  
  delay(700);
 
   
  client.stop();
  Serial.println("Done.");
  client.flush();
 
  delay(200);
}

Speichern in Datenbank

<?php

require_once ('ZugriffaufDatenbank.php');

$var=$_GET['wert'];
echo $var;
$nvar=floatval($var);
echo $nvar;

$sql = "

  INSERT INTO `Netzfrequenz`

  ( 

  `Position` , `Zeitpunkt_der_Messung` , `Messwert` 

  ) 

  VALUES

  (

  NULL , NULL,$nvar

  );

";

$db_erg = mysqli_query($db_link, $sql) 

   or die("Anfrage fehlgeschlagen: " . mysqli_error());

?>

Arduino_Code.ino (1.68 KB)

SpeichernInDatenbank.php (375 Bytes)

julius858:
Bitte helft mir!

Du hast offenbar ein vorhandenes und funktionierendes Demoprogramm total verhackstückt.

Im Original hast Du es auskommentiert wie es richtig ist:
Wenn die Verbindung erfolgreich zustande kommt, dann sende die GET Anforderung an den Server:

 if (ret == 1) {
    Serial.println("connected"); //  report successful connection
    // Make an HTTP request:
   // client.println("GET /webseite/AbrufenDerDaten.php HTTP/1.0");
   // client.println("Host: dedo.bplaced.net"); 
   // client.println();
}

Dein verhackstückter Code funktioniert aber so, dass Du die GET-Anfrage in jedem Fall versuchst zu senden, egal ob die Verbindung zum Server zustande gekommen ist oder nicht.

Ich würde also mal sagen:
Falsche Programmlogik führt zur Programmfehlfunktion.

Außerdem verbrauchst Du zuviel RAM.
Benutzt die F() Makro bei print ("text"); bzw println(F("text")); um RAM zu speichern zB:
client.print(F("?wert="));
Grüße Uwe

Vielen vielen Dank für eure Tipps!

Ich habe nun folgende Verbesserung vorgenommen:

  • ich benutze jetzt das F() Makro
  • die Delays habe ich ersetzt durch eine millis() abfrage
  • In der if Abfrage ist nun der Code enthalten der das PHP Skript aufruft
  • die Serial.println habe ich rausgeschmissen

Leider habe ich immer noch das gleiche Problem.

Für weitere Tipps wäre ich euch sehr dankbar!

Beste Grüße und vielen Dank!

Anbei der verbesserte Code:

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

byte mac[] = {0x90, 0xA2, 0xDA, 0x0F, 0x62, 0xAF };
char serverName[] = "dedo.bplaced.net";
char url[]     = "/webseite/SpeichernInDatenbank.php";
EthernetClient client;
unsigned long zeitalt;
void setup()
{ 
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) { // start ethernet using mac & IP address
    Serial.println("Failed to configure Ethernet using DHCP");  
    while(true)   // no point in carrying on, so stay in endless loop:
      ;
  }
  delay(1000); // give the Ethernet shield a second to initialize
};

void loop()
     {    
  int ret = client.connect(serverName, 80);
  if (ret == 1) {
    client.print(F("GET /webseite/SpeichernInDatenbank.php"));
    
    client.print(F("?wert="));
 
    client.print(88);

    client.println(F(" HTTP/1.1"));

    client.print(F("Host: dedo.bplaced.net" ));
   
    client.println();
    
    client.println(F("User-Agent: Arduino"));

    client.println(F("Connection: close"));
 
    client.println();
    Serial.println(freemem());
   
  client.stop();
  client.flush();
  zeitalt=millis();
  while(millis()-zeitalt<1000)
  {}
   
  } 
  else {
    Serial.println("connection failed, err: ");
   
  }
   
}
  
// this function will return the number of bytes currently free in RAM      
extern int  __bss_end; 
extern int  *__brkval; 
int freemem()
{ 
 int free_memory; 
 if((int)__brkval == 0) 
   free_memory = ((int)&free_memory) - ((int)&__bss_end); 
 else 
   free_memory = ((int)&free_memory) - ((int)__brkval); 
 return free_memory; 
}

arduinocode.ino (1.51 KB)

Ist zwar nicht das Problem:

Das F()-Makro geht auch bei Serial.print().

while(millis()-zeitalt<1000)
  {}

Das bringt gar nichts. Es ist nicht anders als delay(). Du wartest einfach. Richtig geht es so:

julius858:
Leider habe ich immer noch das gleiche Problem.

Für weitere Tipps wäre ich euch sehr dankbar!

Warum startest Du eigentlich eine Denial-of-Service Attacke gegen den Server, wenn eine Verbindung nicht zustande kommt?

Wenn eine Verbindung nicht zustande kommt, dann ist oftmals eine Überlastung des Servers die Ursache dafür. Falls das vorkommt, wäre die korrekte Reaktion eines anständigen Servernutzers, die Anfragehäufigkeit an den Server zu reduzieren und so zur Entlastung des Servers beizutragen.

Du machst genau das Gegenteil: Wenn die Verbindung nicht zustande kommt, startest Du eine Höchstgeschwindigkeitsattacke und flutest den Server verzögerungsfrei mit immer neuen Anfragen, so schnell der Arduino es nur kann.

Halt nein, nicht ganz so schnell wie es möglich ist, denn Du machst ja noch ein Serial.println("connection failed, err: "); bei 9600 Baud, also 25 gesendete Zeichen bei 1 Zeichen pro Millisekunde, was einem delay von 25 Millisekunden zwischen zwei Anfragen entspricht.

Solche Angriffe auf einen Server werden normalerweise mit dem virtuell gezeigten Mittelfinger bestraft.

Überhaupt Deine Abfragerate im Normalbetrieb: Im Normalbetrieb sendet Dein Arduino eine Anfrage pro Sekunde, also 86400 pro Tag an den Server.

Ist das Dein eigener Server oder bist Du aus anderen Gründen sicher, dass Du so ohne weiteres zigtausend Anfragen an den Server pro Tag senden darfst, ohne dass Du wegen übermäßiger Nutzung von Serverressourcen wenigstens zeitweise geblockt wirst?