Lowest cost way to get two dozen temp readings to the linux side

I'm writing distillery control software. Was going to go PLC route but found the Yun and I think it's the way to go. I've got the openwrt side set up using the following software stack


and it's now serving up dynamically created pages. I'm pretty amazed at what this little thing can do. Primarily what the system does is to look at temps and take an action; I'll spare you the detalis. What I'm looking for is the least expensive way to acquire two dozen temps and get them to the linux side. Although I have no qualms about using the bridgeclient and bridge server, it seems they are a bit heavy. What I have in place now as a kind of POC is the following:

#include <Process.h>

void setup() {

  // Wait...
  while (!SerialUSB);

void loop() {
  // Nope

void tryIt() {
  Process p;

  SerialUSB.print("here goes...");

  // Loop through 18b20s and get their temps
  // (String crafted just to prove concept)

  p.runShellCommandAsynchronously("echo \"t1:8|t2:9|t3:10\">/mnt/sda1/tempData");

  // If success should get nothing, otherwise error from openwrt

  while (p.available() > 0) {
    char c = p.read();

This works absolutely fine. What did not work was if the file didn't exist on the SD card (in this case /tempData)

Question 1: What process runs the script that interprets and executes the shell command? Who is the owner of this process?

I dug through the source and found what I believe is the command:

/bin/ash -C "the shell command"

When I run it from the linux shell it works as expected:

/bin/ash -c "/bin/echo foo>bar"

creates a file called bar having the contents of foo. Another issue on the linux side, I cant set permission to world writeable using either 666 or og+w

Question 2: How do I set world writeable permissions on a file?

and in closing

Question 3: Is using Process the lowest cost method of writing a lengthy string of text?

Partial answer...

I changed the code to:

p.runShellCommandAsynchronously("echo $USER>/mnt/sda1/whoami");

And after running the contents of the file was "root".

Related to #3: Would you find it advantageous to send your temperature values directly to a php script for uploading into the database (presumably?) or is storing them on the SD card a necessary step in your process for other reasons?

And after more trial and error, I determined by escaping the I/O redirection character thusly:

p.runShellCommandAsynchronously("echo xyz\>/mnt/sda1/testCreateAFile3");

The file is created on the fly as expected. Assuming this is a reasonably efficient approach, I can take advantage of the linux shell to do things like:

p.runShellCommandAsynchronously("echo \"`date`|154\"\>\>/mnt/sda1/testCreateAFile3");

Which will append to the file and preface each aquired temp with a date/time stamp:

root@linino:/mnt/sda1# cat testCreateAFile3
Mon Jan 23 19:11:34 UTC 2017|154

Related to #3: Would you find it advantageous to send your temperature values directly to a php script for uploading into the database (presumably?) or is storing them on the SD card a necessary step in your process for other reasons?

Eventually I absolutely will. At this time Im just working on my Arduino / Yun skills. But you're absolutely correct, with moderate additional effort I could have called php-cgi with the -q option (to suppress headers) and write the input directly to SQLite or an external data logging service.

This is fairly representative of what I do if the number of readings is predictable and I want to upload directly to my database:

void dbcpunified() { //inserts readings from stations 1,2,3,4 into the DB
  Process query; //this sends information on stations 1 and 2 to the db
  query.addParameter(String(timestamps[0]));  //insert timestamp for these readings
  query.addParameter(String(readings[0]));  //insert reading from station 1
  query.addParameter(String(readings[1]));  //insert reading from station 2
  query.addParameter(String(readings[2]));  //update reading from station 3
  query.addParameter(String(readings[3]));  //update reading from station 4
  query.addParameter(String(timestamps[offset])); //SQL will update the row matching this timestamp
$var1 = $argv[1];  //timestamp for station 1 and 2
$var2 = $argv[2];  //station 1
$var3 = $argv[3];  //station 2
$var4 = $argv[4];  //adjustmentdial
$var5 = $argv[5];  //station 3
$var6 = $argv[6];  //station 4
$var7 = $argv[7];  //timestamp for station 3 and 4
$var8 = $argv[8];  //statistics time

$DBServer = '10.0.0.xxxxx'; 
$DBUser   = 'yun';
$DBPass   = 'xxxxxxxxxxxxxx';
$DBName   = 'yun';   
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName);
// check connection
if ($conn->connect_error) {
  trigger_error('Database connection failed: '  . $conn->connect_error, E_USER_ERROR);
INSERT INTO assy5cp (timestamp, station1, station2, adjustmentdial) VALUES ($var1,$var2,$var3,$var4);
UPDATE assy5cp SET station3=$var5, station4=$var6 WHERE timestamp=$var7;
if($conn->multi_query($sql) === false) {
  trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);

I'm using MySQL and am honestly ignorant on whether there are any important differences with SQLite.
The above uses these packages:
php5, php5-cli, php5-mod-mysqli

For writing to the SD card, I've slightly modified one of the available functions:

void writeToFile(String data, String dest, int append) { //this function takes a String of data to be written, a String of desired destination file name (name only, not path or extension), and a int 1=append data 0=overwrite data.
  String destn = "/mnt/sda1/" + dest + ".txt"; //this builds the file path
  int charlen = destn.length() + 1; //this calculates the needed char length + 1 for a NULL at the end
  char destin[charlen];  //initializes the char array
  destn.toCharArray(destin, charlen); //stores the file path as a char array
  if (append == 0) FileSystem.remove(destin);  //if the option is set to overwrite the file, removes the old file
  File dataFile = FileSystem.open(destin, FILE_APPEND); //writes to the file
  if (dataFile) {  // if the file is available, write to it:
  // if the file isn't open then you could signal an error here
  else { }

I've no idea how execution time compares, but you do have to #include <FileIO.h> rather than #include <Process.h>