Issue with multiple calls to functions using Process.h library/objects - HELP!!

Hello all,

This issue is frustrating me, I’m currently creating an interface using Arduino YUN to control a water pressurizer using a few sensors, then upload all data and allow control from my Home Automation System.

At this point I have two functions that I’m trying to put together, first one to check if the YUN is connected to the internet in order to start uploading data, this function runs only once on SETUP and it works if you run it separately from the second function, see below;

/***************************************************************************
*SUB_yunwificheck 
*This SUBROUTINE will wait until YUN is connected to internet and print
*SSID and IP address the YUN to a LCD object and serial if required.
*Also it requires the corresponding script loaded on YUN's memory;
*DEFAULT script is /mnt/sd/Arduino/luascripts/ssid-ip.lua
*RETURNS; nothing
*INPUTS; 
*String scriptfullpath - String containing script full path
*DEFAULT BUILTIN SCRIPT PATH: /usr/bin/pretty-wifi-info.lua
*boolean serialprint - True if serial print enabled, for debugging purposes
***************************************************************************/
void SUB_yunwificheck(String scriptfullpath, boolean serialprint)    {

Process yunwificheck;    //Declares Process Variable

//Declare constants
int maxretries=10;    //Maximum connection retries

//Declare variables
int pointer=1;    //Declares and initialize pointer integer
char charbuffer[16];    //Declares char buffer 16 char max per LCD
int retries;    //Declares variable for retries


tryagain:
delay(3000);    //delay for wifi connection
retries += 1;   //increment retries

//Sends SHELL command to YUN using full path
//This script need to be installed on YUN or media
yunwificheck.runShellCommand(scriptfullpath);
  if (yunwificheck.available() > 0) {   //if there is response then proceed else try again
    LCD.clear();    //clear LCD
    LCD.setCursor(0,0);   //Set cursor to Row=0,Col=0
    while (yunwificheck.available() > 0)    //While YUN is replying then listen
      {
          charbuffer[pointer] = yunwificheck.read();    //store response char
          if (charbuffer[pointer] == '0')  {    //if empty then try again
            if(serialprint == true) SerialUSB.println("Empty Char received, trying again...");
            goto tryagain;
          }
          if (charbuffer[pointer] == '\n')  {   //if carriage return then
            LCD.setCursor(0,1);                 //change to second row on LCD
            delay(100);
            goto nextchar;
          }
          nextchar:
          if(serialprint == true) SerialUSB.print(charbuffer[pointer]);
          if (charbuffer[pointer] != '\n') LCD.print(charbuffer[pointer]);
          pointer += 1;     //adds 1 to pointer   
      }
  } else  {   //if there is no response from YUN
    if(serialprint == true) SerialUSB.println("Trying again...");
    if (retries <= maxretries)  {   //if this retry is less than max retries then try again
      goto tryagain;
    } else  {
      LCD.print("Connection Error");
      goto wifiend;   //go to the end
    }
  }
wifiend:  
if(serialprint == true) SerialUSB.println("******************************************************");
yunwificheck.close();
}

Then this is the second and more important function, it uses curl commands to send POST requests and upload data to my home automation system. It also works independently.

/***************************************************************************
*FN_zipatosyncpost
*This is a FUNCTION that assembles and sends HTTP synchronous POST to Zipato
*servers to write values to Virtual Meters.
*Each zipato Virtual Meter has 16 values.
*RETURNS; Integer with Response Code
*INPUTS;
* String Zserial - Serial number for Zipato Controller
* String Zapi - API Key from Virtual Meter
* String Zep -  EP Key from Virtual Meter
* String Zvalue - Virtual Meter value placeholder name
* int Val - Value to be writen into placeholder
* boolean PrintSerial - If this value is TRUE this function will print more
*                       information about Zipato response (debug).
***************************************************************************/
int FN_zipatojsonpost(String Zserial, String Zapi, String Zep, String Zvalue,int Val, boolean PrintSerial){
  
  Process zipatoclient;    //Declare Client
  
   //Declare Zipato Constants
  const String Zurl="https://my.zipato.com/zipato-web/remoting/attribute/";    //Define Zipato basic URL, this does not change
  
  //Declare Variables
  String URL;   //String to hold complete URL
  int str_len;  //Integer to hold lenght of URL
  char URLchar[200];  //Char array to hold URL
  int retries=0;    //Integer to hold timeout timer
  unsigned int respcode;   //Integer to hold response code from Zipato
  
   
  URL = Zurl+"set?serial="+Zserial+"&apiKey="+Zapi+"&ep="+Zep+"&"+Zvalue+"=";   //Build first part of URL
  URL += Val;   //Convert Integer to String by concatenating it to the first part of URL
  if (PrintSerial==true) SerialUSB.println("Sending JSON Request");   //If required print header
    
  str_len = URL.length()+1;  //Count number of characters on URL and store it
  URL.toCharArray(URLchar,str_len);   //Convert URL string into URL char and store it

  zipatoclient.begin("curl");
  zipatoclient.addParameter("-D");
  zipatoclient.addParameter("-X");    //for other than GET
  zipatoclient.addParameter("POST");  //Type of request
  zipatoclient.addParameter("-k");    //enable insecure
  zipatoclient.addParameter("-w");    //format output
  zipatoclient.addParameter("%{response}\\n%{http_code}");  //{response}\n{responsecode}
  zipatoclient.addParameter(URLchar);   //add Zipato URL
  zipatoclient.run();
  if (PrintSerial==true) SerialUSB.print("Response:");    //print header if required
            
            while (zipatoclient.available() > 0) {      //While there is response from server read response
                char c = zipatoclient.read();           //Load response to char
                if (c == '\n') respcode=zipatoclient.parseInt();    //If carriage return found get response code
                if ((PrintSerial==true) && (c != '\n')) SerialUSB.print(c);     //Print if required
            }
   if (PrintSerial==true) SerialUSB.println();    //Print if required
   zipatoclient.close();
   return respcode;          
}

This is the main routine, and I have the following issues;

  1. If I first call “SUB_yunwificheck” as intended, all subsecuent calls to “FN_zipatojsonpost” returns empty from YUN and data is not uploaded.
  2. Made a test and commented out call to “SUB_yunwificheck”, then called “FN_zipatojsonpost” once and it worked, every 15 minutes it uploaded data and gave me good responses. Then added a second call to a different place holder and both uploaded every 15 minutes. Tried with three and they worked.
  3. Then moved on and added all calls I need for all the values I want to update and NONE of the calls worked, not even the first.

Don’t really understand why this is happening, I have been adding delays and doing many tests but no luck. Please help me, any advice is well received.

/***************************************************************************
*Project - YUN Water Pump version 0.1
*Date - 20170808
*LCD SDA >> Pin A4 for UNO, Pin D2 for YUN
*LCD SCL >> Pin A5 for UNO, Pin D3 for YUN
***************************************************************************/

//Include Required Libraries
#include <Bridge.h>   //Required for communication between arduino and YUN
#include <Wire.h>       //Required for I2C comm (LCD Display)
#include "Suli.h"       // Required for Standard LCD control
#include "LCD_RGB_Arduino.h"    //Required for Standard LCD Control


//Declare Library Objects
rgb_lcd LCD;    //Declare RGB LCD

//Declare Constants
boolean debugmode=true;
int R=255;    //Red channel for RGB LCD (0-255)
int G=255;    //Green channel for RGB LCD (0-255)
int B=255;    //Blue channel for RGB LCD (0-255)
const long heartbeatdel=900000;   //Asynchronous delay for post requests 15 min (900000)

// Define Variables for Zipato
String ZboxSerial="MYSERIAL";                        //Zipato Controller Serial, this changes if controller changes.
String ZboxApiKey="MYAPI";   //Zipato API Key, this changes if virtual device changes.
String ZboxEp="MYEP";      //Zipato EP Key, this changes if virtual device changes.
String ZboxValue="value1";                                //Zipato identificator for Virtual Meter value to be written, this changes as required.

//Timer Variables
long heartbeatMillis=0;    //Declare Timer variables for multitask delays
int syncupdatedel=500;    //Declare Syncronous delay for periodic update (all meters)

//Declare Process Variables
String ZipatoPostURL;   //String to store assembled Zipato POST URL
int ValueOut;          //Value to send
int Response;         //Response code from Zipato Server

/***************************************************************************
* SETUP ROUTINE - Runs only once
****************************************************************************/
void setup() {

  LCD.begin(16, 2);     //Initialize 16x2 LCD
  LCD.setRGB(R,G,B);    //Initialize LCD RGB Setting
  LCD.clear();          //Clear LCD
  LCD.setCursor(0,0);   //Set cursor to Row=0,Col=0
  
  SerialUSB.begin(9600);  //Initialize serial port
  if (debugmode == true) while (!Serial);    // Do nothing until serial monitor is opened if debug mode enabled
   
  LCD.print("YUN Water Pump");
  LCD.setCursor(0,1);
  LCD.print("Connecting...");
  LCD.setCursor(0,0);
  Bridge.begin();   // Comunicate with Linux processor
  delay(10000);
  
  SUB_yunwificheck("/mnt/sd/Arduino/luascripts/ssid-ip.lua",debugmode);   //call subroutine
  
  delay(5000);
  LCD.clear();
  LCD.setRGB(0,0,0);
  
  if (debugmode == true) SerialUSB.println("Heartbeat");
  ValueOut = random(0,999); //Generate Random Value as Heartbeat to send to Zipato as Heartbeat
  Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
  
  
}

/***************************************************************************
* LOOP ROUTINE - This routine runs continuosly
****************************************************************************/
void loop() {
  unsigned long curMillis = millis();     //define variable for timekeeping
    
    //UPDATE ALL METERS TO ZIPATO EVERY 15 MINUTES
    if(curMillis - heartbeatMillis >= heartbeatdel) {
      heartbeatMillis = curMillis;   //Update time
      
      //HEARTBEAT
      if (debugmode == true) SerialUSB.println("Heartbeat");
      ZboxValue="value1";  
      ValueOut = random(0,999); //Generate Random Value as Heartbeat to send to Zipato      
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //BATTERY LEVEL VOLTS
      delay(500);
      if (debugmode == true) SerialUSB.println("Battery Level Volts");
      ZboxValue="value2";  
      ValueOut = 5.0;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //BATTERY LEVEL %
      delay(500);
      if (debugmode == true) SerialUSB.println("Battery Level %");
      ZboxValue="value3";  
      ValueOut = 100;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //Water Level mm
      delay(500);
      if (debugmode == true) SerialUSB.println("Water Level mm");
      ZboxValue="value4";  
      ValueOut = 980;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //Water Level %
      delay(500);
      if (debugmode == true) SerialUSB.println("Water Level %");
      ZboxValue="value5";  
      ValueOut = 99;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //Water Level Litters
      delay(500);
      if (debugmode == true) SerialUSB.println("Water Level Litters");
      ZboxValue="value6";  
      ValueOut = 489;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //Water Pressurizer Current mA
      delay(500);
      if (debugmode == true) SerialUSB.println("Water Pressurizer Current");
      ZboxValue="value7";  
      ValueOut = 1200;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      //Status Alerts
      delay(500);
      if (debugmode == true) SerialUSB.println("Status Alerts");
      ZboxValue="value16";  
      ValueOut = 0;
      Response = FN_zipatojsonpost(ZboxSerial,ZboxApiKey,ZboxEp,ZboxValue,ValueOut,debugmode);    //Make POST request to Zipato and store response
      
    }
    //UPDATE ALL METERS TO ZIPATO EVERY 15 MINUTES

    
}