Can't figure out how to get a process to runasyncronously

Hi,

In my code I am trying the following. Basically I set a process going in the background to get the wifi signal strength then I do all the other things I need to do then get the result. trouble is as soon as I start using the runshellcommandasync it stops doing some of the other things in the background. i.e it stops updating my output to thingspeak. the rest of the code works perfectly when i comment out the first couple of lines.

Just after a pointer as to where i am going wrong with using the runsasync process

thanks

void loop()                                                                                                             // The main program loop
{
        Process GetWifiStrength;                                                                                        // Create a new shell process
        GetWifiStrength.runShellCommandAsynchronously("/usr/bin/pretty-wifi-info.lua | grep Signal");                   // Run a process in the background to get the Wifi signal strength

        if(config.ControllerMode==2)                                                                                    // If the value stored in EEPROM for ControllerMode = 2
        {
                LastWinterPumpTime = millis();                                                                          // Reset the timer before entering the loop
                WinterModeLoop();                                                                                       // Enter a persistant winter mode loop to prevent the pump bearings from seizing up.
        }
        TestPanelCritical();                                                                                            // Test if the Panel is over its maximum temperature
        TestFrostProtection();                                                                                          // Test if the system is nearing freezing point 
        TestIfFrozen();                                                                                                 // If the system has frozen stop pumping
        TestTropicalMode();                                                                                             // Test if the system is above the user selected temperature and the Panel is lower thant the Pool temperature by 2 degrees
        TestNormalOperation();                                                                                          // The normal loop. i.e Panel hotter than pool by x
        IfNoneApply();                                                                                                  // If none of the above apply then just sit collecting heat

    //    if (GetWifiStrength.available())                                                                                              // Once the process is complete
    //    {
    //            WifiStrength = GetWifiStrength.parseInt();                                                                            // Parse the returned Wifi Strength to an integer   
    //            Console.println(WifiStrength);                
    //    }         
}/code]

One problem I see is that you are creating the Process object at the top of the loop, and starting it. Then, you do some additional processing, Finally, you check to see if there is any output available. Then, whether or not you got any output from the Process, you exit the loop() function. The Process object (local to loop()) is on the stack and goes out of scope once loop() exits. On the next pass, you start all over again: allocate a Process object on the stack, start a new process, and maybe you will get some output to process at the bottom of the loop. You are spending all of your time creating and abandoning processes, and rarely looking at the output.

Another issue is the use of parseInt() - this is a potentially blocking function. Maybe it is holding things up if some characters are available (which gets you into the if statement controlling the parseInt) but not enough to immediately satisfy the parseInt() call? Or perhaps your command is returning an invalid response that cannot be parsed properly?

At a minimum, I think you should declare the Process object globally so that it can survive multiple passes through the loop() function. Odds are you will start it on one pass, and not have an answer until a later pass. You'll need some logic to control when you need to start or restart the process: perhaps you only want to do it periodically? Or maybe the logic is as simple as start it once in setup(), then in loop() look to see if it is still running: if not, check for output, and then immediately restart it?

Thanks,

I've made some progress based on what you suggested. I am now creating process globally along with my variable declarations.

However when I add the

GetWifiStrength.runShellCommandAsynchronously("/usr/bin/pretty-wifi-info.lua | grep Signal");

Everything else continues to work in the code but my updating of thingspeak breaks.

For updating thingspeak I use

client.getAsynchronously(URL);

could the two in some way be conflicting behind the scenes?

mearsy25:
could the two in some way be conflicting behind the scenes?

I suppose it's possible, but I would be surprised. I use several Process objects, all running asynchronously at the same time, and I've had no issues. However, I've not tried throwing an asynchronous client post at the same time.

I'm only seeing a hint of everything that your project is doing based on the functions that are being called in the loop() function, but it seems like this is a fairly involved project. You might want to consider trying to do most of the processing on the Linux side: it is trivial for it to get the WiFi signal strength, and it will do a better job of updating ThingSpeak. I would suggest you do as much of the processing as possible on the Linux side, and just use the sketch to handle hardware I/O processing. That's where the power of the Yun really lies.