Data Drop with Arduino Yun

This tutorial shows how to upload data directly from an Arduino Yun to Data Drop, using the Arduino Device Driver. To interface with Data Drop, the Arduino Yun needs to be connected to the internet. Note that all of this functionality is only compatible with the Arduino Yun and will not function with the Arduino Uno.

Setting Up the Yun for Internet Connectivity.

The easiest way to set up the Arduino Yun is to connect the Ethernet cable jack to the network. This requires no setup on the Yun and is also the most reliable form of network connection. Note that the Yun has to make outgoing requests to the internet, so your network administrator may need to allow the access through your firewall, if it exists.

To set up the Arduino Yun to use a wireless connection over Wi-Fi, you will need to set it up to connect to your wireless network. The manufacturer provides documentation online on how to do this at this (WebLink[link, https://www.arduino.cc/en/Guide/ArduinoYun#toc14]).

Uploading the Sketch to the Board

Now that the Arduino Yun has been set up to connect to the internet, the next step is to upload the custom Mathematica sketch to the board. This sketch is what enables the Arduino Yun to communicate with Mathematica and also provides Data Drop functionality, in the form of functions that upload values to Data Drop.

First, open a connection to the device with (RefLink[DeviceOpen, paclet:ref/DeviceOpen]), specifying the option "BoardType"->"Yun" to enable Yun support.

DeviceOpen["Arduino",{"/dev/tty.usbmodem1421","BoardType"->"Yun"}]

By default, this will upload to the device the custom Mathematica sketch, as the option "InitialUpload" defaults to (RefLink[True, paclet:ref/True]). This enables the special function (RefLink[DatabinAdd, paclet:ref/DatabinAdd]) on the Arduino.

A prerequisite to uploading to Data Drop is having a (RefLink[Databin, paclet:ref/Databin]) to upload the data to. This can either be a preexisting databin or a new one made with (RefLink[CreateDatabin, paclet:ref/CreateDatabin]).

bin=CreateDatabin[];

Adding Data with DeviceExecute

The (RefLink[DatabinAdd, paclet:ref/DatabinAdd]) function will add the current value of the specified pin to Data Drop in the bin. To upload to the bin, either the "UUID" or the "ShortID" of the bin, or the bin itself is necessary as the value of the option "Databin". Additionally, the pin to read from has to be specified. It can either be specified with the option "Databin" in (RefLink[DeviceExecute, paclet:ref/DeviceExecute]), or it can be configured as a default bin with (RefLink[DeviceConfigure, paclet:ref/DeviceConfigure]).

DeviceExecute["Arduino",DatabinAdd,{"A0","Databin"->bin}]

Using (RefLink[DeviceConfigure, paclet:ref/DeviceConfigure]) to specify a "Databin" requires a re-upload.

DeviceConfigure["Arduino","Upload"->"Databin"->bin];

Now calling the function does not require a "Databin" to be specified.

DeviceExecute["Arduino",DatabinAdd,"A0"]

Scheduling the (RefLink[DatabinAdd, paclet:ref/DatabinAdd]) function works too; this is done asynchronously from the Wolfram Language kernel and will continue if the Wolfram Language session is exited. This is done with the option "Scheduling". Here, every three seconds for a maximum of 10 times, the value of pin 4 will be uploaded to Data Drop.

DeviceExecute["Arduino",DatabinAdd,{4,"Scheduling"->{3,10}}]

When uploading to Data Drop, by default the name of the key uploaded is of the form "DigitalPinX" or "AnalogPinX", depending on what type of pin is read from. This can be changed with the option "Key".

DeviceExecute["Arduino",DatabinAdd,{4,"Key"->"Pin4Value"}]

Automatically Uploading to Data Drop

Data can be automatically added to Data Drop by uploading a "BootFunction" to the Arduino Yun. This "BootFunction" is run immediately as soon as the device turns on. This enables you to deploy to the Arduino Yun a task to upload to Data Drop, then remove the device and deploy it in the field and have the device just start uploading on its own.

This will upload a single value from pin "A5" as soon as the device turns on.

DeviceConfigure["Arduino","Upload"->"BootFunction"-><|"Code"->DatabinAdd,"Pin"->"A5","Databin"->bin|>];

It is also easy to schedule this to run on a specified schedule after turning on with the "Scheduling" option. Here, the automatic upload is scheduled to be run every 60 seconds indefinitely.

DeviceConfigure["Arduino","Upload"->"BootFunction"-><|"Code"->DatabinAdd,"Pin"->"A5","Databin"->bin,"Scheduling"->60|>];

Adding Custom Data Values to Data Drop

It is also possible to upload custom data to Data Drop from within C/C++ code functions uploaded to the Arduino Yun with the "Functions" option to (RefLink[DeviceConfigure, paclet:ref/DeviceConfigure]).

There are three functions prototyped in the sketch that can be used to upload custom values to Data Drop: DatabinIntegerAdd, DatabinRealAdd, and DatabinStringAdd, which all upload val to the (RefLink[Databin, paclet:ref/Databin]) specified by binID, with the (RefLink[Key, paclet:ref/Key]) of keyName. These allow you to code custom functions that upload values other than the pin values to Data Drop.

void DatabinIntegerAdd(char * binID, char * keyName, long val)

DatabinIntegerAdd uploads (RefLink[Integer, paclet:ref/Integer]) numbers to the (RefLink[Databin, paclet:ref/Databin]).

void DatabinRealAdd(char * binID, char * keyName, double val)

DatabinRealAdd uploads (RefLink[Real, paclet:ref/Real]) numbers to the (RefLink[Databin, paclet:ref/Databin]).

void DatabinStringAdd(char * binID, char * keyName, char * val)

DatabinStringAdd uploads (RefLink[String, paclet:ref/String]) numbers to the (RefLink[Databin, paclet:ref/Databin]).

For example, if you want to calculate the average of a pin value and upload the average, a custom function can be written to do this.

DeviceConfigure["Arduino","Upload"->"Functions"-><|"AverageDatabinUpload"-><|"Code"->"
void avgCalc()
{
	int value = 0;
	int iteration;

	//get the values every 0.01 seconds 100 times
	for(iteration = 0; iteration <100; iteration++)
	{
		value += analogRead(A0);
		delay(1);
	}

	//now calculate the average
	float avg = value/100.0;

	//upload to datadrop

	DatabinRealAdd(\""<>bin["ShortID"]<>"\",\"AverageHumidity\",avg);
}"
|>
|>
];

After uploading, this function can be called normally as any custom function would with (RefLink[DeviceExecute, paclet:ref/DeviceExecute]).

DeviceExecute["Arduino","AverageDatabinUpload"]

It can even be scheduled on demand with the "Scheduling" option. Here, this upload will take place 45 seconds in the future after evaluating.

DeviceExecute["Arduino","AverageDatabinUpload","Scheduling"->{45}]

This function can also be easily adapted into a "BootFunction" for automatic running as soon as the device powers up. The "Scheduling" option here configures the function to be run every 30 seconds.

DeviceConfigure["Arduino","Upload"->"BootFunction"-><|"Code"->"
void avgCalc()
{
	int value = 0;
	int iteration;

	//get the values every 0.01 seconds 100 times
	for(iteration = 0; iteration <100; iteration++)
	{
		value += analogRead(A0);
		delay(1);
	}

	//now calculate the average
	float avg = value/100.0;

	//upload to datadrop

	DatabinRealAdd(\""<>bin["ShortID"]<>"\",\"AverageHumidity\",avg);
}",
"Scheduling"->30
|>
];