Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Ethernet library server.available() problem

  1. #1
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24

    Ethernet library server.available() problem

    Hi, I'm sorry for this huge post but I need to explain it clearly.
    I'm working on the realization of an Escape Room.
    I would use Teensy as controller of each game, connected via Ethernet to a PC.
    After the first trial I found some problem with the communication with the software due by the server.available() function.

    This is my configuration:
    From the modem of my office (and later from the one of the escape room) I connect a Router (netgear R6220). From the router I connect my pc and a switch (TL-SG1024D (1Gbit)).
    I use the router as a DHCP server reserving all the IP that I need (with the correspondent MAC address).
    Then I use a Teensy 3.2 and a Teensy 3.5 with the WIZ820io Adaptor and the WIZ820io Module, and an Arduino Mega with an Ethernet shield based on W5100.
    These three board are connected to the switch and are uploaded with the following code (with the right configuration of IPs and MAC addresses)

    Code:
    /*
       A prop with a button that sends a signal to ERM & can also trigger a relay
    */
    
    #include <Ethernet.h>
    
    #define BUTTON_PIN 5
    //A14 per teensy, 5 per Mega
    #define RELAY_PIN 6
    
    
    bool useDHCP = false;
    
    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network:
    
    byte mac[] = {0x04, 0xE9, 0xE5, 0x06, 0xE1, 0x2B}; //Dipende da ogni dispositivo, da trovare con T3_readmac.ino (Teensy) o generare (Arduino)
    IPAddress ip(10, 0, 0, 103);
    
    // Initialize the Ethernet server library
    // with the IP address and port you want to use
    // (port 80 is default for HTTP):
    EthernetServer server(80);
    
    // Track the room game state
    bool relayTriggered = false;  // has the button in the room been pressed?
    
    
    
    
    void setup() {
      //start serial connection (debugging)
      Serial.begin(9600);
    
      pinMode(9, OUTPUT);
      digitalWrite(9, LOW);    // begin reset the WIZ820io
      pinMode(10, OUTPUT);
      digitalWrite(10, HIGH);  // de-select WIZ820io
      digitalWrite(9, HIGH);   // end reset pulseo
    
      // NOTE: pin 1 & 2 are used for Serial
      // 4 & 10 - 13 are used for ethernet
    
      pinMode(BUTTON_PIN, INPUT_PULLUP);   // Game btn
      pinMode(RELAY_PIN, OUTPUT);   // Control mag lock or lights
    
      // start the Ethernet connection and the server:
      if (useDHCP) {
        Serial.println("Using DHCP");
        Ethernet.begin(mac); // Use DHCP instead of ip
      }
      else {
        Serial.println("Not using DHCP");
        Ethernet.begin(mac, ip);
      }
      server.begin();
      Serial.print("server is at ");
      Serial.println(Ethernet.localIP());
    
    
      // Initial game state
      relayTriggered = false;
    }
    
    
    
    void loop() {
      //read the pushbutton value into a variable
      int gameBtnVal = digitalRead(BUTTON_PIN);
    
      //print out the value of the pushbutton
      //Serial.println(gameBtnVal);
    
      // Keep in mind the pullup means the pushbutton's
      // logic is inverted. It goes HIGH when it's open,
      // and LOW when it's pressed
      if (gameBtnVal == LOW) {
        trigger();
      } else reset();
    
      // listen for incoming Ethernet connections:
      listenForEthernetClients();
    
      // Maintain DHCP lease
      if (useDHCP) {
        Ethernet.maintain();
      }
    
    
      // Use serial for debugging to bypass web server
      if (Serial.available()) {
        //read serial as a character
        char ser = Serial.read();
    
        switch (ser) {
          case 'r': // reset prop
            reset();
            break;
    
          case 'b': // button press
            trigger();
            break;
        }
      }
    }
    
    
    /*
       Game states
    */
    
    
    // actions after button has been pressed
    void trigger() {
      // While the code below is safe to run multiple times
      // it's best not to re-run it in case an expensive operation
      // is later added
      if (relayTriggered) {
        return;
      }
    
      relayTriggered = true;
      digitalWrite(RELAY_PIN, HIGH);
      Serial.println("solved");
    }
    
    // Reset the prop
    void reset() {
      relayTriggered = false;
      digitalWrite(RELAY_PIN, LOW);
    }
    
    
    /*
       URL routing for prop commands and polling
    */
    
    // This function dictates what text is returned when the prop is polled over the network
    String statusString() {
      return relayTriggered ? "solved" : "not solved";
    }
    
    // Actual request handler
    void processRequest(EthernetClient& client, String requestStr) {
      Serial.println(requestStr);
      // Send back different response based on request string
      if (requestStr.startsWith("GET /status")) {
        Serial.println("polled for status!");
        writeClientResponse(client, statusString());
      } else if (requestStr.startsWith("GET /reset")) {
        Serial.println("Room reset");
        reset();
        writeClientResponse(client, "ok");
      } else if (requestStr.startsWith("GET /trigger")) {
        Serial.println("Network prop trigger");
        trigger();
        writeClientResponse(client, "ok");
      } else {
        writeClientResponseNotFound(client);
      }
    }
    
    
    /*
       HTTP helper functions
    */
    
    void listenForEthernetClients() {
      // listen for incoming clients
      EthernetClient client = server.available();
      if (client) {
        Serial.println("Got a client");
        // Grab the first HTTP header (GET /status HTTP/1.1)
        String requestStr;
        boolean firstLine = true;
        // an http request ends with a blank line
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank) {
              processRequest(client, requestStr);
              break;
            }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
              firstLine = false;
            } else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
    
              if (firstLine) {
                requestStr.concat(c);
              }
            }
          }
        }
        // give the web browser time to receive the data
        delay(1);
        // close the connection:
        client.stop();
      }
    }
    
    
    void writeClientResponse(EthernetClient& client, String bodyStr) {
      // send a standard http response header
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/plain");
      client.println("Access-Control-Allow-Origin: *");  // ERM will not be able to connect without this header!
      client.println();
      client.print(bodyStr);
      Serial.println(bodyStr);
    }
    
    
    void writeClientResponseNotFound(EthernetClient& client) {
      // send a standard http response header
      client.println("HTTP/1.1 404 Not Found");
      client.println("Access-Control-Allow-Origin: *");  // ERM will not be able to connect without this header!
      client.println();
    }
    This code is given by the Escape room software developer to connect an Arduino to his browser based software (Escape Room Master.com).
    I set the room for a test and all the connection works in the test mode. The teensy answer to requests (using the /reset and /trigger stirngs) from the software in the right way.
    Click image for larger version. 

Name:	test.PNG 
Views:	7 
Size:	15.5 KB 
ID:	13910Click image for larger version. 

Name:	puzzle trigger.PNG 
Views:	5 
Size:	12.3 KB 
ID:	13912Click image for larger version. 

Name:	serial monitor.PNG 
Views:	7 
Size:	8.0 KB 
ID:	13911
    But when I launch the room (open the webpage of the live view of my room) if the Teensy are running, the sketches return false as output of server.available() and the board cannot communicate with the software.
    Returning from there in the test mode the server.available() continue to return false (but the sketch is running).
    If I restart the Teensy when the live view of my room is open, they begin to communicate correctly with the software.

    This does not happen with the Arduino board...

    There is an alert on the manual that say "Please make sure you are using the w5500 adapters, and NOT using the w5100 adapters as they do not conform to current hardware and network specifications." can the w5100 on the arduino board generate a connection problem for the Teensy?

    How can I resolve without power on the boards after the software is started?

    Thanks
    Luca

  2. #2
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24
    Hi I made some other test studiying the ethernet protocol but without results.
    Someane have some suggestions?
    It will be very helpful!
    Thanks
    Luca

  3. #3
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24
    Sorry but I need to solve this problem and I cannot find a solution myself.
    There is someone that can help me?
    Thanks
    Luca

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,596
    I've put this one on my list of bugs to investigate. Will likely look into it early next week.

    I see your code seems to listen for HTTP requests. When I run your code on a board here, what should I run in my browser to test it?

  5. #5
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,472
    I ran your server sketch on a T3.2 (IDE 1.8.5 1.40) with my local IP and mac address. Server seems to be working. I accessed from browser with http://192.168.1.15/reset and http://192.168.1.15/trigger and got back ok. I also ping'd the server and did a
    telnet 192.168.1.15 80
    get


    and all that seemed to work just fine. I tested with both a WIZ820io and WIZ850io.

    When your tests are failing, can you ping the T3.2 or T3.5 from a console window? can you try telnet to port 80 on T3.5 and T3.2 when things seem broken?

    you might turn on an LED in the while(client.connected() ) loop and turn it off before the client.stop() -- then you can see if the server is hung assembling a line.
    Last edited by manitou; 06-30-2018 at 05:39 PM.

  6. #6
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24
    Quote Originally Posted by PaulStoffregen View Post
    When I run your code on a board here, what should I run in my browser to test it?
    hi Paul, thanks!
    You need to run the room named Bovisa in https://escaperoommaster.com/dashboard/rooms/
    login escaperoom and same password.
    Luca

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,596
    I do not understand how I am supposed to use that public site to communicate with a Teensy board on my desk, using a IP number assigned by my private network.

  8. #8
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24
    Quote Originally Posted by PaulStoffregen View Post
    I do not understand how I am supposed to use that public site to communicate with a Teensy board on my desk, using a IP number assigned by my private network.
    You are right, sorry.
    In the Room Management page you can create an event (or use the one that I had created) specifing the IP.
    If you give me the right IP I set it for you.

    Thanks
    Luca

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,596
    This isn't going to work. The IP number is assigned by my router (using NAT routing) for the internal network. It is not reachable directly from the outside world.

    I also know nothing about how your site is supposed to work. The page I saw is complex with no apparent instructions. I need a relatively simple way to test which can run here on my network, where the IP number of the Teensy+Wiznet is accessible.

  10. #10
    Member
    Join Date
    Nov 2014
    Location
    Italy
    Posts
    24
    i connect PC and Teensy on a switch connected to my router where I assign the private static IP's.

    Unfortunately is not my site and the user manual is not so good. It is the first voice of the menu. I understand that it's not so easy to make some tests, I hoped there was some known problem I was not aware of about HTTP's requests on Teensy.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •