Angewandte Informationstechnologie IO­Projekte mit der USB­Schnittstelle Einführung in die Elektronik Dr. Leander Brandl 2009 it.brgkepler.at ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Inhalt 1 1.1 1.2 1.3 1.4 1.5 2 2.1 2.2 2.3 2.4 2.5 2.6 Die USB­Schnittstelle...............................................................................................................................3 Kommunikation zwischen Computern und USB­Geräten................................................................................3 Verbindung zwischen USB­Geräten............................................................................................................ 3 Steckverbindungen..................................................................................................................................3 Serielle Übertragung................................................................................................................................4 Selbstbau von Schaltungen mit einer USB­Schnittstelle................................................................................ 5 Der IO­Warrior........................................................................................................................................6 Funktionsumfang und Eigenschaften.......................................................................................................... 6 Anschlussbelegung.................................................................................................................................. 7 Grundschaltung...................................................................................................................................... 8 Bauplan und Materialliste......................................................................................................................... 8 Erstellung eigener Software für den IO­Warrior..........................................................................................10 Anwendung 1 ­ Erste Verbindung mit dem IO­Warrior ­ IOW_Verbindung...................................................... 10 3 Einlesen von Schaltzuständen................................................................................................................. 13 3.1 Prinzip einer Halbleiterdiode....................................................................................................................13 3.2 Grundschaltung zum Schutz der Eingänge................................................................................................ 13 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 2 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 1 Die USB­Schnittstelle 1.1 Kommunikation zwischen Computern und USB­Geräten Der USB (Universal Serial Bus) ist ein Bus mit nur einem Master, von dem alle Aktivitäten ausgehen. Der Master (Computer) kann Daten zu einem USB­Gerät senden oder Daten von einem solchen anfordern. Kein USB­Gerät kann Daten von sich aus an den Master oder andere USB­Geräte absenden! 1.2 Verbindung zwischen USB­Geräten Die Verbindung zwischen dem Master und einem USB­Gerät erfolgt durch ein 4­poliges, geschirmtes Kabel. Darin befinden sich zwei Leitungen für die Spannungsversorgung (Vcc +5V und GND) und zwei Datenleitungen (Data+ und Data­). Die beiden Datenleitungen sind verdrillt um eingestrahlte Störungen weitestgehend zu eliminieren. In der folgenden Abbildung ist der Aufbau einer USB­Kabelverbindung grafisch dargestellt: Vcc +5V Data ­ Data + GND Schirm Abbildung 1.2.1 ­ Aufbau einer USB­Kabelverbindung 1.3 Steckverbindungen Für die Verbindung von USB­Geräten kommen genormte Steckverbindungen zum Einsatz. Diese sind verpolungs­ und vertauschungssicher gestaltet. Es wird zwischen zwei unterschiedlichen Bauarten unterschieden: in Richtung eines Hostcontrollers (meist der USB­ Anschluss eines Computers) werden Stecker mit der Bezeichnung Typ­A verwendet, verbundene Geräte werden mit einem Stecker der Bezeichnung Typ­B angeschlossen. 4 3 2 1 1 Stecker Typ­A 1 2 4 3 2 Data ­ (WEISS) 3 4 Buchse Typ­A 2 1 3 4 Buchse Typ­B Stecker Typ­B 1 Vcc +5V (ROT) 2 3 Data + (GRÜN) 4 GND (SCHWARZ) Abbildung 1.3.1 ­ Typen und Anschlussbelegung von USB­Steckern und Buchsen Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 3 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 1.4 Serielle Übertragung Datenpakete Daten werden in Paketen zu 8 Bytes oder bis zu 256 Bytes versandt und empfangen. Der gesamte Datenverkehr erfolgt in einem Rahmen von exakt einer Millisekunde. Innerhalb eines Rahmens können Datenpakete für mehrere Geräte verarbeitet werden. Datenpaket Datenpaket Datenpaket 1 ms Abbildung 1.4.1 ­ Datenpakete bei der Datenübertragung über den Universal Serial Bus Lowspeed­ und Highspeed­Übertragung Die übertragenen Datenpakete können als Lowspeed­ oder Fullspeed­Signale übertragen werden. Die Datenrate bei einer Lowspeed­Verbindung beträgt 1,5 MBit/s ­ daraus ergibt sich die Länge für ein Bit von 666,7 ns. Bei einer Fullspeed­Verbindung erhält man eine Datenrate von 12 MBit/s, woraus sich eine Länge von 83,33 ns für ein Bit ergibt. Schnittstellen nach dem USB 2.0­Standard bieten weiters eine Highspeed­Verbindung mit 480 MBit/s an. Spannung U Data + + 3,3 V 0V 666,7 ns Zeit t Data ­ Spannung U Data + + 3,3 V 0V 83,33 ns Zeit t Data ­ Abbildung 1.4.2 ­ Datensignale einer Lowspeed­ und einer Fullspeed­Verbindung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 4 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Datenübertragung über das USB­Protokoll Im Gegensatz zu früher verwendeten Schnittstellen werden die Daten nicht mehr direkt über die Schnittstellenelektronik an das angeschlossene Gerät übermittelt, sondern mit Hilfe eines speziellen Protokolls übertragen. Dazu wird beim Sender (Computer), wie auch beim Empfänger (z. B. Drucker) ein Mikroprozessor benötigt, der die zu übertragenden Daten "einpackt" und nach der Übertragung wieder "auspackt". Dies macht es nicht möglich, entsprechende Baugruppen, wie Relais, Leuchtdioden, ... direkt über eine Steuerleitung mit einem Computer zu verbinden, wie dies zum Beispiel bei der parallelen Schnittstelle der Fall war. Auf der Seite eines USB­Geräts ist zunächst immer ein Decoder von Nöten, der die übermittelten Daten rückübersetzt und die daraus resultierenden elektrischen Signale der weiteren Elektronik zur Verfügung stellt. Data + Dokument, das in einem Programm erstellt wurde Daten 0100010101 Daten 0100010101 USB­PROTOKOLL USB Sender Data ­ Steuerelektronik für Motoren und Druckdüsen USB Empfänger Abbildung 1.4.3 ­ Datenübertragung über das USB­Protokoll 1.5 Selbstbau von Schaltungen mit einer USB­Schnittstelle Für den Selbstbau von elektronischen Schaltungen, die man in Verbindung mit einem Computer betreiben möchte, stellt diese Art der Signalübertragung eine große Hürde dar. Möchte man eigene Schaltungen realisieren, die man über die USB­Schnittstelle an einen Computer anschließen möchte, könnte man Mikroprozessoren verwenden, die bereits über USB­Anschlüsse verfügen ­ z. B. PIC16C745 oder PIC16C765 der Firma Microchip. Neben dem Aufbau der zusätzlich benötigten Elektronik für den Empfänger­Teil ist in diesen Mikrocontrollern auch noch entsprechende Software zu implementieren, die das USB­Protokoll interpretieren kann, die übertragenen Daten aus diesem ausliest und für die angeschlossene Elektronik aufbereitet. Der IO­Warrior der Firma Code Mercenaries Eine sehr interessante und kompfortable Lösung stellen die von der Firma Code Mercenaries hergestellten Bauteile mit der Bezeichnung IO­Warrior dar. Bei diesen handelt es sich um Mikrocontroller, die bereits vorprogrammiert sind und auf denen die Software zur Auswertung des USB­Protokolls bereits implementiert ist. Ein weiteres großes Plus dieser Mikrocontroller ist, das für den Betrieb dieser USB­Bauteile auf dem jeweiligen Computer keine Treiber installiert werden müssen und diese direkt von der erstellten Applikation heraus angesprochen werden können. Ohne über Administrations­Rechte zu verfügen um Treiber installieren zu können, lassen sich selbst entwickelte Schaltungen umgehend in Betrieb nehmen. Weiter Informationen zu diesen Mikrocontrollern sind unter folgender Adresse zu finden: www.codemercs.com Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 5 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 2. Der IO­Warrior Einfache Bauteile wie Relais oder Schalter an einen Computer anschließen? Dies ist seit dem seriellen und parallelen Schnittstellen alles andere als einfach. Als Standard für die Verbindung zu hat sich der USB (Universal Serial Bus) durchgesetzt. Diesen für einfache Selbstbau­Projekte zu großen Aufwand dar und setzt umfangreiches Wissen in der Programmierung von Mikrocontrollern sich der eigentlichen Aufgabe ­ der selbstgebauten IO­Schaltung ­ zuwenden kann. Verschwinden von externer Hardware nutzen stellt einen voraus, bevor man USB­zu­Seriell­ oder USB­zu­Parallel­Adapter stellen auch keine gute Alternative dar, da diese meist über Treiber in das System als virtuelle Geräte eingebunden werden und nicht direkt über die entsprechenden Hardware­Adressen angesprochen werden können, wie es bei einer "echten" seriellen oder parallelen Schnittstelle der Fall war. Vor einigen Jahren hat die Firma Code Mercenaries als Lösung all dieser Probleme vorprogrammierte Mikrocontroller mit der Bezeichnung IOWarrior auf den Markt gebracht. Diese sind in drei unterschiedlichen Varianten mit unterschiedlichem Funktionsumfang erhältlich: IOWarrior24, IOWarrior40 und IOWarrior56 Nicht zuletzt stellen diese Bauteile eine gute Variante für den Selbstbau von elektronischen Schaltungen aufgrund der traditionellen Bauform dar in der diese erhältlich sind. Durch die Miniaturisierung und industrielle Fertigung von Leiterplatten sind die meisten Mikrocontroller mit USB­Schnittstelle nur in SMD­Bauform erhältlich, was den Einsatz bei Selbstbau­Schaltungen ­ zum Beispiel auf Lochrasterplatinen ­ so gut wie unmöglich macht. Betrieb ohne die Installation von Treibern Werden die IOWarrior über die USB­Schnittstelle an einen Computer angeschlossen, so können diese ohne die Installation von Software­Treibern in Betrieb genommen werden. Diese Mikrocontroller melden sich am Betriebssystem als HID (Human Interface Device ­ z. B. Tastatur oder Joystick) an ­ die entsprechenden Treiber sind bereits standardmäßig in allen Betriebssystemen vorhanden. Einfache Implementierung bei der Programmierung eigener Anwendungen Begleitend zu der Software, die auf den Mikrocontrollern installiert ist, bietet Code Mercenaries eine Funktionsbibliothek (iowkit.dll) an, die Funktionen für die Ansteuerung der IO­Warrior­Chips zur Verfügung stellt und in allen gängigen Entwicklungsumgebungen mit den Programmiersprachen C++, Delphi, VisualBasic oder C# verwendet werden kann. Weiters wurde bei der Entwicklung auf die Betriebssystem­Unabhängigkeit geachtet und so stehen diese Funktionsbibliothek, wie einige Programmierbeispiele auch für MacOS und Linux zur Verfügung. Testanwendung ­ AllInOne Zum Testen eigener Schaltungen steht ein frei erhältliches Progamm zur Verfügung, das den vollen Funktionsumfang aller drei Varianten des IOWarriors unterstützt. Dieses steht unter folgender Adresse zum Donwload bereit: www.greinert­dud.de Abbildung 2.0.1 ­ Screenshot der Testanwendung AllInOne 2.1 Funktionsumfang und Eigenschaften Bei den hier vorgestellten Projekten kommt der IOWarrior24 zum Einsatz. Dieser besitzt 16 als Ein­ oder Ausgang programmierbare Pins und benötigt in der Grundschaltung nur drei zusätzliche Bauteile um in Betrieb genommen zu werden. Hier der Funktionsumfang des IOWarrior24: ­ 16 Ein­ oder Ausgänge mit 125Hz Leserate ­ Stromversorgung bis 500mA aus dem USB ­ vollständig implementiertes USB­Protokoll ­ keine Treiberinstallation erforderlich ­ Funktionsbibliothek für einfache Integration in eigene Software Detaillierte Informationen, Datenblätter und Programmierbeispiele werden unter folgender Adresse zum Download zur Verfügung gestellt: www.codemercs.com Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 6 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 2.2 Anschlussbelegung Der IOWarrior24 wird in einem 24­poligen Gehäuse mit der Bezeichnung DIL24 ausgeliefert. Die Nummerierung der Pins eines solchen Bausteins beginnt in der Draufsicht links neben der Einkerbung und setzt sich gegen den Uhrzeigersinn bis zum letzten Pin fort (siehe Darstellung). Ein­ und Ausgänge Deutlich erkennbar sind die 16 Pins, die als Ein­ oder Ausgang konfiguriert werden können. Diese sind zu zwei Ports (Port 0 und Port 1) zusammengefasst, von denen jeder 8 Bits umfasst, welche den 8 Pins eines Ports entsprechen (Port 0.0 ­ Port 0.7). USB­Anschluss Die vier Leitungen des USB können direkt an den IO­Warrior angeschlossen werden: Pin 14 ­ Vcc +5V (rot), Pin 9 ­ GND (schwarz), Pin 15 ­ Data ­ (weiß) und Pin 16 ­ Data + (grün). Pull To GND Pin 10 wird nur bei der Programmierung des Microcontrollers benötigt und ist im laufenden Betrieb auf GND zu legen ­ er ist auf kürzestem Weg mit Pin 9 zu verbinden. Vreg Pin 11 stellt eine regulierte Spannung von 3V zur Verfügung. Diese wird benötigt um den PullUp­Widerstand der Datenleitung Data ­ (weiß) mit Spannung zu versorgen (siehe 2.3 Grundschaltung). Power Mit Hilfe von Pin 12 wird festgelegt, ob es sich bei diesem USB­Gerät um ein LowPower­ oder um ein HighPower­Gerät handelt. Meldet sich dieses Gerät am USB­Anschluss eines Computers an, so wird dabei festgelegt, wie viel Strom dieses von der USB­Schittstelle des Computers maximal entnehmen darf. Wird dieser Pin mit +5V verbunden (Zustand HIGH), so meldet sich der IO­Warrior als HighPower­Gerät an und darf bis zu 500mA an Strom aus der USB­Schnittstelle entnehmen. Setzt man diesen Pin auf den Zustand LOW (Verbindung mit GND), so wird der IOWarrior als LowPower­Gerät erkannt, was bedeutet, dass maximal 100mA aus der USB­Schnittstelle entnommen werden dürfen! Abbildung 2.2.1 ­ Anschlussbelegung und Bauform des IO­Warrior24 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 7 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 2.3 Grundschaltung Um den IOWarrior24 in Betrieb zu nehmen, muss dieser mit nur drei externen Bauteilen beschaltet werden. Zum Verhindern undefinierter Zustände wird die Datenleitung Data ­ (weiß) über einen sogennanten PullUp­Widerstand mit dem Pin Vreg verbunden, der eine Spannung von 3V liefert. Die Kondensatoren dienen dazu um vom IOWarrior24 erzeugte Störungen abzufangen. Da elektronische Bauteile dieser Art die unangenehme Eigenschaft haben bei Schaltvorgängen hohe Stromspitzen zu ziehen, muss die Versorgungsspannung gut entkoppelt werden. Wird dies nicht gemacht, so kann es zur Abstrahlung von Störungen oder zu Funktionsstörungen des IOWarrior24 kommen. C1 100nF 14 Vcc J1 USB 1 +5V 2 D­ 3 D+ 4 GND IO­WARRIOR24 12 Power 11 Vreg R1 1,3kΩ 15 D­ 16 D+ 13 NC PullToGND 10 P P P P P P P P 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 P P P P P P P P 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 GND C2 10μF 1 2 3 4 24 23 22 21 5 20 6 19 7 18 8 17 9 Abbildung 2.3.1 ­ Schaltplan für die Grundschaltung des IOWarrior24 2.4 Bauplan und Materialliste Der Aufbau der hier vorgestellten Schaltungen erfolgt auf einer Lochrasterplatine. Für den Anschluss an einen Computer kommt eine USB­Buchse Typ­B zum Einsatz. Der IOWarrior24 wird nicht direkt auf der Platine verlötet, sondern nach Fertigstellung der Lötarbeiten in einen Sockel eingesetzt. Materialliste: ­ 1 Lochrasterplatine 10cm x 16cm ­ 1 IC­Sockel 24­polig ­ 1 USB­Buchse Typ­B printbar ­ 1 Steckleiste 3­polig ­ 1 Jumper J1 ­ 1 Widerstand 1,3kΏ R1 ­ 1 Kondensator 100nF C1 ­ 1 Elektrolyt­Kondensator 10μF C2 ­ 1 IOWarrior24 Abbildung 2.4.1 ­ Bestückungs­ und Leiterbahnansicht der Grundschaltung des IOWarrior24 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 8 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle C1 100nF J1 R1 1,3kΩ C2 10μF Abbildung 2.4.2 ­ Gesamtansicht der Lochrasterplatine mit der Grundschaltung des IOWarrior24 C1 100nF J1 R1 1,3kΩ C2 10μF Ansicht oben ­ Bauteilseite Ansicht unten ­ Kupferseite Abbildung 2.4.3 ­ Bauplan Gundschaltung ­ Bauteilseite und Kupferseite Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 9 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 2.5 Erstellung eigener Software für den IOWarrior Entwicklungsumgebung SharpDevelop 3 Die Erstellung der Software für die jeweiligen Schaltungen erfolgt mit der Programmiersprache C#. Diese ist für die Erstellung von Windows­Anwendungen weit verbreitet und ist nicht zuletzt deshalb interessant, weil es dafür die kostenfreie Entwicklungsumgebung SharpDevelop gibt. Die hier erstellten Beispiel­Projekte wurden mit SharpDevelop Version 3 erstellt. Diese kann unter der folgenden Adresse aus dem Internet bezogen werden: www.icsharpcode.net .NET framework 3.5 Für die Erstellung von Windows­Anwendungen mit SharpDevelop, wie auch für die spätere Nutzung der fertigen Programme ist die Installation des .NET framework Version 3.5 Voraussetzung. Dabei handelt es sich um eine Laufzeit­Umgebung für Anwendungen, die mit einer .NET­Entwicklungsumgebung programmiert wurden. Diese steht auf den meisten Windows­PCs zur Verfügung. Sollte dies nicht der Fall sein, so kann das .NET framework von der Microsoft­Webseite heruntergeladen und nachinstalliert werden: www.mircorosoft.com iowkit.dll Für die Kommunikation zwischen dem IOWarrior und einer Anwendung bietet die Herstellerfirma dieser Microcontroller die fertige DLL iowkit.dll (Dynamic Link Library ­ Dynamische Laufzeitbibliothek) an, die es sehr einfach macht, die Funktionen dieses Bauteils in eigene Programme zu implementieren. Die USB­Kommunikation wird vollständig von dieser DLL übernommen und man kann sich sofort den eigentlichen Programmieraufgaben widmen. Diese DLL, wie auch einige Beispielanwendungen für verschiedene Entwicklungsumgebungen und Programmiersprachen stehen auf der Web­Seite von Code Mercenaries zum Download bereit: www.codemercs.com Zusammengefasset benötigt man: ­ .NET framework Version 3.5 (www.microsoft.com) ­ SharpDevelop 3 (www.icsharpcode.net) ­ iowkit.dll (www.codemercs.com) 2.6 Anwendung 1 ­ Erste Verbindung mit dem IO­Warrior ­ IOW_Verbindung Das erste Programm soll die Kommunikation mit einem am Computer angeschlossenen IOWarrior testen und die beiden am IOWarrior gespeicherten Werte ProduktID und Seriennummer auslesen. Verwendete Komponenten ProduktIDLabel (Label) SeriennummerLabel (Label) IdSnButton (Button) Abbildung 2.6.1 ­ Screenshot der Anwendung IOW_Verbindung Speicherort der iowkit.dll DLLs werden grundsätzlich im Ordner Laufwerk:\Windows\System32 abgelegt. Somit kann ein und dieselbe DLL auch von verschiedenen Anwendungen genutzt werden, die diese benötigen. Alle Anwendungen, die auf eine DLL zugreifen, suchen diese automatisch in dem oben angeführten Verzeichnis. Wenn es nicht möglich ist (weil man zum Beispiel nicht über die notwendigen Rechte verfügt), eine DLL in diesen Ordner zu speichern, so kann eine DLL auch im gleichen Ordner liegen, in dem sich die lauffähige Anwendung (die .exe­Datei) befindet. Dieser Weg soll hier eingeschlagen werden. Wird eine fertige Anwendung weitergegeben, so ist natürlich auch die iowkit.dll mitzugeben. Diese muss sich beim Ausführen der Anwenung im selben Ordner wie die Anwendung befinden! Bei der Entwicklung mit SharpDevelop befindet sich die lauffähige Anwendung während der Entwicklungszeit im Ordner Laufwerk:\Anwendung\bin\Debug bzw. im Ornder Laufwerk:\Anwendung\bin\Release. In diesen Ordner muss die iowkit.dll kopiert werden, wenn eine neue Anwendung erstellt wird. Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 10 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Einbinden der Funktionen aus der iowkit.dll Um Funktionen aus einer externen DLL einbinden zu können muss zuerst eine Referenz auf die Klasse System.Runtime.InteropServices hinzugefügt werden. Das Einbinden der Funktionen aus der iowkit.dll erfolgt in der Definition der Klasse des Formulars. Zusätzlich wird noch ein Handle (Englisch für „Griff“ oder „Henkel“) definiert. Über diesen Handle jeweiligen Funktionen in der Folge auf den IOWarrior zugreiffen. können die using System; using System. Collections. Generic; using System. Drawing; using System. Windows. Forms; using System. Runtime. InteropServices; namespace IOW_Verbindung { /// <summary> /// Description of MainForm. /// </summary> public partial class MainForm : Form { // Definition der global verfügbaren Variablen int IowHandle; // Import der benötigten Funktionen aus der iowkit. dll [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 short IowKitGetProductId(int iowHandle) ; [DllImport("iowkit", SetLastError=true) ] public static extern bool IowKitGetSerialNumber(int iowHandle, ref short serialNumber) ; public MainForm( ) { // The InitializeComponent( ) call is required for Windows Forms designer support. InitializeComponent( ) ; } } } // TODO: Add constructor code after the InitializeComponent( ) call. Quellcode 2.6.1 ­ Import der benötigten Funktionen aus der iowkit.dll Herstellen der Verbindung zum IOWarrior Die Anwendung soll beim Starten überprüfen, ob ein IOWarrior am Computer angeschlossen wurde. Ist dies der Fall, so wird der Handle dieses IOWarriors ermittelt und in der Variable IowHandle abgelegt. Wurde kein IOWarrior gefunden, so soll dies mit einem entsprechenden Hinweis in einer MessageBox angezeigt werden. Diese Aufgaben sollen als Reaktion auf das Event Load der Klasse MainForm ausgeführt werden. void MainFormLoad( obj ect sender, EventArgs e) { // Verbindung zu IOWarrior herstellen } IowHandle = IowKitOpenDevice() ; if (IowHandle==0) MessageBox. Show("Kein IO-Warrior gefunden! ") ; Quellcode 2.6.2 ­ Herstellen der Verbindung zu einem IOWarrior beim Start der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 11 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Ermitteln der ProduktID und der Seriennummer des angeschlossen IOWarriors Die iowkit.dll stellt dazu die beiden Funktionen IowKitGetProductId() und IowKitGetSerialNumber() zur Verfügung. Die ProduktID ist im IOWarrior mit 2 Byte gespeichert, die Seriennummer ist eine Zahl, die aus 4 Byte besteht. Als ProduktIDs wurden von Code Mercenaries die drei Werte 0x1500 (IOWarrior40), 0x1501 (IOWarrior24) und 0x1503 (IOWarrior56) vergeben. Für die Seriennummer ergeben sich 4256 verschiedene Möglichkeiten, wodurch gewährleistet ist, dass es nie zwei IOWarrior mit der selben Seriennummer geben wird und auch mehrere IOWarrior gleichzeitig an einen Computer angeschlossen werden können. Die Funktion IowKitGetProductId() liefert einen ganzzahligen Wert zurück, der mit der gewünschten ProduktID (hier 0x1501 in hexadezimaler Schreibweise für den IOWarrior24) verglichen werden kann. Für den Aufruf der Funktion IowKitGetSerialNumber() muss zuvor bereits ein Array definiert werden in das die Werte beim Auslesen aus dem IOWarrior geschrieben werden. Zur Ausgabe müssen diese Werte aus dem Array noch zu einem String zusammengefasst werden. void IdSnButtonClick( obj ect sender, EventArgs e) { // Variablendefinition int ProduktID = 0; short[] SerienNummer = new short[8] ; string SerienNummerString = ""; // ProduktID ermitteln und ausgebem ProduktID = IowKitGetProductId(IowHandle) ; if (ProduktID==0x1501) { ProduktIDLabel. Text = "Produkt ID: IOWarrior24"; } else { ProduktIDLabel. Text = "Produkt ID: unbekannt"; } // Seriennummer ermitteln und ausgeben if (IowKitGetSerialNumber(IowHandle, ref SerienNummer[0] ) ) { foreach (char c in SerienNummer) SerienNummerString = SerienNummerString + c; SeriennummerLabel. Text = "Seriennummer: " + SerienNummerString; } else { SeriennummerLabel. Text = "Seriennummer: unbekannt"; } } Quellcode 2.6.3 ­ Auslesen und Anzeigen der ProduktID und der Seriennummer eines angeschlossenen IOWarrior24 Trennen der Verbindung zum IOWarrior Vor dem Schließen einer Anwendung muss die Verbindung zum IOWarrior unbedingt getrennt werden. Dies sollte nicht dem Benutzer ­ zum Beispiel durch den Klick auf einen Button ­ überlassen werden, sondern automatisch durch die Anwendung selbst geschehen. Dazu ruft man als Reaktion auf das Event FormClosing die Funktion IowKitCloseDevice() auf und übergibt dieser den Handle des IOWarriors. void MainFormFormClosing( obj ect sender, FormClosingEventArgs e) { // Verbindung zum IOWarrior trennen } IowKitCloseDevice(IowHandle) ; Quellcode 2.6.4 ­ Automatisches Trennen der Verbindung zum IOWarrior beim Beenden der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 12 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 3. Einlesen von Schaltzuständen Alle 16 IO­Pins des IOWarrior24 können als Ein­ oder Ausgänge dienen. Wenn diese als Eingänge genutzt werden, kommt die, für Microcontroller übliche, inverse Logik zur Anwendung: ist ein Eingang offen, so liefert der Microcontroller der Wert 1 zurück, ist ein Eingang geschlossen (zum Beispiel über einen Taster oder Schalter mit GND verbunden), so wird der Wert 0 zurückgeliefert. Dieser Zusammenhang muss also bei der Erstellung der Software berücksichtigt werden, wenn die vom IOWarrior24 übermittelten Daten der beiden Ports ausgewertet werden. 3.1 Prinzip einer Halbleiterdiode Eine Diode besteht im Prinzip aus zwei Halbleiterschichten (meist Silizium), die Strom in nur einer Richtung durchlässt. Diese können in elektronischen Schaltungen unter anderem dazu verwendet werden um zu verhindern, das Strom in der falschen Richtung durch den Stromkreis fließt, wodurch zum Beispiel andere Bauteile zerstört werden können. Das Schaltsymbol veranschaulicht deutlich die beiden Richtungen, die als Durchlassrichtung und als Sperrrichtung bezeichnet werden. Damit durch eine Diode Strom in Durchlassrichtung fließen kann, muss eine gewisse Durchlasspannung erreicht werden ­ bei einer Silizium­Diode beträgt diese 0,7V. Dies bedeutet aber auch, dass diese 0,7V den anderen ­ in Serie geschalteten ­ Verbrauchern in diesem Stromkreis nicht mehr zur Verfügung stehen und sich die Spannung entsprechend um diesen Betrag reduziert. In dem gezeigten Beispiel liegt an der Glühbirne also nur mehr eine Spannung von 11,3V an, da 0,7V an der vorgeschalteten Diode abfallen. Durchlassrichtung Schaltsymbol und Bauformen Sperrrichtung Abbildung 3.1.1 ­ Bauformen ­ Sperr­ und Durchlassirchtung einer Diode in einem einfachen Stromkreis 3.2 Grundschaltung zum Schutz der Eingänge Damit ein Mikrocontroller durch das Anlegen falscher Spannungen oder falscher Polung an den Eingängen nicht beschädigt wird, können diese durch eine einfache Schaltung mit zwei Dioden geschützt werden. Diese Dioden verhindern, dass Spannungen kleiner als 0V (negative Spannungen) oder Spannungen größer als 5V an einem Eingang anliegen. 14 Vcc IO­WARRIOR24 GND P P P P P P P P 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 1 2 3 4 24 23 22 21 9 Abbildung 3.2.1 ­ Schutzschaltung für die Eingänge des IOWarrior24 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 13 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 3.3 Bauplan und Materialliste Für das Einlesen von Schaltzuständen werden zwei Taster verwendet. Diese beiden Taster werden mit je einem Pin des IOWarriors24 und dem Ground GND verbunden. Zwei Dioden dienen pro Taster zum Schutz der Eingänge gegen negative Spannungen und gegen Spannungen, die +5V übersteigen. Materialliste: ­ 2 Taster ­ 4 Dioden N4148 Abbildung 3.3.1 ­ Materialliste und Bauplan Bauteilseite Abbildung 3.3.2 ­ Bestückungs­ und Leiterbahnansicht der Schaltung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 14 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 3.4 Anwendung 2 ­ Einlesen von Schaltzuständen ­ IOW_Taster Die zweite Anwendung soll die Zustände der beiden Taster ermitteln und diese in zwei Panels grafisch darstellen. Zusätzlich zur Anzeige der Produkt ID und der Seriennummer des angeschlossenen IOWarriors sollen auch noch die Werte des Arrays Data[] angezeigt werden. Verwendete Komponenten ProduktIDLabel (Label) SeriennummerLabel (Label) Data0Label, Data1Label, Data2Label (Label) TasterLinksPanel, TasterRechtsPanel (Panel) ReadTimer (Timer, Interval 20) Abbildung 3.4.1 ­ Screenshot der Anwendung IOW_Taster Einbinden der Funktionen aus der iowkit.dll Zum Einbinden der Funktionen aus der DLL muss die Klasse System.Runtime.InteropServices mit einer using­ Anweisung hinzugefügt werden. Zum Austausch von Daten zwischen der Anwendung und dem IOWarrior werden die beiden Funktionen IowKitWrite() und IowKitRead() verwendet. Zusätzlich zum Handle wird noch ein Byte­Array definiert. Dieses dient zum Datenaustauch zwischen der Anwendung und dem IOWarrior. namespace IOW_Taster { /// <summary> /// Description of MainForm. /// </summary> public partial class MainForm : Form { int IowHandle; byte[] Data; [ 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 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 int IowKitWrite(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) ; public MainForm( ) { // The InitializeComponent( ) call is required for Windows Forms designer support. InitializeComponent( ) ; } } } // TODO: Add constructor code after the InitializeComponent( ) call. Quellcode 3.4.1 ­ Import der benötigten Funktionen aus der iowkit.dll und Definiton der globalen Variablen Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 15 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Scnittstelle Herstellen der Verbindung zum IOWarrior Der Aufbau der Verbindung zum IOWarrior soll wie in der Anwendung zuvor als Reaktion auf das Event Load der Klasse MainForm ausgeführt werden. Ergänzend sollen nun auch an dieser Stelle die Produkt­ID und die Seriennummer bestimmt und angezeigt werden. Das Einlesen der Zustände der beiden Ports des IOWarrior erfolgt alle 50ms. Dazu wird der Anwendung ein Timer hinzugefügt, der beim Start der Anwendung deaktiviert ist und dessen Zeitintervall auf den Wert 50 gesetzt ist. Wurde ein IOWarrior gefunden, dann soll dieser Timer aktiviert und das Array Data[] mit entsprechenden Werten initialisiert werden: Data[0] dient zur Übergabe von Werten an den IOWarrior Data[1] beinhaltet den Zustand des Ports 0, wenn der IOWarrior Daten an die Anwendung sendet oder empfängt Data[2] beinhaltet den Zustand des Ports 1, wenn der IOWarrior Daten an die Anwendung sendet oder empfängt Data[0] = 0x00 ... der IOWarrior liefert in den Werten Data[1] und Data[2] die Zustände der beiden Ports zurück Data[1] = 0x00 ... alle Pins dieses Ports sind Ausgänge und erhalten den Wert Data[2] = 0xA0 ... die Pins P1.6 und P1.8 werden als Eingänge verwendet und auf 1 gesetzt (10100000) 0 void MainFormLoad( obj ect sender, EventArgs e) { // Variablendefinition int ProduktID = 0; short[ ] SerienNummer = new short[ 8] ; string SerienNummerString = ""; // Verbindung zu IOWarrior herstellen IowHandle = IowKitOpenDevice( ) ; if ( IowHandle==0) { MessageBox. Show( "Kein IO-Warrior gefunden! ") ; } else { // ProduktID ermitteln und anzeigen ProduktID = IowKitGetProductId( IowHandle) ; if ( ProduktID==0x1501) { ProduktIDLabel. Text = "Produkt ID: IOWarrior24"; } else { ProduktIDLabel. Text = "Produkt ID: unbekannt"; } // Seriennummer ermitteln und anzeigen if ( IowKitGetSerialNumber( IowHandle, ref SerienNummer[ 0] ) ) { foreach( char c in SerienNummer) SerienNummerString = SerienNummerString + c; SeriennummerLabel. Text = "Seriennummer: " + SerienNummerString; } else { SeriennummerLabel. Text = "Seriennummer: unbekannt"; } // Byte-Array für den Datenaustausch initialisieren Data = new byte[3] ; Data[0] = 0x00; Data[1] = 0x00; Data[2] = 0xA0; IowKitWrite(IowHandle, 0, ref Data[0] , 3) ; Quellcode 3.4.2 ­ Herstellen der Verbindung zum IOWarrior24 und Initialisieren der Anwendung Dr. Leander Brandl 2009 ­ www.anderslernen.com Anhang ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Scnittstelle } // Timer zum Einlesen der Pinzustände aktivieren ReadTimer. Enabled = true; } Quellcode 3.4.2 Fortsetzung ­ Herstellen der Verbindung zum IOWarrior24 und Initialisieren der Anwendung Auslesen der Zustände der Ports aus dem IOWarrior Mit der Funktion IowKitReadNonBlocking() können die Zustände der einzelnen Pins der beiden Ports bestimmt werden. Dieser Funktion werden der Handle des IOWarriors, ein Buffer­Array und die Anzahl der übertragenen Bytes (hier 3) übergeben. Nach dem Aufruf dieser Funktion können die Zustände der Pins aus den Werten von Data[1] und Data[2] bestimmt werden. Die Überprüfung, ob ein Bit auf 0 oder 1 gesetzt ist, kann nur über einen "Umweg" der entsprechenden Dezimal­ bzw. Hexadezimalzahlen erfolgen, da ein direkter Zugriff auf die einzelnen Bits in diesen Byte­Werten nicht möglich ist. Aufgrund der inversen Logik der Eingänge eines Mikroprozessors liefert der IOWarrior den Wert 1, wenn ein Eingang geöffnet ist, bzw. der jeweilige Pin nicht mit GND verbunden ist. Wird ein Eingang geschlossen, so ist die logische Entsprechung dieses Pins der Wert 0. Die tabellarische Darstellung Seite soll diesen Zusammenhang verdeutlichen. Möchte man überprüfen, ob ein Taster geschlossen ist, muss man bei den vom IOWarrior gelieferten Werten der beiden Ports herausfinden, ob an der Stelle des entsprechenden Bits eine 0 steht. Dies geschieht mit dem Operator & für logische Verknüpfungen zweier Bytes. Dabei werden die einzelnen Bits mit einander nach der Vorschrift für das logische UND miteinander verglichen. Um zu ermitteln, ob der Zustand des Pins 1 geschlossen ist, wird die logische Verknüpfung 0xFD & 0x02 durchgeführt und überprüft, ob das Ergebnis 0x00 ist. Ist dies der Fall, dann ist der Eingang Pin 1 am IOWarrior geschlossen. P 0. 1 1 1 1 1 1 1 0 1 ( 0xFD) & 0 0 0 0 0 0 1 0 ( 0x02) --------------------------------------Ergebnis 0 0 0 0 0 0 0 0 ( 0x00) ( der vom IOWarrior zurückgeliferte Wert) Pin Binär Hexadezimal Dezimal P 0.1 11111101 FD 253 P 0.0 P 0.2 P 0.3 P 0.4 P 0.5 P 0.6 P 0.7 P 0.0 und P 0.3 P 0.2 und P 0.6 11111110 11111011 11110111 11101111 11011111 10111111 01111111 11110110 10111011 FE FB F7 EF DF BF 7F F6 BB 254 251 247 239 223 191 127 246 187 Abbildung 3.4.2 ­ Werteübersicht für Eingangspins des IOWarrior in binärer, hexadezimaler und dezimaler Schreibweise Sind alle Eingangspins offen, so wird für diesen Port der Wert 25510 bzw. 0xFF16 (alle Bits auf 1 gesetzt) zurückgeliefert. Zusammenfassend kann man festhalten: Will man überprüfen, welche Eingänge geschlossen sind, so ist der entsprechende Wert darauf zu überprüfen, an welchen Stellen (Bits) eine 0 gesetzt ist. Das Auslesen der Port­Zustände aus dem IOWarrior, die Ausgabe der Werte und das Setzen der Farben der beiden Panels erfolgt in der Behandlung des vom Timer ausgelösten Events Tick. Dieses wird basierend auf der Einstellung für den Timer alle 50 Millisekunden ausgelöst ­ somit wird die Anzeige der Anwendung 20 mal pro Sekunde mit den aktuellen Werten des IOWarrior aktualisiert. Dr. Leander Brandl 2009 ­ www.anderslernen.com Anhang ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle void ReadTimerTick( obj ect sender, EventArgs e) { int TasterLinksStatus; int TasterRechtsStatus; IowKitReadNonBlocking(IowHandle, 0, ref Data[0] , 3) ; Data0Label. Text = "Data[ 0] = " + String. Format( "{ 0: X2} ", Data[ 0] ) + " ( " + Data[ 0] . ToString( ) + ") "; Data1Label. Text = "Data[ 1] = " + String. Format( "{ 0: X2} ", Data[ 1] ) + " ( " + Data[ 1] . ToString( ) + ") "; Data2Label. Text = "Data[ 2] = " + String. Format( "{ 0: X2} ", Data[ 2] ) + " ( " + Data[ 2] . ToString( ) + ") "; TasterLinksStatus = Data[2] & 0x20; TasterRechtsStatus = Data[2] & 0x80; if ( TasterLinksStatus==0x00 ) { TasterLinksPanel. BackColor = Color. Red; } else { TasterLinksPanel. BackColor = Color. Black; } if ( TasterRechtsStatus==0x00 ) { TasterRechtsPanel. BackColor = Color. Red; } else { TasterRechtsPanel. BackColor = Color. Black; } } Quellcode 3.4.3 ­ Ermitteln der Zustände der Pins Beenden der Anwendung Wird die Anwendung geschlossen, muss zuerst der Timer deaktiviert und dann die Verbindung zum IOWarrior getrennt werden. Dies geschieht wie im ersten Beispiel als Reaktion auf das Event FormClosing des Formulars. void MainFormFormClosing( obj ect sender, FormClosingEventArgs e) { // Timer zum Einlesen der Pinzustände deaktivieren ReadTimer. Enabled = false; } // Verbindung zum IOWarrior trennen IowKitCloseDevice( IowHandle) ; Quellcode 3.4.4 ­ Trennen der Verbindung zum IOWarrior beim Schließen der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 18 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 4. Setzen von Pin­Zuständen ­ Ansteuerung von Leuchtdioden Die 16 IO­Pins des IOWarriors können als Ein­ oder Ausgänge genutzt werden. Wenn diese als Ausgänge verwendet werden, kann jeder Pin den Schaltzustand +5V oder 0V annehmen. Der maximale Strom, der einem Ausgangspin entnommen werden darf ist aber so gering (max 2mA), dass Verbraucher nicht direkt an einen Pin angeschlossen werden dürfen. Die Entnahme eines zu hohen Stroms führt zur Zerstörung des IOWarrior. Zum Steuern oder Schalten von Verbrauchen kommt ein Transistor zum Einsatz. Dieser fungiert dabei als eine Art Schalter, der aufgrund eines geringen Stoms (Ausgangspin des IOWarriors) eine höheren Strom schaltet. Mit Hilfe eines Transistors kann man somit eine Leuchtdiode ein­ und ausschalten. Die Betriebsspannung von Leuchtdioden liegt ­ je nach Bauart ­ bei ca. 2V. Da die Spannung, die die USB­Schnittstelle zur Verfügung stellt 5V beträgt, muss vor die Leuchtdiode noch ein entsprechender Vorwiderstand geschaltet werden. 4.1 Prinzip eines Transistors Ein Transistor besteht aus drei Halbleiterschichten (meist Silizium). Die drei Anschlüsse werden als Basis, Kollektor und Emitter bezeichnet. Daraus ergeben sich zwei Stromkreise, zwischen denen der Transistor als eine Art "Bindeglied" darstellt. Der Strom im Basisstromkreis (Basis ­ Emitter) entscheidet über das Verhalten eines Transistors. Der Strom im Kollektorstromkreis (Kollektor ­ Emitter) ist abhängig von der Größe des Stroms im Basisstromkreis. Vereinfacht kann man sagen: Fließt bei einem Transistor Strom von der Basis zum Emitter, dann gibt der Transistor den Weg Kollektor­Emitter frei und es kann Strom vom Kollektor zum Emitter fließen. Bei der Planung von elektronischen Schaltungen mit einem Transistor ist im Basis­ und Kollektorstromkreis zu berücksichtigen, dass es ­ wie bei der Diode ­ einen Spannungsabfall an den Halbleiterschichten gibt. Für die Berechnung der Spannungsverteilung auf die einzelnen Verbraucher im Kollektorstromkreis ist somit auch der Typen­ spezifische Spannungsabfall am Transistor zu berücksichtigen! Bauformen TO­92 TO­126 KEIN Strom Basis ­ Emitter > Transistor "sperrt" > KEIN Strom Kollektor ­ Emitter TO­220 TO­3 Strom Basis ­ Emitter > Strom Kollektor ­ Emitter Abbildung 4.1.1 ­ Bauformen ­ Verhalten eines Transistors bezogen auf den Basisstrom Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 19 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 4.2 Elektrische Widerstände ­ das Ohm´sche Gesetz Elektrische Widerstände werden eingesetzt um die Spannung zu reduzieren oder den Strom in einem Stromkreis zu begrenzen. Da die überschüssige elektrische Energie dabei von einem Widerstand in Wärme umgesetzt wird, müssen diese je nach Anforderung entsprechend groß dimensioniert sein. Der Zusammenhang zwischen elektrischer Spannung, Strom und Widerstand wird durch das Ohm´sche Gesetz beschrieben. Sind zwei der drei Größen bekannt, so lässt sich rechnerisch die dritte Größe bestimmen. U R = = = = = R ... Widerstand [Ohm] U ... Spannung [Volt] I ... Strom [Ampere] 150 Ω Hier wird an einen Widerstand mit 150Ω eine Spannung von 12V angelegt. Mit Hilfe des Ohm´schen Gesetzes lässt sich der Strom (roter Pfeil) berechnen, der über diesen Widerstand fließt: I = U / R = 12V / 150Ω = 0,08A Abbildung 4.2.1 ­ Ohm´ sches Gesetz ­ Zusammenhang zwischen Strom, Spannung und Widerstand in einem einfachen Stromkreis Für die Angabe von Widerstandswerten wurde eine international gültige Farbkodierung eingeführt. Diese kann aus vier oder fünf Farbringen bestehen. Zu den Zahlenwerten der ersten Ringe kommt ein Multiplikator und ein Ring für die mögliche Toleranz der Abweichung des tatsächlichen vom angegebenen Wert dazu. Abbildung 4.2.2 ­ Farbkodierung von Widerständen Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 20 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 4.3 Die Leuchtdiode LED Leuchtdioden wandeln elektrische Energie in Licht um. Sie funktionieren wie Halbleiterdioden, die in Durchlassrichtung Licht emittieren. Die Kurzbezeichnung LED steht für "Light Emitting Diode". Es gibt Leuchtdioden in verschiedenen Farben, Größen und Bauformen ­ die gebräuchlichsten Bauformen haben einen Durchmesser von 5 mm. Leuchtdioden müssen je nach Farbe exakt mit der vorgegebenen Spannung betrieben werden. Ist die Spannung zu niedrig, emittiert die LED kein Licht, wird eine zu hohe Spannung angelegt, so wird die Halbleiterschicht und somit die Leuchtdiode zerstört. Weiters ist beim Anschluss einer Leuchtdiode auf die richtige Polung zu achten: Kathode (abgeflachte Seite) ­ Minus, Anode ­ Plus Schaltsymbol und Bauform Abbildung 4.3.1 ­ Leuchtdiode ­ Schaltsymbol und Bauform Wenn man eine Leuchtdiode in einem Stromkreis mit einer höheren als der für den jeweiligen Typ vorgesehenen Spannung betreiben will, so muss ein Vorwiderstand verwendet werden, an dem die Differenzspannung abfällt. Standard­LEDs werden mit einem Strom von 10mA betrieben. Möchte man eine rote Leuchtdiode in einem Stromkreis mit einer Spannung von 12V verwenden, so muss am Vorwiderstand eine Spannung von 9,9V (12V ­ 2,1V) abfallen. Mit Hilfe des Ohm´schen Gesetzes lässt sich die Größe des benötigten Vorwiderstandes berechnen. 2,9V ROT 2,1V / 10mA GRÜN 2,5V / 10mA GELB 2,5V / 10mA 5V UWiderstand = Uges ­ ULED LED rot: LED gelb: UWiderstand = 5V ­ 2,1V = 2,9V UWiderstand = 5V ­ 2,5V = 2,5V 2,1V Betriebsspannung / Stom R = UWiderstand / I R = 2,9V / 0,01A = 290Ω R = 2,5V / 0,01A = 250Ω Abbildung 4.3.2 ­ Berechnung des Vorwiderstands für Leuchtdioden Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 21 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 4.4 Schaltplan Möchte man mit einem Ausgang des IOWarriors eine LED ein­ und ausschalten, so kommen ein Transistor und ein Vorwiderstand zum Einsatz. Der Ausgang des IOWarriors wird mit der Basis des Transistors verbunden. Die LED und der Vorwiderstand befinden sich im Kollektor­Stromkreis. Zwischen einem Pin des IOWarriors und GND liegt ­ je nach Zustand ­ eine Spannung von 0V oder 5V an. Bei 0V fließt kein Strom über die Basis des Transistors und somit auch kein Strom vom Kollektor zum Emitter. Die LED bleibt dunkel. Beträgt die Spannung am entsprechenden Pin 5V, so fließt Strom über die Basis des Transistors. Dieser schaltet nun den Weg "Kollektor ­ Emitter" durch und es fließt Strom über den Vorwiderstand und die Leuchtdiode. Durch den Vorwiderstand ist gewährleistet, dass an der Leuchtdiode exakt die Spannung anliegt, die für den jeweiligen Typ vorgegeben ist. 14 Vcc IO­WARRIOR24 GND P P P P P P P P 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 1 2 3 4 24 23 22 21 9 Abbildung 4.4.1 ­ Schaltplan zum Schalten einer LED mit dem IOWarrior 4.5 Materialliste und Bauplan Beim Aufbau dieser Schaltung kommen Standard­Leuchtdioden in den Farben rot, gelb und grün zum Einsatz. Diese kann dann zum Beispiel bei der Programmierung einer Ampelsteuerung verwendet werden. Zum Schalten der Leuchtdioden wird ein Transistor vom Typ BC548 verwendet. Der Spannungsabfall zwischen Kollektor und Emitter beträgt bei diesem Typ 0,2V. Zum Berechnen der Vorwiderstände muss von der Betriebsspannung der Schaltung (5V) der Spannungsabfall am Transistor (0,2V) und die Spannung der Leuchtdiode (2,1V bei rot bzw. 2,5V bei gelb und grün) abgezogen werden, bevor diese mit dem Ohm´schen Gesetz bestimmt werden können. Berechnung der Vorwiderstände für die Leuchtdioden: LED rot: LED gelb: UWiderstand = Uges ­ UKollektorEmitter ­ ULED R = UWiderstand / I UWiderstand = 5V ­ 0,2V ­ 2,1V = 2,7V R = 2,7V / 0,01A = 270Ω UWiderstand = 5V ­ 0,2V ­ 2,5V = 2,3V R = 2,3V / 0,01A = 230Ω Abbildung 4.5.1 ­ Berechnung der Vorwiderstände für die LEDs Materialliste: ­ 3 Leuchtdioden (rot, gelb, grün) 5mm Anschlussbelegung BC548 ­ 3 Transistoren BC548 ­ 2 Widerstände 220Ω (LED gelb, grün) ­ 1 Widerstand 270Ω (LED rot) EBC Abbildung 4.5.2 ­ Materialliste und Anschlussbelegung des BC548 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 22 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Abbildung 4.5.3 ­ Bauplan Bauteilseite Abbildung 4.5.4 ­ Bestückungs­ und Leiterbahnseite Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 23 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 4.6 Anwendung 3 ­ Schalten von LEDs ­ IOW_Leds Aufbauend auf dem Programm zum Einlesen der Zustände von Tastern sollen mit dieser Anwendung die drei Leuchtdioden ein­ und ausgeschaltet werden können. Das Herstellen der Verbindung zum IOWarrior und die Anzeige der Inhalte der drei Werte im Array Data werden aus dem Projekt IOW_Taster übernommen. Das Ein­ und Ausschalten der LEDs soll mit drei Checkboxen auf der Programmoberfläche umgesetzt werden. Dieses Programm könnte dann in der Folge noch zu einer automatisch ablaufenden, Zeit­gesteuerten Ampelsteuerung erweitert werden. Verwendete Komponenten ProduktIDLabel (Label) SeriennummerLabel (Label) Data0Label, Data1Label, Data2Label (Label) WertBar (TrackBar, Minimum ­40, Maximum 40) RotCheckBox (CheckBox) GelbCheckBox (CheckBox) GruenCheckBox (CheckBox) RotPanel, GelbPanel, GruenPanel (Panel) Abbildung 4.6.1 ­ Screenshot der Anwendung IOW_Leds Einbinden der Funktionen aus der iowkit.dll Zum Einbinden der Funktionen aus der DLL und der Definiton der globalen Variablen kommt Quellcode 3.4.1 zur Anwendung. Herstellen der Verbindung zum IOWarrior Wenn die Pins des IOWarriors als Ausgänge genutzt werden, setzt man diese auf den Zustand 0 oder 1, um eine Ausgangsspannung von 0V (LO) oder 5V (HI) zwischen dem jeweiligen Pin und GND zu erhalten. Nach dem Herstellen der Verbindung und dem Einlesen der ProduktID und der Seriennummer wird das Data­Array initialisiert. Das Byte Data[0] erhält den Wert 0x00. Data[1] und Data[2] beschreiben die Zustände der 8 Bits der beiden Ports. Damit die LEDs beim Starten der Anwendung ausgeschaltet sind, werden alle Bits auf 0 und beide Ports somit auf 0x00 (00000000) gesetzt. Nach dem Setzen der Werte im Data­Array werden diese mit der Funktion IowKitWrite() an den IOWarrior übermittelt. void MainFormLoad( obj ect sender, EventArgs e) { // Variablendefinition int ProduktID = 0; short[ ] SerienNummer = new short[ 8] ; string SerienNummerString = ""; // Verbindung zu IOWarrior herstellen IowHandle = IowKitOpenDevice( ) ; if ( IowHandle==0) { MessageBox. Show( "Kein IO-Warrior gefunden! ") ; } else { // ProduktID ermitteln und anzeigen ProduktID = IowKitGetProductId( IowHandle) ; Quellcode 4.6.1 ­ Initialisieren des Data­Arrays und des IOWarrior Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 24 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle if ( ProduktID==0x1501) { ProduktIDLabel. Text = "Produkt ID: IOWarrior24"; } else { ProduktIDLabel. Text = "Produkt ID: unbekannt"; } // Seriennummer ermitteln und anzeigen if ( IowKitGetSerialNumber( IowHandle, ref SerienNummer[ 0] ) ) { foreach( char c in SerienNummer) SerienNummerString = SerienNummerString + c; SeriennummerLabel. Text = "Seriennummer: " + SerienNummerString; } else { SeriennummerLabel. Text = "Seriennummer: unbekannt"; } // Byte-Array für den Datenaustausch initialisieren Data = new byte[ 3] ; Data[ 0] = 0x00; } } Data[1] = 0x00; Data[2] = 0x00; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Quellcode 4.6.1 Fortsetzung ­ Initialisieren des Data­Arrays und des IOWarrior Übertragen der Zustände an die Ausgangspins Klickt man auf eine Checkbox, so wird deren Eigenschaft Checked entweder auf true oder false gesetzt. Als Reaktion auf das Event CheckedChanged soll der entsprechende Pin des IOWarriors auf HI bzw. LO gesetzt werden. Da bei der Übertragung der Pin­Zustände zum IOWarrior immer die Zustände aller 8 Pins beider Ports gesendet werden, müssen auch die zuvor gültigen Werte für alle anderen Pins berücksichtigt werden. Möchte man ein Bit auf 1 setzen, so muss der ursprüngliche Zustand der Bits mit Hilfe einer logischen ODER­ Verknüpfung erweitert werden. 0 1 ( 0x41) ursprünglicher Zustand Port | Ergebnis ursprünglicher Zustand und zweites Bit auf 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 ( 0x02) zweites Bit auf 1 --------------------------------------0 1 0 0 0 0 1 1 ( 0x43) Soll ein Bit auf 0 gesetzt werden, so muss der ursprüngliche Zustand der Bits mit Hilfe einer logischen UND­ Verknüpfung und des inversen Wertes des gewünschten Bits berechnet werden. Port 0 1 0 0 0 0 1 1 ( 0x43) & 1 1 1 1 1 1 0 1 ( 0xFD) --------------------------------------- Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 ursprünglicher Zustand zweites Bit auf 0 Seite 25 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Anschluss der LEDs an den IOWarrior in der augebauten Schaltung LED rot Port 1 Bit 3 0x08 00001000 Data[2] LED grün Port 0 Bit 7 0x80 10000000 Data[1] LED gelb Port 1 Bit 1 0x02 00000010 Data[2] Abbildung 4.6.2 ­ Anschluss der LEDs an den IOWarrior und entsprechende Bits der jeweiligen Ports void RotCheckBoxCheckedChanged( obj ect sender, EventArgs e) { int WertNeu; if ( RotCheckBox. Checked==true) { RotPanel. BackColor = Color. Red; WertNeu = Data[2] | 0x08; Data[ 2] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } else { RotPanel. BackColor = Color. Black; } WertNeu = Data[2] & 0xF7; Data[ 2] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data0Label. Text = "Data[ 0] = " + String. Format( "{ 0: X2} ", Data[ 0] ) + " ( " + Data[ 0] . ToString( ) + ") "; Data1Label. Text = "Data[ 1] = " + String. Format( "{ 0: X2} ", Data[ 1] ) + " ( " + Data[ 1] . ToString( ) + ") "; Data2Label. Text = "Data[ 2] = " + String. Format( "{ 0: X2} ", Data[ 2] ) + " ( " + Data[ 2] . ToString( ) + ") "; } void GelbCheckBoxCheckedChanged( obj ect sender, EventArgs e) { int WertNeu; if ( GelbCheckBox. Checked==true) { GelbPanel. BackColor = Color. Yellow; WertNeu = Data[2] | 0x02; Data[ 2] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } else { GelbPanel. BackColor = Color. Black; } } WertNeu = Data[2] & 0xFD; Data[ 2] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data0Label. Text = "Data[ 0] = " + String. Format( "{ 0: X2} ", Data[ 0] ) + " ( " + Data[ 0] . ToString( ) + ") "; Data1Label. Text = "Data[ 1] = " + String. Format( "{ 0: X2} ", Data[ 1] ) + " ( " + Data[ 1] . ToString( ) + ") "; Data2Label. Text = "Data[ 2] = " + String. Format( "{ 0: X2} ", Data[ 2] ) + " ( " + Data[ 2] . ToString( ) + ") "; Quellcode 4.6.3 ­ Senden der Zustände der Ausgangspins an den IOWarrior als Reaktion auf die Änderung einer Checkbox Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 26 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle void GruenCheckBoxCheckedChanged( obj ect sender, EventArgs e) { int WertNeu; if ( GruenCheckBox. Checked==true) { GruenPanel. BackColor = Color. Green; WertNeu = Data[1] | 0x80; Data[ 1] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } else { GruenPanel. BackColor = Color. Black; } WertNeu = Data[1] & 0x7F; Data[ 1] = ( byte) WertNeu; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data0Label. Text = "Data[ 0] = " + String. Format( "{ 0: X2} ", Data[ 0] ) + " ( " + Data[ 0] . ToString( ) + ") "; Data1Label. Text = "Data[ 1] = " + String. Format( "{ 0: X2} ", Data[ 1] ) + " ( " + Data[ 1] . ToString( ) + ") "; Data2Label. Text = "Data[ 2] = " + String. Format( "{ 0: X2} ", Data[ 2] ) + " ( " + Data[ 2] . ToString( ) + ") "; } Quellcode 4.6.3 Fortsetzung ­ Senden der Zustände der Ausgangspins an den IOWarrior als Reaktion auf die Änderung einer Checkbox Beenden der Anwendung Beim Schließen der Anwendung wird die Verbindung zum IOWarrior getrennt. Dies geschieht wie in den beiden vorangegangenen Beispielen als Reaktion auf das Event FormClosing des Formulars. void MainFormFormClosing( obj ect sender, FormClosingEventArgs e) { // Verbindung zum IOWarrior trennen IowKitCloseDevice( IowHandle) ; } Quellcode 4.6.4 ­ Trennen der Verbindung zum IOWarrior beim Schließen der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 27 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 5. Erweiterung der Ausgänge mit einem Schieberegister Der IOWarrior24 stellt 16 Ausgänge zur Verfügung. Benötigt man eine größere Anzahl von Ausgängen um zum Beispiel eine LED­Anzeigetafel anzusteuern, so kommen spezielle Bauteile zur Porterweiterung ­ sogenannte Schieberegister ­ zum Einsatz. Zur Übertragung von Daten an ein Schieberegister werden nur drei Datenleitungen benötigt. Die meisten Schieberegister verfügen über ein Auffangregister. Damit wird erreicht, dass Daten in das Register eingegeben werden können ohne, dass sich die tatsächlichen Ausgangszustände ändern. Erst wenn alle Zustände in das Auffangregister geschrieben wurden, werden diese an die einzelnen Ausgänge durch einen Impuls am Pin mit der Bezeichnung STROBE weitergegeben. 5.1 Der IC 4094 Der am häufigsten eingesetzte Schieberegister­Bauteil trägt die Bezeichnung 4094. Dieser verfügt über drei Eingänge (DATA, CLOCK und STROBE) und über 8 Ausgänge. Diese müssen je nach Anwendung (zum Beispiel beim Anschluss von LEDs) mit Widerständen versehen werden und sollten pro Ausgang mit maximal 25mA belastet werden. 16 1 Strobe Data Clock A0 Vcc +5V Vcc +5V A4 A5 A6 A1 A2 A7 A3 GND 9 8 Data OUT Abbildung 5.1.1 ­ Anschlussbelegung des 4094 Zusätzlich verfügt dieser integrierte Schaltkreis über einen Daten­Ausgang. Über diesen können weitere Bauteile angeschlossen und mit Daten befüllt werden. Somit lassen sich mehrere Bauteile vom Typ 4094 hintereinander schalten wodurch man die Anzahl der Ausgänge beliebig erweitern kann. 3 Clock 2 Data 1 3 Strobe Data OUT 4094 A0 A1 A2 A3 A4 A5 A6 A7 9 4 5 6 7 14 13 12 11 Clock 2 Data 1 Strobe Data OUT 4094 A0 A1 A2 A3 A4 A5 A6 A7 9 4 5 6 7 14 13 12 11 Abbildung 5.1.2 ­ Schaltplan und Umsetzung der Kaskadierung mehrerer Schieberegister­Bauteile Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 28 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Das Setzen der Zustände der Ausgänge geschieht in zwei Schritten: Zuerst werden die gewünschten Zustände der 8 Ausgänge als 8 Bits nacheinander in das Auffangregister geschoben. Der Zustand des Eingangs DATA entspricht dabei dem Zustand den der jeweilige Ausgang haben soll. Mit einem Impuls am Eingang CLOCK werden alle Bits im Auffangregister um eine Stelle weitergeschoben. Sind alle 8 Bits im Auffangregister, werden diese mit einem Impuls am Eingang STROBE an die Ausgänge übergeben. Auffangregister Ausgänge CLOCK DATA 1 0 0 1 0 0 1 Auffangregister 0 Ausgänge 1 0 0 1 0 0 1 0 Auffangregister Ausgänge STROBE 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 Auffangregister Ausgänge Abbildung 5.1.3 ­ Schematische Darstellung des Befüllen des Schieberegisters 4094 Um das Schieberegister 4094 einmal vollständig zu befüllen, müssen die Eingänge wie folgt gesetzt werden: Data HI oder LO (1. Bit) Clock HI ­ LO Data HI oder LO (2. Bit) Clock HI ­ LO Data HI oder LO (3. Bit) Clock HI ­ LO Data HI oder LO (4. Bit) Clock HI ­ LO Data HI oder LO (5. Bit) Clock HI ­ LO Data HI oder LO (6. Bit) Clock HI ­ LO Data HI oder LO (7. Bit) Clock HI ­ LO Data HI oder LO (8. Bit) Clock HI ­ LO Strobe HI ­ LO (Auffangregister ­ Ausgänge) Abbildung 5.1.4 ­ Abfolge der Zustände von DATA, CLOCK und STROBE beim Befüllen des Schieberegisters 4094 Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 29 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 5.2 Schaltplan Der IOWarrior24 bietet sich optimal für die Ansteuerung von Schieberegister­Bauteilen mit einem Computer an. Dabei werden nur drei Ausgänge des IOWarrior24 benötigt, die als Datenleitungen für das Schieberegister dienen. Da die Ausgänge des IOWarrior entweder +5V (HI) oder 0V (LO) liefern, können diese direkt mit dem Schieberegister 4094 verbunden werden, da dieses an den Eingängen DATA, CLOCK und STROBE genau diese Pegel erwartet. Werden an den Ausgängen des Schieberegisters Leuchtdioden angeschlossen, müssen entsprechende Vorwiderstände zum Einsatz kommen, da die Spannung an den Ausgängen beim Zustand HI +5V beträgt. 14 Vcc IO­WARRIOR24 GND P P P P P P P P 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 1 2 3 4 24 23 22 21 3 Clock 2 Data 1 Strobe 15 4094 9 GND 16 Vcc A0 A1 A2 A3 A4 A5 A6 A7 4 5 6 7 14 13 12 11 8 Abbildung 5.2.1 ­ Schaltplan zur Ansteuerung eines Schieberegisters 4094 mit dem IOWarrior Anschluss der Datenleitungen des Schieberegisters 4094 an den IOWarrior Clock Port 0 Bit 0 0x01 00000001 Data[1] Strobe Port 0 Bit 2 0x04 00000100 Data[1] Data Port 0 Bit 1 0x02 00000010 Data[1] Abbildung 5.2.2 ­ Anschlussbelegung und entsprechende Bits am Port 0 des IOWarrior24 5.3 Materialliste und Bauplan Beim Anschluss der Leuchtdioden ist besonders auf die Pin­Belegung des Schieberegisters zu achten damit diese in derselben Reihenfolge der Bits im Schieberegister richtig auf der Platine platziert werden (siehe Abbildung 5.1.1). Materialliste: ­ 8 Leuchtdioden rot 5mm ­ 8 Widerstände 270Ω ­ 1 IC Sockel 16­polig ­ 1 Schieberegister 4094 Abbildung 5.3.1 ­ Materialliste Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 30 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Abbildung 5.3.2 ­ Bauplan 5.4 Anwendung 4 ­ Ansteuern von LEDs mit einem Schieberegister ­ IOW_Schieberegister Bei dieser Anwendung werden die LEDs nicht direkt mit dem IOWarrior ein­ und ausgeschaltet. Das Schalten der LEDs übernimmt das Schieberegister 4094. Der IOWarrior stellt das Bindeglied zwischen der Anwendung und dem Schieberegister dar. Mit Hilfe von 8 Checkboxen soll der gewünschte Zustand der LEDs festgelegt werden. Beim Klick auf den Send­Button erfolgt die Übertragung des gewählten Bit­Musters an das Schieberegister. In der Folge könnte an Stelle eines Buttons zum Senden auch ein Timer zum Einsatz kommen, der in regelmäßigen Abständen den mit den Checkboxen festgelegten Zustand der LEDs automatisch überträgt. Verwendete Komponenten ProduktIDLabel (Label) SeriennummerLabel (Label) SendButton (Button) A0Box ... A7Box (CheckBox) Abbildung 5.4.1 ­ Screenshot der Anwendung IOW_Schieberegister Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 31 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Definition globaler Variablen und Import der benötigten Funktionen aus der iowkit.dll Zu Beginn werden die globale Variable IowHandle und das Array Data[] definiert. Zum Import der benötigten Funktionen aus der iowkit.dll muss die Klasse System.Runtime.InteropServices mit einer using­Anweisung eingebunden werden. public partial class MainForm : Form { // Definition der global benötigten Variablen int IowHandle; byte[ ] Data; // Import der benötigten Funktionen aus der iowkit. dll [ 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 IowKitReadNonBlocking( int iowHandle, int numPipe, ref byte buffer, int length) ; [ 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) ; ... Quelltext 5.4.1 ­ Definition globaler Variablen und Import der benötigten Funktionen aus der iowkit.dll Herstellen der Verbindung zum IOWarrior Das Herstellen der Verbindung, das Initialisieren der Anwendung und des IOWarrior erfolgt beim Öffnen der Anwendung in der Ereignisbehanldung des Events Load der Klasse MainForm. Nach dem Herstellen der Verbindung angeschlossenen IOWarriors eingelesen. zum IOWarrior werden die ProduktID und die Seriennummer des Die verwendeten Pins P0.0, P0.1 und P0.2 werden als Ausgänge eingesetzt. Das Byte Data[0] ist auf 0x00 zu setzen und alle Bits beider Ports werden auf 0 gesetzt ­ Data[1] und Data[2] bekommen den Wert 0x00 (00000000). void MainFormLoad( obj ect sender, EventArgs e) { // Variablendefinition int ProduktID = 0; short[ ] SerienNummer = new short[ 8] ; string SerienNummerString = " " ; // Verbindung zu IOWarrior herstellen IowHandle = IowKitOpenDevice( ) ; if ( IowHandle==0) { MessageBox. Show( " Kein IO-Warrior gefunden! " ) ; } else { // ProduktID ermitteln und anzeigen ProduktID = IowKitGetProductId( IowHandle) ; Quelltext 5.4.2 ­ Herstellen der Verbindung zum IOWarrior und Initialisieren des Data­Arrays Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 32 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle } if ( ProduktID==0x1501) { ProduktIDLabel. Text = " Produkt ID: IOWarrior2 4 " ; } else { ProduktIDLabel. Text = " Produkt ID: unbekannt" ; // Seriennummer ermitteln und anzeigen if ( IowKitGetSerialNumber( IowHandle, ref SerienNummer[ 0] ) ) { foreach( char c in SerienNummer) SerienNummerString = SerienNummerString + c; SeriennummerLabel. Text = " Seriennummer: " + SerienNummerString; } else { SeriennummerLabel. Text = " Seriennummer: unbekannt" ; } } } // Byte-Array für den Datenaustausch initialisieren Data = new byte[ 3] ; Data[ 0] = 0x00; Data[ 1] = 0x00; Data[ 2 ] = 0x00; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Quelltext 5.4.2 Fortsetzung ­ Herstellen der Verbindung zum IOWarrior und Initialisieren des Data­Arrays Übertragen der Information aus den Checkboxen an das Schieberegister Soll die Information ­ bestehend aus 8 Bit ­ an das Schieberegister übertragen werden, so ist das in 5.1.3 und 5.1.4 dargestellte Verfahren anzuwenden. Die drei Datenleitungen DATA, CLOCK und STROBE können nicht direkt geschaltet werden, deren Zustand entspricht je einem Bit des Ports 0 des IOWarrior. Bei jedem Aufruf der Funktion IowKitWrite() werden die Zustände aller drei Datenleitungen neu übergeben und müssen deshalb sinngemäß richtig gesetzt sein. Bei der programmiertechnischen Umsetzung ist somit besonders darauf zu achten, dass das Setzen des Zustands des DATA­Eingangs am Schieberegister zu erfolgen hat, bevor der CLOCK­Eingang auf HI und wieder auf LO gesetzt wird. void SendButtonClick( obj ect sender, System. EventArgs e) { if ( A7Box. Checked==true) { Data[ 1] = 0x02; // Data HI IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x03; // Clock HI ( Data bleibt HI) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x02; // Clock LO ( Data bleibt HI) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } else { Data[ 1] = 0x00; // Data LO IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x01; // Clock HI ( Data blcibt LO) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x00; // Clock LO ( Data bleibt LO) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } Quelltext 5.4.3 ­ Übertragen der Information aus den Checkboxen an das Schieberegister Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 33 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle void SendButtonClick( obj ect sender, System. EventArgs e) { if ( A6Box. Checked==true) { Data[ 1] = 0x02; // Data HI IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x03; // Clock HI ( Data bleibt HI) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x02; // Clock LO ( Data bleibt HI) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } else { Data[ 1] = 0x00; // Data LO IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x01; // Clock HI ( Data blcibt LO) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Data[ 1] = 0x00; // Clock LO ( Data bleibt LO) IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; } // . . . . . . . . . dieselbe IF-Abfrage sinngemäß für die Checkboxen A5Box - A1Box if ( A0Box. Checked==true) { Data[ 1] = 0x02; // IowKitWrite( IowHandle, Data[ 1] = 0x03; // IowKitWrite( IowHandle, Data[ 1] = 0x02; // IowKitWrite( IowHandle, } else { Data[ 1] = 0x00; // IowKitWrite( IowHandle, Data[ 1] = 0x01; // IowKitWrite( IowHandle, Data[ 1] = 0x00; // IowKitWrite( IowHandle, } } Data[ 1] = 0x04; // Strobe IowKitWrite( IowHandle, 0, Data[ 1] = 0x00; // Strobe IowKitWrite( IowHandle, 0, Data HI 0, ref Data[ 0] , 3) ; Clock HI ( Data bleibt HI) 0, ref Data[ 0] , 3) ; Clock LO ( Data bleibt HI) 0, ref Data[ 0] , 3) ; Data LO 0, ref Data[ 0] , 3) ; Clock HI ( Data blcibt LO) 0, ref Data[ 0] , 3) ; Clock LO ( Data bleibt LO) 0, ref Data[ 0] , 3) ; HI ref Data[ 0] , 3) ; LO ref Data[ 0] , 3) ; Quelltext 5.4.3 Fortsetzung ­ Übertragen der Information aus den Checkboxen an das Schieberegister Beenden der Anwendung Beim Schließen der Anwendung wird die Verbindung zum IOWarrior getrennt. Dies geschieht wie in den vorangegangenen Anwendungen als Reaktion auf das Event FormClosing des Formulars. void MainFormFormClosing( obj ect sender, FormClosingEventArgs e) { // Verbindung zum IOWarrior trennen IowKitCloseDevice( IowHandle) ; } Quelltext 5.4.4 ­ Trennen der Verbindung zum IOWarrior beim Beenden der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 34 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 6. Eingabe variabler Werte mit einem Drehimpulsgeber Immer mehr ersetzen Drehimpulsgeber herkömmliche Potentiometer und Stufenschalter. Diese arbeiten gegenüber mechanischen Potentiometern nahezu verschleißfrei und sind auch gegenüber der Störung durch hochfrequente Signale unempfindlich. Ein Drehimpulsgeber ist ein Bauteil, der beim Drehen Impulse erzeugt. Diese Impulse sind von der Drehrichtung abhängig und können mit einer entsprechenden, zusätzlich benötigten Elektronik ausgewertet werden. Oft sind Drehimpulsgeber noch mit einer zusätzlichen Druck­Taster­Funktion ausgerüstet. Mit einem Drehimpulsgeber kann daher eine einfache Werteingabe oder Menüauswahl erfolgen. Durch Drehen kann ein Wert geändert oder ein Menüpunkt ausgewählt werden und mit einem Druck auf die Achse erfolgt die Bestätigung dieses Werts oder des Menüpunkts. 6.1 Aufbau und Signalschema eines Drehimpulsgebers Der hier dargestellte Drehimpulsgeber besitzt 5 Pins: 3 Pins für die Drehimpulse (A, B und GND) und 2 Pins für die Taster­Funktion. Dreht man die Achse, so entsteht an den Pins A und B ein Taktmuster. Diese beiden Pins dienen dabei als Schalter, welche je nach Stellung der Achse entweder geöffnet oder geschlossen sind. B GND Taster A Abbildung 6.1.1 ­ Aufbau eines Drehimpulsgebers Die Drehachse besitzt bei den in elektronischen Geräten zur Eingabe von Werten verwendeten Drehimpulsgebern pro Umdrehung meist 30 leichte Rastpositionen. Pro Umdrehung erzeugen beide "Schalter" 15 Rechteckimpulse, welche um etwa 6ms zueinander verschoben sind. Bei einer Drehung im Uhrzeigersinn ergibt sich für AB die folgende Bitabfolge: 01 00 10 11 01 00 10 11 ... ... ... Bei einer Drehung gegen den Uhrzeigersinn ergeben sich für AB die Bitzustände: 10 00 01 11 10 00 01 11 ... ... ... Daraus lässt sich die Richtung bestimmen in welche die Achse des Drehimpulsgebers bewegt wurde. Zu beachten ist dabei, dass die Frequenz der Bestimmung der Schaltzustände von A und B hoch genug sein muss um die Verschiebung von 6 ms auflösen zu können. Rasterpositionen Drehung im Uhrzeigersinn Drehung gegen den Uhrzeigersinn A B A B 1 0 1 0 1 0 1 0 Abbildung 6.1.2 ­ Signalschema an den beiden Pins A und B bei unterschiedlicher Drehrichtung Analyse der Signale Eine Software zur Auswertung der Signale muss die Zustände der beiden Schalter in einem entsprechend kleinen Zeitintervall abfragen und auf eine Änderung der Schaltzustände reagieren. Eine solche Änderung kann entweder das Erreichen einer Rastposition oder das Wechseln in eine Position zwischen den Rasten sein. Eine Analyse der Drehrichtung wird nur bei Erreichen einer Rastposition durchgeführt. An den Rastpositionen sind beide Schalter geschlossen (AB = 11) oder beide Schalter geöffnet (AB = 00). Aufgrund des Zustands vor Erreichen einer dieser Rastpositionen kann die Richtung der Drehung bestimmt werden, die zu diesem Zustand geführt hat. Die Software muss die Werte vor einer Änderung zwischenspeichern, da diese zur Bestimmung der Drehrichtung bei Erreichen einer Rastposition benötigt werden. Aus dem Taktmuster ergibt sich: Rastposition 00: zuvor 01 ­ Drehung im Uhrzeigersinn, zuvor 10 ­ Drehung gegen den Uhrzeigersinn Rastposition 11: zuvor 10 ­ Drehung im Uhrzeigersinn, zuvor 01 ­ Drehung gegen den Uhrzeigersinn Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 35 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 6.2 Schaltplan Der Anschluss eines Drehimpulsgebers an den IOWarrior ist verhältnismäßig einfach. Die beiden Pins A und B können direkt mit je einem Pin des IOWarrior verbunden werden. Der mittlere Anschluss des Drehimpulsgebers GND wird mit der Masse des IOWarrior verbunden. Ein Pin des Druck­Tasters wird mit einem Pin des IOWarrior verbunden, der zweite mit GND. IO­WARRIOR24 GND P P P P P P P P 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 1 2 3 4 24 23 22 21 B GND A 9 Abbildung 6.2.1 ­ Schaltplan Anschluss eines Drehimpulsgebers an den IOWarrior 6.3 Bauplan Abbildung 6.3.1 ­ Bauplan Anschluss eines Drehimpulsgebers an den IOWarrior Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 36 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle 6.4 Anwendung 5 ­ Auswertung der Daten eines Drehimpulsgebers ­ IOW_Drehimpulsgeber Diese Anwendung soll die Drehbewegung und den Zustand des Druck­Tasters des Drehimpulsgebers auswerten und grafisch darstellen. Der einzustellende Wert soll im Bereich zwischen ­40 und +40 liegen, in einem Label angezeigt werden und zusätzlich einen Schieberegler bewegen. Dabei ist zu berücksichtigen, dass auch eine Änderung des Schiebereglers mit der Maus den Wert verändern kann. Ein Panel soll den gedrückten Zustand des Druck­Tasters signalisieren. Verwendete Komponenten ProduktIDLabel (Label) SeriennummerLabel (Label) WertLabel (Label) WertBar (TrackBar, Minimum ­40, Maximum 40) TasterPanel (Panel) ReadTimer (Timer, Interval 20) Abbildung 6.4.1 ­ Screenshot der Anwendung IOW_Drehimpulsgeber Definition globaler Variablen und Import der benötigten Funktionen aus der iowkit.dll Zu Beginn werden die globale Variable IowHandle und das Array Data[] definiert. Zusätzlich werden in dieser Anwendung noch die globalen Variablen A, B, Aold und Bold (Zustand der Schalter im Drehimpulsgeber) und die Variable Wert (der mit dem Drehimpulsgeber veränderbare Zahlenwert) verwendet. Zum Import der benötigten Funktionen aus der iowkit.dll muss die Klasse System.Runtime.InteropServices mit einer using­Anweisung eingebunden werden. public partial class MainForm : Form { // Definition der global benötigten Variablen int IowHandle; byte[ ] Data; int A, Aold; int B, Bold; int Wert; // Import der benötigten Funktionen aus der iowkit. dll [ 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 IowKitReadNonBlocking( int iowHandle, int numPipe, ref byte buffer, int length) ; [ 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) ; ... Quelltext 6.4.1 ­ Definition globaler Variablen und Import der benötigten Funktionen aus der iowkit.dll Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 37 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Herstellen der Verbindung zum IOWarrior Beim Start der Anwendung werden in der Ereignisbehandlung des Events Load die ProduktID und die Seriennummer des angeschlossenen IOWarriors eingelesen. Bei der Initialisierung des Data­Arrays und des IOWarriors ist das Byte Data[0] auf 0x00 zu setzen. Da die drei Pins P0.4, P0.5 und P0.6 als Eingänge genutzt werden, sind diese auf 1 zu setzen ­ das Byte Data[1] bekommt den Wert 0x70 (01110000). Die Pins am Port 1 werden nicht benötigt und auf 0 gesetzt ­ Data[2] erhält den Wert 0x00 (00000000). Weiters müssen noch die globalen Variablen initialisiert werden. Die Variablen A und B (aktueller Zustand der Schalter im Drehimpulsgeber), Aold und Bold (Zustand der Schalter im Drehimpulsgeber vor der letzten Änderung) und Wert (der vom Drehimpulsgeber veränderbare Zahlenwert der Anwendung) erhalten den Wert 0. Abschließend muss noch der Timer gestartet werden, der in einem Intervall von 20ms den Zustand der Pins des IOWarriors und somit auch des Drehimpulsgebers einliest. void MainFormLoad( obj ect sender, EventArgs e) { // Variablendefinition int ProduktID = 0; short[ ] SerienNummer = new short[ 8] ; string SerienNummerString = " " ; // Verbindung zu IOWarrior herstellen IowHandle = IowKitOpenDevice( ) ; if ( IowHandle==0) { MessageBox. Show( " Kein IO-Warrior gefunden! " ) ; } else { // ProduktID ermitteln und anzeigen ProduktID = IowKitGetProductId( IowHandle) ; if ( ProduktID==0x1501) { ProduktIDLabel. Text = " Produkt ID: IOWarrior2 4 " ; } else { ProduktIDLabel. Text = " Produkt ID: unbekannt" ; } // Seriennummer ermitteln und anzeigen if ( IowKitGetSerialNumber( IowHandle, ref SerienNummer[ 0] ) ) { foreach( char c in SerienNummer) SerienNummerString = SerienNummerString + c; SeriennummerLabel. Text = " Seriennummer: " + SerienNummerString; } else { SeriennummerLabel. Text = " Seriennummer: unbekannt" ; } // Byte-Array für den Datenaustausch initialisieren Data = new byte[ 3] ; Data[ 0] = 0x00; Data[1] = 0x70; // P0. 4, P0. 5 und P0. 6 auf HI Data[ 2 ] = 0x00; IowKitWrite( IowHandle, 0, ref Data[ 0] , 3) ; Quelltext 6.4.2 ­ Initialisieren der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 38 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle // Variablen für die Schalterzustände des Drehimpulsgebers initialisieren A = 0; Aold = 0; B = 0; Bold = 0; Wert = 0; } } // Timer zum Einlesen der Pinzustände aktivieren ReadTimer. Enabled = true; Quelltext 6.4.2 Fortsetzung ­ Initialisieren der Anwendung Auswertung der Pinzustände In der Ereignisbehandlung des Timer­Events werden die Pinzustände eingelesen und analysiert. Basierend auf der in 6.1 beschriebenen Bitfolge wird die Drehrichtung bestimmt. Pin A des Drehimpulsgebers ist mit P0.6 der IOWarrior verbunden, es muss der Zustand des siebenten Bits von Port 0 ermittelt werden (0x40 bzw. 01000000). Der Schaltzustand von Pin B entspricht Pin P0.5 und somit dem sechsten Bit von Port 0 (0x20 bzw. 00100000). Der Druck­Taster ist mit Pin P0.4 verbunden ­ dessen Zustand entspricht also dem fünften Bit des Port 0 des IOWarrior (0x10 bzw. 00010000). Mit zwei if­Abfragen kann die Drehrichtung bestimmt werden ­ in den jeweiligen Bedingungen ist das Schema der Abfolge der Schaltzustände der Pins A und B des Drehimpulsgebers umgesetzt (siehe 6.1). Nach der Anzeige der geänderten Werte wird der aktuelle Zustand der Pins A und B in den Variablen Aold und Bold für den nächsten Vergleich abgelegt. void ReadTimerTick( obj ect sender, EventArgs e) { int AStatus = 0; int BStatus = 0; int TasterStatus = 0; IowKitReadNonBlocking( IowHandle, 0, ref Data[ 0] , 3) ; AStatus = Data[ 1] & 0x4 0; if ( AStatus==0x00) A=1; else A=0; BStatus = Data[ 1] & 0x2 0; if ( BStatus==0x00) B=1; else B=0; TasterStatus = Data[ 1] & 0x10; if ( TasterStatus==0x00) TasterPanel. BackColor = Color. Green; else TasterPanel. BackColor = Color. Black; if ((A==1) &&(B==1) &&(Aold==0) &&(Bold==1) | | (A==0) &&(B==0) &&(Aold==1) &&(Bold==0) ) { if ( Wert < 4 0) Wert++; // Drehung im Uhrzeigersinn } if ((A==1) &&(B==1) &&(Aold==1) &&(Bold==0) | | (A==0) &&(B==0) &&(Aold==0) &&(Bold==1) ) { if ( Wert > -4 0) Wert--; // Drehung gegen den Uhrzeigersinn } WertLabel. Text = "Wert: " + Wert. ToString( ) ; // Aktualisieren der Anzeige WertBar. Value = Wert; // Aktualisieren der Anzeige } Aold = A; Bold = B; Quelltext 6.4.3 ­ Analyse und Auswertung der Drehbewegung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 39 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Schnittstelle Änderung des Schiebereglers im Programmfenster mit der Maus Bewegt ein Anwender den Schieberegler mit der Maus, so muss diese Änderung auch die globale Variable Wert betreffen. Damit ist gewährleistet, dass der Drehimpulsgeber bei der nächsten Drehung den aktuellen Wert der Variable weiter verändert. void WertBarScroll( obj ect sender, EventArgs e) { // Bewegen des Schiebereglers mit der Maus im Programmfenster Wert = WertBar. Value; } Quelltext 6.4.4 ­ Reaktion auf die Änderung des Schiebereglers mit der Maus Beenden der Anwendung Wird die Anwendung geschlossen, so muss die Verbindung zum IOWarrior getrennt werden. Zuvor ist noch der Timer zu deaktivieren. void MainFormFormClosing( obj ect sender, FormClosingEventArgs e) { // Timer zum Einlesen der Pinzustände deaktivieren ReadTimer. Enabled = false; } // Verbindung zum IOWarrior trennen IowKitCloseDevice( IowHandle) ; Quelltext 6.4.5 ­ Trennen der Verbindung zum IOWarrior beim Schließen der Anwendung Dr. Leander Brandl 2009 ­ it.brgkepler.at ­ Stand: 24.05.2009 Seite 40 ANGEWANDTE INFORMATIONSTECHNOLOGIE IO­Projekte mit der USB­Scnittstelle Anghang A ­ Zahlensysteme Möchte man 256 verschiedene Zustände darstellen, so sind dazu im binären Zahlensystem 8 Bit nötig. Eine Zusammenfassung von 8 Bit wird als 1 Byte bezeichntet und kann in den angeführten Zahlensystemen Werte aus den folgenden Bereichen annehmen: Binär 00000000 ­ 11111111 Dr. Leander Brandl 2009 ­ www.anderslernen.com Dezimal 0 ­ 255 Hexadezimal 00 ­ FF Anhang