0

I have some code, that turns a LED on/off based on a value on a website (blank page containing a number. The number on the page indicate the number of times the LED should flash.

The problem is that the loop keep running.
I can fix the problem by setting the integer value manually (int c = 3).

Not sure what my problem is.
Maybe one of you can point me in the right direction.

Url: http://b2b.as/lan.php?pid=8855

Code:

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 104 };
char server[] = "b2b.as";

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(1000);

  Serial.println(Ethernet.localIP());
  Serial.println();

  // Set digital pin as output
  // 5V
  pinMode(8, OUTPUT);
}

void loop()
{

  //
  Serial.print("\n-----\n");

  // Connect to the server
  Serial.print("connecting to URL ...");

  // Start LAN connection
  EthernetClient client;
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /lan.php?pid=8855");
    client.println();
  } else {
    Serial.println("connection failed");
  }

  // Wait a moment for data to arrive
  // Note: This is NOT a reliable way of doing this!
  delay(1000);

  if (client.available() > 0) {

    char c = atoi(client.read());

    Serial.print("page value (pick): ");
    Serial.print(c, DEC);
    Serial.print("\n");

    for (int x = 1; x <= int(c); x++) {
      Serial.print("picking: #");
      Serial.println(x);
      digitalWrite(8, HIGH);
      Serial.println("8 HIGH ...");
      delay(5000); // Add switch
      digitalWrite(8, LOW);
      Serial.println("8 LOW ...");
      delay(1000);
    }

    Serial.print("end");

  }

  // Disconnect the client
  if (client.connected()) {
    //Serial.println();
    Serial.print("disconnecting");
    client.stop();
  }

  // Wait another 9s, which will give us a delay of roughly 10s
  delay(9000);
}
gre_gor
  • 6,669
  • 9
  • 47
  • 52
Kenneth Poulsen
  • 929
  • 10
  • 25
  • That doesn't look like a proper HTTP request. And a HTTP server doesn't just return a single byte. https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Example_session – gre_gor Apr 09 '17 at 11:48
  • it's a php page and it return a value from 0-100 – Kenneth Poulsen Apr 09 '17 at 11:51
  • The server also sends a bunch of headers. And `client.read()` reads a single byte. This only produces numbers from 0 to 9. – gre_gor Apr 09 '17 at 11:54
  • your correct - I can see a bunch of headers when i inspect the page. Is there a way to make arduino ignore the headers and just grab the output on the page? – Kenneth Poulsen Apr 09 '17 at 12:12

2 Answers2

0

I assume that the call to lan.php?pid=8855 will just return the value without any formatting, e.g., HTML, XML, JSON. Then your code basically converts the ASCII character 3 to an integer which gives you the integer value 33 (see ASCII Table). Therefore, your loop won't stop.

Solution

Just use the atoi function to convert it to an integer.

char c = atoi(client.read());
Jens Meder
  • 4,237
  • 1
  • 25
  • 25
  • I already tried using atoi, but it does not return anything - contain no value. – Kenneth Poulsen Apr 09 '17 at 10:21
  • How did you verify that? If you just try to print the return value of `atoi` via `Serial.println` you will not see anything because the character value 3 corresponds to a control character which by default is "invisible". – Jens Meder Apr 09 '17 at 10:25
  • Okay, need to do some further testing then :) – Kenneth Poulsen Apr 09 '17 at 10:27
  • If you can enter only one digit numbers you can also try to simply substract the character value `0` (corresponds to integer value 30) from `client.read()`. `char c = client.read() - '30';` – Jens Meder Apr 09 '17 at 10:27
  • The value on the page can be higher than one digit numbers. The "for" loop is not running. It should run, right? If c contain an integer equal or higher than 1. – Kenneth Poulsen Apr 09 '17 at 10:33
  • If you have a valid integer value that is higher or equal to 1 then it should run. You might want to print the value of `c` via `Serial.print(c, DEC);` to verify your value of the `c` variable. – Jens Meder Apr 09 '17 at 10:37
  • returns the value "0", i will update my original post with the revised code and the url page. – Kenneth Poulsen Apr 09 '17 at 10:50
0

It seems that toInt() was the function I was looking for. It convert a string to integer and fixes the loop.

https://www.arduino.cc/en/Reference/StringToInt

Code has been updated and it seems to work:

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 104 };
char server[] = "b2b.as";

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(1000);

  Serial.println(Ethernet.localIP());
  Serial.println();

  // Set digital pin as output
  // 5V
  pinMode(8, OUTPUT);
}

void loop()
{

  //
  Serial.print("\n-----\n");

  // Connect to the server
  Serial.print("connecting to URL ...");

  // Start LAN connection
  EthernetClient client;
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /lan.php?pid=8855");
    client.println();
  } else {
    Serial.println("connection failed");
  }

  // Wait a moment for data to arrive
  // Note: This is NOT a reliable way of doing this!
  delay(1000);

  if (client.available() > 0) {

    String pickNum;

    while (client.available()) {
        char c = client.read();  // gets one byte from serial buffer
        pickNum += c; // count
        delay(2);  // delay for buffer
    }

    Serial.print("page value (pick): ");
    Serial.println(pickNum);

    for (int x = 1; x <= pickNum.toInt(); x++) {
      Serial.print("picking: #");
      Serial.println(x);
      digitalWrite(8, HIGH);
      Serial.println("8 HIGH ...");
      delay(1000); // Add switch
      digitalWrite(8, LOW);
      Serial.println("8 LOW ...");
      delay(1000);
    }

    Serial.print("end");

  }

  // Disconnect the client
  if (client.connected()) {
    //Serial.println();
    Serial.print("disconnecting");
    client.stop();
  }

  // Wait another 9s, which will give us a delay of roughly 10s
  delay(9000);
}
Kenneth Poulsen
  • 929
  • 10
  • 25