Daten per URL an Arduino senden

Hallo zusammen!

Ich bin kurz vorm aufgeben... Ich möchte per URL über das lokale Netzwerk Zahlen an einen Arduino Leonardo senden, der dann eben jene Zahlen über USB als Keyboard in einen PC eingibt. Bis Zahl Nr. 5 klappt das auch super, ab dem nächsten Eintrag schickt er immer eine weitere Zahl mit dazu. Also nicht 1, sondern 15, oder 25, oder 35... Woran könnte das liegen?

Der Code ist folgender


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

#include <Keyboard.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //assign arduino mac address
byte ip[] = {192, 168, 178, 199 }; // ip in lan assigned to arduino
byte gateway[] = {192, 168, 178, 1 }; // internet access via router
byte subnet[] = {255, 255, 255, 0 }; //subnet mask
EthernetServer server(8080); //server port arduino server will use
EthernetClient client;
char serverName[] = "web.comporium.net"; // (DNS) zoomkat's test web page server
//byte serverName[] = { 208, 104, 2, 86 }; // (IP) zoomkat web page server IP address

String readString; //used by server to capture GET request 

//////////////////////

void setup(){

Keyboard.begin();

  //pinMode(5, OUTPUT); //pin 5 selected to control
  Ethernet.begin(mac,ip,gateway,gateway,subnet); 
  server.begin();
  Serial.begin(9600); 
  Serial.println("server/client 1.0 test 7/03/12"); // keep track of what is loaded
  Serial.println("Send an g in serial monitor to test client"); // what to do to test client
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) 
  {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'g')
    {
      sendGET(); // call client sendGET function
    }
  }  

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
       Serial.println(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
          }
          else {   
            client.println(F("HTTP/1.1 200 OK")); //send new page on browser request
            client.println(F("Content-Type: text/html"));
            client.println();

            client.println(F("<HTML>"));
            client.println(F("<HEAD>"));
            client.println(F("<TITLE>Arduino GET test page</TITLE>"));
            client.println(F("</HEAD>"));
            client.println(F("<BODY>"));

            client.println(F("<H1>Zoomkat's simple Arduino 1.0 button</H1>"));

             
          
          // custom buttons
          client.print(F("<input type=submit value=1 target=inlineframe style=width:100px;height:45px onClick=location.href='/?A;'>"));
          client.print(F("<input type=submit value=2 target=inlineframe style=width:100px;height:45px onClick=location.href='/?B;' target=inlineframe>"));
          client.print(F("<input type=submit value=3 target=inlineframe style=width:100px;height:45px onClick=location.href='/?C;' target=inlineframe>"));
          client.print(F("<input type=submit value=4 target=inlineframe style=width:100px;height:45px onClick=location.href='/?D;' target=inlineframe>"));

          client.print(F("<input type=submit value=5 target=inlineframe style=width:100px;height:45px onClick=location.href='/?E;' target=inlineframe>"));
           client.println();
          client.print(F("<input type=submit value=Senden target=inlineframe style=width:100px;height:45px onClick=location.href='/?Z;' target=inlineframe>"));
   
                      client.println(F("<IFRAME name=inlineframe style='display:none'>"));          
            client.println(F("</IFRAME>"));

            client.println(F("</BODY>"));
            client.println(F("</HTML>"));
          }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf('A') >0) //1
          {
            Keyboard.write(49);
            
          }
if(readString.indexOf('B') >0) //1
          {
            Keyboard.write(50);
            
          }

          if(readString.indexOf('C') >0) //1
          {
            Keyboard.write(51);
            
          }

          if(readString.indexOf('D') >0) //1
          {
            Keyboard.write(52);
            
          }

          if(readString.indexOf('E') >0) //1
          {
            Keyboard.write(53);
            
          }

          if(readString.indexOf('Z') >0) //1
          {
            Keyboard.write(176);
            
          }
         

  

          //clearing string for next read
          readString="";
       
      

        }
      }
    }
  }
} 

//////////////////////////
void sendGET() //client function to send and receive GET data from external server.
{
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0");
    client.println();
  } 
  else {
    Serial.println("connection failed");
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read();
    Serial.print(c);
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop();

}

beschreib mal wo das in deinem Sketch passieren soll. Ich sehe nur dass du den URL nach BUCHSTABEN wie A B C D E Z durchsuchst und dann schickst du was ans keyboard.
von Zahlen sehe ich da nichts.

Das liegt daran, dass er den ASCII-Codewert verwendet (1, 2, 3, ...)

client.print(F("<input type=submit value=1 target=inlineframe style=width:100px;height:45px onClick=location.href='/?A;'>"));

Hier wird über die URL A an den Arduino gegeben, falls der Knopf mit der "1" gedrückt wurde.

 if(readString.indexOf('A') >0) //1
          {
            Keyboard.write(49);
            
          }

Hier wird mit readString nach "A" geschaut und wenn A in der URL vorhanden wird der ASCI Code 49 an die Tasttatur geschickt. 49 sollte hier in ' ' stehen, die ' ' habe ich beim hin und her probieren wohl gelöscht. Wie gesagt, funktioniert bis 5 super, danach hängt er immer eine Zahl mit dran....

Nein.. 49 oder '1' aber nicht '49'

Sie sollten wahrscheinlich nicht beim ersten '\n' anhalten, da möglicherweise noch Daten vom Client gesendet werden und das client.stop(); den Puffer nicht freigibt.

Da Dein Code komplett unformatiert ist, zitiere ich mal aus dem, was ich hier habe.
Mach mal aus:

          if (readString.indexOf('A') > 0) //1
          {
            Keyboard.write(49);
          }
          if (readString.indexOf('B') > 0) //1
          {
            Keyboard.write(50);
          }
          if (readString.indexOf('C') > 0) //1
          {
            Keyboard.write(51);
          }
          if (readString.indexOf('D') > 0) //1
          {
            Keyboard.write(52);
          }
          if (readString.indexOf('E') > 0) //1
          {
            Keyboard.write(53);
          }
          if (readString.indexOf('Z') > 0) //1
          {
            Keyboard.write(176);
          }

neu:

          if (readString.indexOf('A') > 0) //1
          {
            Keyboard.write(49);
          }
          else if (readString.indexOf('B') > 0) //1
          {
            Keyboard.write(50);
          }
          else if (readString.indexOf('C') > 0) //1
          {
            Keyboard.write(51);
          }
          else if (readString.indexOf('D') > 0) //1
          {
            Keyboard.write(52);
          }
          else if (readString.indexOf('E') > 0) //1
          {
            Keyboard.write(53);
          }
          else if (readString.indexOf('Z') > 0) //1
          {
            Keyboard.write(176);
          }

Und dann gehört das abgekürzt.
Aber dazu müsste man wissen, was Du da vor hast um aus dem was sinnvolles zu machen.
Willst Du aus dem String ALLE Großbuchstaben in Zahlen wandeln?
'A' - 17 ist auch '0'; während 'B' - 17 eben auch '1' ergibt...

bei welcher "Ziffer"/ welchen Button passiert das genau?
Zeige mal was in Serial Monitor ankommt.

aus meiner Sicht sind die if Abfragen nicht eindeutig genug. Die Fragen nur auf das vorkommen des Buchstaben ab, da werden dann halt mehrere if true.

Ich habe die Großbuchstaben nur für die Fehlersuche genomen. Vorher hatte ich einfach für Knopf 1 IndexOf('1') usw. Es soll lediglich die Möglichkeit bestehen, Zahlen von 1 bis 10 und die Return Taste an den Arduino weiter zu geben.
else if probiere ich gleich aus!

Und wenn es dabei dann immer noch zu mehr Übergaben kommt, dann werden mehr serialle Ausgaben nötig um zu sehen, was da kommt. Die dann in HEX - damit die notPrintable-Zeichen auch auf dem SerMon erscheinen...

Mit else if folgendes Fehlerbild:
Tasten 1-5 funktionieren, die jeweilige Zahl wird korrekt ausgegeben. Ab Taste 6 bis Return wird jetzt die Zahl 5 ausgegeben... ASCI Zahlen sind korrekt angelegt...

poste den vollständigen Code....


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

#include <Keyboard.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //assign arduino mac address
byte ip[] = {192, 168, 178, 199 }; // ip in lan assigned to arduino
byte gateway[] = {192, 168, 178, 1 }; // internet access via router
byte subnet[] = {255, 255, 255, 0 }; //subnet mask
EthernetServer server(8080); //server port arduino server will use
EthernetClient client;
char serverName[] = "web.comporium.net"; // (DNS) zoomkat's test web page server
//byte serverName[] = { 208, 104, 2, 86 }; // (IP) zoomkat web page server IP address

String readString; //used by server to capture GET request 

//////////////////////

void setup(){

Keyboard.begin();

  //pinMode(5, OUTPUT); //pin 5 selected to control
  Ethernet.begin(mac,ip,gateway,gateway,subnet); 
  server.begin();
  Serial.begin(9600); 
  Serial.println("server/client 1.0 test 7/03/12"); // keep track of what is loaded
  Serial.println("Send an g in serial monitor to test client"); // what to do to test client
}

void loop(){
  // check for serial input
  if (Serial.available() > 0) 
  {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'g')
    {
      sendGET(); // call client sendGET function
    }
  }  

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
       Serial.println(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
          }
          else {   
            client.println(F("HTTP/1.1 200 OK")); //send new page on browser request
            client.println(F("Content-Type: text/html"));
            client.println();

            client.println(F("<HTML>"));
            client.println(F("<HEAD>"));
            client.println(F("<TITLE>Arduino GET test page</TITLE>"));
            client.println(F("</HEAD>"));
            client.println(F("<BODY>"));

            client.println(F("<H1>Zoomkat's simple Arduino 1.0 button</H1>"));

             
          
          // custom buttons
          client.print(F("<input type=submit value=1 target=inlineframe style=width:100px;height:45px onClick=location.href='/?A;'>"));
          client.print(F("<input type=submit value=2 target=inlineframe style=width:100px;height:45px onClick=location.href='/?B;' target=inlineframe>"));
          client.print(F("<input type=submit value=3 target=inlineframe style=width:100px;height:45px onClick=location.href='/?C;' target=inlineframe>"));
          client.print(F("<input type=submit value=4 target=inlineframe style=width:100px;height:45px onClick=location.href='/?D;' target=inlineframe>"));

          client.print(F("<input type=submit value=5 target=inlineframe style=width:100px;height:45px onClick=location.href='/?E;' target=inlineframe>"));
          
          client.print(F("<input type=submit value=6 target=inlineframe style=width:100px;height:45px onClick=location.href='/?F;' target=inlineframe>"));
          client.print(F("<input type=submit value=7 target=inlineframe style=width:100px;height:45px onClick=location.href='/?G;' target=inlineframe>"));
          client.print(F("<input type=submit value=8 target=inlineframe style=width:100px;height:45px onClick=location.href='/?H;' target=inlineframe>"));
          client.print(F("<input type=submit value=9 target=inlineframe style=width:100px;height:45px onClick=location.href='/?I;' target=inlineframe>"));




           client.println();
          client.print(F("<input type=submit value=Senden target=inlineframe style=width:100px;height:45px onClick=location.href='/?Z;' target=inlineframe>"));
   
                      client.println(F("<IFRAME name=inlineframe style='display:none'>"));          
            client.println(F("</IFRAME>"));

            client.println(F("</BODY>"));
            client.println(F("</HTML>"));
          }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
           if (readString.indexOf('A') > 0) //1
          {
            Keyboard.write(49);
          }
          else if (readString.indexOf('B') > 0) //1
          {
            Keyboard.write(50);
          }
          else if (readString.indexOf('C') > 0) //1
          {
            Keyboard.write(51);
          }
          else if (readString.indexOf('D') > 0) //1
          {
            Keyboard.write(52);
          }
          else if (readString.indexOf('E') > 0) //1
          {
            Keyboard.write(53);
          }
        else if (readString.indexOf('F') > 0) //1
          {
            Keyboard.write(54);
          }
          else if (readString.indexOf('G') > 0) //1
          {
            Keyboard.write(55);
          }
else if (readString.indexOf('H') > 0) //1
          {
            Keyboard.write(56);
          }
          else if (readString.indexOf('I') > 0) //1
          {
            Keyboard.write(57);
          }


          else if (readString.indexOf('Z') > 0) //1
          {
            Keyboard.write(176);
          }
         

  

          //clearing string for next read
          readString="";
          
      

        }
      }
    }
  }
} 

//////////////////////////
void sendGET() //client function to send and receive GET data from external server.
{
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0");
    client.println();
  } 
  else {
    Serial.println("connection failed");
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read();
    Serial.print(c);
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop();

}

Möglicherweise haben Sie an anderer Stelle in der URL ein 'E'?

➜ print readString

@heiko7878
das E ist zum Beispiel im GET drinnen.
Darum schrieb ich ja du sollst dir auf der seriellen Schnittstelle ausgeben, was dir der Browser reinschickt und hier posten!

14:57:58.481 -> ?

14:57:58.481 -> Z

14:57:58.481 -> ;

14:57:58.481 ->

14:57:58.481 -> H

14:57:58.481 -> T

14:57:58.481 -> T

14:57:58.481 -> P

14:57:58.481 -> /

14:57:58.481 -> 1

14:57:58.481 -> .

14:57:58.481 -> 1

14:57:58.481 ->

14:57:58.481 ->

14:57:58.481 ->

14:57:58.481 -> GET /?Z; HTTP/1.1

14:57:58.481 ->

Ich habe alle Tasten nacheinander gedrückt

genau das meine ich.
Das schickt dir der Browser rein...
du suchst mit deinen if dann nach A B C D
E ---> bingo kommt schon im GET vor
G wäre das nächste Problem ...

Angebot: du liest dir 60 Minuten meine Seite durch:
https://werner.rothschopf.net/202001_arduino_webserver_post.htm

wenn du dann der Meinung bist dass das der bessere Weg ist, zeige ich dir gern die etwa zwei Stellen die du adaptieren musst um statt Pins zu schalten etwas ans keyboard auszugeben (Zeile 84ff und Zeile 132ff).

Ok, da setze ich mich heute abend dran. vielen Dank schon einmal für eure Unterstützung, ich war echt ratlos mittlerweile!

Zerlege den String und lese nur das, was nach dem ? und vor dem ; kommt
Fertig.
Nix, was Raketenwissenschaft ist und lässt sich mit dem bisherigen Wissen ganz einfach umsetzen.

So, fürs erste funktioniert der Aufbau. Ich habe einfach Variablen genutzt, die nicht in dem HTTP GET vorkommen und demnach in jeder Anwort vom Browser enthalten sind. Ist zwar nicht sauber, reicht jedoch für meine nötigen 10 Zahlen und die Return Taste aus. Ich möchte damit quasi Remote über das Netzwerk die notwendigen Zahlen für einen Bitlocker per Arduino HID eingeben. Die Übertragung etc. funktioniert auch, die auf der Website gedrückten Zahlen kommen am Remote Rechner (Windows gestartet, Word / Editor). Auf Bitlocker Ebene klappt das jedoch nicht, es werden keine Eingaben verarbeitet. Liegt das vielleicht daran, dass der Bitlocker den Arduino nicht als Tastatur möchte? Sicherheitsgründe?