This tutorial is very similar to the one on 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 official documentation.
Part | Quantity | Identification |
---|---|---|
Oak with soldered headers | 1 | |
Breadboard | 1 | |
Jumper wires | 4 | |
RGB LED | 1 | whitish LED with 4 leads, one longer than the others |
Resistor, 220 ohm | 3 | Red-Red-Brown |
These are the same components used with the RGB LED tutorial. Feel free to substitute any resistor value between 100-1k ohms.
Note: You need to install curl to push data to the Particle API.
This function creates an interface between your Oak and particle.io. We create a function with a given name, and 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 syntax looks like Particle.function(“name”, function_name)
, and you then have a function that look like the below example, which is run when the function is triggered. You would normally place the Particle.function
command in the setup() portion of your code. Have a look at the example sketch at the bottom of the page to better understand how function is used.
int function_name(String arg) { // code goes here Serial.print(arg); }
We would access this function like this:
curl https://api.particle.io/v1/devices/id_goes_here/name/ \ -d access_token=token_goes_here -d "args=hello"
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
.
This might seem complicated, but it's fairly straightforward. Let's connect a circuit and test it out!
In the second code example, we will use the Arduino function indexOf()
to parse multiple values sent to particle.io in one String. The function works on the String
class, so you append it to the name of the String
variable. Let's say we have a variable called theString
and it contains “a,b,c”. You could find the location of “b” with:
theString.indexOf("b");
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).
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 a time. Below, we will use this strategy to send the RGB values in one shot instead of using Particle.function()
three separate times.
It works like this:
String theString = "a,b,c"; // variables to hold each thing we want to extract String char1, char2; // the positions of each thing int loc1, loc2; // find first comma, then take the string from the start to the comma's location loc1 = theString.indexOf(","); char1 = theString.substring(0, loc1); // 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);
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
.
Please complete the circuit used in the RGB LED tutorial.
The following code will create Particle.function()
s in order to allow setting of each channel of an RGB LED:
// 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); } // for each Particle.function() definition above // we create a matching function // it will take the argument passed with curl (always a String variable), // convert it to an integer, and 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); } int set_g(String arg) { bright_g = arg.toInt(); analogWrite(7, bright_g); } int set_b(String arg) { bright_b = arg.toInt(); analogWrite(8, bright_b); } // we don't even need a loop() section! The Oak will // essentially wait for a call to one of the above functions // and spring into action when it comes through void loop() { }
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.
# function name to call is here ----| | curl https://api.particle.io/v1/devices/id_goes_here/r \ -d access_token=token_goes_here -d "args=1023" | # value sent --|
When this URL is sent, it triggers the Oak to run the set_r
function, which 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.
# function name to call is here ----| | curl https://api.particle.io/v1/devices/id_goes_here/g \ -d access_token=token_goes_here -d "args=1023" | # value sent --|
Keep playing around with different function names and brightness values. What happens if you try to send nonsense like the letter a
? Set a color to 0, send a letter, and observe the result. Repeat after setting to to 1023. Why does that happen (hint!?
What if you wanted direct access to all three key variables without having to call separate functions? The Particle.function()
documentation states that only one String
value may be passed with the call.
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 search for them. We will use the one described here.
// each color's brightness 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() { // just one function! Particle.function("set", set_rgb); // initialize each color pin as an output pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); } int set_rgb(String arg) { // find the location of the first comma // extract from 0 to the comma, storing the value // as an integer loc1 = arg.indexOf(","); bright_r = arg.substring(0, loc1).toInt(); // find the next comma by searching starting at the last one // extract from the last comma to this one // store as an integer in bright_g loc2 = arg.indexOf(",",loc1+1); 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() { }
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:
curl https://api.particle.io/v1/devices/id_goes_here/set \ -d access_token=token_goes_here -d "args=1023,0,512"
That will turn on red all the way and blue halfway, creating a pinkish color. Play around with other value combinations and set some colors!
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.