Tutorial: Spark Variable and Function on One Web Page

Hi @Dup

Sorry I was away for a while.

How fast are you running the update on the web side? The second argument to window.setInterval which is 1000 in the example above is the time in milliseconds between calls to the function to updated the web page side of the variables. It is possible to do this too quickly and overload the Spark cloud host, so 1 sec (1000 ms) is a good minimum.

Which browser are you using? I like Chrome–it seems to run well for me both on PC and Mac.

1 Like

Hi bko,
thanks!

Chrome works best!

Also, I have many buttons (function + variable) which may be causing problems. I will try to clean things up and see if it helps. Currently, the time is set at 1000ms but I will try to increase slightly and test.
I will have a look later this week as we are on vacation and I will let you know how I make out!

Dup!
Thanks!

1 Like

Thank you so much for this tutorial! I am having some trouble and hope you can help:

I am using chrome on a mac. It’s a basic tutorial and you’ve done a great job explaining so I’m sure it’s something silly :wink: I have copied the code from my SC and webpage editor directly.

So, I first wired up everything according to your picture. To test my configuration I first ran the test code from here: http://community.spark.io/t/servo-h-library-included-with-arduino-solved/1209/12

It worked fine. Here is the test code copied directly from my Spark Build page (I changed the pin to A0 so I didn’t have to move any wires):

Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 

int pos = 0;    // variable to store the servo position 

void setup() 
{ 
  myservo.attach(A0);  // attaches the servo on pin A0 to the servo object 
} 


void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
}

Like I said that code works fine and the servo moves like it should.

So then I flashed the SC with the actual tutorial code:

Servo myservo;  // create servo object to control a servo
    
int pos = 0;    // variable to store the servo position

void setup()
{
  myservo.attach(A0);  // attaches the servo on the A0 pin to the servo object
  Spark.function("setpos", setPosition);
  Spark.variable("getpos", &pos, INT);
}

void loop()
{
}

int setPosition(String posValue) {
    pos = posValue.toInt();
    myservo.write(pos);
    return 0;
}

And then created a webpage with my token and device name filled in (not on here, of course- I put in fake ones):

<!DOCTYPE HTML>
<html>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<body>
    <P>Set Servo Position:<br><br>
    <input type="range" name="degBox" id="degBoxId" min="0" max="180" step="1" value="90" list="myData" onchange="setValue(this)">
    <!-- This adds the tick marks to the range but does not in Safari -->
    <datalist id="myData">
       <option value="0">
       <option value="30">
       <option value="60">
       <option value="90">
       <option value="120">
       <option value="150">
       <option value="180">
    </datalist>
    <br><br>
    <button id="minusbutton" onclick="fineAdjust(-5)">&lArr; -5 &deg;</button>
    <button id="plusbutton"  onclick="fineAdjust(+5)">+5 &deg; &rArr;</button>
    <br><br>
    <P>Current Position: <span id="curPos"></span><br>

    <script type="text/javascript">
      var deviceID    = "HARRY_POTTER";
      var accessToken = "hg45ghg45hg5hg45hg45hg45hg54hg5hg";
      var setFunc = "setpos";
      var getFunc = "getpos";

      window.setInterval(function() {
        requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/" + getFunc + "/?access_token=" + accessToken;
        $.getJSON(requestURL, function(json) {
                 document.getElementById("curPos").innerHTML = json.result + "&deg;";
                 document.getElementById("curPos").style.fontSize = "28px";
                 document.getElementById("degBoxId").value = parseInt(json.result);
                 });
      }, 1000);

      function setValue(obj) {
        var newValue = document.getElementById('degBoxId').value;
        sparkSetPos(newValue);
      }

      function fineAdjust(value) {
        var currentValue = parseInt(document.getElementById('curPos').innerHTML);
        var setValue = value + currentValue;
        sparkSetPos(setValue);
        document.getElementById("degBoxId").value = setValue;
      }

      function sparkSetPos(newValue) {
	var requestURL = "https://api.spark.io/v1/devices/" +deviceID + "/" + setFunc + "/";
        $.post( requestURL, { params: newValue, access_token: accessToken });
      }

    </script>
</body>
</html>

And I refreshed and re-flashed and saved several times and no luck. Any ideas at all? I also noticed on the webpage that the “Current Position” isin’t showing- not sure if that helps or not? Here is a screenshot of the webpage:

Thanks again for the tut and any suggestions appreciated :slight_smile:

OK I just realized the name of the device is not what I should be putting in there- I should have clicked on the device name to get the actual device ID…DUH!! OH well it works fine now, sorry for the trouble :slight_smile:

2 Likes

Hi!
I seem to be having difficulty with Spark.variables. Sometimes I get it and most of the time not {
“error”: “Timed out.”}. I am using the example above. My code stays up because Spark.publish continues to work. I wonder if it is similar to the 9 char String issue?

any ideas will help!
Dup!

window.setInterval(function() {
        requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/" + getFunc + "/?access_token=" + accessToken;
        $.getJSON(requestURL, function(json) {
                 document.getElementById("curPos").innerHTML = json.result + "&deg;";
                 document.getElementById("curPos").style.fontSize = "28px";
                 document.getElementById("degBoxId").value = parseInt(json.result);
                 });
      }, 1000);

The 1000 above is 1000ms or 1 second–that may be too fast if you have slow link or are far away from the Spark Cloud server.

What happens if you change 1000 to 2000?

Hi bko!
Same thing. I tried up to 10000ms.
There is something in my code that must be hanging things up! My core is always connected and continues to publish. How often does the variable get pulled onto the cloud?

Perhaps a workaround is to use a function then publish the result?

A function that triggers a publish will work great, but I am not having the same problems you are with variables so it is probably worth figuring it out.

yes, thanks
something else that may be related is that I cannot flash a second time OTA without a factory reset. I will keep investigating

There is another thread and github issue where publishing too quickly causes the OTA flash to fail. Are you publishing events at 1 per second or similar speed?

every 5 second at the moment, I will try 10 s to see the effect. I also noticed that the cyan will flash rapidly every 60 seconds give or take. I am wondering if it is my code having too many unsigned long LastUpTime1, LastUpTime2, 3, etc… ?
thanks!

bko,
It works! By separating when each publish is performed by 2s, it allows the variables and the OTA to work :smile:

Now that my functions work as well, how would I make something turn “on” referenced to time of day? Outdoor lights ON between 7 to 11 pm?

You should check out this post where I wrote some code for a pump controller with a web page interface:

Thank you for this post! Helped me out a lot :slight_smile:

1 Like

@bko Great tutorial. Thank you.

3 Likes

Hi, how can I acces it from my phone?

Hi @KarinaMendez

What I do is put the HTML file on a service like Dropbox where I can access it from my phone.

There are lots of other more professional options such as the Particle iOS and Android SDKs–this is just meant to show you how it works and provide the basic functionality.

1 Like

If you’re not that into native apps, there’s also the ParticleJS library which allows you to interact with the API more easily, over the web.

2 Likes

I’ve been trying to open it in my phone and it does but doesn’t send the data to the core, and the problem I have is that I added the function that recieves the data to my code, but my code has a lot going on in the loop() and the web app never gets to the function, can you help me with this?

Hi @KarinaMendez

A bunch of folks here can help you if you post your code.

If you added a new Particle function to your firmware code, you also have to change the HTML/Javascript side to match.