User Tools

Site Tools


oak:tutorials:particle-function

Oak: using Particle.function()

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.

Components used

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.

Concepts

Particle.function()

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!

indexOf()

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).

substring()

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.

Circuit

Please complete the circuit used in the RGB LED tutorial.

Code

Code: setting colors

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!?

Code: sending multiple values

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!

Conclusion

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.txt · Last modified: 2016/05/27 01:30 by pfeerick