Tutorial: Spark Variable and Function on One Web Page

and it working
:smile:

Thank you Moors7 :smiley:

2 Likes

I’ve read through the whole article, and i kind of understand how it works (and it does work when i test it), except that i have no clue how to do this properly to two different servos.

Could someone give me a headsup about how to start with it, or is it just copy pasting the whole thing with different variables?

Thanks in advance!

Two different devices:
Depending on what exactly you want to do, you could add a DeviceID parameter to the sparkSetPos function. When using the controls, you could pass the relevant ID over, which it would then use to reach the respective device. Using radio buttons to select a device might be easiest then.

One device, two servos:
The easiest would indeed be to use new functions and variables. There are enough available to for two sets. If you wanted to get fancy, you’d pass an extra argument to the function, targeting a specific servo, but that’d mean you’d have to parse the arguments, which may or may not add complexity.

1 Like

Thanks a lot for this post. I’m a software dev completely new to hardware and would like to power my photon AND servo using a battery.

I have a standard size full-rotation servo. Here’s the exact servo I have: https://www.sparkfun.com/products/9347

I’d like to be able to power both the servo and photon using a battery. I’m considering using Sparkfun’s power shield (https://www.sparkfun.com/products/13626) but can’t figure out which battery would fit my needs.

Does anyone have any insight into the type of battery I should use?

Thanks!

First of all, excellent tutorial @bko, I am extremely new to particle and cloud variables and functions. I’ve spent many hours looking this over and it has helped me to understand how to send variable data to a private webpage. However, on my first project I want to send data from the private webpage to my photon to update a variable that is used in the loop function. I have tried adapting the post method you used to activate your function for updating my variable but I haven’t had any luck. I’ve been at it for several hours but I would appreciate any guidance you could provide. I have stripped down my code to just this portion so it would be easier. Here is the code:

SYSTEM_THREAD(ENABLED);
int offsetTime;
int offsetTimeAdj;

void setup() {
  Serial.begin(9600);
  delay(100);
  waitUntil(Particle.connected);
  Particle.variable("poffsetTime", offsetTime);
  Particle.variable("poffsetTmAd", &offsetTimeAdj, INT);
  offsetTime =15;
}

void loop() {
 
  offsetTime = offsetTimeAdj;
  delay(2000);
}

Here is the webpage code:

 <!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 onload="start()">
<h3>Current Open/Close Offset Time: <span id="offset"></h3><br>
<h3>Enter New Offset Time <input type="number" id="offset1" min="5" max="30" maxlength="2" value= "20" size="3"></h3><br>
<button id="pageupdate" onclick="start()">Update Page</button>

<script type="text/javascript">
function start() {
document.getElementById("offset").innerHTML = "Waiting for data...";
var deviceID = "My Device ID";
var accessToken = "My Access Token";
var offsetTm = "poffsetTime";
var offAdj= "poffsetTmAd";

var requestURL1 = "https://api.particle.io/v1/devices/" +deviceID + "/" + offAdj + "/";
var newValue = document.getElementById('offset1').value;
$.post( requestURL1, { params: newValue, access_token: accessToken});

requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/" + offsetTm + "/?access_token=" + accessToken;
$.getJSON(requestURL, function(json) {
document.getElementById("offset").innerHTML = json.result;
                 });
    }
</script>
</body>
</html>

The get portion is just a repeat of the one in the tutorial just substituting in my variables. It works fine. If I change the photon code so there is a specific integer value assigned to it, the webpage displays that value. When I run the code as currently written it shows a value of 0.

Again, this is my first attempt ever using HTML, javascript, or particle cloud variables. Any help would be appreciated.

If you want to update a variable on the device side, you need to register a Particle.function() (or Particle.subscribe()) as target for your POST request (or event in case of Particle.subscribe()).

Your code does only register Particle.variable() and they can only be requested (read but never set remotely) via GET.

1 Like

Thank you @ScruffR, that would explain why no matter how I changed the syntax, it wouldn’t work.

The demo up at the top of this thread declares a function and variable for set’ing and get’ing values. The variable part you have down, but the function can set the variable value easily, you just have to write a small function on your device and declare it. Since Particle functions always take a String as input, if you have a numeric variable, you will need to convert but that’s easy too.

3 Likes

Hi I was trying to make user type the device id and access token instead of directly typing in the code. So I put all the functions in a big function called start() and call it on a button click. This results in errors saying all the nested function are not declared. I know it’s not good practice to create nested functions but i dont know what else I can do to achieve.

Showing your new code would help, along with the actual error messages :wink:

2 Likes

e.g. not nesting them but making them global?

But sure, showing what you have would help too :wink:

1 Like
    <P>Access Token:<input type="password" size="40" name="accessToken" id="accText" >
    <br><br>
    <p>Device ID:<input type="text" size="40" name="deviceID" id="dvText">
    <br><br>
    <button id="connectbutton" onclick="start()">Connect</button>
     <div class="slider-wrapper">
      <input type="range" name="degBox" id="degBoxId" min="500" max="8000" step="1" value="4000" list="myData" onchange="setValue(this)">
    </div>
    <!-- slider datalist here -->
    <button id="minusbutton" onclick="fineAdjust(-50)">&lArr; -50</button>
    <button id="plusbutton"  onclick="fineAdjust(+50)">+50 &rArr;</button>
    
    <script type="text/javascript">
	    function start(objButton) {
	        document.getElementById("connectbutton").innerHTML = "Running";
	        var accessToken = document.getElementById('accText').value;
	        var deviceID = document.getElementById('dvText').value;
                var setFunc = "setT";
                var getFunc = "getT";
                 //the rest is bko's original functions for the servo. 
           }
    </script>

“Uncaught ReferenceError: fineAdjust is not defined at HTMLButtonElement.onclick” this is the error message. All the nested functions have the same error if i want to click on the plus/minus button or the slider.

Hi @poolnoodle

In the original demo, there are a couple of ways to move the servo--the slider for big moves which calls setValue on the Javascript side, plus the two fine adjust buttons (see above code) which call fineAdjust with a plus-or-minus 50 argument to move the servo in smaller steps. You seem to have deleted or changed the scope of the fineAdjust Javascript.

Thanks for the reply. and yes I did change the scope because I adjusted this code to use the website to control the delay() in photon, since the units are in millisecond i make the numbers bigger. It does work perfectly fine on the delay function.

Hi @poolnoodle

So the error you are getting is that the fineAdjust Javascript function cannot be seen from the HTML side. You need to put this function in global scope.

1 Like

Sorry I am very new to html and javascript. I did try to move these functions in the global scope. But since reading the user input of device id and stuff are still in the start(), all the functions outside of start() that requires a device id or accesstoken are showing errors of cannot connect to api. They probably can’t access the device id and access token value inside the start().

I also tried to create a separate function to get the user input and return as an array but somehow I can’t access to the values either:(

You will have to use these two lines in any function that needs the deviceID and access token to read it from the HTML side.

1 Like

Omgg it worked!!! Thank you so so much

1 Like

It will be amazing to see an update version of this, since the photos doens’t show anymore.

Me too very much appreciate if anyone can update this.