Author Topic: GET request and WiFi server at the same time  (Read 8961 times)

davidjwatts

  • Newbie
  • *
  • Posts: 6
GET request and WiFi server at the same time
« on: January 05, 2014, 01:42:03 pm »
Hi,

I am quite new to the DigiX but I have the server sketch up and running, serving up a page over a public IP. Now I don't have a static IP at home so I need to run it through a little PHP on my external server to get that IP periodically, this means that I can serve up my DigiX page here -  http://digix.davidjwatts.com/ and my php invisibly echos the correct URL (something like xx.xx.xx.xxx:8080).

To do that I need to run the server but I also need to sent a get or post request to another PHP page to alert it to my public URL and save it to a database.

I have all the PHP code working but the DigiX gets stuck after

Connect
start at mode
next
wait for a

show in the serial monitor window.

I have added my code and serial monitor output below it would be great to know if this is possible.

Thanks,

David

My code:

Code: [Select]
#include <DigiFi.h>
#include <DueTimer.h>
DigiFi wifi;

void setup()
{
  Timer3.attachInterrupt(sendip);
  Timer3.start(120000000);
  Serial.begin(9600);
  wifi.begin(9600);
  wifi.setDebug(true);

  //DigiX trick - since we are on serial over USB wait for character to be entered in serial terminal
  while(!Serial.available()){
    Serial.println("Enter any key to begin");
    delay(1000);
  }

  Serial.println("Starting");

  while (wifi.ready() != 1)
  {
    Serial.println("Error connecting to network");
    delay(15000);
  } 

  Serial.println("Connected to wifi!");
 // sendip();
  delay(3000);
  Serial.print("Server running at: ");
  String address = wifi.server(8080);//sets up server and returns IP
  Serial.println(address);

//  wifi.close();
}

void loop()
{

  if ( wifi.serverRequest()){
      Serial.print("Request for: ");
     Serial.println(wifi.serverRequestPath());
     if(wifi.serverRequestPath()!="/")
       wifi.serverResponse("404 Not Found",404);
      else
       wifi.serverResponse("<html><body><h1>This is a test</h1><img src='https://s3.amazonaws.com/ksr/assets/000/645/893/b26589d6d6963a8682d4919851ec4d58_large.jpg?1370375878' /></body></html>"); //defaults to 200
  }

  delay(10); 
}

void sendip(){
 if(wifi.get("digix.davidjwatts.com","/myphppageforip.php")){
   
    Serial.println("done ip send");
  }
}

My serial output:

Code: [Select]
Enter any key to begin
Enter any key to begin
Starting
start at mode
next
wait for a
clear buffer
+ok

+ok

echo off
AT+E

+ok

AT+E

+ok

Check Link
+ok=BTHomeHub2-5SK5(mac)

OUT
+ok=BTHomeHub2-5SK5(mac)

+ok

+ok

AT+ENTM

+ok

AT+ENTM

+ok

exit at mode
+ok=BTHomeHub2-5SK5(mac)

Connected to wifi!
Server running at: start at mode
next
wait for a
clear buffer
+ok

+ok

echo off
AT+E

+ok

AT+E

+ok

+ok=TCP,Server,8080,127.0.0.1

+ok

+ok=DHCP,192.168.1.65,255.255.255.0,192.168.1.254

+ok

+ok

AT+ENTM

+ok

AT+ENTM

+ok

exit at mode
192.168.1.65
GET / HTTP/1.1
Host:*ip*:8080
Accept: */*

/
Request for: /
GET / HTTP/1.1
Host: *ip*:8080
Accept: */*

/
Request for: /
Connect
start at mode
next
wait for a
« Last Edit: January 05, 2014, 02:08:33 pm by davidjwatts »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: GET request and WiFi server at the same time
« Reply #1 on: January 05, 2014, 04:29:41 pm »
try this - see one line change in sendip()

Code: [Select]

#include <DigiFi.h>
#include <DueTimer.h>
DigiFi wifi;

void setup()
{
  Timer3.attachInterrupt(sendip);
  Timer3.start(120000000);
  Serial.begin(9600);
  wifi.begin(9600);
  wifi.setDebug(true);

  //DigiX trick - since we are on serial over USB wait for character to be entered in serial terminal
  while(!Serial.available()){
    Serial.println("Enter any key to begin");
    delay(1000);
  }

  Serial.println("Starting");

  while (wifi.ready() != 1)
  {
    Serial.println("Error connecting to network");
    delay(15000);
  } 

  Serial.println("Connected to wifi!");
 // sendip();
  delay(3000);
  Serial.print("Server running at: ");
  String address = wifi.server(8080);//sets up server and returns IP
  Serial.println(address);

//  wifi.close();
}

void loop()
{

  if ( wifi.serverRequest()){
      Serial.print("Request for: ");
     Serial.println(wifi.serverRequestPath());
     if(wifi.serverRequestPath()!="/")
       wifi.serverResponse("404 Not Found",404);
      else
       wifi.serverResponse("<html><body><h1>This is a test</h1><img src='https://s3.amazonaws.com/ksr/assets/000/645/893/b26589d6d6963a8682d4919851ec4d58_large.jpg?1370375878' /></body></html>"); //defaults to 200
  }

  delay(10); 
}

void sendip(){
 if(wifi.get("digix.davidjwatts.com","/myphppageforip.php")){
   
    Serial.println("done ip send");
  }
 //change back to server mode
 wifi.server(8080);
}


dbell

  • Newbie
  • *
  • Posts: 44
Re: GET request and WiFi server at the same time
« Reply #2 on: January 05, 2014, 07:11:51 pm »
David, I wanted to make my DigiX server available remotely as well, but have no idea how to go about it.

Could you explain a bit to me how the php code on your public server obtains your IP address (am I correct in understanding this will be the external address of your home/office network?), then links to the DigiX?
If you want to take the discussion off line, you can mail me at dbell () thebells () net

Thanks!

Dave

davidjwatts

  • Newbie
  • *
  • Posts: 6
Re: GET request and WiFi server at the same time
« Reply #3 on: January 06, 2014, 12:01:43 pm »
try this - see one line change in sendip()

Code: [Select]

#include <DigiFi.h>
#include <DueTimer.h>
DigiFi wifi;

void setup()
{
  Timer3.attachInterrupt(sendip);
  Timer3.start(120000000);
  Serial.begin(9600);
  wifi.begin(9600);
  wifi.setDebug(true);

  //DigiX trick - since we are on serial over USB wait for character to be entered in serial terminal
  while(!Serial.available()){
    Serial.println("Enter any key to begin");
    delay(1000);
  }

  Serial.println("Starting");

  while (wifi.ready() != 1)
  {
    Serial.println("Error connecting to network");
    delay(15000);
  } 

  Serial.println("Connected to wifi!");
 // sendip();
  delay(3000);
  Serial.print("Server running at: ");
  String address = wifi.server(8080);//sets up server and returns IP
  Serial.println(address);

//  wifi.close();
}

void loop()
{

  if ( wifi.serverRequest()){
      Serial.print("Request for: ");
     Serial.println(wifi.serverRequestPath());
     if(wifi.serverRequestPath()!="/")
       wifi.serverResponse("404 Not Found",404);
      else
       wifi.serverResponse("<html><body><h1>This is a test</h1><img src='https://s3.amazonaws.com/ksr/assets/000/645/893/b26589d6d6963a8682d4919851ec4d58_large.jpg?1370375878' /></body></html>"); //defaults to 200
  }

  delay(10); 
}

void sendip(){
 if(wifi.get("digix.davidjwatts.com","/myphppageforip.php")){
   
    Serial.println("done ip send");
  }
 //change back to server mode
 wifi.server(8080);
}


Unfortunately it is still getting stuck in the startATMode function judging by the degub messages. Its stops in the same place
Code: [Select]
while(!Serial1.available()){delay(1);}
I am not sure how efficient stopping the wifi and then restarting would be but that may work, I will give it a go and post back.

davidjwatts

  • Newbie
  • *
  • Posts: 6
Re: GET request and WiFi server at the same time
« Reply #4 on: January 06, 2014, 12:19:48 pm »
David, I wanted to make my DigiX server available remotely as well, but have no idea how to go about it.

Could you explain a bit to me how the php code on your public server obtains your IP address (am I correct in understanding this will be the external address of your home/office network?), then links to the DigiX?
If you want to take the discussion off line, you can mail me at dbell () thebells () net

Thanks!

Dave

Sure, I am all about sharing. I am going to throw up a video tutorial about it once I have it working but here is the gist of it and some code.

You need to know your external ip address - https://www.google.co.uk/search?q=what+is+my+ip

But if, like me, you are a home broadband user the your IP may change when your DCHP license expires or if you reset your router. Mine changes a lot because my router is crap and needs resetting daily which a lot of the time results in a new IP.

I have a website and the web host (vidaost) allows for mysql databases and php so I thought I would use that as a go between. You could just have your DigiX push data to your server regularly but I would prefer it to serve the information when required, this may end up being a bridge too far though.

My current approach to save the IP is to request this PHP page:

Code: [Select]
<?php
$val 
$_SERVER['REMOTE_ADDR'];
$val $val ':8080';
$con=mysqli_connect("localhost","username","password","database");
// Check connection
if (mysqli_connect_errno())
  {
  echo 
"Failed to connect to MySQL: " mysqli_connect_error();
  }

mysqli_query($con,"UPDATE iptable SET ipaddress='$val' WHERE id = '1'");

mysqli_close($con);

  echo 
$val;
?>


This save the IP address and appends it with the port that is serving the data. I also had to set up port forwarding and a static IP address from my router to my DigiX. This means that when I connect the DigiX it always recieved the same IP on my home network and is routed as a HTTP server. through my public IP address. Unfortunately it also means that the default public URL routes to the DigiX on port 80, the login screen. Which is why I chose to hide all of that behind the PHP CURL stuff below.

Code: [Select]
<?php

$con
=mysqli_connect("localhost","username","password","database");
// Check connection
if (mysqli_connect_errno())
  {
  echo 
"Failed to connect to MySQL: " mysqli_connect_error();
  }
$url2 0;
$result mysqli_query($con,"Select ipaddress FROM iptable WHERE id = '1'");
while(
$row mysqli_fetch_array($result))
  {
  
$url2 $row['ipaddress'];
  }
mysqli_close($con);
function 
get_data($url) {
$ch curl_init();
$timeout 5;
curl_setopt($chCURLOPT_URL$url);
curl_setopt($chCURLOPT_RETURNTRANSFER1);
curl_setopt($chCURLOPT_CONNECTTIMEOUT$timeout);
$data curl_exec($ch);
curl_close($ch);
return $data;
}
echo 
get_data($url2);
?>

In order to allow interaction with the DigiX you would need to expand it by adding other pages for various requests, always hiding the URL. I just chose a sub domain on my site to hide behind but a standard yourdomain.com/digix.php would also be fine.

I hope that helps but please feel free to ask more questions, there is no point in me keeping any of this to myself.

David

davidjwatts

  • Newbie
  • *
  • Posts: 6
Re: GET request and WiFi server at the same time
« Reply #5 on: January 06, 2014, 01:37:57 pm »
Well, I had another go, I thought I was being clever, but it turns out something is going on I don't really understand.

The code below sets out a series of functions to stop the wifi and then restart it so that I can get the URL then stop and restart the wifi into server mode.

The loop is stopped by a boolean value just in case that was causing an issue.

None of this of course works. It doesn't event print out my serial statements when the timer is called.

Do not try this code, it crashes my IDE and serial monitor.

Anyone got any ideas? 

FYI I have changed the name of the PHP file in the code below so it will return a 404 but I am using an accessible URL in actual code.

Code: [Select]
#include <DigiFi.h>
#include <DueTimer.h>
DigiFi wifi;
boolean servermode = false;
void setup()
{
   Timer3.attachInterrupt(startsendip);
   
  Serial.begin(9600);
  wifi.begin(9600);
  wifi.setDebug(true);

  //DigiX trick - since we are on serial over USB wait for character to be entered in serial terminal
  while(!Serial.available()){
    Serial.println("Enter any key to begin");
    delay(1000);
  }
  Timer3.start(30000000);
  Serial.println("Starting");

  while (wifi.ready() != 1)
  {
    Serial.println("Error connecting to network");
    delay(15000);
  } 

  Serial.println("Connected to wifi!");
 // sendip();
  delay(3000);
  Serial.print("Server running at: ");
  String address = wifi.server(8080);//sets up server and returns IP
  Serial.println(address);

//  wifi.close();
}

void loop()
{

  if(servermode == true){
  if ( wifi.serverRequest()){
      Serial.print("Request for: ");
     Serial.println(wifi.serverRequestPath());
     if(wifi.serverRequestPath()!="/")
       wifi.serverResponse("404 Not Found",404);
      else
       wifi.serverResponse("<html><body><h1>This is a test</h1><img src='https://s3.amazonaws.com/ksr/assets/000/645/893/b26589d6d6963a8682d4919851ec4d58_large.jpg?1370375878' /></body></html>"); //defaults to 200
  }

  delay(10); 
  }
 
}

void sendip(){
   if(wifi.get("digix.davidjwatts.com","/myphppageforip.php")){
    String body = wifi.body();
    Serial.println(body);
    Serial.println("done ip send");
   
  }
  else{
     Serial.println("error");
  }
  delay(3000);
 
 restartserver();
}

void startsendip(){
  servermode = false;
 wifi.close();
  delay(3000);
   wifi.begin(9600);
  wifi.setDebug(true);
  delay(3000);
  sendip();
 
}

void restartserver(){
  delay(3000);
 wifi.begin(9600);
  wifi.setDebug(true);
 
  delay(3000);
 
  wifi.server(8080);
  delay(100);
  servermode = true;
}

dbell

  • Newbie
  • *
  • Posts: 44
Re: GET request and WiFi server at the same time
« Reply #6 on: January 06, 2014, 10:26:37 pm »
Thanks, David!
I have it working now, assuming a fixed external IP; I'm fortunate in that mine hasn't changed in several years, despite modem restarts.
When I get some more time, I'll implement something like you've done.

Dave

davidjwatts

  • Newbie
  • *
  • Posts: 6
Re: GET request and WiFi server at the same time
« Reply #7 on: January 07, 2014, 03:38:43 pm »
Thanks, David!
I have it working now, assuming a fixed external IP; I'm fortunate in that mine hasn't changed in several years, despite modem restarts.
When I get some more time, I'll implement something like you've done.

Dave

I am glad you got it sorted, I will keep searching for a way to get my intended project to work and post back my results.

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: GET request and WiFi server at the same time
« Reply #8 on: January 09, 2014, 12:22:18 am »
David,

I've been working at debugging this the last two nights and it is driving me crazy that it doesn't work

I finally concluded the timer was at fault - I still can't figure out why

After removing the timer I still couldn't get it, but was closer - then I found a bug in the get function

Here is what I arrived at - which works for me - attached is the DigiFi.cpp library file with the small bug fix - it will be in the next release (tonight or tomorrow night probably) as well

Code: [Select]

#include <DigiFi.h>
DigiFi wifi;

void setup()
{

  Serial.begin(9600);
  wifi.begin(9600);
  wifi.setDebug(true);

  //DigiX trick - since we are on serial over USB wait for character to be entered in serial terminal
  while(!Serial.available()){
    Serial.println("Enter any key to begin");
    delay(1000);
  }

  Serial.println("Starting");

  while (wifi.ready() != 1)
  {
    Serial.println("Error connecting to network");
    delay(15000);
  } 

  Serial.println("Connected to wifi!");
 // sendip();
  delay(3000);
  Serial.print("Server running at: ");
  String address = wifi.server(8080);//sets up server and returns IP
  Serial.println(address);
 
  //  wifi.close();
}

long lastCheck = 0;

void loop()
{

  if ( wifi.serverRequest()){
      Serial.print("Request for: ");
     Serial.println(wifi.serverRequestPath());
     if(wifi.serverRequestPath()!="/")
       wifi.serverResponse("404 Not Found",404);
      else
       wifi.serverResponse("<html><body><h1>This is a test</h1><img src='https://s3.amazonaws.com/ksr/assets/000/645/893/b26589d6d6963a8682d4919851ec4d58_large.jpg?1370375878' /></body></html>"); //defaults to 200
  }
 
  if(millis() - lastCheck > (120 * 1000)){ //send every 120 seconds
    lastCheck = millis();
    sendip();
  }
   
  delay(100); 
}

void sendip(){
 
 //clear out any lingering data from an interrupted request
  while(Serial1.available()){Serial1.read();}
 
 if(wifi.get("digix.davidjwatts.com","/myphppageforip.php")){
   
    Serial.println("done ip send");
  }
 //change back to server mode
 
 wifi.server(8080);
}
« Last Edit: January 09, 2014, 12:23:58 am by digistump »

davidjwatts

  • Newbie
  • *
  • Posts: 6
Re: GET request and WiFi server at the same time
« Reply #9 on: January 11, 2014, 01:35:51 pm »
Thanks (Erik...?) you are a bona fide genius and dedicated to boot.

It did indeed work, thank you. And it was interesting to compare the two DigiFi.cpp files to see what you had changed. I have been over the code and I think I understand the previous issue.

One odd thing, I was pummeling the DigiX with requests and I saw a AT command appear in the http response instead of the usual server response, do you know what might of caused that? I wasn't using the serial monitor at the time so I am not sure what stage it was at.

Also, could I request a change to DigiFi::get and post? (and corresponding change to DigiFi.h)

bool DigiFi::get(char *aHost, char *aPath, char *aAgent){
    if(connect(aHost) == 1){
        //delay(500);
       Serial1.print("GET ");
        Serial1.print(aPath);
        Serial1.print(" HTTP/1.1\r\nHost: ");
        Serial1.print(aHost);
   Serial1.print("\r\nUser-Agent: ");
   Serial1.print(aAgent);


Adding a User-Agent as an optional argument would mean that I and others could track the request through various site analytics software. It would also just be cool to see that the DigiX requested 'this page' at a certain time/date. I believe it is also a required header for some web APIs.

I tried it out and it seems to work fine for me but I don't want to rely on a modified library, that would be asking for trouble in the long run.

Thanks for your hard work on this, I think it will be really useful to a lot of people who cannot get a fixed IP or just want to call out as well as serve data.
« Last Edit: January 11, 2014, 02:03:34 pm by davidjwatts »