Täglich grüßt das Murmeltier - Ardu und Webabfrage

Sorry, wenn ich zum Xten Male das alte Problem anspreche, aber ich habe so viele verschiedene Seiten dazu gefunden, jeder macht es etwas anders, da möchte ich gerne durchsteigen und auch verstehen, was ich da mache und warum es klappt (oder in meinem Falle eben nicht so)

Zur Sache: Angedacht ist eine Webseite, welche Eingaben ermöglicht und diese dann in einer Datei speichert. Die Webseite ist kein Thema, das habe ich alles, funktioniert auch so wie es soll.

Nur der Ardu will nicht so ganz wie ich und ich habe irgendwie das Gefühl, daß es im Bereich der Verbindung/des Lesens hakt, daß der Kleine gar nicht erst ins weite Internet kommt, sondern irgendwo im Router hängenbleibt.

In der Datei sind im Moment die Daten als 6-stellige Zahlenfolge gespeichert. 000000 bedeutet beide Schalter aus, 999999 beide an. Die Zahlen dazwischen sollen später für andere Funktionen genutzt werden.
Zu finden im Web ist sie nach dem Schema "http://meineURL.de/test/test.txt"

Mein Sketch so weit:

#include <EtherCard.h>

// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };
// ethernet interface ip address
static byte myip[] = { 192, 168, 2, 20 };
// gateway ip address
static byte gwip[] = { 192, 168, 2, 1 };
// subnet ip address
byte subnet[]  = { 255, 255, 255, 0 };


byte Ethernet::buffer[700];
static uint32_t timer;

//Webseite
char website[] PROGMEM = "http://meineURL.de/test";

// called when the client request is complete
static void my_callback (byte status, word off, word len) {
  Ethernet::buffer[off+300] = 0;
  String stringOne = ((const char*) Ethernet::buffer + off);
  
  
 //Abfragen 
  if (stringOne.substring(1,3) == "000") {
    digitalWrite(2, LOW); 
  }
  
  if (stringOne.substring(1,3) == "999") {
    digitalWrite(2, HIGH); 
  }  
  
  if (stringOne.substring(4,6) == "000") {
    digitalWrite(3, LOW); 
  }
  
  if (stringOne.substring(4,6) == "999") {
    digitalWrite(3, HIGH); 
  }
}

void setup () {

  pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);    

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  
  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
  ether.packetLoop(ether.packetReceive());
  
  if (millis() > timer) {
    timer = millis() + 5000;
    ether.browseUrl(PSTR("/"), "test.txt", website, my_callback);   
  }
}

Rein logisch sollte er IMO alles so abfragen wie gedacht. aber irgendwo hakt es da noch.

Wäre nett, wenn mir da mal jmd weiterhelfen könnte und den Code mal überfliegen, ggfls Verbesserungsvorschläge liefern könnte. Obwohl meine "Programmierung" großteils aus Copy und Paste besteht, versuche ich das, was da steht auch zu verstehen und ggfls abzuändern. Eigentlich dachte ich ich habe es hier so weit richtig, aber irgendwo hakt es eben leider noch...

Achtung:
die EtherCard-Library wird für Arduino-Ethernet-Anwendungen mit dem Ethernet-Controller ENC28J60 verwenden.

Falls du ein "normales" Ethernet-Shield im Einsatz hast, musst du die Standard-Ethernet-Library Ethernet.h und deren Methoden verwenden.

Tipp:
Falls dies deine erste Ethernet-Anwendung mit Arduino ist, würde ich zuerst mittels der Beispiel-Sketche sicherstellen, dass die grundsätzliche Ethernet-Kommunikation geht. Als Beispiele Webclient und Webserver testen.

Ich habe den ENC28J60, das passt schon...

Allerdings treiben mich die Beispielsketche grade zur Verzweiflung...

In dem "testDHCP" Code sind diverse Serial.print Befehle drin.

Serial.println("\n[testDHCP]");
Serial.print("MAC: ");

werden im Monitor irgendwie "ignoriert", einfach nicht "gedruckt". Dann folgt die MAC adresse mit Doppelpunkten dazwischen in einer Reihe. Danach kommen mit Glück noch diverse IP Adresse, aber wieder (!) ohne die festgelegten Texte vorweg. Bei der 3. IP ist sind vorweg ein paar Leerzeichen und dann ein Å...

Lösche ich alles was mit der MAC/IP Variablen Ausdruckerei zu tun hat, schreibt er sauber die beiden oben genannten Zeilen aus. WTF?????

Habe schon diverse Baudraten probiert, gibt alles keine Besserung....

Hier noch mal der komplette Beispielsketch:

// Arduino demo sketch for testing the DHCP client code
//
// Original author: Andrew Lindsay
// Major rewrite and API overhaul by jcw, 2011-06-07
//
// Copyright: GPL V2
// See http://www.gnu.org/licenses/gpl.html

#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[700];

void setup () {
  Serial.begin(57600);

    Serial.println("\n[testDHCP]");
  
  Serial.print("MAC: ");
  
    for (byte i = 0; i < 6; ++i) {
    Serial.print(mymac[i], HEX);
    if (i < 5)
      Serial.print(':');
  }
  Serial.println();
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  Serial.println("Setting up DHCP");
  if (!ether.dhcpSetup())
    Serial.println( "DHCP failed");
  
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("Netmask: ", ether.mymask);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);

}

void loop () {}

Nachtrag, es muss irgendwie an " if (!ether.dhcpSetup()) " liegen, wenn ich das lösche, druckt er das "Formblatt" richtig, aber alle IPs sind nur 0.0.0.0

Nachtrag, es muss irgendwie an " if (!ether.dhcpSetup()) " liegen, wenn ich das lösche, druckt er das "Formblatt" richtig, aber alle IPs sind nur 0.0.0.0

Da das Problem vermutlich bei der Vergabe der IP-Adresse liegt, würde ich im ersten Schritt die IP-Adresse (Client-IP, GW etc) fix eintragen und testen.

Ich habe 2 Dinge getan:

  1. den mini Pro 168 gegen einen Uno getauscht, plötzlich taten auch die Beispiele. Ich werde bei Gelegenheit mal ein mini Pro 368 antesten.

  2. ich habe den Code mal entsprechend dem Beispiel umgebaut.

Allerdings hakt es irgendwo immer noch und zwar im Bereich der void my_callback

Ich habe mal ein paar Serial Print eingebaut, um zu sehen, wo er ist und hakt.

Code:

#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[700];

static uint32_t timer;

//Webseite
char website[] PROGMEM = "meineURL.de";

// called when the client request is complete
static void my_callback (byte status, word off, word len){
  
  Serial.println("Blubber");
  
  Ethernet::buffer[off+300] = 0;
  String stringOne = ((const char*) Ethernet::buffer + off);
  
    Serial.println(stringOne);
  
  
 //Abfragen 
 if (stringOne.substring(0,3) == "000") {
   digitalWrite(2, LOW); 
 }
  
 if (stringOne.substring(0,3) == "999") {
  digitalWrite(2, HIGH); 
 }  
  
  
  if (stringOne.substring(3,7) == "000") {
    digitalWrite(3, LOW); 
  }
  
  if (stringOne.substring(3,7) == "999") {
    digitalWrite(3, HIGH); 
  }
  

}

void setup () {

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);    
  
  
  
  Serial.begin(57600);
  Serial.println("\n[testDHCP]");

  Serial.print("MAC: ");
  for (byte i = 0; i < 6; ++i) {
    Serial.print(mymac[i], HEX);
    if (i < 5)
      Serial.print(':');
  }
  Serial.println();
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  Serial.println("Setting up DHCP");
  if (!ether.dhcpSetup())
    Serial.println( "DHCP failed");
  
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("Netmask: ", ether.mymask);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);
}

void loop () {

  
  ether.packetLoop(ether.packetReceive());
  
  if (millis() > timer) {
    timer = millis() + 5000;
    ether.browseUrl(PSTR("/verzeichnis/"), "schalter.txt", website, my_callback);   
    Serial.println("check");
    
  }


}

Die Ausgabe im Monitor:

[testDHCP]
MAC: 74:69:69:2D:30:31
Setting up DHCP
My IP: 192.168.2.118
Netmask: 255.255.255.0
GW IP: 192.168.2.1
DNS IP: 192.168.2.1
check
check
check
....

Daran sieht man, daß er zwar den void loop abarbeitet (check...), aber schon beim void my_callback bekomme ich kein Feedback mehr, er scheint da also nix auszuführen.

Den Teil habe ich so übernommen, mir ist nicht klar, was die Aspekte in den Klammern genau bedeuten sollen, irgendwie habe ich da beim googeln nix Hilfreiches gefunden.....

plaubel:

  1. den mini Pro 168 gegen einen Uno getauscht, plötzlich taten auch die Beispiele. Ich werde bei Gelegenheit mal ein mini Pro 368 antesten.

Der Atmega168 hat nur 1KB SRAM statt 2KB wie der 328. Die Lib krallt sich aber schon sehr viel Speicher für den Puffer (700 byte) und der Befehl String stringOne = ((const char*) Ethernet::buffer + off); erzeugt zusätzlich von diesem Puffer eine Kopie. Damit liegst Du sicher weit über dem, was der Atmega168 liefern kann und es treten die von dir beobachteten spannenden Probleme auf.
Versuch mal den Puffer kleiner zu machen und zusätzlich die String-Klasse zu vermeiden. Da Du nur lesend auf den Speicher zugreifen musst, kannst Du auch direkt auf dem Puffer arbeiten.

Werd ich dann mal machen, thnx. Wobei es nun erstmal darum geht das grundsätzlcih auf dem Uno zum laufen zu bekommen....

OK, ich habe es grundsätzlich zum Laufen bekommen... Mal wieder ne Zeile vergessen gehabt (die Webseite über die DNS aufzulösen)...

Allerdings habe ich ein anderes Problem, was ich mit Tricks umgehen kann, mich würder aber interssieren, warum das nicht so geht und ggfls wie man das sonst machen müsste.

Aber ich glaube ich mal dazu mal einen neuen Thread auf, weil es mit dem Ursprung nicht mehr so viel zu tun hat...

Hallo Arduinos,
habe seit 3 wochen das Fieber ...
versuche mit meinem ProMini 328 eine Webabfrage, leider seit Anfang an erfolglos...
hier mal der Code, find den Fehler einfach nicht...

/

/ Arduino demo sketch for testing the DHCP client code
//
// Original author: Andrew Lindsay
// Major rewrite and API overhaul by jcw, 2011-06-07
//
// Copyright: GPL V2
// See http://www.gnu.org/licenses/gpl.html

#include <EtherCard.h>
#include <SPI.h>
static byte mymac[] = { 0xAA,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[320];
//byte Ethernet::buffer[700];
int wait = 5000; // milliseconds
int t = 0;
char website[] PROGMEM = "www.qslnet.de";      // URL der Webseite
static void my_callback (byte status, word off, word len) {
// -----------------------------------------------------------------------------------------

// called when the client request is complete

/*
static void my_callback (byte status, word off, word len) {
  String stringOne = ((const char*) Ethernet::buffer + off);
  Serial.print(stringOne);
  Ethernet::buffer[700] = 0;  
  t = 1;
  if (stringOne.endsWith("aus") && t == 1) {
    digitalWrite(2, LOW);
    Serial.print("Relais aus");
    t = 0;
  }
  
  if (stringOne.endsWith("ein") && t == 1) {
    digitalWrite(2, HIGH);  
    Serial.print("Relais ein");
    t = 0;
  }
}
*/

// -----------------------------------------------------------------------------------------
}
void setup () {
  Serial.begin(57600);
  Serial.println("\n[testDHCP]");

  Serial.print("MAC: ");
  for (byte i = 0; i < 6; ++i) {
    Serial.print(mymac[i], HEX);
    if (i < 5)
      Serial.print(':');
  }
  Serial.println();
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  Serial.println("Setting up DHCP");
  if (!ether.dhcpSetup())
    Serial.println( "DHCP failed");
  
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("Netmask: ", ether.mymask);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);

  pinMode(2, OUTPUT);
  digitalWrite(2, LOW); // Ausgang zu Beginn auf "aus" setzen
  Serial.print("Startzustand: Relais aus");
  
}

// -----------------------------------------------------------------------------------------

void loop () {
  
delay(wait);
  ether.packetLoop(ether.packetReceive());
  Serial.print("\n");
  ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, my_callback );
  //ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, NULL );
  //ether.browseUrl(PSTR("/"), "relais.txt" , website, my_callback );
  //ether.browseUrl(PSTR("/relais.txt"), website, my_callback);  
//  static void my_callback (byte status, word off, word len) {
  String stringOne = ((const char*) Ethernet::buffer);
  Serial.print("String enthaelt: ");
  Serial.print(stringOne);
  Ethernet::buffer[700] = 0;  
  t = 1;
  if (stringOne.endsWith("aus") && t == 1) {
    digitalWrite(2, LOW);
    Serial.print("Relais aus");
    t = 0;
  }
  
  if (stringOne.endsWith("ein") && t == 1) {
    digitalWrite(2, HIGH);  
    Serial.print("Relais ein");
    t = 0;
  }
//}
//  }

}

bin mir nicht sicher, ob es überhaupt zum Auslesen kommt, denn ob an oder aus wird seriell nicht ausgegeben, wenn, als falsche buchstaben, gibts jemanden, der sein problem gefixt hat ?
freu mich über jeden Tip
MfG
Holger

Mach bei allen print() Aufrufen das F()-Makro um den String damit der Flash bleibt und nicht ins RAM kopiert werden:

Serial.println(F("Text im Flash"));

Und wenn es geht auf die String Klasse verzichten:

byte buffer[300];

byte* pBuffer = buffer;

Schon hat man einen Zeiger auf den Puffer ohne das irrsinnigerweise der Inhalt kopiert wird

Um zu überprüfen ob ein Teil-String in einem String enthalten ist gibt es bei C Strings/char Arrays strstr():
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#ga6a441da9211eb85881d99c60b1003552

Hallo, danke für den ersten Tip,

//Abfrage ob in der Relais.txt ein oder aus steht,
//ggf dann schalte port 2 ein oder aus

#include <EtherCard.h>
#include <SPI.h>
static byte mymac[] = { 0xAA,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[300];
//byte Ethernet::buffer[700];
int wait = 5000; // milliseconds
int t = 0;
char website[] PROGMEM = "www.qslnet.de"; // URL der Webseite
static void my_callback (byte status, word off, word len) {
// -----------------------------------------------------------------------------------------
}
void setup () {
Serial.begin(57600);
Serial.println(F("\n[testDHCP]"));

Serial.print(F("MAC: "));
for (byte i = 0; i < 6; ++i) {
Serial.print(F(mymac*, HEX));*

  • if (i < 5)*

  • Serial.print(F(':'));*

  • }*

  • Serial.println(F());*

  • if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)*

  • Serial.println(F( "Failed to access Ethernet controller"));*

  • Serial.println(F("Setting up DHCP"));*

  • if (!ether.dhcpSetup())*

  • Serial.println(F( "DHCP failed"));*

  • ether.printIp("My IP: ", ether.myip);*

  • ether.printIp("Netmask: ", ether.mymask);*

  • ether.printIp("GW IP: ", ether.gwip);*

  • ether.printIp("DNS IP: ", ether.dnsip);*

  • pinMode(2, OUTPUT);*

  • digitalWrite(2, LOW); // Ausgang zu Beginn auf "aus" setzen*

  • Serial.print(F("Startzustand: Relais aus"));*

}
void loop () {

delay(wait);

  • ether.packetLoop(ether.packetReceive());*

  • Serial.print(F("\n"));*

  • ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, my_callback );*

  • //ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, NULL );*

  • //ether.browseUrl(PSTR("/"), "relais.txt" , website, my_callback );*

  • //ether.browseUrl(PSTR("/relais.txt"), website, my_callback); *
    // static void my_callback (byte status, word off, word len) {
    _ String stringOne = ((const char*) Ethernet::buffer);_

  • Serial.print(F("String enthaelt: "));*

  • Serial.print(F(stringOne));*

  • Ethernet::buffer[700] = 0; *

  • t = 1;*

  • if (stringOne.endsWith("aus") && t == 1) {*

  • digitalWrite(2, LOW);*

  • Serial.print(F("Relais aus"));*

  • t = 0;*

  • }*

  • if (stringOne.endsWith("ein") && t == 1) {*

  • digitalWrite(2, HIGH); *

  • Serial.print(F("Relais ein"));*

  • t = 0;*

  • }*
    }
    bekomme aber beim kompilieren und aufspielen auf den Arduino den Fehler: F was not declaret in this scope...

1.) Packe deinen Code immer in Code-Tags in dem du ihn markierst und den #-Knopf anklickst.

Oder so [ code ] test [ / code ] ohne die Leerzeichen

2.) Das geht nicht:

Serial.print(F(':'));
Serial.print(F(mymac, HEX));
Serial.print(F(stringOne));

Ein char ist kein string/char Array. Ein String Objekt ist kein char Array. F() ist nur für String-Literale ("text")! Es geht auch nicht mit Methoden die nicht von der Arduino Stream Klasse abgeleitet sind.

Da war ich oben etwas undeutlich :frowning: Es war nur für C-Strings gemeint

 Serial.println(F());

Das ist noch größerer Unfug.

nun geht ja mein problem weiter, der unleserliche teil wird nur länger,
weis jemand rat ??

//Abfrage ob in der Relais.txt ein oder aus steht,
//ggf dann schalte port 2 ein oder aus

#include <EtherCard.h>
#include <SPI.h>
static byte mymac[] = { 0xAA,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[400];
//byte Ethernet::buffer[700];
int wait = 5000; // milliseconds
int t = 0;
char website[] PROGMEM = "www.qslnet.de"; // URL der Webseite
static void my_callback (byte status, word off, word len) {
// -----------------------------------------------------------------------------------------
}
void setup () {
Serial.begin(57600);
Serial.println(F("\n[testDHCP]"));

Serial.print(F("MAC: "));
for (byte i = 0; i < 6; ++i) {
Serial.print(mymac*, HEX);*

  • if (i < 5)*

  • Serial.print(':');*

  • }*

  • Serial.println();*

  • if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)*

  • Serial.println(F( "Failed to access Ethernet controller"));*

  • Serial.println(F("Setting up DHCP"));*

  • if (!ether.dhcpSetup())*

  • Serial.println(F( "DHCP failed"));*

  • ether.printIp("My IP: ", ether.myip);*

  • ether.printIp("Netmask: ", ether.mymask);*

  • ether.printIp("GW IP: ", ether.gwip);*

  • ether.printIp("DNS IP: ", ether.dnsip);*

  • pinMode(2, OUTPUT);*

  • digitalWrite(2, LOW); // Ausgang zu Beginn auf "aus" setzen*

  • Serial.print(F("Startzustand: Relais aus"));*

}
void loop () {

delay(wait);

  • ether.packetLoop(ether.packetReceive());*

  • Serial.print(F("\n"));*

  • ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, my_callback );*

  • //ether.browseUrl(PSTR("/member/dk0gsk/"), "relais.txt" , website, NULL );*

  • //ether.browseUrl(PSTR("/"), "relais.txt" , website, my_callback );*

  • //ether.browseUrl(PSTR("/relais.txt"), website, my_callback); *
    //static void my_callback (byte status, word off, word len) {
    _ String stringOne = ((const char*) Ethernet::buffer);_

  • Serial.print(F("String enthaelt: "));*

  • Serial.print(stringOne);*

  • Ethernet::buffer[700] = 0; *

  • t = 1;*

  • if (stringOne.endsWith("aus") && t == 1) {*

  • digitalWrite(2, LOW);*

  • Serial.print(F("Relais aus"));*

  • t = 0;*

  • }*

  • if (stringOne.endsWith("ein") && t == 1) {*

  • digitalWrite(2, HIGH); *

  • Serial.print(F("Relais ein"));*

  • t = 0;*

  • }*
    }
    nur die antwort ist:
    [testDHCP]
    MAC: AA:69:69:2D:30:31
    Setting up DHCP
    My IP: 192.168.2.122
    Netmask: 255.255.255.0
    GW IP: 192.168.2.1
    DNS IP: 192.168.2.1
    Startzustand: Relais aus
    String enthaelt: ªii- 1Æ<@ã¬
    String enthaelt: ÿÿÿÿÿÿÆ<@ã¬
    .....