Using BridgeClient in Python Scripts.

This took me an afternoon to figure out, so I figured I would post it here hoping that others could use it. I have a project where I plan to pass values between the Arduino and the Linino environments and BridgeClient.py seemed to be the right way to go about it...

#!/usr/bin/python

import sys    
sys.path.insert(0, '/usr/lib/python2.7/bridge/') 
                                                
from bridgeclient import BridgeClient as bridgeclient
                                                     
value = bridgeclient()                              
                                                     
value.put('key','value') 
                          
print value.get('key')

Nice, this is very useful. This seems to be the less memory eating method to access variables in every environment (Arduino, python and javascript using ajax)

Do you have the sketch that goes along with this? I'm having a heck of a time setting up 2 way communications between a sketch and a python program. The Process library "write" function doesn't appear to work. Also its missing several of the variations mentioned in the documentation (i.e. ability to write strings, ...).

Thanks in advance. The software doesn't feel quick baked yet. I'm trying to basically make the arduino be a slave to the lineo side so that I can do all of my programming in Python.

The Arduino code that I am currently using is as follows (I can’t make any claims to it completeness, but it is working… )

#include <Bridge.h>

char D12value[2];

void setup() {
  pinMode(12,OUTPUT);
  Bridge.begin();
}

void loop() {
  Bridge.get("D12",D12value,2);
  int D12int = atoi(D12value);
  digitalWrite(12,D12int);
  delay(50);  
}

On the Linino/Python side value.put('D12','0') or value.put('D12','1') will set the mode of Pin D12 on the Arduino…

There is an example of Bridge.put() in the “Bridge” example included with the Ardunio IDE.

For what its worth… this is all early proof of concept code… ultimately I am looking for

Android App → HTTPS/cgi-bin/python → bridge → Arduino/D12 → Power Switch Tail → Grundfos Hot Water Loop Pump.

I am currently learning just enough Android Application Development to trigger the HTTPS calls…

Excellent. Thank you. Now for a more difficult question. :slight_smile:

Can you do a Bridge.put() back up to your Python program? I have not been successful at this. I’ve read all of the source code for the Arduino Bridge, the Linio Bridge, and the Python BridgeClient, and no luck.

Thanks again.

I have not written anything that uses Bridge.put() on the Arduino side. It is used in the Bridge example included with the Arduino IDE.

  if (client.read() == '/') {
    // Read value and execute command
    value = client.parseInt();
    analogWrite(pin, value);

    // Send feedback to client
    client.print(F("Pin D"));
    client.print(pin);
    client.print(F(" set to analog "));
    client.println(value);

    // Update datastore key with the current pin value
    String key = "D";
    key += pin;
    Bridge.put(key, String(value));
  }

Just for you information. I kind of got the Bridge.put() code to work... kind of. It is very flakey and only works some of the time. Also I found that it is easy to crash the Bridge process running on linino. Just put a non-string and it will crash. There isn't much in the way of exception handling. I'm continuing to see if I can make it more reliable. Its very difficult since the serial monitor behaves more erratically on Yun than on Uno.

Interesting, for what its worth, I am "reading" ie: bridge.get() on the Arduino side ever half second and "writing" value.put() at least twice a day and am having no trouble.

Just checked uptime, 7 days now.. no issues...

If you can provide code examples, I wouldn't mind looking it over/testing.

Ok. I’ve now gotten it to work reliably. However it is very, very slow. I’m only seeing about 4 get/puts per second, or a little over 1 transaction per second between my python program and my sketch. Is there a faster way other than writing my own bridge?

I’m asking because I want to do all of my programming using the arduino as a slave to my python program. I want to do my programming in Python on the Linino side. To do this I need at least 10 transactions per second, I’d like 100 if I could.

When I looked at the BridgeClient.py I found that in the end it was setting up a new socket to the local port for every get or put. Very inefficient. Indeed it isn’t much faster than using the Bridge REST interface from a remote computer.

I’m looking for performance similar to what I was seeing in my old Raspberry Pi <-> Uno combination using Firmata.

Any ideas? (Just so you know I’m having a blast regardless of how it sounds.)

I might have an idea....

I've spent the last couple of days on the same problem. The goal is to have a Python script that listens to OSC messages from an application on my phone, and to pass on values retrieved from some of the messages to control PWM pins. Getting the Python script to run properly was surprisingly straightforward, given my (lack of) Linux and Python skills. So far, the script reads floats between -127 and +127 from two faders and sends the values back to the phone, where they're displayed in two text boxes as feedback.

All this works very fast and smooth. Excellent.

Then I tried to pass on the values to the Arduino sketch. I had been hoping that runShellCommandAsynchronously() would do the job, but apparently that's not possible. At least I couldn't get it to work.

After many, many hours of trying all kinds of things I found this thread. I managed to get it working, but, as mentioned above, the speed is simply unacceptable. However, using code from bridgeclient.py I was able to speed it up significantly. Adding

from bridgeclient import BridgeClient as bridgeclient
json = TCPJSONClient('127.0.0.1', 5700)

to the script, and replacing value.put('D13','%i' % (fader1Feedback)) with json.send({'command':'put', 'key':'D13', 'value':'%i' % (fader1Feedback)}) did the trick. Avoiding opening and closing a socket for every put is the key.

This will need a lot more testing and refining, but so far it looks promising.

Here's the relevant part of the script. Hope it's helpful.

#!/usr/bin/python

import OSC
import time, threading
import sys    
sys.path.insert(0, '/usr/lib/python2.7/bridge/') 
                                                
from bridgeclient import BridgeClient as bridgeclient
from tcp import TCPJSONClient
                                                     
value = bridgeclient()
json = TCPJSONClient('127.0.0.1', 5700)

receive_address = ('192.168.1.144', 12345)

s = OSC.OSCServer(receive_address)

client = OSC.OSCClient()

s.addDefaultHandlers()

fader1Feedback = 0

# define a message-handler function for the server to call.
def printing_handler(addr, tags, stuff, source):
    global fader1Feedback
    global fader2Feedback
    if addr=="/1/fader1":
      fader1Feedback = int(stuff[0])
      msg = OSC.OSCMessage("/1/label2")
      msg.append('0')
      msg.insert(0, fader1Feedback)
      client.sendto(msg, ('192.168.1.109', 1234))
      print "%i" % fader1Feedback
      #value.put('D13','%i' % (fader1Feedback))
      json.send({'command':'put', 'key':'D13', 'value':'%i' % (fader1Feedback)})

I've just opened an issue on bridge github https://github.com/arduino/YunBridge/issues/4 Anyone willing to code something similar and provide a pull request?

Hi everyone. I'm working on a project and i would like to implement all the control law and filters in the faster AR9331 microprocessor on a python script rather than in the mcu, but I'm fighting with the issue of the laggy "bridge method" to excange data between the mcu and the linino side. It would be really a pity if I could not use the powerful microprocessor to do computation just because of the latency in the comunication between the linino side and the atmega. I tried the advice posted by wpunkts, it enhances the performance respect the built-in "BridgeClient" method, but not enough. Did someone figure out how to speed up the bridge? Anyone have some other hints? Thank you!

Is the delay you're experiencing happening on the mcu or cpu side? If it's the mcu, take a look at this http://forum.arduino.cc//index.php?topic=192823.msg1448287#msg1448287

Thank you Federico for answered me. Yes, i think the delay that i'm experiencing is on the mcu side. I'm looking at your suggestion, isn't it related to the REST call? Does it works even if I wanna use directily the bridge acces trough a Python script? Sorry I'm a little bit confused about REST call (via browser?) and the lets say "normal use" of the bridge (bridge.get, bridge.put). Thank you!

My suggestion is related to the use of YunClient and YunServer. Bridge.get and put are not affected

I don't understand (probably because of the noob factor). There's a serial connection between the two sides. Why is it not possible to just pass data on it monitoring in python on one side and in the sketch on the other?

mediamad:
I don’t understand (probably because of the noob factor). There’s a serial connection between the two sides. Why is it not possible to just pass data on it monitoring in python on one side and in the sketch on the other?

I came up with the same thoughts and asked the same question in another thread.
Why all this bridge class heck? Why not simply using the well know Serial in the sketch and having access on the Linino site with JSON and WebSockets like node.js offers?

What kind of performance are you expecting? Maybe you'll find this discussion interesting

Very interesting indeed. Kind of surprised this wasn't already taken care of via library upon release. Seems a no brainer if using the Arduino as a dumb I/O. Throughput in most cases would be a non issue.

If you're suggesting we should change some library and have working code to share, I'm eager to test it