Is ⎕NA faster than ⎕SH/⎕CMD?
I am writing code for my Raspberry Pi robot to read a HMC5883L 3 axis compass.
The HMC5883L is attached to the Pi as an I2C device.
There is a lot of Python code around to read this compass on a Pi.
Ideally, my APL code would read:
Code: Select all
Start_Turning
:While target<⎕SH 'python Get_Bearing.py'
:EndWhile
Stop_Turning
However, during the time it takes to get a reading via Python, the robot can have turned thru 5 or more degrees. This makes getting the robot to accurately turn to a desired direction (+/-0.5 degree) very difficult. So I end up with
Code: Select all
:While target<⎕SH 'python Get_Bearing.py'
Start_Turning
⎕DL 0.02
Stop_Turning
:EndWhile
This works but produces very jerky movements.
(The 0.02 delay is the smallest time period that my robot can cope with while still overcoming friction and producing an actual movement. Less than that, it stutters but does not actually turn.)
So I have cobbled together some C code (from code obtained on the internet) that is much faster. This call itself makes use of some I2C C library calls.
Currently, my compiled C code outputs the compass bearing to stdout. Thus I can make a fast compass reading via a simple ⎕SH call.
Code: Select all
Start_Turning
:While target<⎕SH 'Get_Bearing_viaC'
:EndWhile
Stop_Turning
Using this, the overshoot is limited to less than 2 degrees
(With more complex APL control code, I can now achieve +/- 0.7 degrees of my target.)
Would there be any great speed advantage in compiling the C code into a "shared object" (the Linux equivalent of a DLL) and then using ⎕NA to make the call instead?
(You might well be saying "Try it and test which is faster!".
Well I have, but my C programming skills have so far only resulted in a module that ⎕NA rejects, stating that it can't be dynamically loaded.)
If a ⎕NA call is going to be significantly faster than effectively the same C code via a ⎕SH call, then I will perceiver in producing a shared object library.
Possibly a more APL solution (with no need of any C compiling) would be to call the I2C library modules (the ones my C code already uses) directly from APL via multiple ⎕NA calls. (⎕NA calls to "Initialization" would be done outside of the "while" loop, with only the ⎕NA calls to take a reading, done inside.)
Has anyone had any experience in accessing the I2C "registers" directly from APL?
(Via ⎕ARBIN on /dev/i2c-1 possibly?)
Any suggestions gratefully received.
Happy New Year!
Ray Cannon