Page 1 of 1

Access Easylase.dll from Python

Posted: Fri 03 Sep, 2010 3:30 pm
by bambam
Ich versuche, die Easylase-USB-Karte ueber die mitgelieferte .dll von Python unter Windows 7 aus anzusteuern, scheitere aber leider. Die API der Funktion ist so dokumentiert:

Code: Select all

Function EasyLaseWriteFrame(CardNumber:integer, Datapointer:pointer, Byteanzahl:integer, Punktspeed :word):boolean 
Senden eines Laserframes ab @Datapointer an Karte Nummer (CardNumber). Die maximale Framegröße beträgt 16000 Bildpunkte, entprechend 128.000 Bytes. Der Wert Punktspeed enthält die Ausgabegeschwindigkeit in PPS für diesen Frame und reicht von 1000 bis 65535.
CardNumber = 0 - Anzahl Karten 
Byteanzahl = 0 – 1FFFFh 
Punktspeed = 1000 - FFFFh
Rückgabewert = true -> Okay, = false -> USB Fehler.
Hier http://www.laserfreak.net/forum/viewtop ... 1&p=117056 steht, dass das erste Argument (CardNumber) auch ein pointer sein soll. Mein einfachster code sieht also so aus:

Code: Select all

from ctypes import *
elib = CDLL("jmlaser.dll")
cid = c_int(elib.EasyLaseGetCardNum()-1)
frame = create_string_buffer(17)
ok = elib.EasyLaseWriteFrame(byref(cid),frame,hex(16),hex(2500))
Davon kriege ich immer eine exception: access violation reading 0x012F7000 (oder eine andere Adresse). Meine Vermutung ist, das Python den pointer frame nicht richtig uebergiebt. Kann mir da jemand helfen?

Danke schonmal,
Benjamin

Re: Access Easylase.dll from Python

Posted: Fri 03 Sep, 2010 5:35 pm
by gento
Welche Easylase mit welcher *.DLL benutzt Du ?
Gento

Re: Access Easylase.dll from Python

Posted: Sat 04 Sep, 2010 12:24 pm
by bambam
Die .dll hat die VErsionsnummer 2.23.0.0
Die Easylase-Karte ist die erste, ohne Kontrolleuchte und DMX through und so (Versionsnummer finde ich darauf nicht...)

Re: Access Easylase.dll from Python

Posted: Sun 05 Sep, 2010 8:00 pm
by afrob
bambam wrote:

Code: Select all

from ctypes import *
elib = CDLL("jmlaser.dll")
cid = c_int(elib.EasyLaseGetCardNum()-1)
frame = create_string_buffer(17)
ok = elib.EasyLaseWriteFrame(byref(cid),frame,hex(16),hex(2500))
Vielleicht geht's mit stdcall-Aufrufkonvention:

Code: Select all

elib = WINDLL("jmlaser.dll")
Grüsse,
afrob

Re: Access Easylase.dll from Python

Posted: Tue 07 Sep, 2010 10:45 am
by bambam
Hi afrob,

du bist der Beste, mit meinen bescheidenen Kenntnissen waere ich NIE darauf gekommen, 1000 Dank! Es laeuft, alles ist gut.

Hier ein bisschen Code, der sendet ein offendes Rechteck an den Laer (falls mal jemand etwas aehnliches machen will):

Code: Select all

from ctypes import *
from numpy import *
import time
elib = WinDLL("jmlaser.dll")

def dec2bin(val):
    nbits = 16
    basis = 2**(arange(1-nbits,1,dtype=float))
    bin = int8(remainder(floor(val*basis),2))
    return bin

def bin2dec(bin):
    nbits = 8
    basis = 2**arange(0,nbits)[::-1]
    val = chr(sum(bin*basis))
    return val

def makeFrame(Xdata,Ydata,R=0,G=255,B=0,I=255):
    npoints = len(Xdata)
    frameob = c_char*(8*npoints)
    frame = frameob()
    for fid in range(npoints):
        idx0 = fid*8
        binx = dec2bin(Xdata[fid])
        frame.__setitem__(idx0,bin2dec(binx[8::]))
        frame.__setitem__(idx0+1,bin2dec(binx[0:8]))
        biny = dec2bin(Ydata[fid])
        frame.__setitem__(idx0+2,bin2dec(biny[8::]))
        frame.__setitem__(idx0+3,bin2dec(biny[0:8]))
        frame.__setitem__(idx0+4,chr(R))
        frame.__setitem__(idx0+5,chr(G))
        frame.__setitem__(idx0+6,chr(B))
        frame.__setitem__(idx0+7,chr(I))
    return frame

# generate coordinates of an open rectangle
xmax = 2000
Xdata = concatenate((arange(0,xmax,1),ones(xmax)*xmax,arange(xmax,0,-1)))
Ydata = concatenate((ones(xmax)*0,arange(0,xmax,1),ones(xmax)*xmax))
ndata = len(Xdata)

frame = makeFrame(Xdata,Ydata)
speed = 10000
cid = c_int(elib.EasyLaseGetCardNum()-1)
ok = elib.EasyLaseWriteFrame(pointer(cid),pointer(frame),ndata*8,speed)
time.sleep(double(ndata)/speed)
schluss = elib.EasyLaseClose()