ich möche über den PC ewtas steuern, sprich nur ein I/O Modul.
Gibt es so etwas?
SetOutput(1)
SetOutput(2)
....
SetOutput(16)
GetInput(1)
...
GetInput(16)
Ereignisorientiert -- Event, wenn der Eingang sich ändert.
Welcher Anbieter bietet so etwas an?
www.stahl.de ?
www.beckhoff.de ?
www.icp-deutschland.de
www.janz.de
Man wird etwas erschlagen, ich tue mr schwer was gut und einfach
ist...?
Anzusteuern mit C# oder mit C++ VS2005/2008
Habt Ihr Erfahrungen? Könnt Ihr was empfehlen?
Grüße Andrea
> ich möche über den PC ewtas steuern, sprich nur ein I/O Modul.
Wenn Du etwas kaufst, ist dort i.d.R. auch eine DLL/OCX dabei, mit dem
Du auch unter C# diese Dinge ansteuern kannst...
--
Greetings
Jochen
My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Allerdings nicht für HighSpeedOperations. Da es sich hier um eine
dezentrale -Steuerung
handelt , spricht man von Aktuatuere (Module auf der Hutschiene) auf dem
Bus.(tcp-packet = ~5-10ms laufzeit)
In zweiter Linie gibt es NationalInstruments www.natinst.com hier kannst du
alles bestellen
wenn denn der Geldbeutel fett genug ist, dafür gibt es dann HighTech auf PCI
II Karten ohne Limits.
Willst du nur mal so was Schalten, ist Conrad dein Freund. Hier bekommst du
IO/Boards
für 100 Euronen. www.conrad.de
Ansonnsten gibt es dort auch die alte CentronicRelais -Karte die kommt am
Druckerport.
Leider kann man ab Win XP nicht mehr ohne Umwege direkt auf die SerialBits
und ParBits zugreifen.
Also so oder so frage des Geldbeutels.
Es bleibt natürlich der Fotoempfindliche Transistor den man auf den
Bildschirm Klebt :-)
grüße
Karsten Schulz
Hast zufällig Beispiele parat?
Gruß, Andrea
Die Conrad -Karten kenne ich nur aus dem Katalog, wie auch immer sie gartet
sind
man kann sie in einem Thread auslesen, und Stati oder Events generieren.
Man könnte davon ausgehen das auch diese viel Software dabei haben.
Einfach Karte aussuchen und Bezeichnung im Google posten dann gibt es
sicherlich mehr Details.
>http://sine.ni.com/nifn/cds/view/comp/p/sn/n24:USB,n25:8854,n4:7692/lang/de/nid/1036/ap/daq/sd/50d9c3e020c84010VgnVCM100000940aa482RCRD
>Hast zufällig Beispiele parat?
Natinst liefert DLLs für seine Karten dort kannst du
dir die Daten auch autonom in den Speicher schreiben lassen.
Ich hatte von NatInst den CVI Compiler mit dem konnte man in
standard 'C' die Karten via DMA auslesen.
Hier 2 Quellteile von Ni bezüglich einiger IO/s auslesen, die haben aber
aber auch massig ActivX und Com Controls um nur noch wenig mit der
eigentlichen Materie umgehen zu müssen..
Die sind ja Marktführer und lassen Dich nicht allein.
grüße
Karsten Schulz
/*********************************************************************
*
* Example program:
* AI1Pt.c
*
* Description:
* Read one channel, one point at a time, immediately
*
* Example Category:
* AI
*
* Example Task Types:
* 1PT, 1CH, IMMED
*
* List of key parameters:
* iChan
*
* [Since variables are hardcoded, there is no guarantee that this
* program will work for your setup. This example is simply
* presented as a code snippet of how you can use NI-DAQ functions
* to perform a task.]
*
* List of NI-DAQ Functions used in this example:
* AI_VRead, NIDAQErrorHandler
*
* [NOTE: For further details on each NI-DAQ function, please refer
* to the NI-DAQ On-Line Help (NIDAQPC.HLP).]
*
* Pin Connection Information:
* Connect your analog signal to AI channel 1. The default analog
* input mode for the DAQ device will be used.
*
* [For further I/O connection details, please refer to your hardware
* User Manual.]
*
* [For further details on how to run this example, please refer to
* the NI-DAQ Examples On-Line Help (NIDAQEx.HLP).]
*
*********************************************************************/
/*
* Includes:
*/
#include "nidaqex.h"
/*
* Main:
*/
void main(void)
{
/*
* Local Variable Declarations:
*/
i16 iStatus = 0;
i16 iRetVal = 0;
i16 iDevice = 1;
i16 iChan = 1;
i16 iGain = 1;
f64 dVoltage = 0.0;
i16 iIgnoreWarning = 0;
iStatus = AI_VRead(iDevice, iChan, iGain, &dVoltage);
iRetVal = NIDAQErrorHandler(iStatus, "AI_VRead", iIgnoreWarning);
if (iStatus == 0) {
printf(" The voltage at AI channel %d is %lf volts.\n", iChan,
dVoltage);
}
}
/* End of program */
/*********************************************************************
*
* Example program:
* DAQexScn.c
*
* Description:
* Read a waveform from two analog input channels using external scan
* interval timing but with internal sample timing (uses low-level
* NI-DAQ functions)
*
* Example Category:
* AI
*
* Example Task Types:
* BUF, NCH, BURST, EXTTIM, ASYNC, INTTRIG
*
* List of key parameters:
* iExtScan, iScanTB, uScanInt
*
* [Since variables are hardcoded, there is no guarantee that this
* program will work for your setup. This example is simply
* presented as a code snippet of how you can use NI-DAQ functions
* to perform a task.]
*
* List of NI-DAQ Functions used in this example:
* DAQ_Config, NIDAQErrorHandler, DAQ_Rate, SCAN_Setup, SCAN_Start,
* DAQ_Check, NIDAQYield, SCAN_Demux, DAQ_VScale, DAQ_Clear,
* NIDAQPlotWaveform
*
* [NOTE: For further details on each NI-DAQ function, please refer
* to the NI-DAQ On-Line Help (NIDAQPC.HLP).]
*
* Pin Connection Information:
* Connect your analog signals to AI channels 1 and 2. The default
* analog input mode for the DAQ device will be used. Also, connect
* a digital pulse train to the 'external scan clock' pin. (NOTE:
* This is NOT the pin labelled "SCANCLK" but instead is a counter
* output pin.)
*
* [For further I/O connection details, please refer to your hardware
* User Manual.]
*
* [For further details on how to run this example, please refer to
* the NI-DAQ Examples On-Line Help (NIDAQEx.HLP).]
*
*********************************************************************/
/*
* Includes:
*/
#include "nidaqex.h"
/*
* Main:
*/
void main(void)
{
/*
* Local Variable Declarations:
*/
i16 iStatus = 0;
i16 iRetVal = 0;
i16 iDevice = 1;
i16 iChan = 1;
i16 iStartTrig = 0;
i16 iExtScan = 2;
i16 iGain = 1;
f64 dSampRate = 1000.0;
u32 ulCount = 200;
f64 dGainAdjust = 1.0;
f64 dOffset = 0.0;
i16 iUnits = 0;
i16 iSampTB = 0;
u16 uSampInt = 0;
i16 iScanTB = 0;
u16 uScanInt = 0;
static i16 piBuffer[200] = {0};
static f64 pdVoltBuffer[200] = {0.0};
i16 iDAQstopped = 0;
u32 ulRetrieved = 0;
i16 iNumChans = 2;
static i16 piChanVect[2] = {1, 2};
static i16 piGainVect[2] = {1, 1};
i16 iIgnoreWarning = 0;
i16 iYieldON = 1;
/* Setup for external scan timing with iExtScan = 2. */
iStatus = DAQ_Config(iDevice, iStartTrig, iExtScan);
iRetVal = NIDAQErrorHandler(iStatus, "DAQ_Config",
iIgnoreWarning);
/* Convert sample rate (S/sec) to appropriate timebase and sample
interval values. (NOT scan interval values) */
iStatus = DAQ_Rate(dSampRate, iUnits, &iSampTB, &uSampInt);
iStatus = SCAN_Setup(iDevice, iNumChans, piChanVect, piGainVect);
iRetVal = NIDAQErrorHandler(iStatus, "SCAN_Setup",
iIgnoreWarning);
/* Acquire data from a single channel */
iStatus = SCAN_Start(iDevice, piBuffer, ulCount, iSampTB,
uSampInt, iScanTB, uScanInt);
iRetVal = NIDAQErrorHandler(iStatus, "SCAN_Start",
iIgnoreWarning);
printf(" Apply your external scan timing pulses to the 'external scan
clock' pin.\n");
while ((iDAQstopped != 1) && (iStatus == 0)) {
/* Loop until all acquisition is complete. HINT: You can be
doing other foreground tasks during this time. */
iStatus = DAQ_Check(iDevice, &iDAQstopped, &ulRetrieved);
iRetVal = NIDAQYield(iYieldON);
}
iRetVal = NIDAQErrorHandler(iStatus, "DAQ_Check", iIgnoreWarning);
iStatus = SCAN_Demux(piBuffer, ulCount, iNumChans, 0);
iRetVal = NIDAQErrorHandler(iStatus, "SCAN_Demux",
iIgnoreWarning);
iStatus = DAQ_VScale(iDevice, iChan, iGain, dGainAdjust, dOffset,
ulCount, piBuffer, pdVoltBuffer);
iRetVal = NIDAQErrorHandler(iStatus, "DAQ_VScale",
iIgnoreWarning);
/* CLEANUP - Don't check for errors on purpose. */
/* Set scan timing back to initial state. */
iStatus = DAQ_Config(iDevice, 0, 0);
iStatus = DAQ_Clear(iDevice);
printf(" The plot shows Channel 1 data then Channel 2 data.\n");
/* Plot acquired data */
iRetVal = NIDAQPlotWaveform(pdVoltBuffer, ulCount, WFM_DATA_F64);
}
/* End of program */
Um Events / Signale mußt
----- Original Message -----
From: "Andrea Müller" <post...@arcor.de>
Newsgroups: microsoft.public.de.vc
Wie schnell mußt du auf ein Event reagieren ?
Denn das ist ausschlaggebend.
Jimmy
Andrea Müller schrieb:
Suche halt ein konkretes Beispiel.
Grüße Andrea
Hallo,
Bei einer solch kleiner Zeit wirst du unter Windows ein Problem haben.
(Ist nicht Echtzeitfähig, aus mit einer entsprechenden Erweiterung.)
Für solche Fälle würde ich entweder einen einfachen µController
verwenden (Conrad, ...)
Habe selbst mal den R8C von Renesas ausprobiert. Für kleine Sachen
vollkommen ausreichend.)
Oder wenn man mehr Daten / Geschwindigkeit / Echtzeitfähigkeit machen will,
dann ist es besser gleich eine kleine SPS zu verwenden.
Da gibt es auch eine Menge hersteller.
Sigmatek, Beckhoff, ... ich glaube auch bei Conrad Elektronik gibt es
eine kleine SPS,
bin aber nicht sicher.
Jimmy
http://www.keithley.com/products/dataacqmodules/usbmodules?mn=KUSB-3100
KUSB-3100
es gibt zum einen NI (www.ni.com), die sind arber ziemlich teuer. Nur wenn
es unbedingt sein muss.
Ich empfehle dir die Produkte von Meilhaus http://www.meilhaus.de/
Empfehlen kann ich dir die LabJack-Komponenten von Meilhaus. Mit dem
LabJackU12 habe ich selbst schon gearbeitet, dieser funktioniert sehr gut
und die Schnittstelle ist sehr einfach.
Kommt ganz darauf an, was für Anforderungen du hast. Einfach etwas
rumstöbern, dort findest du auf jeden Fall was.
Viele Grüße
Karsten
"Andrea Müller" <post...@arcor.de> schrieb im Newsbeitrag
news:6d5dd371-5704-4b36...@x41g2000hsb.googlegroups.com...
"Andrea Müller" <post...@arcor.de> schrieb im Newsbeitrag
news:ebdd85b9-cce0-4641...@b1g2000hsg.googlegroups.com...
Hallo,
>
> Wie schnell mußt du auf ein Event reagieren ?
> Denn das ist ausschlaggebend.
Ich würde sagen kleiner gleich 10ms
http://www.beckhoff.ru/default.asp?twincat/twincat_io.htm
Schau doch mal ob du mit einem speziellen Hardware-Timer zurecht kommst den
bekommst du unter http://www.kithara.de/ge/home.php
kostet halt ein bischen was.
NI (www.ni.com) stellt Echtzeithardware zur Verfügung, vielleicht gibt es
bei denen was, das du brauchen kannst.
Bei NI kannst du anrufen, die helfen dir in der Regel recht gut weiter.
Viele Grüße
Karsten
Suche halt ein konkretes Beispiel für
- C++,MFC
- C#
VS2005/2008 .NET
Hast Du eins?
Grüße Andrea
du hast Angst vor den Interface Überraschungen die diese Dinge mit sich
bringen,
kauf einfach die Karte die deinen Anforderungen entspricht, das Auslesen ist
nicht das Problem,
da haben sich die Leute um den Kartenhersteller schon gekümmert.
Für NI habe ich ja schon ein Example gepostet. Das Wago Header
um das Mobus protokolls ist unten anzusehen.
Vorneweg ein Listing -ausschnitt wie mans ausließt, mit einer guten
Netzwerkkarte
und ner guten Leitung beides für 100Euro habbar, kann man latenzen um die
4ms
erreichen, je nach dem wie man wann wieviel ausließt.
grüße
Karsten Schulz
CWago::CWago(void)
{
m_handle = 0;
}
CWago::~CWago(void)
{
}
void CWago::Delete(void)
{
for(LstBlk::iterator it = m_blklst.begin(); it != m_blklst.end(); it++)
(*it).Delete();
if(m_handle)
::MBTDisconnect(m_handle);
::MBTExit();
}
// "191.168.2.151",502
bool CWago::Create(CString IpStr, int IpPort)
{
if(::MBTInit() == S_OK)
if(::MBTConnect( IpStr, IpPort,true,1000, &m_handle ) != S_OK )
return false;
return true;
}
bool CWago::Add(WagoType Type, int Adress)
{
if(!m_handle)
return false;
m_blklst.push_back(CWagoBlk(Type,m_handle,Adress));
return true;
}
CWagoBlk *CWago::GetBlock(int Block)
{
if(Block >= m_blklst.size())
return 0;
return &m_blklst[Block];
}
bool CWago::GetVal(int Block, int Slot, float &Value)
{
if(Block >= m_blklst.size())
return false;
return m_blklst[Block].GetVal(Slot,Value);
}
bool CWago::PutVal(int Block, int Slot, float Val)
{
if(Block >= m_blklst.size())
return 0;
return m_blklst[Block].PutVal(Slot,Val);
}
//-----------------------------------------------------------------------------
//
|
// WAGO Kontakttechnik GmbH
|
// Hansastr.27
|
// 32423 Minden
|
//
|
// Copyright (C) WAGO FROM 2001
|
// All Rights Reserved
|
//
|
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// OPC TOOLBOX Project - WAGO MODBUS/TCP
|
//
|
// Filename : MBT.h
|
// Version : 1.00.release
|
// Date : 29-Oktober-2001
|
//
|
// Description : Interface of MODBUS/TCP DLL
|
//
|
//-----------------------------------------------------------------------------
#ifndef _MBT_H_
#define _MBT_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define MODBUSTCP_TABLE_OUTPUT_REGISTER 4
#define MODBUSTCP_TABLE_INPUT_REGISTER 3
#define MODBUSTCP_TABLE_OUTPUT_COIL 0
#define MODBUSTCP_TABLE_INPUT_COIL 1
#define MODBUSTCP_TABLE_EXCEPTION_STATUS 7
//-----------------------------------------------------------------------------
// Type Definitions
|
//-----------------------------------------------------------------------------
typedef void (WINAPI *MBTReadCompleted)(
IN HANDLE hSocket, // socket handle
IN DWORD callbackContext, // callback context, handed over at the call
IN LONG errorCode, // result of the read operation
IN BYTE tableType, // type of MODBUS/TCP
tables(MODBUSTCP_TABLE_xxx)
IN WORD dataStartAddress, // start address of the registers or coils to
be
// read
IN WORD numRead, // number of the registers or coils to be read
IN WORD numBytes, // number of the bytes to be read
IN LPBYTE pReadBuffer // memory section with the data to be written
);
typedef void (WINAPI *MBTWriteCompleted)(
IN HANDLE hSocket, // socket handle
IN DWORD callbackContext, // callback context, handed over at the call
IN LONG errorCode, // result of the write operation
IN BYTE tableType, // type of MODBUS/TCP
tables(MODBUSTCP_TABLE_xxx)
// output registers or output coils
IN WORD dataStartAddress, // start address of the registers or coils to
be
// written
IN WORD numWrite, // number of the registers or coils to be
written
IN LPBYTE pWriteBuffer // memory section with the data to be written
);
//-----------------------------------------------------------------------------
// Prototypes
|
//-----------------------------------------------------------------------------
// initializes the MODBUS/TCP library
LONG WINAPI MBTInit();
// terminates the MODBUS/TCP library
LONG WINAPI MBTExit();
// creates a socket and connects it to the given device port
LONG WINAPI MBTConnect(
IN LPCTSTR szHostAddress, // TCP/IP address of device
IN WORD port, // TCP port in device for communication
IN BOOL useTCPorUDP, // TRUE - TCP; FALSE - UDP
IN DWORD requestTimeout, // maximal time for managing an I/O request
(ms)
OUT HANDLE *hSocket // handle of the connected socket
);
// aborts the connection to a device and releases the socket
LONG WINAPI MBTDisconnect(
IN HANDLE hSocket // handle of the connected socket
);
// read from a connected socket
LONG WINAPI MBTReadRegisters(
IN HANDLE hSocket, // handle of the connected socket
IN BYTE tableType, // Modbus/TCP Tabellen Typ
(MODBUSTCP_TABLE_xxx)
// (here: input register or output register
IN WORD dataStartAddress, // start address of the registers to be read
IN WORD numWords, // number of the registers to be read
OUT LPBYTE pReadBuffer, // memory section from which the data are read
// (NULL at asynchronous call)
OPTIONAL IN MBTReadCompleted fpReadCompletedCallback = NULL,
// C-callback function, called after
termination
// of asynchronous reading (NULL at synchronous
// call)
OPTIONAL IN DWORD callbackContext = 0
// context, handed over to the asynchronous
// (callback function (0 at synchronous call)
);
// write to a connected socket
LONG WINAPI MBTWriteRegisters(
IN HANDLE hSocket, // handle of the connected socket
IN WORD dataStartAddress, // start address of the registers to be
written
IN WORD numWords, // number of the registers to be written
IN LPBYTE pWriteBuffer, // memory section from which the data are
written
// (NULL at asynchronous call)
OPTIONAL IN MBTWriteCompleted fpWriteCompletedCallback = NULL,
// C-callback function, called after
termination
// of asynchronous writing (NULL at synchronous
// call)
OPTIONAL IN DWORD callbackContext = 0
// context, handed over to the asynchronous
// (callback function (0 at synchronous call)
);
// read from a connected socket
LONG WINAPI MBTReadCoils(
IN HANDLE hSocket, // handle of the connected socket
IN BYTE tableType, // Modbus/TCP Tabellen Typ
(MODBUSTCP_TABLE_xxx)
// (here: input coil or output coil
IN WORD dataStartAddress, // start address of the coils to be read
IN WORD numBits, // number of the coils to be read
OUT LPBYTE pReadBuffer, // memory section from which the data are
read
// (NULL at asynchronous call)
OPTIONAL IN MBTReadCompleted fpReadCompletedCallback = NULL,
// C-callback function, called after
termination
// of asynchronous reading (NULL at synchronous
// call)
OPTIONAL IN DWORD callbackContext = 0
// context, handed over to the asynchronous
// (callback function (0 at synchronous call)
);
// write to a connected socket
LONG WINAPI MBTWriteCoils(
IN HANDLE hSocket, // handle of the connected socket
IN WORD dataStartAddress, // start address of the coils to be written
IN WORD numBits, // number of the coils to be written
IN LPBYTE pWriteBuffer, // memory section from which the data are
written
// (NULL at asynchronous call)
OPTIONAL IN MBTWriteCompleted fpWriteCompletedCallback = NULL,
// C-callback function, called after
termination
// of asynchronous writing (NULL at synchronous
// call)
OPTIONAL IN DWORD callbackContext = 0
// context, handed over to the asynchronous
// (callback function (0 at synchronous call)
);
// read from a connected socket
LONG WINAPI MBTReadExceptionStatus(
IN HANDLE hSocket, // handle of the connected socket
OUT LPBYTE pExceptionStatus,
// memory section from which the data are read
// (NULL at asynchronous call)
OPTIONAL IN MBTReadCompleted fpReadCompletedCallback = NULL,
// C-callback function, called after
termination
// of asynchronous reading (NULL at synchronous
// call)
OPTIONAL IN DWORD callbackContext = 0
// context, handed over to the asynchronous
// (callback function (0 at synchronous call)
);
WORD WINAPI MBTSwapWord(const WORD wData);
DWORD WINAPI MBTSwapDWord(const DWORD dwData);
#ifdef __cplusplus
}
#endif
#endif
"Andrea Müller" <post...@arcor.de> schrieb im Newsbeitrag
news:35670eae-d0e8-4b16...@a22g2000hsc.googlegroups.com...
4ms ?
Wie soll das unter Windows sicher funktionieren ?
Ist doch kein Echtzeit.
Jimmy
5ms Das ist die Laufzeit für das TCP Paket, da hat die Echtzeit nichts mit
zu tun,
wenn du bei der Auslesung Excel/Word startest hast du halt Verzögerungen.
Unter Windows kannst du in 10ms immer reagieren, wenn der Rechner nicht
mit Spam zugemüllt ist. Wo soll das Problem sein? Echtzeit -reaktionen gibt
es nirgens.
Latenzen weit unter 5ms zb. im TTL Pegelbereich(100µs und weit weniger)
könnte man
mit einr embedded CPU einhalten. Unter Windows tun wir dies mit wie auch
immer
gearteten zweit/klein Computer zb. einer WagoKlemme, sie ist TTL Schnell,
benötigt halt
für den Datentransport über Ethernet mehr Zeit, als über RS485(Profibus) via
DMA like
NI hast Du die Daten schneller im Ram als deine Zeitscheibe je einen neuen
Schlitz erreicht.
Echtzeit gibt es nirgendwo, es gibt Intervalle in denen reagiert werden
kann, und wenn
ein Thread unter windows läuft, und kein Mist zusätzlich, reagiert das
locker unterhalb
von 5-10ms, das kannst du an jedem Oszi ausprobieren.
Willst du automatische regel Antworten mit Zeitfenstern die genau sind,
brauchst du
ein Echtzeitmeßsystem , das liefern nur Microcontroler. zb. ne SPS oder der
RTX Kernel unter Windows in Verbindung mit der den HiTech -Boxen von
www.aerotech.com . Mit denen erreiche ich reaktionen im 10ns Bereich in
verbindung mit Fahrbewegungen und Linescancameras unter Windows, wobei
Win nur noch als Auftraggeber eine Rolle spielt.
grüße
Karsten Schulz
"Johann Obermayr" <Johann....@sigmatek.at> schrieb im Newsbeitrag
news:uGImelsn...@TK2MSFTNGP03.phx.gbl...
>
> 4ms ?
> Wie soll das unter Windows sicher funktionieren ?
> Ist doch kein Echtzeit.
Du musst nur tief genug im System eingreifen, z.B. mit einem Timer bzw.
Treiber von Kithara.
http://www.kithara.de/ge/custom_driver.php
Viele Grüße
Karsten
>Suche halt ein konkretes Beispiel für
>
> - C++,MFC
> - C#
> VS2005/2008 .NET
>
>Hast Du eins?
>
> Grüße Andrea
Ich verstehe deine Sorgen, aber da brauchst du dir, wie mein Namenskollege
Karsten Schulz schon geschrieben hat, kein keine Sorgen machen. Die
Schnittstellen sind nicht schwer zu verstehen.
Wenn du den LabJack U12 als Beispiel verwendest findest du unter folgendem
Link den Treiber, Dokumentation und Cod-Beispiele.
Bei dem Softwarepaket sind Beispiele dabei, die kannst du dir anschauen.
http://www.labjack.com/labjack_u12_downloads.php
Viele Grüße
Karsten
ich möchte halt nicht selber alle Eingänge pollen, das soll die
Komponente machen.
Sonst habe ich evt. wieder Threadprobleme etc.
Kann mir jemand sagen, konkret wie ich
-Ausgänge setze
-Eingänge auslese
-Event Zustandsänderungen der Eingange abfragen kann.
SetOutput(1)
SetOutput(2)
....
SetOutput(16)
GetInput(1)
...
GetInput(16)
Ereignisorientiert -- Event, wenn der Eingang sich ändert.
Ich habe eine Karte 16 Ausgänge, 16 Eingänge
Oder sehe ich das flasch, was ich brauche?
Das sieht alles so kompliziert aus.
Eine einfache funktionsbasierte Schnittstelle, mehr will ich nicht.
http://www.kithara.de/ge/custom_driver.php
Die Plattformen scheint ja zu gehen
C#
C++
Wie macht man es mit www.kithara.de ?
Viele Grüße Andrea
##############################################################################
IoPort Module
Wie können die vom PCI-Plug&Play dynamisch zugewiesenen Ressourcen
ermittelt werden?
entweder mit 'KS_getBusData': Iterieren über alle im System
befindlichen PCI-Geräte, bis anhand der Parameter (Vendor-Id, Device-
Id, etc.) das gesuchte Gerät gefunden wurde
oder mit 'KS_getResourceInfoEx': Übergabe der Parameter des gesuchten
Gerätes und Auswertung der beschreibende Datenstruktur
mit 'KS_getResourceInfo' lassen sich auch die Daten anderer
Schnittstellen ermitteln, z.B. serielle ("COM") oder parallele ("LPT")
Schnittstellen, Netzwerkkarten ("NET") für das Packet Module sowie USB-
Geräte ("USB")
Wenn der direkte I/O-Port-Zugriff genutzt werden soll, ist zunächst
der I/O-Bereich für den Direktzugriff freizuschalten:
err = KS_enableIoRange(
myBaseAddress, // Basisadresse der Hardware
8, // Anzahl der I/O-Register
KSF_SIZE_8_BIT); // Flags, hier byte-weiseNun können
die freigegebenen Hardware-Register direkt adressiert werden:
byte value = KS_inpb(
myBaseAddress + 2); // Adresse, 1 Byte lesen
... // Byte auswerten
KS_outpb(
myBaseAddress + 4, // Adresse, 1 Byte schreiben
value); // Byte schreibenWenn die I/O-
Basisadresse einer PCI-Karte vom Plug&Play-Manager dynamisch vergeben
wurde, kann diese ganz leicht ermittelt werden, indem entweder alle
PCI-Baugruppen durchsucht werden, bis die gewünschte (anhand Vendor-
und Device-ID) gefunden wird:
err = KS_getBusData(
&pciData, // Adresse der PCI-Struktur
busNumber, // Bus-Nummer
slotNumber, // Gerätenummer und Funktion
0); // Flags, hier 0
if (pciData.vendorID == XXXX && pciData.deviceID == YYYY)
...Oder es wird sofort die gewünschte ID-Kombination gesucht:
err = KS_getRessourceInfo(
"PCI\\VENxxxx&DEVyyyy", // ID-Kombination
&resourceInfo); // Adresse der Resourcen-InfoDie
erhaltenen Datenstrukturen enthalten nun die benötigten Angaben über
Interrupt-Leitung und benutzte I/O- oder Speicher-Basisadressen.
Plattformen
Echtzeitfähigkeit wird nur auf der Kernel-Ebene erzielt. Dazu werden C/
C++ oder Delphi (Win32) benö… [mehr…]
Echtzeitfähigkeit wird nur auf der Kernel-Ebene erzielt. Dazu werden C/
C++ oder Delphi (Win32) benötigt. Dennoch unterstützt die »RealTime
Suite« verschiedene Plattformen, wie z.B. auch die .NET-Umgebung:
C++Builder (Borland/CodeGear) mit VCL-Oberfläche
Microsoft Visual C++ 6 mit MFC-Oberfläche
Visual Studio 2005 C++ mit MFC-Oberfläche
Delphi (Object Pascal) Win32 mit VCL-Oberfläche
Visual Studio 2005 C# mit WPF-Oberfläche
Die Lösung besteht darin, den zeitkritischen Code in eine DLL zu
verlagern, die mit den Funktionen der »RealTime Suite« direkt auf die
Kernel-Ebene geladen wird und dadurch in den Echtzeit-Kontext gelangt.
Sofort verwendbare Programmgerüste für die genannten Plattformen
befinden sich in jeder Software-Lieferung.
Das habe ich angeschaut.
Visual C++ OCX: A user-submitted simple example of a Visual C++
windows program that calls functions from the LabJack U12 OCX. If the
program does not run, you probably have a different version of the OCX
than us, and need to re-import it in VC by going to Projects=>Add To
Project=>Components and Controls=>Registered ActiveX
Controls=>Ljackuwx Control. 12/6/2002, 37 KB
*----------------------------------------------------------*
'* Name : BitSet *
'*----------------------------------------------------------*
'* Purpose : Sets a given Bit in Number *
'*----------------------------------------------------------*
Public Function BitSet(Number As Long, _
ByVal Bit As Long) As Long
If Bit = 31 Then
Number = &H80000000 Or Number
Else
Number = (2 ^ Bit) Or Number
End If
BitSet = Number
End Function
Kannst Du mal ein Beispiel geben?
SetOutput(1)
SetOutput(2)
....
SetOutput(16)
GetInput(1)
...
GetInput(16)
Ereignisorientiert -- Event
Mehr will ich nicht ;-)
Zum Schluß noch evtl. eine Übersicht wie ich am besten Eingänge
abfrage
0000 0000 1100 1111
1111 1111 1111 1111
mit XOR, OR, AND
! | &
Operatoren
Viele Grüße
Andrea
>ich möchte halt nicht selber alle Eingänge pollen, das soll die
>Komponente machen.
>Sonst habe ich evt. wieder Threadprobleme etc.
Kann ich verstehen, da musst du schauen was die Beispiele hergeben.
Threadprobleme sind übel, aber durch eine saubere Programmierung sollte das
kein Problem sein. Threads sind eigentlich was alltägliches (vorallem in der
Messtechnik).
>Kann mir jemand sagen, konkret wie ich
>-Ausgänge setze
>-Eingänge auslese
>-Event Zustandsänderungen der Eingange abfragen kann.
Das kommt darauf an welche Hardware du verwendetst, aber das liest du im
Handbuch nach. Z.B. bei dem LabJack U12 im Handbuch das du runterladen
kannst, ist das ganz gut beschrieben.
>SetOutput(1)
>SetOutput(2)
>....
>SetOutput(16)
>GetInput(1)
>...
>GetInput(16)
>Ereignisorientiert -- Event, wenn der Eingang sich ändert.
Kommt auch auf die Hardware an, zur Not selbst programmieren.
>Ich habe eine Karte 16 Ausgänge, 16 Eingänge
Welche Karte hast du denn ?
>Oder sehe ich das flasch, was ich brauche?
>Das sieht alles so kompliziert aus.
>Eine einfache funktionsbasierte Schnittstelle, mehr will ich nicht.
Was du brauchst musst du wissen, je nachdem was du für Anforderungen du
hast.
Das ist nicht kompliziert, einfach die Lesen- oder Schreiben-Funktion
aufrufen mit den entsprechenden Parametern.
Wenn zu an einem Eingang pollen musst, dann kannst du einen winzigen Thread
machen der einen Event oder Windows-Message schickt, wenn sich der Wert
geändert hat. An der Stelle wo du den Wert brauchst wartest du halt drauf.
Die API, die du meistens mit den Karten bekommst ist schon sehr einfach !
Einfacher geht es meist nicht mehr !
>http://www.kithara.de/ge/custom_driver.php
>Die Plattformen scheint ja zu gehen
>
>C#
>C++
>
>
>Wie macht man es mit www.kithara.de ?
Du musst du nun wirklich das Handbuch lesen und das ein oder andere Beispiel
anschauen. Ich selbst habe es noch nicht ausprobiert.
Viele Grüße
Karsten
ich glaube du brauchst nicht das OCX, du kannst die DLL und die Lib
(ljackuw.lib) mit dem Header (ljackuw.h) verwenden.
hier einige Beispiele auf Basis des LabJack U12:
Da gibt es zwei verschiedene Arten von digitalen Kanälen IO und D. Siehe
Handbuch.
Verwaltet habe ich meine Kanäle aber in einer Variablen. Genauso die States.
Daher die Bit-Schieberei.
// Schreiben aller Digitalen Kanäle
// Parameter: lChannels - Kanäle auf die geschrieben werden soll
// lStates - Zustand der Kanäle
void LJU12::WriteDigiChannels(long lChannels, long lStates)
{
long lRet = 0, lTrisD = 0, lTrisIO = 0, lStateD = 0, lStateIO = 0, lDummy =
0;
lTrisIO = lChannels & 0x0000000F;
lChannels = lChannels >> 4;
lTrisD = lChannels & 0x0000FFFF;
lStateIO = lStates & 0x0000000F;
lStates = lStates >> 4;
lStateD = lStates & 0x0000FFFF;
lRet = DigitalIO(&m_lID,0,&lTrisD,lTrisIO,&lStateD,&lStateIO,1,&lDummy);
//alternativ kannst du auch EDigitalOut verwenden da werden die
digitalen Kanäle einzeln gesetzt.
return lRet;
}
// Lesen aller Digitalen Kanäle
// Parameter: lChannels - Kanäle von denen gelesen werden soll
// *lStates - Zustand der Kanäle
long LJU12::ReadDigiChannels(long lChannels, long *lStates)
{
long lRet = 0, lTrisD = 0, lTrisIO = 0, lStateD = 0, lStateIO = 0, lDummy =
0;
long lCh = 0;
lCh = lChannels;
lTrisIO = lChannels & 0x0000000F;
lCh = lCh >> 4;
lTrisD = lCh & 0x0000FFFF;
lRet = DigitalIO(&m_lID,0,&lTrisD,lTrisIO,&lStateD,&lStateIO,1,&lDummy);
*lStates = lStateD & 0x0000FFFF;
*lStates = *lStates << 4;
lStateIO = lStateIO & 0x0000000F;
*lStates = *lStates | lStateIO;
return lRet;
}
Der Fantasie sind keine Grenzen gesetzt, je nachdem wie dein Wrapper auf die
Schnittstelle aussieht !
viele Grüße
Karsten