Where is the documentation for the Python side of Bridge?

There seem to be several different ways to communicate between the ATmega and Python scripts running on the linux side of the Yun, but I can find any documentation for the Python interface to Bridge. Even the examples that purport to show how this works only show the Arduino code, not the Python code. There are a number of message threads that show bits and pieces of this, and several that refer to the BridgeClient python library, but no docs that explain and illustrate all the options.

Even this thread (HowTo: Write to Bridge Mailbox from Python - Arduino Yún - Arduino Forum) which seems to be closest to what I need doesn't close the loop: it shows how to send messages from Python to Arduino using the Mailbox, but not how to receive messages back from the Arduino.

I've looked at bridgeclient.py and some of the other python files along with it, but none of the code is documented. Is there simply no documentation available for the Python side of the Bridge?

Also... can anyone provide instructions for setting up a persistent bidirectional socket for communication between a Python script and an Arduino sketch on the Yun?

Thanks.

David

dagoch:
but I can find any documentation for the Python interface to Bridge.

I have also been unable to find any such documentation. Anything I've accomplished has been by trial and error, and by muddling through the source code.

Even this thread (HowTo: Write to Bridge Mailbox from Python - Arduino Yún - Arduino Forum) which seems to be closest to what I need doesn't close the loop: it shows how to send messages from Python to Arduino using the Mailbox, but not how to receive messages back from the Arduino.

Forum member sonnyyu has worked out quite a few tricks with the Yun, and has documented them on his site http://www.ibuyopenwrt.com/

One of his examples is MailboxWriteMessage which writes in the sketch, and reads with Python.

Also... can anyone provide instructions for setting up a persistent bidirectional socket for communication between a Python script and an Arduino sketch on the Yun?

Not specifically a socket, but when when I want to do bi-directional communications between the sketch and a Python script, I use a Process library object.

For example, this is what might be in a sketch (It's a copy/paste of several sections from a larger sketch, I don't promise that it compiles and runs as-is):

Process           Proc;          // Linux process manager object

void setup()
{
   Proc.begin("/mnt/sda1/scanner/scannerProcess.py");
   Proc.addParameter(ID);
   Proc.runAsynchronously();
}



void loop()
{
   Proc.println("Some data...");      // Write something to the process

   while (Proc.available())           // As long as there is data from the process
   {
      char ch = Proc.read();          // Read a character from the process
      process(ch);                    // Process the character
   }

}

Then, on the Python side, one issue is that the printed output from a Python script is buffered. That means nothing will be received from the sketch until the process exits, or enough data is sent that it fills a buffer. I've used two ways to deal with this, the first being to start the script with the shebang [color=blue]#!/usr/bin/python -u[/color] where the -u says to used unbuffered I/O. This works but using Python's print() function adds space between printed elements, and adds newline characters.

In my latest project, I wanted better control over the output so I didn't want to use Python's silly print statement, so I added this to the beginning of my Python code:

import sys

def write(value):
    sys.stdout.write(str(value))

Unlike print(), sys.stdout.write() doesn't add any spaces between elements, and doesn't add newlines after each call. To make writing a little easier, and to make sure everything was strings that the sketch could read not send any binary data, I added that write function definition. So, to send something to the sketch, I could simply code something like:

    write('Length: ' + str(len(code)))

To have the Python code read from the sketch, I used something like this:

# Process until the end of the world (or reset, whicever comes first.)
while True:
    # wait for and read a line of text from the sketch (stdin)
    # strip any whitespace characters
    code = raw_input().strip().upper()
    # Do something with the input value here...

raw_input() reads a line of text from stdin, ending with a newline (which is added by the println() call when writing to the Process object.) In my case, I wanted to ignore any leading/trailing whitespace so I added the trim() call, and I wanted everything uppercase so I added the upper() call. Your needs may vary.

I've run into issues where the Python script may crash due to coding stupidity on my part, so I've changed the launch logic around to make it relaunch automatically. Instead of starting the Process object in setup(), I have this code at the top of loop():

void loop(void)
{
  if (!Proc.running())               // Is our Process object still running?
  {
    Proc.close();                    // No, close the dead process to clean up resources

    // Try to restart the process
    Proc.begin("/mnt/sda1/scanner/scannerProcess.py");
    Proc.addParameter(ID);
    Proc.runAsynchronously();
  }

  // Continue on with the rest of loop()...

This way, if the process should stop for whatever reason, it is automatically restarted. While this last idea is new, I've used this basic Process communications method in several projects, and it has been very reliable. I also think it's fairly low overhead compared to some of the other methods (probably the only way to get more efficient is to bypass the Bridge altogether and implement Serial1 communications directly, but then you lose all of the other Bridge functions.) In the message thread you quoted, I only used the WriteMailbox idea because I had an independent process (not launched by the sketch) which I wanted to be able to send data to the sketch. It was easier to just use the Bridge's Mailbox class than it was to figure out how to send the data to the other Python process so it could forward it to the sketch.

dagoch:
Is there simply no documentation available for the Python side of the Bridge?

If they had never built the "bridge" in the first place and had just treated the Yun as a Linux PC with a Leonardo in close company there would have been no need to write documentation.

As it is, it is a struggle to use it the simple way.

...R

Robin2:
If they had never built the "bridge" in the first place and had just treated the Yun as a Linux PC with a Leonardo in close company there would have been no need to write documentation.

Correct, but then they would have to write lots MORE documentation since the Linux side is so completely different from the Arduino side. In fact, without the '32U4 processor and Bridge library, it wouldn't really be an Arduino, it would just be another Raspberry Pi or BeagleBone, albeit a much less powerful version.

It's the '32U4 processor and Bridge library that make it an Arduino. It allows people who are already experienced with Arduino to ease into the Linux side by using the Bridge to give them extra capabilities without having to learn an entirely new toolset and programming mentality.

Sometimes I think you would be better off forgetting about the Yun, and just using a Raspberry Pi and an AlaMode Shield - similar total prices, more powerful Linux, and just the development environment you want.

ShapeShifter:
it wouldn't really be an Arduino, it would just be another Raspberry Pi or BeagleBone, albeit a much less powerful version.

It's the '32U4 processor and Bridge library that make it an Arduino.

Well IMHO that is exactly what it is - a less powerful RPi with an Leonardo attached. Why did/do they want to pretend it is not.

The Leonardo is the Arduino part.

What attracted me to the Yun rather than the RPi was the fact that I don't need a TV screen (which I don't have) for the Yun.

(All said in a spirit of friendship)

...R

Robin2:
What attracted me to the Yun rather than the RPi was the fact that I don't need a TV screen (which I don't have) for the Yun.

You can certainly use the RPi over SSH without an HDMI screen.

(All said in a spirit of friendship)

Same here!

ShapeShifter:
You can certainly use the RPi over SSH without an HDMI screen.

I had the impression it would not do that "out of the box" - but perhaps I should have bought an RPI rather than a Yun :slight_smile:

...R

There is a program called UltraVNC which you can run on either pc or android device that you can use as a remote display for your RPI.