How to open a URL with Spark Core?

@bstolte,

You can probably know i got it working with the logs on your server side :wink:

I managed to get the sending working and made into a function added in your code.

gist.github.com/kennethlimcp/df875f7851a2a19069a8

Can you try and tell me how its goes? :smile:

That works!! :smiley:

The PIR picks up the motion and calls that URL which then sends a text to my phone. It does send 3-4 texts for each time it detects motion but it’s working.

Thank you very much for all your help, greatly appreciate it. I’ll keep tweaking it from here to see if I can get it to just text once for each time it detects motion. If you’re interested you can see each time it generates a text message here: http://bstolte.com/motion_sms/

Side note: it’s pretty cool when my phone starts getting text messages when you’re working on the code :smile:

@bstolte you need to work on the code.

I’m getting my core all cranky cos i don’t have the PIR attached and i think when the loop keeps calling the getrequest() too often crazy stuff happens!

let me edit and see how things go.

The idea is you need to restrict sending to once every X seconds

@kennethlimcp Yup my core is cranky too. It seems to detect the motion, send a few texts and then reset itself.

I’ll try and get it down to sending once every X secs and post the code back here.

It’s a big issue actually cos the core gets into some form of panic which might be hard to resolve.

Add the

client.flush();
client.stop();

before the return(1) and see how it turns out

Just a follow up. If I include client.stop(); it will run the code but not hit the URL and trigger the text message. If I remove client.stop(); it will run and send text messages.

In both cases, from what I’m seeing in the serial output , it’s cycling through the motion detected loop anywhere from 3-7 times.

Connected
Motion detected!
Connected
Connected
Connected
Motion ended!

“Connected” occurs in the getrequest() and “Motion detected” happens right after. It looks like it cycles back through getrequest() a few more times perhaps because the PIR sensor is still reading motion or is just slow to clear out after motion has been detected. I tried putting delays in there but didn’t really help.

I’m thinking I need to re-write so I can limit the call to getrequest() just once per motion being detected and then let it clear out.

Latest here but haven’t had much time in the past couple of days to play with it.

1 Like

Yeah you need to limit like interval before a next send can be executed! :wink:

Hi @bstolte

I think if you add small delay like delay(50); before the client.stop() you should find it will work. I think you are killing the connection before it has a chance to finish sending.

It would also be better to add rate limiting in the real application by saving the value of millis(); when you send and not sending for a certain time after than.

2 Likes

Hi @bko and @kennethlimcp

Just wanted to say thanks again for all the help. @bko suggestion was spot on, using millis();, and I found code that “solved” the problem here.

Thanks!! :smile:

3 Likes

@bstolte, now you are successfully opening your url, please could you post either the complete solution or at least the TCP client part of the code that successfully sends :

http://1.1.1.1/statussubmit.php?&ph=2&ec=1&temp=25&humidity=60&light=1&waterlvl=0

Is it exactly as in @kennethlimcp’s gihub post?
I’d find it a very helpful example.

@phec, you can take a look at the code I’m using here:

gist.github.com/bstolte/11188547

Basically the getrequest() function does the work of opening the connection and calling the URL.

I also limited the number of times it can call the URL to once per minute. The URL it calls in my implementation will trigger a text message to my phone - I only wanted one text message per minute. Not sure if you need this part but thought I’d call it out if you were wondering why it was there.

Let me know if I can help answer any other questions.

1 Like

Sorry to revive an old thread. I’m using basically identical code to @bstolte in the last post and it works – sort of. I’ve set it to call a URL every 5 minutes. It didn’t appear to be working, and I spent hours trying variations based on @bko 's code, using other hints in this thread. Suddenly it worked – once. I left it running for ~24 hours and it appears to have called the URL 7 times (out of ~288), without any apparent pattern (i.e. it is not sending every 5 hours, it seems random).

I’ve set up debug statements so I know that client.connected() returns true nearly every time. I’ve pinged my server and added delays longer than the ping time to no avail. I’ve spark.published the variable and then observed through the https://api.spark.io/v1/devices/ url, it updates continuously and without flaw, every 5 minutes.

Any ideas on why this would work intermittently? Is there any additional debug info available from client.connected() or other routines?

Thank you!
Brett

The key thing that lots of folks forget is that your server is sending you stuff even though it is a GET request and you may not be interested in the response. If you don’t pickup the bytes it sends and flush them, it will get backed up and the core will reboot. The general recipe is to send a request, wait for a response from the server with a time out, and then read any data that has come in until there is no more data.

I’m not certain I understand. Do you think putting a little more delay before flush, or after the GET request would help? The file I’m requesting is less than 2kB so hopefully that doesn’t take long. And the Spark isn’t rebooting itself: it keeps chugging along and publishing the current state, as far as I can tell. I will add an UpTime to the published variables just to make sure.

Thanks for the help!

Something Iike this:

// do GET request here
unsigned long lastTime = millis();
while( client.available()==0 && millis()-lastTime<10000) { //ten second timeout
  }  //do nothing
lastTime = millis();
while( client.available() && millis()-lastTime<10000 ) {  //ten seconds
  client.read();  //flush data
}
client.flush();  //for safety

Ok, that causes the Spark to crash. I get a one red blink as the error.

I minimized the code so that it is basically just a wrapper for the connection code:

int getrequest(){
client.connect(server, 80);

if (client.connected()) {
        Serial.println("Connected to server.");
        client.print("GET ");
        client.print("/my/url.php?variable=123.45");
        client.println(" HTTP/1.0");
        client.print("Host: ");
        client.println(server);
        client.println("Connection: close");
        client.println();

        unsigned long lastTime = millis();
        while( client.available()==0 && millis()-lastTime<10000) { //ten second timeout
          }  //do nothing
        lastTime = millis();
        while( client.available() && millis()-lastTime<10000 ) {  //ten seconds
          client.read();  //flush data
        }
        client.flush();  //for safety

        //client.flush();
        delay(400);
        client.stop();
        Serial.println("sent and closed");
    return 1;
     }
    else {
        client.flush();
        client.stop();
        Serial.println("Not connected");
        return 0;
    }     

}

OK I tested this and it work for me. Maybe you should look at your server?

char server[] = "www.google.com";
char url[] = "search?q=unicorn";

TCPClient client;

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

}

void loop() {
    
    Serial.println("Starting request");
    int retval = getrequest();
    Serial.print("Returns ");
    Serial.println(retval);
    delay(10000);
}

int getrequest(){
client.connect(server, 80);

if (client.connected()) {
        Serial.println("Connected to server.");
        client.print("GET ");
        client.print(url);
        client.println(" HTTP/1.1");
        client.print("Host: ");
        client.println(server);
        client.println("Connection: close");
        client.println();

        unsigned int count = 0;
        unsigned long lastTime = millis();
        while( client.available()==0 && millis()-lastTime<10000) { //ten second timeout
          }  //do nothing
        lastTime = millis();
        while( client.available() && millis()-lastTime<10000 ) {  //ten seconds
          client.read();  //flush data
          count++;
        }
        client.flush();  //for safety

        //client.flush();
        delay(400);
        client.stop();
        Serial.print("sent and closed-bytes: ");
        Serial.println(count);
    return 1;
     }
    else {
        client.flush();
        client.stop();
        Serial.println("Not connected");
        return 0;
    }
}
1 Like

Wow, thank you! For whatever reason, your code worked. I then integrated it into mine, and now mine is working as well. It is late so I’m confused, but tomorrow I’ll have to investigate line-by-line to see what the differences are.

A couple observations: every once in a while the “sent and closed-bytes” (while using your Unicorn Search code directly) will return a larger byte value. About 1/8 of the time. Haven’t figured out why. Second, it does crash on occasion, with the single red blink error message. In the last hour of playing I think I’ve seen this behavior 3x. I think this is with your code directly but I may have modified it slightly, I can’t trust my memory.

I’m going to let it run overnight and check results. But THANK YOU! for all your help, very much appreciated.

Brett

3 Likes

Hi @bko, could have a problem using wifi shared from my cellphone? Since I typed exactly the same code and it does not work. The same thing happen using code from tutorial TCPClient atDocs Spark(Does nothing). is there something I need to keep in mind changing your code?(i.e. maybe something in code changes from countries? IDK) Thanks as always! :smile:

There was some funny thing that some people ran into where they needed an extra newline in an HTTP request or extra time after the request when using their phone’s hotspot. I have never tried my phone as a hotspot (cost is high with my plan) so I really can’t say.

Try searching around the forum here for phone hotspot problems and see if someone else has good ideas for you.

1 Like