Seite 1 von 1

Access Easylase.dll from Python

Verfasst: Fr 03 Sep, 2010 3:30 pm
von 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: Alles auswählen

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: Alles auswählen

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

Verfasst: Fr 03 Sep, 2010 5:35 pm
von gento
Welche Easylase mit welcher *.DLL benutzt Du ?
Gento

Re: Access Easylase.dll from Python

Verfasst: Sa 04 Sep, 2010 12:24 pm
von 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

Verfasst: So 05 Sep, 2010 8:00 pm
von afrob
bambam hat geschrieben:

Code: Alles auswählen

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: Alles auswählen

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

Re: Access Easylase.dll from Python

Verfasst: Di 07 Sep, 2010 10:45 am
von 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: Alles auswählen

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()