Help with Process.write()

Hoping ShapeShifter will see this post, I see he has posted multiple topics on this but I didn’t see any examples.

Basically the Bridge.put proved too slow for my application so I’m trying to use Process.write instead but it seems like I might be missing something.

The python script runs fine when I PuTTY into the Yun and execute it, it reads data from the stdin as expected and saves it to the file.

I just want the sketch to send the data to it on the stdin.

I have a python sctipt that runs in a loop and listens to input on sys.stdin, I send it scripts from mcu using Process.write() but it’s not working.

mcu side, didn’t include the imports…etc:

#include <Process.h>
#include <Bridge.h>
Process proc;
void setup() {
  Bridge.begin();
  proc.runShellCommandAsynchronously("python /test/procWrite.py results");
  delay(2000);
  proc.write('H');
  proc.write('E');
}

Python:

#!/usr/bin/python
import sys

filename = sys.argv[1]
fullpath = '/test/' + filename + '.txt'

dataFile = open(fullpath, 'a')

while True:
	mcuData = sys.stdin.readline()
	mcuData = mcuData.rstrip('\n')
	if (mcuData == 'E'):
		dataFile.close()
		break
	dataFile.write(mcuData + '\n')

After hour of suffering :o >:( :disappointed_relieved: I'm missing this in my python code:

mcuData = mcuData.strip()

right before:

if mcuData == "END":

I'm glad you got it working. Yes, it's helpful to call strip() to delete all white space from the beginning and end of the string before making comparisons. The rstrip('\n') call you had only deletes newline characters from the end, and may leave other characters in place that makes the subsequent comparison fail.

I'm surprised that what you posted works. You are write()ing individual characters, but reading lines. As I think of it, it may be that sys.stdin.readilne() has a timeout - it will read up until it sees a newline, or gets a timeout. You may get better performance if you send strings with a newline, as it may eliminate the timeout. I use println() to write to the Process object, which adds a newline automatically. Keep in mind that while the reference only lists those methods actually defined by the Process class, the class derives from Stream, so it also supports all of the Stream methods like print() and println(). You can use all of the same methods you use with other Stream objects like the Serial object. For example, you can also use readStringUntil() when reading from the Process.

Finally, I've found it helpful to use unbuffered I/O on the Python side. You are sending data back to the sketch, but in the default buffered mode the sketch likely won't see anything until the Python script fills the output buffer, or the script terminates. With unbuffered mode, the sketch receives any Process output immediately. To use unbuffered I/O, add the "-u" parameter to the process call, or to the script's shebang:

proc.runShellCommandAsynchronously("python -u /test/procWrite.py results");
#!/usr/bin/python -u

In your case, I would add it to both. I normally put it in the shebang, and then call the script using just the name without explicitly calling python - that way the system picks up the proper command (and -u option) from the shebang. You are explicitly calling python in the Process call, so it will likely ignore the shebang, therefore make sure you add the -u to that call.

Thanks! I switched to Process.println(string) and I can now write full strings. I don't read back from Python, I only write to it so I didn't bother with the buffer.

The strings I write are fixed 55 characters in length only, I didn't think 55 characters is a lot but for some reason I'm not able to achieve more than 2 Process.println(string) executions per second, each is averaging roughly ~480ms to complete.

I looked into the post that suggests using serial but I haven't mastered the basics yet to go down that route :/

Hey ShapeShifter, have you seen the LininoIO? http://wiki.linino.org/doku.php?id=wiki:upgradetolininoio I understand you first have to install LininoOS in place of the YunOS, but I'm wondering it this LininoIO is add-on is a solution to the slow mcu to Linux issue.

I see too many damage warnings in the wiki, not sure if it's a mature product?!?!

I've not timed the write speed through Process(), but your posted rates seem slow. Truthfully, my use age of Process.println() has been with low data rates: for example sending a sample once ore second, or only in response to a user action. I never measured the response time, but also never noticed a significant delay.

Seeing your full code (both sides) might help. Are you creating the Process every time? It doesn't look like it from your example above since the Python code enters an infinite loop, but if so, the process creation could take some significant time.

I have no experience with Linino or Bridge library alternatives.