Showing posts with label 6. Bridge stuff. Show all posts
Showing posts with label 6. Bridge stuff. Show all posts

Thursday, January 29, 2015

Publishing sketch values on a web page hosted by the Yun

This is a simple way to get values from the sketch made visible to a browser that can connect to the Yun.
The Arduino Yun wil be used as leightweight webserver.
The sketch just puts the values in the Bridge, the webserver reads them from there.

I am using "bottle" as example webserver.

Sketch code:

/* vim: set filetype=cpp: */
#include 

void setup()
{
  Bridge.begin();
}

void loop()
{

    char value[40];  // 40 is probably too much
    uint32_t my_time;
    uint32_t my_random;

    while(true)
    {
       my_time=millis();
       my_random=random(99);

       ultoa(my_time,value,10);
       Bridge.put("TIME",value);
       ultoa(my_random,value,10);
       Bridge.put("RAND",value);

       delay(1000);
    }

}

Python code:

#!/usr/bin/python

import sys
from bottle import run, route, get, post, request

sys.path.insert(0, '/usr/lib/python2.7/bridge/')
from bridgeclient import BridgeClient as bridgeclient
bc = bridgeclient()

@route('/status')
def status():
    try:
        t =  bc.get("TIME")
        r =  bc.get("RAND")
        return "Time="+t+"
 Rand="+r
    except:
        return "Oops\n"

def main():

    run(host='0.0.0.0', port=48964, debug=True)

if __name__ == '__main__':
    main()


After starting the python code on the linux side you can browse to http://arduino.local:48964/status and get:


Monday, December 23, 2013

Bridge Communication - part 5

My part4 was maybe too optimistic. It seems some people still have problems with long strings over the Bridge. A fix was found (http://forum.arduino.cc/index.php?topic=196091.msg1517378#msg1517378)

Until an official release do:

  • Using SSH or YunSerialTerminal, connect to the linux side of the yun.
  • Edit file /usr/bin/run-bridge, changing "python bridge.py" with "python -u bridge.py" (ie: add a "-u" to the command line)
  • Edit file /usr/bin/kill-bridge, again changing "python bridge.py" with "python -u bridge.py" (ie: add a "-u" to the command line)
  • Type kill-bridge and re-run your sketch


Saturday, November 30, 2013

Bridge Communication - Part 4

The new IDE 1.5.5 was released with Bridge bug fixes. This solved so far all my Bridge issues :-)

Thursday, November 28, 2013

Bridge communication - Part3

Sometimes the Bridge seems to fail, decided to make a simple stress test:

The basic idea of the test is:

For a certain message length=M do:
- reset MCU
- cpu puts random message of length M and a single char ID (key1)
- mcu constinuously checks for a new ID, if it finds a new ID, it puts the message back to the cpu (key2)
- cpu checks (after a couple of seconds) if it gets the message it had sent.
- if YES: repeat (max 200 times for now)
- if NO: failure and decrease M
Results get written in a file.

To rule out timing issues I put quite some delays in the process (2 second wait on the cpu side, 2*250ms on the mcu side).

The result is imho quite amazing (not all lengths tested for now):

msg_length=60 FAILURE after 21 messages
msg_length=55 FAILURE after 21 messages
msg_length=50 FAILURE after 21 messages
msg_length=45 FAILURE after 21 messages
msg_length=40 FAILURE after 21 messages
msg_length=35 FAILURE after 21 messages
msg_length=30 FAILURE after 21 messages
msg_length=25 SUCCES 199 messages
msg_length=20 SUCCES 199 messages
msg_length=15 SUCCES 199 messages

Note that the buffer size on the mcu side is identical for each message length.

So all message lengths above or equal to 30 seem to fail, and surprisingly each time after 21 message exchanges??
Below that length no failures were detected.

Code:

#include "Bridge.h"

void setup() 
{
  Bridge.begin();
}

void loop() 
{
      unsigned int len;
      char buffer[64];
      char prevID='-';
      while(true)
      {
          Bridge.get("key",buffer,64);
          if(buffer[0]!=prevID)
          {
              // new message
              delay(250);
              Bridge.put("key2",&buffer[1]);
              prevID=buffer[0];
          }
          delay(250);
      }
}
and
#!/usr/bin/python
import sys    
import time
import string
import random

def rand_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for x in range(size))

sys.path.insert(0, '/usr/lib/python2.7/bridge/') 
from bridgeclient import BridgeClient as bridgeclient
bc = bridgeclient()                              

from subprocess import call

f=open('test_result.txt','w')

cnt4=0
msg_id='a'
n_loops=200

for msg_length in range(60,10,-5):
   print "msg_length set to ",msg_length
   #reset mcu
   print "resetting mcu now"
   call(["reset-mcu"])
   time.sleep(5)
   for loop in range(1,n_loops):
       time.sleep(2)
       if cnt4==0:
         msg_id='a'
         cnt4=1
       elif cnt4==1:
         msg_id='b'
         cnt4=2
       elif cnt4==2:
         msg_id='c'
         cnt4=3
       else:
         msg_id='d'
         cnt4=0
       msg=rand_generator(msg_length)  
       toput=msg_id+msg
       print "put",toput
       bc.put('key',toput)
      
       # wait for identical returned value
       trial=1
       while trial<4:
           time.sleep(1)
           r = bc.get('key2')
           print "get ",r
           if r is None:
             print "   No answer key found yet"
           else:
             if r==msg:
                 print "   OK after",trial," trials"
                 break
             else:
                 print "   FAIL"
                 trial=trial+1
       if trial>=4:
         f.write("msg_length=")
         f.write(str(msg_length))
         f.write(" ")
         f.write("FAILURE after ")
         f.write(str(loop))
         f.write(" messages\n")
         break
       elif loop==n_loops-1:
         f.write("msg_length=")
         f.write(str(msg_length))
         f.write(" ")
         f.write("SUCCES ")
         f.write(str(loop))
         f.write(" messages\n")
f.close()

 also available on http://forum.arduino.cc/index.php?topic=201484.msg1484792#msg1484792


Sunday, November 17, 2013

Bridge communication - Part2

The message size that I need will be well below 266, more in the range of 30 characters or so. So I am continuing without caring why it crashes if we try to send long messages.

In my setup, the Linino side will be the master, sending out commands to the Sketch side. For example a command to set the temperature. Most commands will be accompanied by a value (e.g. the temperature).

Given the messages stay in the Bridge data store after a get, and the Sketch will be likely polling to see if there is a new command I need something to identify if a message is a new one or not. I will just use 1 character in the message, that should change for every new command.

So the message that the Linino side will put looks as follows:
1 message ID char + command + value

I made a C++ class BridgeComm.h that on top of the bridge, offers this functionality. It has a method that can check for a new message, if so it returns true + the null-terminated command and value.

Maybe the Mailbox class that is shipped with the Arduino does similar things, but it was just less time to make it using the Bridge.

For now the command will be 8 characters, the value 16. But that are just consts that can be changed in whatever I need.

My Yun sketch now looks as follows:

#include <Bridge.h>
#include <Console.h>
#include <BridgeComm.h>

BridgeComm bc;
char command_buff[BridgeComm::REQ_CMD_BUFF_LEN];
char value_buff[BridgeComm::REQ_VAL_BUFF_LEN];

void setup() {
  bc.setup();
  Console.begin();
  while(!Console)
  {
    ;
  }
  Console.println("Connected to the Console!");
}

void loop() {
  if(bc.check_for_command(command_buff,value_buff))
  {
     Console.print("Command received=");
     Console.print(command_buff);
     Console.print(", Value recieved=");
     Console.println(value_buff);       
  }
  delay(200);
}

I made a simple Python script that every 2 seconds sends another command (Temp-Max,Temp-Min,Temp) and a temperature value.
The output of the Yun console looks as follows:

Command received=Temp-Max, Value recieved=22.5
Command received=Temp-Min, Value recieved=23.5
Command received=Temp    , Value recieved=24.5
Command received=Temp    , Value recieved=25.5
Command received=Temp    , Value recieved=26.5
Command received=Temp    , Value recieved=27.5
Command received=Temp    , Value recieved=28.5

Another step in the right direction.

Bridge communication - part1

Some first trials with the Arduino Bridge. Starting simple with put and gets.
A first trial:

  • the Linino puts random characters using key1  (then waits 3 seconds)
  • the Sketch side gets on key1, and puts the same message on key2 (should happen in the 3 seconds)
  • the Linino gets on key2 and compares with what it had put on key1. If OK, it restarts with a longer message. If it fails it tries another get.
At a message length of 266 (always that length) it seems to FAIL:

Trying length 262
put AZORBF9S9C8E1V2YR531TS4GOFRN5YHOLCI5T7KAP1E6SLVH3UPK4SVABTLB7RC80JTCHBPEZHK5ZFE183G5GMHHD552DUBTKJD2PPTU5VANVBHFANI01SIDCEK2PN88REU7V0RJX0T0PS8JPDJX988PBF78Y37XYWHHBOL0FGCZ7AXJPXFKF0MKUH5I2EN89EAN1I9NPWEYVKB5DWCL7NWKTDBDXHQ62MCOOHP348SGNO2J5LPHW8TFVAW9E913T9UGN7
got AZORBF9S9C8E1V2YR531TS4GOFRN5YHOLCI5T7KAP1E6SLVH3UPK4SVABTLB7RC80JTCHBPEZHK5ZFE183G5GMHHD552DUBTKJD2PPTU5VANVBHFANI01SIDCEK2PN88REU7V0RJX0T0PS8JPDJX988PBF78Y37XYWHHBOL0FGCZ7AXJPXFKF0MKUH5I2EN89EAN1I9NPWEYVKB5DWCL7NWKTDBDXHQ62MCOOHP348SGNO2J5LPHW8TFVAW9E913T9UGN7
OK
Trying length 263
put DA4VIB5FV9B8K669U3POPSNQHO1U8NI3JWLBG1LW9YW9028ME309HHPCGW39ZQZQYJ43TIVN367MIIX8N74RPS45V3TFSBX5ZIQGO8FDTP40B10X7A7CLJ3DOGZMDSHNO6V4WWRN1WHAR3GHA094UQ69OKYN46GENJG77C8E322DC16Q3SOTQ5PWE12QD7LOF450ZU5ZUFTLJZCZCL5TA5MBGUCYIEQS9W02F5KP78NI6L4BJT6QCMG9IHQJIS26M9Z64R0
got DA4VIB5FV9B8K669U3POPSNQHO1U8NI3JWLBG1LW9YW9028ME309HHPCGW39ZQZQYJ43TIVN367MIIX8N74RPS45V3TFSBX5ZIQGO8FDTP40B10X7A7CLJ3DOGZMDSHNO6V4WWRN1WHAR3GHA094UQ69OKYN46GENJG77C8E322DC16Q3SOTQ5PWE12QD7LOF450ZU5ZUFTLJZCZCL5TA5MBGUCYIEQS9W02F5KP78NI6L4BJT6QCMG9IHQJIS26M9Z64R0
OK
Trying length 264
put LKAR6LQO7LV74BLY6O4FXM8WJA9X0CP5ZKZLXAT19YM07EM3IBTEV4IOWVFQLUQZ7KSC14I96PAK9WY2DXPXP6UJ0ZIIU6IBU65G1PMOMNSJN2HZXF2DEMID6ZKIE3XZ4O5ZJ80UVP45AQF9TYBU8PNYRFC47NF9O5SM40VXO1ANYVII8IHZ8HQZBJ1NZZLOY1N8XVH7MXVCN5XJ7CKN0VSD19Q6Y9QMOS4H7BOHZNZ3SIU8T8BTRHY3I4C354BAH5EMU2WK
got LKAR6LQO7LV74BLY6O4FXM8WJA9X0CP5ZKZLXAT19YM07EM3IBTEV4IOWVFQLUQZ7KSC14I96PAK9WY2DXPXP6UJ0ZIIU6IBU65G1PMOMNSJN2HZXF2DEMID6ZKIE3XZ4O5ZJ80UVP45AQF9TYBU8PNYRFC47NF9O5SM40VXO1ANYVII8IHZ8HQZBJ1NZZLOY1N8XVH7MXVCN5XJ7CKN0VSD19Q6Y9QMOS4H7BOHZNZ3SIU8T8BTRHY3I4C354BAH5EMU2WK
OK
Trying length 265
put WY8XFBQL8ND0WMVVE1TU409M90YJXC2VMUAD6FSVFUNWD112NPD5ZP389X7SNOIF6D6Z46EY1Z2NBL3I46244MF88NBPGRUIRREXZWZBS5TFI4XMBZXZVIUR2VLYV9FSHBCMWWQ23TNQ8229RKFWX3Q27APKLWCLP80IDVH0NNQU4HJF2DPG3RN1EYH3FGUFHDS2SH34JH34TITEPPA9IB7QWXV7AMEMNXBK5NMF91026XV2BE9FS1PQPW93CUY4QDOUA29KI
got WY8XFBQL8ND0WMVVE1TU409M90YJXC2VMUAD6FSVFUNWD112NPD5ZP389X7SNOIF6D6Z46EY1Z2NBL3I46244MF88NBPGRUIRREXZWZBS5TFI4XMBZXZVIUR2VLYV9FSHBCMWWQ23TNQ8229RKFWX3Q27APKLWCLP80IDVH0NNQU4HJF2DPG3RN1EYH3FGUFHDS2SH34JH34TITEPPA9IB7QWXV7AMEMNXBK5NMF91026XV2BE9FS1PQPW93CUY4QDOUA29KI
OK
Trying length 266
put MAJPFJVK0PEHM866Z170SQR0Z12Z5HI1TGW5THNUY6P0PQ1CEZ1PACJC7ZFJFAIKH7M0L2DZY0GS5CE9Q38XSZ95E1LF2KI7NZKUNSDSR09SVIQV9DMVI43APXHNYKQ5KE6TYF21CU6P4HPQG8YFPRA3PKRULIG5MH4XD9PXQDE0HH06X2FOXUQ1P1MOP9FGESU2LHHJ49L79CJEJSGPWJLRR2NHY75BK1NATEQGNNYD4A3IEOJ0P311KT20A6X4ZG1TU4DKEK
got WY8XFBQL8ND0WMVVE1TU409M90YJXC2VMUAD6FSVFUNWD112NPD5ZP389X7SNOIF6D6Z46EY1Z2NBL3I46244MF88NBPGRUIRREXZWZBS5TFI4XMBZXZVIUR2VLYV9FSHBCMWWQ23TNQ8229RKFWX3Q27APKLWCLP80IDVH0NNQU4HJF2DPG3RN1EYH3FGUFHDS2SH34JH34TITEPPA9IB7QWXV7AMEMNXBK5NMF91026XV2BE9FS1PQPW93CUY4QDOUA29KI
FAIL
got WY8XFBQL8ND0WMVVE1TU409M90YJXC2VMUAD6FSVFUNWD112NPD5ZP389X7SNOIF6D6Z46EY1Z2NBL3I46244MF88NBPGRUIRREXZWZBS5TFI4XMBZXZVIUR2VLYV9FSHBCMWWQ23TNQ8229RKFWX3Q27APKLWCLP80IDVH0NNQU4HJF2DPG3RN1EYH3FGUFHDS2SH34JH34TITEPPA9IB7QWXV7AMEMNXBK5NMF91026XV2BE9FS1PQPW93CUY4QDOUA29KI
FAIL
got WY8XFBQL8ND0WMVVE1TU409M90YJXC2VMUAD6FSVFUNWD112NPD5ZP389X7SNOIF6D6Z46EY1Z2NBL3I46244MF88NBPGRUIRREXZWZBS5TFI4XMBZXZVIUR2VLYV9FSHBCMWWQ23TNQ8229RKFWX3Q27APKLWCLP80IDVH0NNQU4HJF2DPG3RN1EYH3FGUFHDS2SH34JH34TITEPPA9IB7QWXV7AMEMNXBK5NMF91026XV2BE9FS1PQPW93CUY4QDOUA29KI
FAIL

From that length onwards, I keep on receiving the previous message...did the Arduino side crash??
If I reset the Arduino side, things are ok again.

This is the python script:

def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for x in range(size))

sys.path.insert(0'/usr/lib/python2.7/bridge/')
from bridgeclient import BridgeClient as bridgeclient
bc = bridgeclient()                          

for x in range(250,300):
 myrand = id_generator(x)
 print "Trying length",x
 print "put", myrand
 bc.put('to_slave',myrand)
 # wait for identical returned message
 while True:
     time.sleep(3)
     r = bc.get('from_slave')
     if r is None:
        print "No answer key found yet"
     else:
        print "got", r
        if r==myrand:
            print "OK"
            break
        else:
            print "FAIL"

This is the sketch:

#include <Bridge.h>

char value[512];

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

void loop() {
  Bridge.get("to_slave",value,512);
  Bridge.put("from_slave",value);
  delay(100);  
}