Exchange data with a external Linux-Library

Hello,

i have problems with getting back data from a library-call to PIGPIO-Library and i2cReadDevice.
Library: The pigpio library

I also downloaded and want to use this:
A Xojo library for pigpio features in Raspberry Pi projects:

The library itself works and simple calls (only with uinteger and not with ByRef) works fine.

But when i try to exchange data (referenced with ByRef) it is not working:

Declaration:

Method Name: i2cReadDevice
Parameters: i2chandle as uinteger, byref value as ptr, count as uinteger
Return-Type: Integer
Scope: Protected

Code:

Dim DebugString As String
Dim i As Integer
Dim r As Integer
Dim Handle As Integer
Dim DataBuffer As New MemoryBlock(256)
Dim DataBufferPtr As ptr = DataBuffer

' Open I2CDevice
Handle=PIGPIO.i2cOpen(1,8)

' Read data from I2C-Device
If Handle >=0 Then
  r = pigpio.i2cReadDevice(Handle, DataBufferPtr, 11)
  DebugString= "R="+Str(r)+" "
End If

' Close Device
r=PIGPIO.i2cClose(Handle)

' Display result on GUI
For i=0 To 10
   DebugString=DebugString+Str(DataBuffer.Byte(i))+" "
Next i

MainWindow.Label1.Text=DebugString 

But problem: The DebugString contains only 256 times a null (0x00h), even i get back correct “r-value” and the operation on I2C-bus is executed correctly. When i do a debug (remote-debug) and stop after the call, the MemoryBlock contains also 256 bytes of 0x00h
I think i make a mistake with pointer, it’s not clear to me how to use correctly.

Can anyone help me?

@Marco Bungalski — i2cReadDevice can change the value of the Ptr passed ByRef, i.e. DataBufferPtr in this case. You must use the returned value and not the buffer (DataBuffer) that you allocated (which is why you always end up with 256 times null).

Hello Stphane,

can you give me an example how to do this (how to access the returned bytes), please?

@Marco Bungalski — Sure. This should work:

[code]Dim DebugString As String
Dim i, r, Handle As Integer
Dim DataBuffer As New MemoryBlock(256) //It may also work with" Dim DataBuffer as MemoryBlock". It depends on pigpio

Handle=PIGPIO.i2cOpen(1,8)

If Handle >=0 Then
r = pigpio.i2cReadDevice(Handle, DataBuffer, 11)
DebugString= “R=”+Str®+" "

r=PIGPIO.i2cClose(Handle)

if DataBuffer<>nil then
For i=0 To 10
DebugString=DebugString+Str(DataBuffer.Byte(i))+" "
Next I
end if

MainWindow.Label1.Text=DebugString
Else
//Display error
End if [/code]

The problem with your code is that you dereferenced (you should Google that to see how common this mistake is) DataBuffer, i.e. you copied its Ptr to DataBufferPtr. As a consequence, if DataBuffer changes its Ptr, DataBufferPtr still holds the old value. Unfortunately, the way MemoryBlocks are converted to Ptr in Xojo does not make it very obvious.

Hello Stphane,

i changed it but i get an error during compiling of line

r = pigpio.i2cReadDevice(Handle, DataBuffer, 11)

Steuerung.Lese_AEingaenge, line 26
Parameter “value” expects type Ptr, but this is class MemoryBlock.
r = pigpio.i2cReadDevice(Handle, DataBuffer, 11)

@Marco Bungalski — OK, so this should work:

[code]Dim DebugString As String
Dim i, r, Handle As Integer
Dim DataBuffer As New MemoryBlock(256) //It may also work with" Dim DataBuffer as MemoryBlock". It depends on pigpio
Dim DataBufferPtr as Ptr = DataBuffer //<<<ADDED

Handle=PIGPIO.i2cOpen(1,8)

If Handle >=0 Then
r = pigpio.i2cReadDevice(Handle, DataBufferPtr, 11)
DataBuffer = dataBufferPtr //<<<ADDED
DebugString= “R=”+Str®+" "

r=PIGPIO.i2cClose(Handle)

if DataBuffer<>nil then
For i=0 To 10
DebugString=DebugString+Str(DataBuffer.Byte(i))+" "
Next I
end if

MainWindow.Label1.Text=DebugString
Else
//Display error
End if[/code]

Still not working.

I tried

[code]’ *****************************
’ * Lesen der Analog-Eingnge *
’ *****************************
Dim DebugString As String
Dim i As Integer
Dim r As Integer
Dim Handle As Integer
Dim DataBuffer As MemoryBlock
Dim DataBufferPtr As ptr = DataBuffer

’ Open I2CDevice
Handle=PIGPIO.i2cOpen(1,8)

If Handle >=0 Then
r = pigpio.i2cReadDevice(Handle, DataBufferPtr, 11)
DataBuffer = dataBufferPtr
DebugString= “R=”+Str®+" "
End If

’ Close Device
r=PIGPIO.i2cClose(Handle)

If DataBuffer<>Nil Then
For i=0 To 10
DebugString=DebugString+Str(DataBuffer.Byte(i))+" "
Next i
End If

MainWindow.Label1.Text=DebugString

[/code]

and also with

Dim DataBuffer As new MemoryBlock(256)[/code] instead of [code]Dim DataBuffer As MemoryBlock

With Dim DataBuffer As MemoryBlock the App hangs with “Event loop” and with Dim DataBuffer As new MemoryBlock(256) the App terminats with sigHandler: Unhandled signal 11, terminating when the line DebugString=DebugString+Str(DataBuffer.Byte(i))+" " is executed.

But DataBuffer is not Nil, so maybe thats the right way :wink:

@Marco Bungalski — OK. Do you have a link to the PIGPIO’s documentation on how to use i2cReadDevice?

Yes, both links are in my first post.
I also checked and see, that the size of DataBuffer is -1.

@Marco Bungalski — OK so the actual function is defined as

int i2cReadDevice(unsigned handle, char *buf, unsigned count)

so it should be declared in Xojo-pigpio as

i2cReadDevice( handle as integer, buf as Ptr, count as integer) as integer 

There should be no ByRef involved. So it should eventually be:

[code]’ *****************************
’ * Lesen der Analog-Eingänge *
’ *****************************
Dim DebugString As String
Dim i As Integer
Dim r As Integer
Dim Handle As Integer
Dim DataBuffer As New MemoryBlock( 256 ) //<<< Create an empty buffer
Dim DataBufferPtr As ptr = DataBuffer

’ Open I2CDevice
Handle=PIGPIO.i2cOpen(1,8)

If Handle >=0 Then
r = pigpio.i2cReadDevice(Handle, DataBufferPtr, 11) //DataBuffer should work too as it is no longer a ByRef argument
DebugString= “R=”+Str®+" "
End If

’ Close Device
r=PIGPIO.i2cClose(Handle)

DebugString=DebugString+DataBuffer.StringValue( 0, 11 )

MainWindow.Label1.Text=DebugString[/code]

Stphane - Thanks a lot for quick answer and patience. Now it is working!
I only wonder, why in this XoJo lib from Ulrich Bogun the methods are different declared…

But no matter, finally this code works fine:

Declaration:

Method Name: i2cReadDevice Parameters: i2chandle as uinteger, value as ptr, count as uinteger Return Type: Integer Lib: libpigpio.so Soft: Yes Objective-C: No

Code:

[code]Dim DebugString As String
Dim i As Integer
Dim r As Integer
Dim Handle As Integer
Dim DataBuffer As New MemoryBlock(256)
Dim DataBufferPtr As ptr = DataBuffer

’ Open I2CDevice
Handle=PIGPIO.i2cOpen(1,8)

If Handle >=0 Then
r = pigpio.i2cReadDevice(Handle, DataBufferPtr, 11)
DebugString= “R=”+Str®+" "
End If

’ Close Device
r=PIGPIO.i2cClose(Handle)

For i=0 To 10
DebugString=DebugString+Str(DataBuffer.Byte(i))+" "
Next i

MainWindow.Label1.Text=DebugString
[/code]

Marco

@Marco Bungalski — Glad it finally works.

That’s a bug in the library. You should let Ulrich Bogun know about that so he can fix it.