eclipse / mraa

Linux Library for low speed IO Communication in C with bindings for C++, Python, Node.js & Java. Supports generic io platforms, as well as Intel Edison, Intel Joule, Raspberry Pi and many more.
http://mraa.io
MIT License
1.37k stars 614 forks source link

Missing Lua bindings #392

Open surfskidude opened 8 years ago

surfskidude commented 8 years ago

Why are there no bindings for Lua?

arfoll commented 8 years ago

It's just waiting for someone to put the time to get SWIG to generate them :) PRs welcome. It's not really something on my roadmap but I'm happy to give you pointers if you need it!

dedok commented 8 years ago

Hi, @arfoll I have started to write SWIG for lua (I need lua for my project). And I have few questions.

my src/lua/mraa.i

%module(docstring="Lua interface to libmraa") mraa

%inline %{
  #include <inttypes.h>
%}

%include typemaps.i
%include carrays.i

%array_class(uint8_t, uint8Array);

%include ../mraa.i

%init %{
    //Adding mraa_init() to the module initialisation process
    if (mraa_init() != MRAA_SUCCESS)
      fprintf(stderr, "Lua Runtime Error: mraa_init() failed.\n");
%}

-- And simple test result (lua/luajit 5.X+)

mraa = require('mraa')
print(mraa.isSubPlatformId(1)) -- false

As I can see, you have typemap(in) in other bindings. Do I need to add this in my mraa.i file? if yes what do this functions means, and how can I test them?

arfoll commented 8 years ago

Cool, look forward to lua bindings 😃. @hbrinj added those for the mraa_init_io binding. He can explain more how they work (I'm on vacation this week and just have my phone...). @hbrinj would be good to have examples!

I'm happy to merge the lua bindings without some functions working bindings don't have to have a 1:1 mapping if some stuff doesn't make sense. Just make sure to document any %ignore in the interface files with good reasons so we don't forget! On 5 Jun 2016 9:40 p.m., "Vasiliy Soshnikov" notifications@github.com wrote:

Hi, @arfoll https://github.com/arfoll I have started to write SWIG for lua (I need lua for my project). And I have few questions.

my src/lua/mraa.i

%module(docstring="Lua interface to libmraa") mraa

%inline %{

include

%}

%include typemaps.i %include carrays.i

%array_class(uint8_t, uint8Array);

%include ../mraa.i

%init %{ //Adding mraa_init() to the module initialisation process if (mraa_init() != MRAA_SUCCESS) fprintf(stderr, "Lua Runtime Error: mraa_init() failed.\n"); %}

-- And simple test result (lua/luajit 5.X+)

mraa = require('mraa')print(mraa.isSubPlatformId(1)) -- false

As I can see, you have typemap(in) in other bindings. Do I need to add this in my mraa.i file? if yes what do this functions means, and how can I test them?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/intel-iot-devkit/mraa/issues/392#issuecomment-223836292, or mute the thread https://github.com/notifications/unsubscribe/AAfZZmsOcv3z5-53kBETh8nATTcp7MURks5qIzQ5gaJpZM4G9V6x .

dedok commented 8 years ago

Thx, @arfoll, so I'll wait for @hbrinj reply then probably I add some fixes and do code cleaning. After that I'll do pull request )

1) How do i properly test lua binding?

dedok commented 8 years ago

List of binded functions

$ luajit pp.lua  | grep function
getPinCount: function: 0x40e25440
getPlatformVersion: function: 0x40e253f0
isSubPlatformId: function: 0x40e27420
setLogLevel: function: 0x40e27380
pinModeTest: function: 0x40e252a0
hasSubPlatform: function: 0x40e273d0
init: function: 0x40e25110
getI2cBusCount: function: 0x40e25490
pwmFromDesc: function: 0x40e277b0
i2cFromDesc: function: 0x40e27760
uartFromDesc: function: 0x40e276c0
printError: function: 0x40e25250
gpioFromDesc: function: 0x40e27620
setPriority: function: 0x40e251b0
addSubplatform: function: 0x40e27578
getDefaultI2cBus: function: 0x40e27528
getVersion: function: 0x40e25160
getSubPlatformId: function: 0x40e27478
getPinName: function: 0x40e27330
getI2cBusId: function: 0x40e254e0
getPlatformName: function: 0x40e25398
adcSupportedBits: function: 0x40e25348
adcRawBits: function: 0x40e252f0
aioFromDesc: function: 0x40e27670
getPlatformType: function: 0x40e25200
removeSubplatform: function: 0x40e275d0
getSubPlatformIndex: function: 0x40e274d0
uint8Array_frompointer: function: 0x40e250c8
spiFromDesc: function: 0x40e27710
  frompointer: function: 0x40e28330
Hbrinj commented 8 years ago

Hi @dedok, to answer your earlier question, the typemap(in) functions in the swig files for certain languages are there to convert a variable type from the swigged languages to the target language. It's entirely possible that you will need some of these typemaps to be able to pass LUA type variables to C++.

You may also find that you will need typemap(out) to convert from the target language to the swigged language.

To answer your second question, do you have any boards you can test with? if you do then try to add LUA to the board and create a simple program to write to GPIO etc. and read from a GPIO as well, If you don't then try to initialise some IO and see if it breaks etc. when for instance you set it's direction.

dedok commented 8 years ago

Hi, @Hbrinj 1) Thx! I started to read SWIG documentation about typemaps. 2) Thx for advice. Board: intel edison w/ many sensors. 'If you don't then try to initialise some IO and see if it breaks etc. when for instance you set it's direction.' Can you provide to me examples? How can I setup such IO on my linux?

Hbrinj commented 8 years ago

@dedok, so, i'm not so sure about the LUA syntax so i'll write this using something high level like python.

import mraa as m

IOout = m.Gpio(5)
IOin = m.Gpio(6)
IOout.dir(m.DIR_OUT)
IOin.dir(m.DIR_IN)

#should be 0
print("read input line it was: " + IOin.read()) 
IOout.write(1)
#should be 1
print("read input line it was: " + IOin.read())

To achieve this above code, and have it fully work, you should be able to short 2 pins on your Edison. in this case pin 5 and 6.

dedok commented 8 years ago

@Hbrinj thx for code. Today I'll try to test lua bindings on device. Also I'll share my results in comments.

Hbrinj commented 8 years ago

@dedok sweet lemme know if you run into any issues with mraa.

dedok commented 8 years ago

@Hbrinj , hmm, why 2 args?

./pp.lua
luajit: ./pp.lua:32: Error in mraa::Gpio::dir expected 2..2 args, got 1
stack traceback:
        [C]: in function 'dir'
        ./pp.lua:32: in main chunk
        [C]: at 0x0804ba20
  SWIG_check_num_args("mraa::Gpio::dir",2,2)                                        
  if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("mraa::Gpio::dir",1,"mraa::Gpio *");   
  if(!lua_isnumber(L,2)) SWIG_fail_arg("mraa::Gpio::dir",2,"mraa::Dir");            

  if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_mraa__Gpio,0))){                                                                                           
    SWIG_fail_ptr("Gpio_dir",1,SWIGTYPE_p_mraa__Gpio);                              
  }   

Second is number - ok (eg dir), first is Gpio object - why? I trying to figure out this behaviour by reading swig lua docs.

dedok commented 8 years ago

I see your test code works

m = require('mraa')
--tprint(mraa)
if m.init() ~= 0 then
  die('mraa.init != 0')
end

IOout = m.Gpio(5)
IOin = m.Gpio(6)
IOout.dir(IOout, m.DIR_OUT)
IOin.dir(IOin, m.DIR_IN)

print("platform type: ", mraa.getPlatformType())

-- should be 0
print("read input line it was: ", IOin.read(IOin)) 
print("write res: ", IOout.write(IOout, 1))

-- should be 1
print("read input line it was: ", IOin.read(IOin))
platform type:  2
read input line it was:         0
write res:      0
read input line it was:         1

Also I want to figure out how to reduce numbers of args. See comment below.

Hbrinj commented 8 years ago

@dedok, Hi dedok, that is odd behaviour, what kind of object does m.Gpio(5) return? that function behaviour is technically only done in c, if the c++ code is wrapped it should handle passing of the IO struct to the dir functions.

Hbrinj commented 8 years ago

@dedok, i was just looking at the lua swig page for c++ classes, can you access the member functions like this in lua syntax:

IOout = m.Gpio(5)
IOout:dir(m.DIR_OUT)
dedok commented 8 years ago

@Hbrinj Thanks. So today I'll start to implement my case. I guess, I'll spend around 1-2 days. Let's say this would be test of new binding :) Parallel I'll improve my current CMakeLists.txt, eg I'll add gen docs, ... After this I'll do pull request.

Hbrinj commented 8 years ago

@dedok So did what I suggested work? And that's perfect thanks.

dedok commented 8 years ago

@Hbrinj In lua code I did not test access to methods by ':'. I made test only for read/write to Gpio, by accessing to the object via '.'. But as I remember in the lua ':' should work, today evening I'll give you more details about ':'.

Hbrinj commented 8 years ago

Typically I think the ':' method of access is preferred as it abstracts away the need to provide the io

dedok commented 8 years ago

@Hbrinj ':' - works aio & giop - works

So, when I'm done with CMake and docs I'll do pull request.

dedok commented 8 years ago

PR: #527