picolog current data logger python cod

Which product is right for your exact requirements
atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

picolog current data logger python cod

Post by atnilag »

Hi All,

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.

Roland

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

It would be helpful if you could print out the status response codes for the dll calls, not just the open unit call

Code: Select all

status = mydll.PLCM3SetChannel('AP853/071', 2, 1)
print status
status = mydll.PLCM3GetValue('AP853/071', 2, value)
print status
Not sure on the printing of @ instead of AP
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

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.

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/untitled3.py', wdir=r'C:/WinPython-32bit-2.7.5.3/python-2.7.5/Scripts')
unit accessed
12
12
1 @853/071 0 12
2 @853/071 0 12
3 @853/071 0 12
4 @853/071 0 12
3
5 @853/071 0 12

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

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

Code: Select all

handlePointer = c_short()
mydll = ctypes.windll.LoadLibrary('PLCM3.dll')
status = mydll.PLCM3OpenUnit(byref(handlePointer), 'AP853/071')
if status==0:
print 'unit accessed'
mydll.PLCM3SetChannel(handlePointer, 2, 1)
status = mydll.PLCM3SetChannel(handlePointer, 2, 1)
print status
mydll.PLCM3GetValue(handlePointer, 2, value)
status = mydll.PLCM3GetValue(handlePointer, 2, value)
print status
mydll.PLCM3CloseUnit(handlePointer)
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

Hi Martyn,

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

Roland

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

value status: 37
This means that you have requested data and there is none currently available, the error code is

Code: Select all

#define PICO_NO_SAMPLES_AVAILABLE									0x00000025UL
You may need to add a delay between SetChannel and GetValue calls
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

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

Any ideas?

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

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

Roland

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

You may need something like

Code: Select all

import ctypes
import numpy as np
from ctypes import *
values = np.zeros( (9,), dtype=np.int16)
...
print 'values:',values[0],values[1]
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

Hi Martyn,

i have implemented your last suggestion but it creates an exception

import ctypes
from ctypes import *
from time import *
import ctypes
import numpy as np
from ctypes import *
value = np.zeros( (9,), dtype=np.int16)

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


while i<10:

try:
sleep(1)
status = mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value status:',status
mydll.PLCM3GetValue(handlePointer, 2, value)
print 'values:',values[0]

except:
print 'no value available'
i=i+1



mydll.PLCM3CloseUnit(handlePointer)

exception created:

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


while i<10:

try:
sleep(1)
status = mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value status:',status
mydll.PLCM3GetValue(handlePointer, 2, value)
print 'value:',repr(value.value)

except:
print 'no value available'
i=i+1



mydll.PLCM3CloseUnit(handlePointer)

Returns from the code above:

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'
>>>

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

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
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

Hi Martyn

i have changed the code (see below) but i am still getting exceptions.
i am only using the values in the GetValue calls and nowhere else.

i am sorry to be such a pain.

Roland

import ctypes
from ctypes import *
from time import *
import numpy as np

values = np.zeros( (9,), dtype=np.int16)
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


while i<10:

try:
sleep(1)
status = mydll.PLCM3GetValue(handlePointer, 2, values)
print 'values status:',status
mydll.PLCM3GetValue(handlePointer, 2, values)
print 'values:',values[0],values[1]

except:
print 'no value available'
i=i+1



mydll.PLCM3CloseUnit(handlePointer)

returns from the script:

Martyn
Site Admin
Site Admin
Posts: 4491
Joined: Fri Jun 10, 2011 8:15 am
Location: St. Neots

Re: picolog current data logger python cod

Post by Martyn »

It must be the way the values array is being passed through to the dll, this format worked for someone with the TC08 doing a similar thing

Code: Select all

status = mydll.PLCM3GetValue(handlePointer, 2, values.ctypes.data)
Martyn
Technical Support Manager

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

Hi Martyn,

at long last, the last hint was great, it is working now and i can now build my application.
Thanks for your help.
Roland


My code:
import ctypes
from ctypes import *
from time import *
import numpy as np
intermed2=[]
from ctypes import *
values = np.zeros( (1,), dtype=np.int16)
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
while i<5:
sleep(2)
status = mydll.PLCM3GetValue(handlePointer, 2, values.ctypes.data)
# print 'values status:',status
mydll.PLCM3GetValue(handlePointer, 2, values.ctypes.data)
intermed=int(values)
intermed2.append(intermed)
print intermed2
i=i+1
mydll.PLCM3CloseUnit(handlePointer)

atnilag
Newbie
Posts: 0
Joined: Tue Oct 29, 2013 7:23 pm

Re: picolog current data logger python cod

Post by atnilag »

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

Post Reply