Digitale Eingänge auslesen mit C# und IO-Warrior56

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
ThomasB
Posts: 5
Joined: Wed Feb 23, 2011 10:41 pm

Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by ThomasB »

Hallo zusammen,

seit kurzem bin ich stolzer Besitzer eines IO-Warrior56-Kits. Schnell zusammengelötet, gings auch schon gleich ans Eingemachte. Ich habe leider nicht viel Programmiererfahrung und so hapert es auch schon ziemlich am Anfang. Ich habs mittlerweile hinbekommen, beliebige Ausgänge zu schalten (*STOLZ*), jedoch klappt das Einlesen irgendwie nicht. Mein "Programm" liefert nur Nullen. Vielleicht sei noch erwähnt, dass ich mit C# programmiere. Hier mein Code:

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitOpenDevice();

        [DllImport("iowkit", SetLastError = true)]
        public static extern void IowKitCloseDevice(int iowHandle);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitWrite(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitRead(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitReadNonBlocking(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitGetNumDevs();

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitGetDeviceHandle(int numDevice);

        [DllImport("iowkit", SetLastError = true)]
        public static extern short IowKitGetProductId(int iowHandle);

        [DllImport("iowkit", SetLastError = true)]
        public static extern bool IowKitGetSerialNumber(int iowHandle, ref short serialNumber);

        [DllImport("iowkit", SetLastError = true)]
        public static extern bool IowKitSetTimeout(int iowHandle, int timeout);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitCancelIo(int iowHandle, int numPipe);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitReadImmediate(int iowHandle, int value);

        static void Main(string[] args)
        {
            byte[] empfangen = new byte[8];
            empfangen[0] = 0;
            empfangen[1] = 0;
            empfangen[2] = 0;
            empfangen[3] = 0;
            empfangen[4] = 0;
            empfangen[5] = 0;
            empfangen[6] = 0;
            empfangen[7] = 0;

            int handle = IowKitOpenDevice();

            IowKitReadNonBlocking(handle, 0, ref empfangen[0], 8);

            Console.Write(empfangen[1] + "\t" + empfangen[2] + "\t" + empfangen[3] + "\t" + empfangen[4] + "\t" + empfangen[5] + "\t" + empfangen[6] + "\t" + empfangen[7]);

            IowKitCloseDevice(handle);

            Console.ReadLine();
        }
    }
}
Vielleicht kann einem Anfänger jemand auf die Sprünge helfen. Vielen Dank im Voraus.
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Christoph Jung »

Um auf Nummer sicher zu gehen einfach mal mit der ReportID 0xFF versuchen, denn das liefert den aktuellen Status der IO-Ports wieder. Das ganze läuft als Special-Mode. Am besten mal dazu ins Datenblatt schauen und in die Beschreibung zur DLL, da ist so etwas glaub ich erwähnt. Ansonsten schauts soweit in Ordnung aus. Wird denn beim Lesen an den Ausgängen irgendwas geändert, damit man auch eine Änderung mit bekommt?

Oder es mal mit IowKitRead() versuchen, denn das wartet, bis sich an den Ports was ändert, bzw. bis irgend welche Daten gelesen werden. ReadNonBlocking kommt nämlich sofort zurück. Wäre in diesem kleinen Programm warscheinlich die schnellste Art was zu erreichen. Nicht vergessen den Timeout zu setzten, denn sonst "Hängt" das Programm so lange, bis sich an den Ports was ändert.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
ThomasB
Posts: 5
Joined: Wed Feb 23, 2011 10:41 pm

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by ThomasB »

Hallo ...
vielen Dank für die ersten Tipps. Ich habe jetzt mal das Datenblatt durchforstet und bin bei Punkt 5.10.8 fündig geworden. Damit hört es bei mir aber auch schon auf :-/. Aber das scheint genau die Funtion zu sein, die ich suche. Denn ich wollte bevor ich irgendwelche Ausgänge schalte, erst einmal den Ist-Zustand einlesen.

Ich habe daraufhin folgendes versucht, um die Report-ID zu setzen:

Code: Select all

...
static void Main(string[] args)
        {
            byte[] senden = new byte[8];
            senden[0] = 0xFF;
            senden[1] = 0;
            senden[2] = 0;
            senden[3] = 0;
            senden[4] = 0;
            senden[5] = 0;
            senden[6] = 0;
            senden[7] = 0;

            byte[] empfangen = new byte[8];
            empfangen[0] = 0xFF;
            empfangen[1] = 0;
            empfangen[2] = 0;
            empfangen[3] = 0;
            empfangen[4] = 0;
            empfangen[5] = 0;
            empfangen[6] = 0;
            empfangen[7] = 0;

            int handle = IowKitOpenDevice();

            IowKitWrite(handle, 0, ref senden[0], 8);
            IowKitReadNonBlocking(handle, 0, ref empfangen[0], 8);

            Console.Write(empfangen[1] + "\t" + empfangen[2] + "\t" + empfangen[3] + "\t" + empfangen[4] + "\t" + empfangen[5] + "\t" + empfangen[6] + "\t" + empfangen[7]);

            IowKitCloseDevice(handle);

            Console.ReadLine();
        }
...
Allerding kommen bei mir wieder nur Nullen. Wahrscheinlich habe ich irgendwas falsch gemacht...
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Guido Körber »

Über das Interface 0 können nur Reports ohne ReportID gesendet werden.

Und dann wäre wenn das funktioniert der nächste Fehler, dass die Ports natürlich 0 zurück melden werden wenn sie vorher auf 0 gesetzt werden. Der IO-Warrior liefert auch nicht den Ausgangszustand der Pins, sondern immer den Eingangszustand.

Im ersten Beispiel hat ReadNonBlocking auch keine Chance zu funktionieren. Wenn der IO-Warrior noch keine Zustandsdaten geschickt hat, dann kann ReadNonBlocking auch keine liefern. Und da ja die DLL nur kurz aktiviert wird und gleich wieder geschlossen sind halt keine Daten da.
ThomasB
Posts: 5
Joined: Wed Feb 23, 2011 10:41 pm

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by ThomasB »

Hallo...
ich habe mein Beispiel mal ein wenig abgeändert, damit ich überhaupt irgendwas eingelesen bekomme :-/. Und zwar, wenn man einen oder mehrere Werte bei senden[] ändert und dann das Programm startet, zeigt er tatsächlich die Daten an:

Code: Select all

...
static void Main(string[] args)
        {
            byte[] senden = new byte[8];
            senden[0] = 0;
            senden[1] = 255;
            senden[2] = 255;
            senden[3] = 255;
            senden[4] = 255;
            senden[5] = 255;
            senden[6] = 255;
            senden[7] = 255;

            byte[] empfangen = new byte[8];
            empfangen[0] = 0;
            empfangen[1] = 0;
            empfangen[2] = 0;
            empfangen[3] = 0;
            empfangen[4] = 0;
            empfangen[5] = 0;
            empfangen[6] = 0;
            empfangen[7] = 0;

            int handle = IowKitOpenDevice();

            IowKitWrite(handle, 0, ref senden[0], 8);

            for (int i = 0; i < 5; i++)
            {
                IowKitReadNonBlocking(handle, 0, ref empfangen[0], 8);

                //IowKitWrite(handle, 0, ref senden[0], 8);

                Console.Write(empfangen[1] + "\t" + empfangen[2] + "\t" + empfangen[3] + "\t" + empfangen[4] + "\t" + empfangen[5] + "\t" + empfangen[6] + "\t" + empfangen[7] + "\n");

                System.Threading.Thread.Sleep(500);
            }

            IowKitCloseDevice(handle);

            Console.ReadLine();
        }
...
Allerdings möchte ich ja keine Ausgänge setzten, um sie dann wieder einzulesen, sondern eigentlich möchte ich den Ist-Zustand "auslesen". Ich bin ein wenig verwirrt: Ist das jetzt überhaupt möglich? Wie funktioniert das mit dem Special-Mode und der ReportID 0xFF?

Ich hoffe ihr habt Geduld mit mir :-)
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Guido Körber »

Einfach mal ein IOWkitReadImmediate machen.
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Christoph Jung »

IowKitReadImmediate hat bei dem IOW56 einen Fehler. Darum sollte man dort die Special-Mode mit ID 0xFF nehmen.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Christoph Jung »

Schicken Sie mal bitte das Projekt an jung@codemercs.com. Dann schau ich mal drüber,
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Christoph Jung »

Also das Projekt an sich funktioniert. Und mit ein paar änderungen macht es auch ein wenig mehr sinn.

Code: Select all

            IowKitWrite(handle, 0, ref senden[0], 8);
            IowKitSetTimeout(handle, 500);   //Setzen eine Timeouts für die Read-Funktion

            for (int i = 0; i < 50; i++)

Code: Select all

            for (int i = 0; i < 50; i++)
            {
                IowKitRead(handle, 0, ref empfangen[0], 8); //Read nutzen, damit was passiert, wenn an den Pins sich was ändert

                //IowKitWrite(handle, 0, ref senden[0], 8);
Dazu sollte man wissen:
Wenn man bei so einem Programm nichts von extern an den Pins ändert, also pins auf VCC setzt, sieht man keine Änderungen an den Ports.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Guido Körber »

Zu den Special Mode Functions: Die laufen über das zweite Interface und haben beim IOW56 neben der ReportID noch 63 Byte pro Report. Mit der Function ReportID = $FF kann man den IO-Warrior auffordern seinen aktuellen Pinstatus zu senden.
ThomasB
Posts: 5
Joined: Wed Feb 23, 2011 10:41 pm

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by ThomasB »

Vielen Dank für die Tipps. Allerdings funktioniert das ganze immer noch nicht :-(.

Ich habe das Starterkit des IO-Warrior56 inkl. Taster. Aber egal wie ich den dazugehörigen Jumper setze (auf High oder Low) und egal wie ich den Taster auch drücke, es kommen nur Nullen. Habt ihr vielleicht noch einen Verbesserungsvorschlag?

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitOpenDevice();

        [DllImport("iowkit", SetLastError = true)]
        public static extern void IowKitCloseDevice(int iowHandle);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitWrite(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitRead(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitReadNonBlocking(int iowHandle, int numPipe, ref byte buffer, int length);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitGetNumDevs();

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitGetDeviceHandle(int numDevice);

        [DllImport("iowkit", SetLastError = true)]
        public static extern short IowKitGetProductId(int iowHandle);

        [DllImport("iowkit", SetLastError = true)]
        public static extern bool IowKitGetSerialNumber(int iowHandle, ref short serialNumber);

        [DllImport("iowkit", SetLastError = true)]
        public static extern bool IowKitSetTimeout(int iowHandle, int timeout);

        [DllImport("iowkit", SetLastError = true)]
        public static extern int IowKitCancelIo(int iowHandle, int numPipe);

        static void Main(string[] args)
        {
            byte[] senden = new byte[8];
            senden[0] = 0;
            senden[1] = 0;
            senden[2] = 0;
            senden[3] = 0;
            senden[4] = 0;
            senden[5] = 0;
            senden[6] = 0;
            senden[7] = 0;

            byte[] empfangen = new byte[8];
            empfangen[0] = 0;
            empfangen[1] = 0;
            empfangen[2] = 0;
            empfangen[3] = 0;
            empfangen[4] = 0;
            empfangen[5] = 0;
            empfangen[6] = 0;
            empfangen[7] = 0;

            int handle = IowKitOpenDevice();

            IowKitWrite(handle, 0, ref senden[0], 8);

            IowKitSetTimeout(handle, 500);   //Setzen eine Timeouts für die Read-Funktion

            for (int i = 0; i < 50; i++)
            {
                IowKitRead(handle, 0, ref empfangen[0], 8);

                Console.Write(empfangen[1] + "\t" + empfangen[2] + "\t" + empfangen[3] + "\t" + empfangen[4] + "\t" + empfangen[5] + "\t" + empfangen[6] + "\t" + empfangen[7] + "\n");

                System.Threading.Thread.Sleep(500);
            }

            IowKitCloseDevice(handle);

            Console.ReadLine();
        }
    }
}
@ Guido Körber: Was ist mit "zweites Interface" gemeint?


Vielen Dank sagt Thomas.
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Guido Körber »

Also wenn man alle Pins auf Null setzt muss man sich nicht wundern wenn man auch Null zurück bekommt.

Was das zweite Interface betrifft: Datenblatt Kapitel 5 mal anschauen, da steht auch mehr über das Verhalten der I/O Pins.
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by Christoph Jung »

Code: Select all

       static void Main(string[] args)
        {
            byte[] empfangen = new byte[8];
            empfangen[0] = 0;
            empfangen[1] = 0;
            empfangen[2] = 0;
            empfangen[3] = 0;
            empfangen[4] = 0;
            empfangen[5] = 0;
            empfangen[6] = 0;
            empfangen[7] = 0;

            int handle = IowKitOpenDevice();

            IowKitSetTimeout(handle, 500);

            for (int i = 0; i < 50; i++)
            {
                IowKitRead(handle, 0, ref empfangen[0], 8);

                Console.Write(empfangen[1] + "\t" + empfangen[2] + "\t" + empfangen[3] + "\t" + empfangen[4] + "\t" + empfangen[5] + "\t" + empfangen[6] + "\t" + empfangen[7] + "\n");

                System.Threading.Thread.Sleep(500);
            }

            IowKitCloseDevice(handle);

            Console.ReadLine();
        }
Dieser Code sollte funktionieren um den Taster abzufragen. Hab ich gerade selber getestet und funktioniert.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
ThomasB
Posts: 5
Joined: Wed Feb 23, 2011 10:41 pm

Re: Digitale Eingänge auslesen mit C# und IO-Warrior56

Post by ThomasB »

Vielen Dank nochmal!

Habe, nachdem der letzte Code auch nicht funktioniert hat, mal die komplette Starter-Kit-Schaltung durchgemessen. Und siehe da: es fehlte die Verbindung vom Taster S1 zu GND. Nachdem ich die Leiterbahn weiterverfolgt habe, kam ich zum "LOW-Beinchen" des Jumpers J1. Dieser hat - wie gefordert - Kontakt zu GND. Bei genauerem Hinsehen ist mir dann aufgefallen, dass direkt am Beinchen vom Jumper eine kleine Unterbrechung war ... Lack ein wenig abgekratzt ... übergelötet ... und auf einmal funktioniert das Einlesen des Tasters :-)

Mit der Special-Funktion und dem Kapitel 5 werde ich mich dann die nächsten Tage nochmal beschäftigen.

Mfg
Thomas
Post Reply