Pages: [1]   Go Down
Author Topic: Arduino - Control Browser Location  (Read 507 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey everyone,

I'm pretty new to Arduino development, I've been working with it for about 3 weeks now.  I'm a web developer and I've programmed in C++ before, so I'm catching on quick.  Anyway, what I'm trying to do is have a computer use an internet browser to load the IP of the Arduino and display messages based on the outcome of an RFID card.

I understand the difference between a web server and a web client in general terms, but in the world of Arduino it gets a little fuzzy for me and I'm not sure why.  Even in code (that I've gotten to work) I only notice a small difference.  This is the biggest difference I notice, you need this line to  use it as a client [ EthernetClient browser_client = server.available(); ].  I guess I could use help on the difference in terms of Arduioing.

I've gotten my code to read the RFID serial number, and then send that serial to my home web server that has a database on it - it just does a simple query to see if it can find the serial number or not, if it cannot, it returns 0, if it can, it returns a 1.  The Arduino reads the 0 or 1 just fine.  Now this is where I get confused.  If I want a computer to just sit on the IP of the Arduino and at any given time when the RFID reader goes through its thing, how can I show a message on the computer's browser?

Here is a really simple image I put together that shows how my setup looks.


Here is my code:
Code:
#include <Ethernet.h>
#include <SPI.h>

#include <SoftwareSerial.h>

////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
byte database_server[] = { my, ip, address, here };

//The location to go to on the server
//make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
String location = "/?code=";

// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 109); //IP of Arduino on LAN
EthernetServer server(80); //Arduino as a WebServer
////////////////////////////////////////////////////////////////////////

EthernetClient database_client;

char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

int  val = 0;
char code[10];
int bytesread = 0;
#define rxPin 8
#define txPin 9


void setup(){
  Ethernet.begin(mac, ip); //For a WebClient, you only need (mac), but for a WebServer you need at least (mac, ip)...this line opens up the Ethernet for both the WebClient and WebServer
  server.begin(); //Start listening for clients, browsers connecting to the IP set above
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  
  Serial.begin(9600);
  
  pinMode(2,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
  digitalWrite(2, LOW);    // Activate the RFID reader
  
  //For lights
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop(){  
  SoftwareSerial RFID = SoftwareSerial(rxPin,txPin);
  RFID.begin(2400);

  if((val = RFID.read()) == 10)
  {   // check for header
    bytesread = 0; //Reset for next scan
  
    while(bytesread < 10)
    {  // read 10 digit code
      val = RFID.read();

      if(val > 0){ //Sometimes val is -1 and junk is saved as the code, so let's make sure val > 0
        if((val == 10)||(val == 13))
        {  // if header or stop bytes before the 10 digit reading
          break;                       // stop reading
        }
        code[bytesread] = val;         // add the digit          
        bytesread++;                   // ready to read next digit  
      }
    }

    if(bytesread == 10)
    {  // if 10 digit read is complete
      Serial.print("TAG code is: ");   // possibly a good TAG
      Serial.println(code);            // print the TAG code
      
      String pageValue = connectAndRead(code); //connect to the server and read the output
      Serial.println(pageValue); //print out the findings.
      //delay(5000); //wait 5 seconds before connecting again
      
      if(pageValue == "1"){
         browserRedirect();
      }
      
    }
    delay(500);                       // wait
  }
  

}

String connectAndRead(String code){
  //connect to the server

  Serial.println("connecting...");

  //port 80 is typical of a www page
  if (database_client.connect(database_server, 80)) {
    Serial.println("connected");
    database_client.print("GET ");
    database_client.print(location);
    database_client.print(code);
    database_client.println(); //Need to print a blank line so the server knows it's the end of the request

    //Connected - Read the page
    return readPage(); //go and read the output

  }else{
    return "connection failed";
  }

}

String readPage(){
  //read the page, and capture & return everything between '<' and '>'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while(true){

    if (database_client.available()) {
      char c = database_client.read();

      if (c == '<' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part
      }else if(startRead){

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          
          triggerPin((int)c);
          
          stringPos ++;
        }else{
          //got what we need here! We can disconnect now
          startRead = false;
          database_client.stop();
          database_client.flush();
          Serial.println("disconnecting.");
          return inString;

        }

      }
    }

  }
}



void triggerPin(int pin){
  digitalWrite(pin, HIGH);
  delay(25);
  digitalWrite(pin, LOW);
  delay(25);
}



void browserRedirect(){
  Serial.println("BROWSER REDIREDCT");
  // listen for incoming clients
  EthernetClient browser_client = server.available();
  if (browser_client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (browser_client.connected()) {
      if (browser_client.available()) {
        char c = browser_client.read();
        Serial.write(c);
        // 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) {
          // send a standard http response header
          browser_client.println("HTTP/1.1 200 OK");
          browser_client.println("Content-Type: text/html");
          browser_client.println("Connnection: close");
          browser_client.println();
          browser_client.println("<!DOCTYPE HTML>");
          browser_client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          browser_client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            browser_client.print("analog input ");
            browser_client.print(analogChannel);
            browser_client.print(" is ");
            browser_client.print(sensorReading);
            browser_client.println("<br />");      
          }
          browser_client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    browser_client.stop();
    Serial.println("client disonnected");
  }
}

I tried to do what I'm writing about on the line that looks like:
Code:
if(pageValue == "1"){
     browserRedirect();
}

Thanks so much for your help!!
Logged

-TJ Nevis
TJNevis.com

I'm always up for a freelance project if the price is right!

Offline Offline
Full Member
***
Karma: 2
Posts: 219
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

not exactly sure about it.
but i think your problem isnt arduino related, am i right here,
You have trouble with the fact that a web brouwser page load of a simple page is just a thing that happens once
You want the arduino to send a page refresh as well.. but you cannt do a HTML page refresh either because you dont know if there will be new data

Hmm.. it think java should be able to do this
(as web based chat programs deal with the same problem, you never know when the other is going to type)
maybe spend some time on how a web based chat prog works, well your a programmer.
take a look at this http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-simple-web-based-chat-application/

hm other options might be perhaps to let the arduino sendout to twitter
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm confused about what your problem is - probably because you are confused too.

I guess you want your PC to have a live display of some sort that updates when the Arduino detects a relevent RFID.

In that case thje most obvious way to achieve it is to use your existing mechanism for the Arduino to contact your web server via HTTP to check the detected RFID and have your web server also host a webapp that enables clients (browsers) to show a live display that updates when the Arduino notifies it about the RFID.

Since you're a web developer that part should be child's play for you, but in any case it would be a straight forward job to implement something using any AJAX framework you like.

It would be far better to host that webapp here on your web server rather than on your Arduino, because your web server will be far more powerful and capable than an Arduino.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PGTBOOS - Correct, I don't think my issue is Arduino related.  And yes, I do want the page to refresh, with some new text.

PeterH - Right, I want the PC to display something when an RFID tag is scanned.  I had a plan B of using NodeJS and Socket.io to send a message to the browser of the computer based on what the query was and that would do what I was imagining.  I just feel like that solution would be overkill.

I've had some time to think more on how to explain what I'm looking for.  It might just not be possible, but I thought I'd ask in different words.

I put this chunk of code at the top of the void loop() function:
Code:
   EthernetClient browser_client = server.available();
      if (browser_client) {
        while (browser_client.connected()) {
          if (browser_client.available()) {
              browser_client.println("HTTP/1.1 200 OK");
              browser_client.println("Content-Type: text/html");
              browser_client.println();
              browser_client.println("<!DOCTYPE HTML>");
              browser_client.println("<html><h1>TEST!!</h1></html>");
     //browser_client.stop();
          }
        }
      }

As long as I don't call browser_client.stop();, It repeats on the page over and over and over again.

So, what I was wondering, is can I put the client code in such a way that it keeps the connection live on the computer's browser and when the RFID card is read and 0 or 1 is returned from the database, I could send browser_client.println("SOMETHING");?

It may not be possible or maybe I'm just not using the correct combination / order of the code. 

Thanks again for all your help!
Logged

-TJ Nevis
TJNevis.com

I'm always up for a freelance project if the price is right!

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 652
Posts: 50863
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So, what I was wondering, is can I put the client code in such a way that it keeps the connection live on the computer's browser and when the RFID card is read and 0 or 1 is returned from the database, I could send browser_client.println("SOMETHING");?

It may not be possible or maybe I'm just not using the correct combination / order of the code. 
No. The server closes the connection when it has finished processing the GET request from the client.

If the Arduino is a server, all it can do is know what RFID tag was last scanned, and report that the next time it is asked.

If the Arduino is a client, it can issue a GET request to a server, causing a script/executable on the server to execute. The script/executable, could, theoretically, pop up a dialog box or alter a GUI to show the tag data as soon a scan happened.

The server's script/executable does not have to use/understand html.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, thanks for the clarification.  That's kind of what I was thinking as I was testing/confused.  With 3 people leaning towards the same conclusion, that's what I'll have to pursue!  Thanks so much guys!
Logged

-TJ Nevis
TJNevis.com

I'm always up for a freelance project if the price is right!

Earth (I think)
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What if, rather than sending a webpage, you used a telnet connection? Every time the Arduino sees an RFID tag, it sends the ID of the tag over the telnet connection. If you really want a webpage, you could code something similar to http://wolfgang.site40.net/telnet/ (my website), which uses a Java applet to establish a connection to the telnet server. If you want, you could probably even code up a custom applet that only displays the last line sent.
Logged


Pages: [1]   Go Up
Jump to: