User Tools

Site Tools


oak:tutorials:particle-function

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
oak:tutorials:particle-function [2016/03/23 23:19]
jwhendy [Components used] updated
oak:tutorials:particle-function [2016/05/27 01:30] (current)
pfeerick edited to hopefully reduce confusion on how Particle.function is used in code
Line 1: Line 1:
-**In progress!**+===== Oak: using Particle.function() =====
  
-This is currently a copy of particle-variable to use as a template.+This tutorial ​is very similar to the one on [[http://​digistump.com/​wiki/​oak/​tutorials/​particle-variable|Particle.variable()]]. This time, however we will be doing the reverse: //sending// data to the Oak. To accomplish this, we use ''​Particle.function()''​. As an example, we will send ''​POST''​ commands using ''​curl''​ to the Particle API which will control the color of an RGB led connected to the Oak.
  
------+In addition to this tutorial, please do take a look at the [[https://​docs.particle.io/​reference/​firmware/​core/#​particle-function-|official documentation]].
  
-===== Oak: using Particle.variable() ===== 
  
-So, you've got an Oak all set up and ready to go. Now it's time to put its wireless 
-abilities to work!  This lesson will introduce ''​Particle.variable()''​ a method provided by [[https://​www.particle.io/​|particle.io]] for reading data from the Oak. The basic idea is pretty simple, and we'll start with a simple push button. Review the [[oak:​tutorials:​button|tutorial on buttons]] for a refresher if you'd like. In addition, please do take a look at the [[https://​docs.particle.io/​reference/​firmware/​core/#​particle-variable-|official documentation]]. 
- 
-===== Components used ===== 
  
 ===== Components used ===== ===== Components used =====
Line 21: Line 16:
 |Resistor, 220 ohm| 3 | Red-Red-Brown| |Resistor, 220 ohm| 3 | Red-Red-Brown|
  
-These are the same components used with the [[http://​digistump.com/​wiki/​oak/​tutorials/​rgb-led#​components_used|advanced ​LED tutorial]].+These are the same components used with the [[http://​digistump.com/​wiki/​oak/​tutorials/​rgb-led#​components_used|RGB LED tutorial]]. Feel free to substitute any resistor value between 100-1k ohms.
  
 **Note:** You need to install [[https://​curl.haxx.se/​download.html|curl]] to push data to the Particle API. **Note:** You need to install [[https://​curl.haxx.se/​download.html|curl]] to push data to the Particle API.
Line 27: Line 22:
 ===== Concepts ===== ===== Concepts =====
  
-=== Particle.variable() ===+=== Particle.function() ===
  
-This function creates an interface between ​a variable on your Oak and particle.io. ​Each time the variable changes, the Oak will update the value stored in the Particle cloud, which you can then access ​with a call to a website (produced by visiting the page in the browseror issuing a command using ''​curl''​).+This function creates an interface between your Oak and particle.io. ​We create a function ​with a given nameand then access that named function via ''​curl'' ​commands, passing along a value with it. On the Oak side, it finds the function with that name, and then runs it with the value that was passed.
  
-The ''​Particle.variable()''​ function ​takes two parameters: ​the name of the variable in the Particle cloudand the name of the local variable stored on the Oak. For example ​''​Particle.variable("​particle_name",​ oak_name)''​. The value on the Oak would be stored ​in the variable ''​oak_var''​When accessing this variable via the Particle API, you would use the following:+The syntax looks like ''​Particle.function("​name",​ function_name)''​, and you then have a function ​that look like the below examplewhich is run when the function is triggered. You would normally place the ''​Particle.function'' ​command ​in the setup() portion of your codeHave a look at the example sketch at the bottom of the page to better understand how function is used.
  
-<​code>​curl https://​api.particle.io/​v1/​devices/​id_here/​particle_name?​access_token=token_here</​code>​+<​code>​ 
 +int function_name(String arg) 
 +{
  
-===== Circuit =====+  // code goes here 
 +  Serial.print(arg);​
  
 +}
 +</​code>​
  
-=== Button === +We would access this function like this:
-This is the circuit we will begin with, which is explained in the [[http://​digistump.com/​wiki/​oak/​tutorials/​button|tutorial on buttons]].+
  
-[[http://digistump.com/wiki/_media/oak/tutorials/button-pullup.png|{{http:​//​digistump.com/​wiki/​_media/​oak/​tutorials/​button-pullup.png?​400}}]]+<​code>​ 
 +curl https://api.particle.io/v1/devices/id_goes_here/name
 +  ​-d access_token=token_goes_here 
 +  -d "​args=hello"​ 
 +</code>
  
 +The Oak would print "​hello"​ when this ''​curl''​ command is sent (which puts ''​name''​ from above in the URL, //not// function_name). When the Oak receives the call to ''​name'',​ it runs the associated function (''​function_name''​),​ and passes along a ''​String''​ (and only a ''​String''​) which we called ''​arg''​.
  
-=== Photocell ===+This might seem complicated,​ but it's fairly straightforward. Let's connect a circuit and test it out!
  
-Additionally,​ we will recreate the circuit from the [[http://​digistump.com/​wiki/​oak/​tutorials/​photocell|tutorial on photocells]] to read an analog sensor value.+=== indexOf() ===
  
-[[http://​digistump.com/wiki/_media/oak/tutorials/​photocell.png|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell.png?​400}}]]+In the second code example, we will use the Arduino function ''​indexOf()''​ to parse multiple values sent to particle.io in one StringThe function works on the ''​String'' ​//class//, so you append it to the name of the ''​String''​ variableLet's say we have a variable called ''​theString''​ and it contains "​a,​b,​c"​. You could find the location of "​b"​ with:
  
-[[http://​digistump.com/wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg|{{http://​digistump.com/​wiki/​_media/​oak/​tutorials/​photocell-wiring.jpg?​400}}]]+<​code>​ 
 +theString.indexOf("​b"​);​ 
 +</code>
  
 +You can also tell the function not to start looking until a certain location. Remember that the first character in the string is 0. This handy if you have multiple repeating characters. In that case, the function is ''​theString.indexOf("​thing_to_find",​ position_to_start_looking).''​
  
-===== Code =====+=== substring() ​===
  
-=== Reading ​button === +Using ''​substring()''​ in combination with ''​indexOf()''​ will let us send one long ''​String''​ with values separated by commas (or some other character) and extract them one at time. Below, ​we will use this strategy to send the RGB values in one shot instead of using ''​Particle.function()''​ three separate times.
- +
-Here is the code we will start with:+
  
 +It works like this:
 <​code>​ <​code>​
-// variable to store the push button digitalRead() value +String theString = "​a,​b,​c"​;
-int button;+
  
-void setup() +// variables to hold each thing we want to extract 
-{                ​+String char1, char2;
  
-  ​// use the on-board LED to illuminate when the button is pressed +// the positions of each thing 
-  pinMode(1, OUTPUT); +int loc1loc2;
-   +
-  // initialize the digital pin as an input +
-  ​pinMode(10INPUT);+
  
-  ​// Particle.variable() takes two options: +// find first comma, then take the string from the start to the comma'​s location 
-  // 1) the name of the variable ​to access in the GET request +loc1 = theString.indexOf(","​); 
-  // 2the name of the local variable that holds the value to report +char1 = theString.substring(0loc1);
-  ​Particle.variable("​button"​button);+
  
-}+// now we start at one character *past* the first comma and look again 
 +// we extract the characters between the last comma we found and the next one we find 
 +loc2 = theString.indexOf(",",​ loc1 + 1); 
 +char2 = theString.substring(loc1 + 1, loc2); 
 +</​code>​
  
 +We could continue in this pattern for as many commas as we know are present. When we use ''​substring(start,​ stop)'',​ it just pulls out the characters from that range of positions from the larger ''​String''​.
  
-// the loop() routine runs over and over again +===== Circuit =====
-void loop() +
-{+
  
-  button = digitalRead(10);​+Please complete the circuit used in the [[http://​digistump.com/​wiki/​oak/​tutorials/​rgb-led|RGB LED tutorial]].
  
-  ​// for debugging, it's helpful to have a way to know +[[http://digistump.com/wiki/_media/​oak-rgb-led.png|{{http://​digistump.com/​wiki/​_media/​oak-rgb-led.png?​400}}]]
-  ​// that the button is being reported properly+
  
-  if(button ​== HIGH) {digitalWrite(1,​ HIGH); } +===== Code =====
-  if(button ​== LOW) { digitalWrite(1,​ LOW); }+
  
 +=== Code: setting colors ===
 +
 +The following code will create ''​Particle.function()''​s in order to allow setting of each channel of an RGB LED:
 +
 +<​code>​
 +// variables to store the brightness of each color channel of the RGB LED
 +int bright_r = 0;
 +int bright_g = 0;
 +int bright_b = 0;
 +
 +void setup()
 +{                ​
 +
 +  // Particle.function() takes two arguments:
 +  // 1) the name to reference in the URL with curl
 +  // 2) the function name run when the reference name is called\
 +  Particle.function("​r",​ set_r);
 +  Particle.function("​g",​ set_g);
 +  Particle.function("​b",​ set_b);
 +
 +  // initialize each color pin as an output
 +  pinMode(6, OUTPUT);
 +  pinMode(7, OUTPUT);
 +  pinMode(8, OUTPUT);
 +  ​
 } }
-</​code>​ 
  
-Notice that the only additional code other than reading the button is to attach ​"cloud name" to the variable ​so that we can read it from the web. After uploading the code abovepress the button ​to check that the on-board LED illuminates:​+// for each Particle.function() definition above 
 +// we create ​matching function 
 +// it will take the argument passed with curl (always a String ​variable), 
 +// convert ​it to an integerand store it in that color'​s variable 
 +// lastly, it will send that setting ​to that color'​s pin to change ​the color 
 +int set_r(String arg) 
 +
 +  bright_r = arg.toInt();​ 
 +  analogWrite(6,​ bright_r);  
 +}
  
-[[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​button-led-off.jpg|{{oak:​tutorials:​button-led-off.jpg?300 }}]] +int set_g(String arg) 
-[[http://​digistump.com/​wiki/​_media/​oak/​tutorials/​button-led-on.jpg|{{ oak:​tutorials:​button-led-on.jpg?​310 }}]]+{ 
 +  bright_g = arg.toInt(); 
 +  analogWrite(7,​ bright_g); ​ 
 +}
  
-This confirms that the variable ''​button''​ is being read correctlyNextmake sure you have your ''​device_id''​ and ''​access_token''​ as described in the [[oak:​tutorials:​particle-id-token|Particle API wiki entry]]. If you have ''​curl''​ installed, open a command prompt/​terminal,​ and type the command below, replacing ''​id_here''​ and ''​token_here''​ with the appropriate values. Alternatively,​ put the URL below into a browser:+int set_b(String arg) 
 +
 +  bright_b = arg.toInt(); 
 +  analogWrite(8bright_b);  
 +}
  
-<​code>​ +// we don't even need a loop() section! The Oak will 
-$ curl https://api.particle.io/v1/devices/id_here/button?​access_token=token_here+// essentially wait for a call to one of the above functions 
 +// and spring into action when it comes through 
 +void loop() 
 +{  
 +}
 </​code>​ </​code>​
  
-This is the response:+Upload the sketch, and test it out! If all is well, the RGB LED should start out completely off. Try turning on each color, one at a time:
  
 +This will turn on red; we're calling the Particle function named "​r",​ and sending the value 1023.
 <​code>​ <​code>​
-curl https://​api.particle.io/​v1/​devices/​id_here/button?access_token=token_here +                 # function name to call is here ----|          
-+                                                     | 
-  "​cmd":​ "​VarReturn",​ +curl https://​api.particle.io/​v1/​devices/​id_goes_here/r \ 
-  "​name":​ "​button",​ +    -d access_token=token_goes_here 
-  "​result":​ 1, +    ​-d "args=1023
-  "​coreInfo":​ { +               | 
-    "last_app": "",​ +# value sent --|
-    "​last_heard":​ "​2016-03-19T20:​51:​18.623Z",​ +
-    "​connected":​ true, +
-    "​last_handshake_at":​ "2016-03-19T20:​32:​30.268Z",​ +
-    "​deviceID":​ "​12345678",​ +
-    "​product_id":​ 82 +
-  }+
 </​code>​ </​code>​
  
-Neathuh? Keep in mind that we're pulling ​the button up to ''​Vcc'', ​so it's //​non-pressed//​ state reads ''HIGH'', ​or 1. If we press it and re-run ​the curl command/​paste into a browser, we get back the following:+When this URL is sentit triggers ​the Oak to run the ''​set_r'' ​functionwhich converts our ''​String'' ​("​1023"​) to a number, and sets the red channel of the LED to that value (full red).
  
 +Now we'll turn on green, which will make the color yellowish.
 <​code>​ <​code>​
-curl https://​api.particle.io/​v1/​devices/​id_here/button?access_token=token_here +                 # function name to call is here ----|          
-+                                                     | 
-  "​cmd":​ "​VarReturn",​ +curl https://​api.particle.io/​v1/​devices/​id_goes_here/g \ 
-  "​name":​ "​button",​ +    -d access_token=token_goes_here 
-  "​result":​ 0, +    ​-d "args=1023
-  "​coreInfo":​ { +               | 
-    "last_app": "",​ +# value sent --|
-    "​last_heard":​ "​2016-03-19T20:​51:​30.817Z",​ +
-    "​connected":​ true, +
-    "​last_handshake_at":​ "2016-03-19T20:​32:​30.268Z",​ +
-    "​deviceID":​ "​12345678",​ +
-    "​product_id":​ 82 +
-  }+
 </​code>​ </​code>​
  
-Note that the contents in ''​result''​ changedSince the data is sent in ''​json'' ​format, you can use any number of methods ​to query the above URLextract ​the contents of ''​result'',​ and do something based on that value.+Keep playing around with different function names and brightness valuesWhat happens if you try to send nonsense like the letter ​''​a''​? Set a color to 0send a letter, and observe ​the result. Repeat after setting to to 1023. Why does that happen ([[https://​www.arduino.cc/​en/​Reference/​StringToInt|hint!]]?​
  
-=== Code: reading a photoresistor ​===+=== Code: sending multiple values ​===
  
-The only difference in the next example is that instead of a button, we will be reading the analog signal from a photoresistor,​ just as described in [[http://digistump.com/wiki/oak/tutorials/photocell|this tutorial]].+What if you wanted direct access to all three key variables without having to call separate functions? ​The ''​Particle.function()'' ​[[https://docs.particle.io/reference/firmware/core/#​particle-function-|documentation]] states that only //one// ''​String''​ value may be passed with the call.
  
-Here is the code we will use:+Thankfully there are ways to split apart a ''​String''​ if you know the structure. There are several examples of various ways to pass multiple values to ''​Particle.function()''​ if you [[https://​www.google.com/​webhp?​sourceid=chrome-instant&​ion=1&​espv=2&​ie=UTF-8#​q=pass%20multiple%20parameters%20to%20particle.function|search for them]]. We will use the one described [[https://​community.particle.io/​t/​rest-api-arguments-is-there-a-better-way/​960/​2|here]].
  
 <​code>​ <​code>​
-// variable to store our reading +// each color'​s brightness 
-int light;+int bright_r = 0; 
 +int bright_g = 0; 
 +int bright_b = 0; 
 + 
 +// locations of the commas we'll find below 
 +int loc1 = 0; 
 +int loc2 = 0; 
 +int loc3 = 0;
  
 void setup() void setup()
 {                ​ {                ​
  
-  // use the on-board LED to illuminate when the button is pressed +  // just one function! 
-  pinMode(1, OUTPUT);+  Particle.function("​set",​ set_rgb); 
 +   
 +  // initialize each color pin as an output 
 +  pinMode(6, OUTPUT); 
 +  pinMode(7, OUTPUT); 
 +  pinMode(8, OUTPUT);
   ​   ​
-  // initialize the analog pin as an input 
-  pinMode(A0, INPUT); 
- 
-  // Particle.variable() to access this from the cloud 
-  Particle.variable("​light",​ light); 
- 
 } }
  
- +int set_rgb(String arg)
-// the loop() routine runs over and over again +
-void loop()+
 { {
  
-  // take a reading +  // find the location of the first comma 
-  ​light analogRead(A0);+  ​// extract from 0 to the comma, storing the value 
 +  // as an integer 
 +  loc1 arg.indexOf(","​);​ 
 +  bright_r = arg.substring(0,​ loc1).toInt();
  
-  // if the photocell is covered (dark, resistance is low) +  // find the next comma by searching starting at the last one 
-  // turn the on-board LED light on. Otherwise, turn it off. +  // extract from the last comma to this one 
-  ​if(light < 250) { digitalWrite(1, HIGH); } +  ​// store as an integer in bright_g 
-  ​if(light > 250) { digitalWrite(1, LOW); } +  loc2 = arg.indexOf(",",​loc1+1); 
-  delay(25);+  ​bright_g = arg.substring(loc1+1, loc2).toInt();
  
 +  // repeat, taking the value between the last comma and this one
 +  loc3 = arg.indexOf(",",​loc2+1);​
 +  bright_b = arg.substring(loc2+1,​ loc3).toInt();​
 +
 +  // write all three values to their respective color pins
 +  analogWrite(6,​ bright_r);
 +  analogWrite(7,​ bright_g);
 +  analogWrite(8,​ bright_b);
 +  ​
 +}
 +
 +void loop()
 +
 } }
 </​code>​ </​code>​
  
-Now we can call the URL+With only one function that can extract three values separated by commas, ​we can now pass an ''​r,​g,​b''​ formatted argument and have all three colors changed in one shot:
  
 <​code>​ <​code>​
- +curl https://​api.particle.io/​v1/​devices/​id_goes_here/set \ 
-curl https://​api.particle.io/​v1/​devices/​id_here/light?​access_token=token_here +    -access_token=token_goes_here 
-+    -"args=1023,0,512"
-  "​cmd":​ "​VarReturn",​ +
-  "​name":​ "​light",​ +
-  "​result":​ 785, +
-  "​coreInfo":​ { +
-    ​"​last_app":​ "",​ +
-    "​last_heard":​ "2016-03-20T04:​13:​23.389Z",​ +
-    "​connected":​ true, +
-    "​last_handshake_at":​ "​2016-03-20T04:​13:​15.370Z",​ +
-    "​deviceID":​ "​12345678",​ +
-    "​product_id":​ 82 +
-  } +
- +
-$ curl https://​api.particle.io/​v1/​devices/​id_here/​light?​access_token=token_here +
-+
-  "​cmd":​ "​VarReturn",​ +
-  "​name":​ "​light",​ +
-  "​result":​ 193, +
-  "​coreInfo":​ { +
-    ​"​last_app":​ "",​ +
-    "​last_heard":​ "2016-03-20T04:​13:​27.820Z", +
-    "​connected":​ true, +
-    ​"last_handshake_at":​ "​2016-03-20T04:​13:​15.370Z",​ +
-    "​deviceID":​ "​12345678",​ +
-    "​product_id":​ 82 +
-  } +
-}+
 </​code>​ </​code>​
  
-In addition the on-board LED turns on when the cell is coveredas the analog reading drops below 250.+That will turn on red all the way and blue halfwaycreating a pinkish colorPlay around with other value combinations and set some colors!
  
 ===== Conclusion ===== ===== Conclusion =====
  
-And that's it for the basics of getting ​data via particle.io! It's up to you how you get the data and what you do with it. The sky is the limit. Keep in mind that the lessons above are transferable to //any// sensor. If you can read the data, you can make it available in the cloud for access.+And that's it for the basics of sending ​data with ''​curl'' ​via particle.io! ​We learned how to pass values, as well as to utilize one ''​Particle.function()''​ to set many values by sending them in a known format, combined with ''​indexOf''​ and ''​substring()''​ to separate them from one another.  
 + 
 +It's up to you what you send, and how you have the Oak respond to it. For one idea, check out the tutorial on using ''​python''​ to generate or collect ​data (say, from a local sensor) ​and send it to the Oak. The nice thing with these functions ​is that if you can do something on the Oak, you can make it happen when a command is sent with ''​Particle.function()'';​ it's just a matter of slightly re-arranging your code.
oak/tutorials/particle-function.1458800349.txt.gz · Last modified: 2016/03/23 23:19 by jwhendy