Send a value to a variable from a webpage [SOLVED]

Good Morning,

I’m trying to build my own irrigation system. I have a RTC module to take the time and this in my loop.

if(hours >= startH && minutes >= startM) {
  //start irrigation
}
if(hours >= endH && minutes >= endM){
  //stop irrigation
}

This works fine if I set the value of “startH”, “startM” and “endH”, “endM”.
But what could I do if I’d like to set these values from a webpage (or an App)??
In other words, I’d like to have a variable (int startH = 0) that I can change from a web page.

I start from the example “blink a led over internet” and I made a Spark.function but in this example I can just send command “on” or “off”. I need to change at least 4 values in 4 different variables.

Could you help me out here?
Thanks!

1 Like

Totally doable. You know the Particle devices have an in-built RTC, so you don’t really need an external one? They also sync time over the internet, so it’s up-to-date.

Considering the “blink an LED over the internet” example; You use an HTML request to sens a function with a parameter. In this case, the parameter is “on” or “off”. There’s really no reason why you shouldn’t be able to change that to whatever you desire.
In the function, the argument you passed is known as “command” (since that’s what you’ve called it).

int ledToggle(String command) {
   //the variable "command" is the argument you passed
}

Using that, you should be able to assign the argument to a variable you need, after parsing it accordingly.

I’m going to assume you need the minimum of 4 values for startH/endH and startM/stopM? If you were to pass that argument as epoch time, you could parse it on the device. Then you’d only need two functions for the start and stop time. If it’s always a fixed time it needs to run, you could set a fixed stop time: stopTime = startTime + 20 minutes.

Enough said, time for you to try some things. What is the code you’ve come up with so far, if any?
Try creating some code with 4 functions, in which you set your variables by passing it the above-mentioned arguments, after parsing them accordingly.
While testing, I suggest you make use of Serial.print() to print the various things over a serial monitor, so you can see what’s going on. If you want to call functions with arguments easily, you can use the Particle Dev, or perhaps this webpage I made.
I’d recommend starting off easy: 1 function, and just print the argument over serial. Then gradually move up: parse the argument. Then assign it to your variable. Meanwhile, keep printing everything you’re doing so you can keep track.

Once you’ve got the code on the device working properly, you can start with the webapp, which shouldn’t be too complicated :smile:

Let us know if you require further assistance/help.

Thanks Moors7!
First of all it’s great for me to know about the internal RTC. I just tried the Time.hour function and it works perfectly, and I can print out the time on my lcd yet.
Now I’m beginning the coding work about what you suggested me.
I think that probably I’ll ask you something else before I’ll reach my goal :wink:

Thanks again, really.

1 Like

Hi Moors7,

after the yesterday evening troubles (with the cloud), today I worked a lot on my code and thanks to your suggestions I made a great step forward.
Now I compiled a rough code for photon but I’m stuck with HTML code!
I picked up the html of the example (the one with the radio buttons) but I wasn’t able to fit it for my purposes…
I’m more or less here:

 <body>
  <center>
  <br>
  <form action="https://api.particle.io/v1/devices/0000000/functionName1?access_token=00000000" method="POST">
    Start Hour
    <input name="startOra" type="text" size="2" maxlength="2">
    <input type="submit" value="Set">
    <br>
   </form>
  <form action="https://api.particle.io/v1/devices/0000000/functionName2?access_token=0000000000" method="POST">
    Start Minute
    <input name="startMin" type="text" size="2" maxlength="2">
    <input type="submit" value="Set">
  </form>
  </center>
  </body>

in “functionName1” and “functionName2” - in the photon code - I put the “command” list.
If I send values via Particle Dev or your page (great!) it works perfectly but I’d like to build up a simple web page to send all the four values (start hour - start minute && end hour - end minute) at the same time.

So, the problem is that I’d like to send all the parameters in a single “submit” but with the code above it’s impossible.

Could you suggest a better way? Thanks in advance!

Great to hear you’ve been able to make improvement, glad I could help.
Have you given the epoch time a try yet? That might make it easier to combine the hour and minute times.
Regardless, if you want to send the values in one command you’re going to have to parse them on the device. You can use a delimiter to make it easier to differentiate between the separate values. Something like “startH~startM~stopH~stopM”, you could parse them using the tildes.

As far as the HTML is concerned, I’d ditch the forms, and go with JavaScript. It doesn’t require you to reload the page, and provides more flexibility. You could code up your own Ajax requests, or use the particleJS library (check the docs on that on), which I’d recommend. I’ve got an example for calling functions with a button here: http://jordymoors.nl/particle/demos/function_button.html
For a function call with a text input box, you can check the page I’d already linked to. Check the source to see how it works.
Give it a shot, and let me know if that works for you, or if require further help.

1 Like

Hi again Moors7!
Thanks for your kind reply. I followed your link but the browser did non find the page :frowning:
I’m looking at particleJS right now. When you have time, can you check your link? I’m curious about that example :smile:
Thank you!

1 Like

Sorry, had to type the link out of my head, because I couldn’t connect to my server for some reason. I fixed the typo :smile:

However, I think you’ll find this more interesting:
HTML:

<html>
  <head>
      <title>Spark function buttons Example</title>
  </head>

  <body>
    
    <input type="text" class="form-control" placeholder="Start Hour?" id="startHour">
    <input type="text" class="form-control" placeholder="Start Minute?" id="startMinute">
    <input type="text" class="form-control" placeholder="Stop Hour?" id="stopHour">
    <input type="text" class="form-control" placeholder="Stop Minute?" id="stopMinute">
    
    <br>
    
    <button type="button" onclick="sendValues()">Send values</button>
    <!--
    <button type="button" onclick="functionCall('functionName', 'functionArgument')">function 1</button>
    <button type="button" onclick="functionCall('functionName', 'functionArgument')">function 2</button>
    <button type="button" onclick="functionCall('functionName', 'functionArgument')">function 3</button>
    <button type="button" onclick="functionCall('functionName', 'functionArgument')">function 4</button>
    -->
    
    
    <script src="http://cdn.jsdelivr.net/sparkjs/1.0.0/spark.min.js"></script>
    <script>
      //you can use your accesstoken, or your email/passsword to log in. Uncomment accordingly below.

      var accessToken = "accesstoken_here";
      var deviceID = "deviceID_here";
      
      var startHour;
      var startMinute;
      var stopHour;
      var stopMinute;
      
      var combinedTime;
      
      //console.log(startHour + startMinute + stopHour + stopMinute);
      
      function sendValues(){
        startHour = document.getElementById('startHour');
        startMinute = document.getElementById('startMinute');
        stopHour = document.getElementById('stopHour');
        stopMinute = document.getElementById('stopMinute');
        
        combinedTime = startHour.value + '~' + startMinute.value + '~' + stopHour.value + '~' + stopMinute.value;
        console.log(combinedTime);
        
        functionCall('parse', combinedTime);
        
        startHour.value = '';
        startMinute.value = '';
        stopHour.value = '';
        stopMinute.value = '';
      }
      
      
      spark.on('login', function(response) {           
        console.log(response);        
      });

      // callback to be executed by each core
      var callback = function(err, data) {
        if (err) {
          console.log('An error occurred while getting device attrs:', err);
        } else {
          console.log('Device attr retrieved successfully:', data);
        }
      };
      
      function functionCall(functionName, functionArgument){
        // The function needs to be defined  in the firmware uploaded to the
        // the Spark core and registered to the Spark cloud, same thing we do
        // with variables. You pass along the name of the function and the params.
        spark.callFunction(deviceID, functionName, functionArgument, callback);  
      }
      
      // Uncomment a line below depending on your preferred log-in method.   
      //spark.login({ username: 'email@example.com', password: 'password' });  
      spark.login({ accessToken: accessToken });
      
    </script>
  </body>
</html>

Device code:

int startHour = 0;
int startMinute = 0;
int stopHour = 0;
int stopMinute = 0;

void setup() {
    Serial.begin(9600);
    Particle.function("parse",parse);
}

void loop() {

}

int parse(String command){
    char charBuf[20];
    command.toCharArray(charBuf, 20);
    
    //Begin black magic supplied by @mdma at:
    // https://community.spark.io/t/gpio-control-via-gui/6310/7
    const int value_count = 8;  // the maximum number of values
    int values[value_count];    // store the values here
    
    char string[20];
    strcpy(string, charBuf);  // the string to split
    int idx = 0;
    for (char* pt=strtok(string, "~"); pt && idx<value_count; pt=strtok(NULL, "~")) {
       values[idx++] = atoi(pt);
    }
    //End black magic.
    
    startHour = values[0];
    startMinute = values[1];
    stopHour = values[2];
    stopMinute = values[3];

    Serial.println(startHour);
    Serial.println(startMinute);
    Serial.println(stopHour);
    Serial.println(stopMinute);
    
    return 0;
}

Give it a try, and let me know if that works for you :smile:

4 Likes

Thanks again!
I’ll tell you soon!

IT WORKS!
Thank you Moors7! Now I can go on with my irrigation project!!
The code works perfectly and I already put it inside my sketch.
I’ll give you update :smile:

2 Likes

I have tried to copy the HTML and the device code as is and filled in the login information but I can’t get it to work, the parse function does not get executed. Any idea what could be wrong?

How do you know it’s not working, if you can’t see the console?
What browser are you using?
If you connect your device via USB to your computer and open a serial terminal, you might see the Serial.print() output.

You could also add pinMode(D7, OUTPUT); to your setup() and digitalWrite(D7, !digitalRead(D7)); to your int parse(String command) to see the LED toggle.

If it doesn’t work, double check your access token and device ID in your HTML file (the double quotes need to be there too).

Yes, I have the serial terminal running and this is how I see that the parse function is not being executed.

I found the javascript console in Chrome but I don’t see any output there.

I have copy-pasted the code as is from @Moors7’s post added my own access token and device ID and it just worked.
So I guess it’s most likely your Access Token or DevID.

You could also try this page to test if your device actually is running the correct code
http://suda.github.io/particle-web-interface/

1 Like

I have double quotes around my DevID and access token.

When I call the parse function from the page you mentioned with the argument 1~2 I get:
1
2
so that looks fine.

I will double check the DevID and access token once again.

Now it works, it was the single quotes around the access token in the sparl.login that was missing.

Thanks!

Still nothing in the JS console though.

1 Like

I only got German Chrome, so I have to guess the English original, but I can see the output via

 - hamburger menu
   - additional/extra tools
     - dev tools (Ctrl+Shift+I)
      - console (in the tabs bar of the newly opened pane)

Ctrl+Shift+I and Esc should be the easiest :wink:

1 Like

Right clicking the page and selecting “inspect element” should allow you to pick “console” as well. That said, I just copied my own example, pasted in the credentials/deviceID between the double quotes, and it worked…


You might want to double check things, or give it a fresh try, because the code seems to be working…

2 Likes

Thanks for this template to work from! I’ve used a photon for a while now, but am totally new to sending information to it from a webpage.

I’ve used the code in this discussion, can get my photon to respond with the test page ScruffR posted above, but can’t get it to work from my webpage. I have a website that runs wordpress, and just created a new private page where I posted in the html code from above. The page exists, the input boxes and button appear, but when I click the button to post and have the chrome console open, it says: “Uncaught ReferenceError: sendValues is not defined” The error occurs the first time sendValues is mentioned.

Is this not possible from a wordpress page? Any idea what I’m doing wrong?

Are you also including the Javascript part? I’m not exactly sure where in Wordpress you pasted it, but the editor could be filtering the javascript out.

I created a new page in Wordpress and put your code into the main text box editor.

The javascript is the all of the code you wrote above including var, function, spark.login, etc., right? Sorry, I really only know how to write code for arduino/particle right now! :grimacing: