Pages: [1] 2   Go Down
Author Topic: Explanation of println & getting the response in a webpage  (Read 782 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all, and thanks for reading.

Sorry if this is a bit outside of the scope of the Yun forums, being more about a webpage than about the yun itself, but I was wondering if someone knowledgeable could explain how println works in the context of XMLHttprequest, and how exactly I should be receiving data from my Yun, to be stored dynamically on my webpage.

Currently I have a running webpage hosted by the Yun and available on the local network. Using XMLHttprequest, I can send orders to the yun (currently turning an LED on/off via bridge example). However, I cannot get the proper response (pin X set to bool) to return to my webpage (the light will turn on and off properly though). Here is the relevant code:

Code:
function ajaxIt(url)
{
loadDoc(url, function()
{
// DEBUG document.getElementById('para1').innerHTML="Got inside loadDoc.";
if (xmlhttp.readystate==4 && xmlhttp.status = 200)
{
// DEBUG document.getElementById('response').innerHTML=xmlhttp.responseText;
document.getElementById('para1').innerHTML="Got into inner if statement.";
}
});
}
function loadDoc (url, receiveData)
{
// DEBUG document.getElementById('header2').innerHTML="Clicked!";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = receiveData;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
<more script & html...>



Where all elements exist etc. Every example I've seen has it set up this way, and they all seem to get responses. Is there something I'm missing? When I run with DEBUG, it'll get inside of loadDoc, but not the inner if. So either I'm not getting to ready state 4, or status 200 - which leads me to question my understanding of println.

Can anyone enlighten me as to where to search for answers? I've read quite a bit about XMLHttp, and a bit about println, but oddly found little about them working together.

Much thanks for reading and responding.

Humbly,
Kiobod
« Last Edit: June 09, 2014, 04:57:24 pm by kiobod » Logged

Earth
Offline Offline
Edison Member
*
Karma: 52
Posts: 1762
My browser no longer is binding static IP, Floating is the way to go.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your arduino code?  Please use code tag.
Logged

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

For all intents and purposes it's the same as the Bridge example - it will print a response when I type IP address/arduino/digital/13/1 directly into the browser, but my XMLHttp won't grab it and throw it into my webpage.

The part of interest:
Code:
// Send feedback to client
  client.print(F("Pin D"));
  client.print(pin);
  client.print(F(" set to "));
  client.println(value);

Thanks for the response sonny - here's the whole code in case you want to look at it. I'll warn you, it's not very clean right now as I'm developing it as I go, but the digital command and the Yunserver are completely unaltered from the Bridge example.

Code:
/***********************************************************************************
* Arduino Yun pass by HTTP light show manipulator - Kilen Multop with Luay Hammami *
*  Based on the Arduino Yun's Bridge example                                       *
************************************************************************************/

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
//initial values
int count = 0;
int val = 0;
int valy = 0;
const int SIZE = 7;
int lights [SIZE] = {7,8,9,10,11,12,13};

const int OSIZE = 4;
const int ESIZE  = 3;

/******************************************************************************
* The following are functions used within the light show itself, called later *
*******************************************************************************/

void oddOn (int a[]) //turns on the odd numbered lights
{
  val = 0;
  while (val<OSIZE)
  {
  digitalWrite (a[(1+(2*val))], HIGH);
  val++;
  }
 
}
void oddOff (int a[])//turns off odd lights
{
  val = 0;
  while (val<OSIZE)
  {
  digitalWrite (a[(2*val)], LOW);
  val++;
  }
}
 void evenOn (int b[])//turns on the even lights
 {
   val = 0;
   while (val<ESIZE)
   {
   digitalWrite (b[(1+(2*val))], HIGH);
   val++;
   }
 }
 void evenOff(int b[])//turns off the even lights
 {
   val = 0;
   while (val<ESIZE)
   {
   digitalWrite (b[(1+(2*val))], LOW);
   val++;
   }
 }
void switchBlink (int c[]) //one of the events within vegasBlink that occurs, every other light will blink on and off
{
  oddOn(c);
  evenOff(c);
  delay (400);
  evenOn(c);
  oddOff(c);
  delay (400);
}
void vegasBlink (int c[])//does some fancy vegas style blinking, using other functions mostly. Will run under loop
{
  allOn (c);
  delay (400);
  val = 0;
  while (val<5)
  {
  switchBlink(c);
  val++;
  }
  allOff(c);
  delay (600);
  switchBlink(c);
  switchBlink(c);
  allOn (c);
  delay (200);
}

void blinkingLine (int c[])//simple blink in line from one end to the other
{
  val = 0;
  while (val<SIZE)
  {
  digitalWrite (c[val], HIGH);
  delay (500);
  digitalWrite (c[val], LOW);
  val++;
  }
 
}
void allOn (int c[]) // all lights on
{
  val = 0;
  while (val<SIZE)
  {
  digitalWrite (c[val], HIGH);
  val++;
  }
}

void allOff (int c[]) // all lights off
{
  val = 0;
  while (val<SIZE)
  {
  digitalWrite (c[val], LOW);
  val++;
  }
}

void blinkOnOff(int c[]) //another series that will run under main loop
{
  allOn(c);
  delay (1000);
  val = 0;
  while (val<7)
  {
  allOff(c);
  delay (500);
  allOn (c);
  delay (500);
  val++;
  }
}

void runLoop (YunClient client, int pin, YunServer server) //main loop, utilizing while loops to run processes multiple times
{
  while ((count<3) && (pin == 1))
  {
    blinkingLine (lights);
    count++;
  }
  if (client)
  {
    client = server.accept();
    pin = client.parseInt();
  }
   
  while (count<5)
  {
    vegasBlink(lights);
    count++;
  }
  if (client)
  {
    client = server.accept();
    pin = client.parseInt();
  }
 
  while (count<7)
  {
    blinkingLine (lights);
    count++;
  }
  if (client)
  {
    client = server.accept();
    pin = client.parseInt();
  }
 
  while (count<11)
  {
    blinkOnOff (lights);
    count++;
  }
  if (client)
  {
    client = server.accept();
    pin = client.parseInt();
  }
  count=0;
}

/************************************************************************************
* The following sets up the communication processes between the Yun and the network *
*************************************************************************************/

// Listen on default port 5555, the webserver on the Yun
// will forward there all the HTTP requests for us.
YunServer server;

void setup() {
  // Bridge startup
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Bridge.begin();
  digitalWrite(13, HIGH);
  val = 0;
  while (val<SIZE)
  {
  pinMode (lights[val], OUTPUT);
  val++;
  }

  // Listen for incoming connection only from localhost
  // (no one from the external network could connect)
  server.listenOnLocalhost();
  server.begin();
}

void loop()
{
  // Get clients coming from server
  YunClient client = server.accept();

  // There is a new client?
  if (client) {
    // Process request
    process(client, server);

    // Close connection and free resources.
    client.stop();
  }

  delay(50); // Poll every 50ms
}

void process(YunClient client, YunServer server) {
  // read the command
  String command = client.readStringUntil('/');

  // is "digital" command?
  if (command == "digital") {
    digitalCommand(client);
  }
 
  //is "lightsOn" command?
  if (command == "lightsOn")
  {
    lightsOn(client, server);
  }
}

void digitalCommand(YunClient client) {
  int pin, value;

  // Read pin number
  pin = client.parseInt();

  // If the next character is a '/' it means we have an URL
  // with a value like: "/digital/13/1"
  if (client.read() == '/') {
    value = client.parseInt();
    digitalWrite(pin, value);
  }
  else {
    value = digitalRead(pin);
  }

  // Send feedback to client
  client.print(F("Pin D"));
  client.print(pin);
  client.print(F(" set to "));
  client.println(value);

  // Update datastore key with the current pin value
  String key = "D";
  key += pin;
  Bridge.put(key, String(value));
}


void lightsOn(YunClient client, YunServer server)
{
  client.println("You have opened the light show section of the Arduino.");
  int pin = client.parseInt();
  client.println(pin);
  while ((pin == 1) && (valy<1000))
  {
    runLoop(client, pin, server);
    if (client)
    {
      client = server.accept();
      pin = client.parseInt();
    }
    else;
  valy ++;
  allOff(lights);
  }
 
  allOff(lights);
  valy = 0;
 }
« Last Edit: June 09, 2014, 05:02:43 pm by kiobod » Logged

Offline Offline
Edison Member
*
Karma: 36
Posts: 1139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've messed with low level XMLHttpRequest too many years ago to be helpful in any way. Please port your code so to use either jquery or its lightweight version zepto
Your code will look much cleaner.
And since nowadays lots of webdevs are using jquery, you'll also find many more examples/help on google
Logged

Have you upgraded the Yún? If you've just got it, then it needs to be upgraded! Check out the tutorial

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

Okay

I was going to try to avoid learning yet another language (ironically my major is global languages), but if that's the best way to solve the problem, I'll have to do that!

Thanks for the help Federico,
Kiobod
Logged

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

Okay, here's the code ported over to jQuery as best I understand it. Unfortunately now I can't even send commands to the Yun, let alone receive a response. It's rather aggravating, but I'm willing to put in the time to make this work. Thanks for the help.

Code:
!DOCTYPE html>
<html>

<head>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$(document.ready(function()
{
$("#B13on").click(function()
{
$.get('http://10.50.0.167/arduino/digital/13/1', function(data, status)
{
$("#response").text("data");
});
});
});
</script>
</head>

<body style="background-color:rgb(150,150,150)"; font-family: "Arial";>
<h1 style="text-align:center;">
This is my second webpage. I hope it works better than the first.
</h1>

<h2 id="header2">
MANIPULATE PIN 13
</h2>
<p>
<button id="B13on">
13 ON
</button>
<button>
13 OFF
</button>

<h3>
Response from the Arduino
</h3>
<p id="response">
Response will display here.
</p>
</body>
</html>

-Kiobod
Logged

Offline Offline
Edison Member
*
Karma: 36
Posts: 1139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think it should be like this
Code:
<script>
$.ready(function() {
  $("#B13on").click(function() {
    $.get('/arduino/digital/13/1', function(data, status) {
      $("#response").text(data);
    });
  });
});
</script>

Use firefox firebug (or chromium's "inspect element) to debug browser javascript code
Logged

Have you upgraded the Yún? If you've just got it, then it needs to be upgraded! Check out the tutorial

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

:/ Shoot

Sorry Federico, but even copy and pasting your code into mine (and adding the IP address) didn't work. (I tried it without the IP address as well - but that didn't work and hasn't worked traditionally, I think it needs the address to properly REST.)

Any other thoughts? I'm pretty well confused, this method seems to have worked for everyone else...

Also, thanks for the tip about browser debugging, unfortunately, my code as it stands doesn't have any errors (although it did the first time I uploaded)

Thanks for your time

-Kiobod
Logged

Offline Offline
Edison Member
*
Karma: 36
Posts: 1139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does this page run ON the yun? Or on some other computer? For ajax calls to work, they must hit the same "domain" (ip) of the originating page
Logged

Have you upgraded the Yún? If you've just got it, then it needs to be upgraded! Check out the tutorial

Offline Offline
Edison Member
*
Karma: 36
Posts: 1139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

BTW yun's rest api support jsonp as well (this way you can call multiple yun from an page served by another computer)
Logged

Have you upgraded the Yún? If you've just got it, then it needs to be upgraded! Check out the tutorial

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

Hi

Yeah, the page is hosted by the Yun, although I've tried running it locally as well.
Just to re-cap:

*old code using XMLHttprequest was able to send commands, but not receive an answer.
*new code using jQuery .get won't send commands or receive messages.
*arduino is properly sending responses. When in browser, I can access the Yunserver with ip address + arduino/digital/13/0&1, send messages and receive responses.
*there are no syntax errors within the html.

EDIT:
I have also tried using a different method, ().load(), and it didn't make any difference. This bring me back to println. Is there something I need to do so that my program can recognize the println response from the arduino???
Maybe that's just wishful thinking...

« Last Edit: June 11, 2014, 03:07:58 pm by kiobod » Logged

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

Update & bump-

So I went back and was playing around with my simple javascript code, and I removed the requirements for readystate 4 and code 200. The Javascript properly inserted a null string into the target area - so I've narrowed down the problem area.

At this point I know I am sending info from the arduino, I also know that my httprequest is not achieving readystate 4, ergo it isn't actually getting the info from the arduino. So my conclusion is that there is something I'm not doing to tell the arduino where to send the information, or to have the website catch the information. Can anyone enlighten me as to what those might be???

I feel like the answer should be simple, and I'll be kicking myself for not getting it sooner.

Thanks and regards,

Kiobod

EDIT:
So what I think may be going on is that there's some sort of cross-webpage issue, and I'll need to use JSON. Anyone know where I could find some decent resources?
« Last Edit: June 13, 2014, 04:25:18 pm by kiobod » Logged

Offline Offline
Edison Member
*
Karma: 36
Posts: 1139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your problem is with Same Origin Policy [1] you can solve it putting your html page on the Yun. Thus the origin will be the same. Them the code I posted earlier will work as I supposed your html page was served by the yun it self.

If you need to put it elsewhere my advice is still to use jquery: in order to make a JSONP call to the Yun REST API you just need to add
Code:
dataType: "jsonp"
to the object passed to the ajax function [2]. Google for "jquery jsonp"

[1] http://en.wikipedia.org/wiki/Same-origin_policy
[2] http://api.jquery.com/jQuery.ajax/
Logged

Have you upgraded the Yún? If you've just got it, then it needs to be upgraded! Check out the tutorial

Offline Offline
Newbie
*
Karma: 1
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know if this will help but it's a zip file of a project I am working on.
It has 6 gauges for a/d, 4 sliders for pwm, 8 toggle buttons for ports.
It feeds back all data such that it will verify that ports are on/off, the pwm is as set, and of course the a/d.
Buttons change colour to the repsonse, not local action.

I found the standard client.println method slowed things down, so I used concatenation to send as much data as I could. This reduced overall response time from over 800mS to around 400mS from send to recieve/page update.

The work is very messy as yet, I just want things to work, tidy up later after I have learnt what I need to know. ( should bring a smile to some, but it works).

I would love to use sockets, but as yet I don't have a clue. Having read about them, it's easy for those that know, not so easy for the likes of me. one day ......

* www_xml.zip (51.43 KB - downloaded 9 times.)
Logged

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

Thanks for the feedback folks,

@Federico - I hosted this page from the Yun :

Code:
<!DOCTYPE html>
<html>

<head>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$.ready(function() {
  $("#B13on").click(function() {
    $.get('http://10.50.0.167/arduino/digital/13/1', function(data, status) {
      $("#response").text(data);
    });
  });
});
</script>
</head>

<body style="background-color:rgb(150,150,150)";>
<h1 style="text-align:center;">
This is my second webpage. I hope it works better than the first.
</h1>

<p id="para1">
And also some text.
</p>

<button onclick="getElementById('para1').innerHTML='Now is changed'">
click here
</button>

<h2 id="header2">
MANIPULATE PIN 13
</h2>
<p>
<button id="B13on">
13 ON
</button>
<button>
13 OFF
</button>

<h3>
Response from the Arduino
</h3>
<p id="response">
Response will display here.
</p>
</body>
</html>

And still no dice on the response OR getting the light to turn on- I'll move on to use JSON, but from what it sounds like, the communication should've worked at that point, no? Anyways, thanks for the direction.

@Roffey - Thanks man, I've scrolled through your arduino code, and it's pretty close to mine (as far as printing to the server). Once I figure out how to convert your file to a text file instead of an exe html, I'll see how you hosted it on the other side. edit: I managed to open your js file, but it didn't have any whitespaces and was too crazy to decipher, sorry smiley-sad.

Thanks so much for your help guys!
Hope you're enjoying your almost summer (if you're a northern hemisphereian!)
-Kiobod

EDIT:
@ Federico - I've noticed there isn't any documentation of Yunclient.println - what's the difference between .print and .write?
« Last Edit: June 16, 2014, 06:18:11 pm by kiobod » Logged

Pages: [1] 2   Go Up
Jump to: