i have just purchased a picolog current data logger and want to write an application in python.
i have got some basic code:
import ctypes
value=0
i=0
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
mydll.PLCM3CloseUnit('AP853/071')
status = mydll.PLCM3OpenUnit('AP853/071', 0)
if status==0:
print 'unit accessed'
mydll.PLCM3SetChannel('AP853/071', 2, 1)
mydll.PLCM3GetValue('AP853/071', 2, value)
print status
while i<5:
i=i+1
print i,'AP853/071',value,status
else:
print 'bollocks not working'
mydll.PLCM3CloseUnit('AP853/071')
status = mydll.PLCM3OpenUnit('AP853/071', 0)
print status[/quote][/quote]
the output of the code is as follows:
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
unit accessed
0
1 @853/071 0 0
2 @853/071 0 0
3 @853/071 0 0
4 @853/071 0 0
5 @853/071 0 0
3
it seems as if it is accessing the unit as it reports a status 0, also i can't access it through pico recorder while the python script is opening the unit.
firstly im confused why it is printing @ instead of AP, secondly it is not getting any values back from the logger, is this perhaps due to a mismatch of data types between python and the C dll?
in any case i would be most grateful if somebody could help.
Hi Martyn
i have changed the code as follows:
import ctypes
value=0
i=0
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
mydll.PLCM3CloseUnit('AP853/071')
status = mydll.PLCM3OpenUnit('AP853/071', 0)
if status==0:
print 'unit accessed'
mydll.PLCM3SetChannel('AP853/071', 2, 1)
status = mydll.PLCM3SetChannel('AP853/071', 2, 1)
print status
mydll.PLCM3GetValue('AP853/071', 2, value)
status = mydll.PLCM3GetValue('AP853/071', 2, value)
print status
while i<5:
i=i+1
print i,'AP853/071',value,status
else:
print '******** not working'
mydll.PLCM3CloseUnit('AP853/071')
status = mydll.PLCM3OpenUnit('AP853/071', 0)
print status
and i now get the following back:
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Sorry I didn't look closely at what you were doing, python is not one of my usual langauges. You need to have a handle which gets assigned by the open unit call and is then used by all other calls. Something like
thanks for the quick reply, i have now changed my code to the following:
import ctypes
from ctypes import *
value=0
handlePointer = c_short()
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
status = mydll.PLCM3OpenUnit(byref(handlePointer), 'AP853/071')
print 'open unit status:',status
if status==0:
mydll.PLCM3SetChannel(handlePointer, 2, 1)
status = mydll.PLCM3SetChannel(handlePointer, 2, 1)
print 'set channel status:',status
mydll.PLCM3GetValue(handlePointer, 2, value)
status = mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value status:',status
print 'value:',value
mydll.PLCM3CloseUnit(handlePointer)
and get the following reply:
>>> Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Imported NumPy 1.7.1, SciPy 0.12.0, Matplotlib 1.3.0 + guidata 1.6.1, guiqwt 2.3.1
Type "scientific" for more details.
>>> runfile('C:/WinPython-32bit-2.7.5.3/python-2.7.5/Scripts/untitled5.py', wdir=r'C:/WinPython-32bit-2.7.5.3/python-2.7.5/Scripts')
open unit status: 0
set channel status: 0
value status: 37
value: 0
>>>
so from what i gather this tells me that it opens the unit ok, sets the channel ok but something is not correct with the value?
BTW before i added from ctypes import * my ide complained about the byref statement
Hi Martyn,
i really appreachiate your help in this, i have started coding in pythen about a year ago an this is the first time i have come across accessing external hardware.
i have added a 5 second sleep command between setting the channel and requesting the data but as a result i am getting an access violation.
my code is:
import ctypes
from ctypes import *
from time import *
value=0
i=0
handlePointer = c_short()
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
status = mydll.PLCM3OpenUnit(byref(handlePointer), 'AP853/071')
print 'open unit status:',status
if status==0:
mydll.PLCM3SetChannel(handlePointer,2, 1)
status = mydll.PLCM3SetChannel(handlePointer, 2, 1)
print 'set channel status:',status
sleep(5)
status = mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value status:',status
mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value:',value
mydll.PLCM3CloseUnit(handlePointer)
the error message is:
Traceback (most recent call last):
File "C:/WinPython-32bit-2.7.5.3/rk/pico1", line 16
status = mydll.PLCM3GetValue(handlePointer, 2, value)
WindowsError: exception: access violation writing 0x00000000
Hi Martyn,
i think the problem might be with the definition of my value variable, i have defined it as an integer, but i think the dll wants to return an array. but I am not sure how to resolve this.
thanks
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
open unit status: 0
set channel status: 0
no value available
no value available
no value available
no value available
no value available
no value available
no value available
no value available
no value available
no value available
>>>
however the following code returns something, that is why i think it has something to do with the buffering:
import ctypes
from ctypes import *
from time import *
value = ctypes.create_string_buffer(10)
current=''
i=0
handlePointer = c_short()
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
status = mydll.PLCM3OpenUnit(byref(handlePointer), 'AP853/071')
print 'open unit status:',status
if status==0:
mydll.PLCM3SetChannel(handlePointer,2, 1)
status = mydll.PLCM3SetChannel(handlePointer, 2, 1)
print 'set channel status:',status
open unit status: 0
set channel status: 0
value status: 37
value: ''
value status: 0
value: '\xfd'
value status: 0
value: '\x02\x01'
value status: 0
value: '\xf9'
value status: 0
value: ''
value status: 0
value: '\xfa'
value status: 0
value: '\xfe'
value status: 0
value: '\xff'
value status: 0
value: '\xfa'
value status: 0
value: '\xfa'
>>>
You are mixing value and values through the code which is why there is an exception, check through that everything is the same and using values in the GetValue calls
Hi Martyn
Now that this is working, is there a way to do the same on a Linux box?
As the dll is a windows dll, I can't see how this can work, or am I wrong
Roland