USB IO Expander

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

von Michael Wittmann

USB IO Expander.jpg

Einleitung

Oft wäre es praktisch, einige digitale bzw analoge Signale möglichst schnell und einfach grafisch am PC darzustellen oder per digitalem Ausgang verschiedene externe Baugruppen anzusteuern. Da es relativ umständlich ist, dafür jedes mal einen Mikrocontroller zu programmieren, eine Datenübertragung mit dem Rechner herzustellen und das ganze dann auch noch zu visualisieren, ist dieses Projekt entstanden.

Der USB IO Expander besitzt jeweils 16 digitale Ein- und Ausgänge, sowie 4 analoge Eingänge. Zusätzlich sind 4 Relais integriert, sowie SPI und IIC Schnittstellen. Das ganze lässt sich über eine einfach zu bedienende Software von jedem PC aus steuern. Die Anbindung an den Rechner erfolgt über eine galvanisch getrennte USB Schnittstelle, über die das Gerät auch mit Strom versorgt wird.

Anforderungen

Mit dem USB IO Expander soll kein Ersatz für ein vollwertiges Oszilloskop oder einen Logikanalyser geschaffen werden. Dies wäre auf Grund der begrenzten Rechenleistung des verwendeten AVR sowie aus Kostengründen auch gar nicht zufriedenstellend möglich. Aus diesem Grund habe ich mich bewusst auf den niederfrequenten Bereich (einzelne Funktionen bis 100kHz) beschränkt, da alles andere nur Kompromisse gewesen wären. Ein wesentlicher Punkt war jedoch ein vollständige galvanische Trennung vom PC. Dies vereinfacht die Arbeit mit dem Gerät doch sehr, da man nicht aufpassen muss, über andere Geräte Kurzschlüsse über den Schutzleiter herzustellen (Die Masse eines PCs liegt auf Erdpotential, so dass zum Beispiel der gleichzeitige Einsatz eines Programmieradapters kritisch wäre).

Features

  • USB Schnittstelle
  • 16 digitale Eingänge
  • 16 digitale Ausgänge
  • 4 unabhängige Analoge Eingänge
  • 4 Relais
  • SPI Schnittstelle
  • IIC Schnittstelle (für zukünftige Erweiterungen)
  • Stromversorgung über USB
  • galvanische Trennung zum Rechner
  • einfach zu bedienende Steuersoftware am PC
  • Ausgabe von Mustern an den digitalen Ausgängen möglich (Patterngenerator; bis maximal 100kHz)
  • eingeschränkt als Logic Analyser verwendbar (auch bis 100 kHz; gleichzeitig mit dem Pattern-Generator verwendbar )

Hardware

Schnittstellen

USB

Die USB Schnittstelle hat 2 Funktionen. Einmal geschieht die Stromversorgung über diese, zum anderen wird sie auch für die Datenübertragung zum PC genutzt, da die meisten neuen Computer keine seriellen Schnittstellen mehr haben. Das Gerät meldet sich als USB-seriell Konverter am PC an und fordert den maximal möglichen Strom von 500mA an. Deshalb kann man den USB IO Expander nur an aktiven USB Hubs bzw direkt am Rechner verwenden. Passive Hubs werden nicht unterstützt. Die 500mA werden jedoch höchstens benötigt, falls alle 4 Relais eingeschaltet sind und alle 16 digitalen Ausgänge mit den maximal erlaubten 20mA belastet werden. Um eine komplette galvanische Trennung vom PC zu erreichen, wurden die RX/TX Leitungen der UART mittels Optokopplern isoliert und die 5V USB Spannung mit einem galvanisch isolierten DC/DC Wandler entkoppelt. Zusätzlich ist ein FET vorhanden, der – wie in der USB Spezifikation gefordert – die Versorgungsspannung des Gerätes abschaltet, falls der USB Controller im PC das verlangt. Es wird ein FT232R USB-seriell Wandlerchip verwendet. Es wäre zwar auch möglich, eine USB Schnittstelle in Software im AVR zu integrieren, hier sprechen jedoch mehrere Dinge dagegen: Zum einen ist es so nur sehr schwer möglich die serielle Schnittstelle galvanisch zu trennen, zum anderen ist der Controller damit ziemlich ausgelastet, so dass weniger Rechenleistung bzw Speicher für seine eigentlichen Aufgaben zu Verfügung steht. Da man den FT232 für unter 4 Euro bekommt, war mir das den zusätzlichen Aufwand nicht Wert. Zudem sollte der FT232 Treiber auch unter Linux funktionieren (jedoch noch nicht getestet). Hier sieht man einen Ausschnitt aus dem Schaltplan:

Usb io expander layout usb sch.png

Das Bauteil ganz oben ist der DC/DC Wandler, der die Versorgungsspannungen galvanisch trennt. F1 ist eine Polyfuse, die im Falle eines Kurzschlusses den USB Port trennt. Auf Grund des begrenzten Kurzschlussstroms des DC/DC Wandler kann man sich die Sicherung evtl. sparen, was jedoch nicht unbedingt zu empfehlen ist. Die beiden Optokoppler auf der rechten Seite sorgen schließlich noch für die galvanische Trennung der RX/TX Leitungen, so dass der USB Port komplett vom restlichen Gerät entkoppelt ist.

Digitale Ein-/Ausgänge

Es sind jeweils 16 Ein- und Ausgänge vorhanden, die für 5V TTL Pegel ausgelegt sind. Es wurde großer Wert darauf gelegt, das Gerät möglichst robust zu gestalten. Deshalb vertragen die Eingänge Spannung bis zu 12V. Die Ausgänge sind kurzschlussfest. Sie sind darauf ausgelegt, pro Ausgang bis zu 20mA zu liefern. So kann man LEDs ohne zusätzliche Transistoren anschließen. Die digitalen Ein-/Ausgänge sind zusätzlich durch integrierte gesockelte Treiber geschützt, so dass man im Falle eines Defekts nur diesen austauschen muss. Die Ansteuerung der insgesamt 32 Leitungen ist über 4 Schieberegister vom Typ 4021 realisiert. Als Treiberbausteine kommen 4 ICs vom Typ 74AC245 zum Einsatz (der AC Typ wurde wegen der höheren Strombelastbarkeit gewählt, prinzipiell kann aber jeder kompatible Chip verwendet werden – dann aber evtl. mit Einschränkungen beim maximal entnehmbaren Strom).

Analoge Eingänge

Zusätzlich sind 4 analoge Eingänge verfügbar, die Spannungen im Bereich von 0-5V mit einer Auflösung von 8Bit messen können. Auch hier sind Spannungen bis 12V ohne Beschädigung der Hardware möglich, auch wenn sich der messbare Bereich auf 5V beschränkt. Eventuell muss man hier einen externen Spannungsteiler zuschalten. Zur A2D Wandlung wird der integriert Wandler des AVR verwendet.

Relais

Die 4 eingebauten Halbleiterrelais können Ströme bis zu einem Ampere schalten. Sie sind durch optionale interne 5x20mm Sicherungen abgesichert, so dass auch hier eine Beschädigung der Hardware fast ausgeschlossen ist.

SPI

Weiterhin befindet sich eine SPI Schnittstelle im Gerät. Diese kann frei konfiguriert werden und sollte so für jede Anwendung verwendbar sein, die 8Bit Daten erwartet. Auch die SPI Schnittstelle ist tolerant gegenüber 12V Spannungen, arbeitet selber jedoch auch mit 5V TTL Pegeln. Es wird die im AVR integrierte SPI Schnittstelle verwendet.

IIC

Für das IIC Interface wird die im AVR integrierte Schnittstelle verwendet. Außerdem ist diese ebenfalls mit Schutzdioden ausgestattet, und überlebt so Spannungen bis 12V. Im momentanen Entwicklungsstand ist die IIC Schnittstelle jedoch noch nicht in die Software integriert, da sie nur für eventuelle Erweiterungen dient (z. B. Hinzufügen eines Temperatursensors).

Controller

Als Controller ist ein Mikrocontroller vom Typ AtMega8 verbaut. Dieser ist mit 14,746 Mhz getaktet, um eine Problemlose UART Übertragung zu gewährleisten. Außerdem bietet er genug Speicherreserven um evtl noch weitere Softwarekomponenten hinzuzufügen.

Platine

Die Platine besteht eigentlich aus zwei Teilen, und zwar der eigentlichen Controller-Platine und einer weiteren optionalen, die nur die Sicherungen für die Relais aufnimmt und zur Befestigung einer Schraubklemme am Gehäuse dient. Die doppelseitige Controller-Platine hat eine Größe von ca 7x10 cm und passt genau in ein "TEKO WALL 3" Gehäuse von Reichelt. Sie ist auf folgendem Bild zu sehen:

Usb io expander layout brd.png

Die Relais-Out Platine ist ebenfalls doppelseitig und genau so groß, dass darauf vier 5x20mm Sicherungen Platz haben. Sie hat auf einer Seite eine Ausbuchtung. Diese sollte durch einen Schlitz im Gehäuse gesteckt werden, um dort eine Schraubklemme aufzulöten. Diese ist dann von außen erreichbar. Die Relais-Out Platine ist optional und kann weggelassen werden, falls man die Sicherungen für die Relais nicht benötigt bzw die Anschlüsse der Relais anderweitig aus dem Gehäuse führen möchte. Die Relais-Out-Platine ist hier zu sehen:

Usb io expander layout rel brd.png

Um das ganze möglichst kompakt zu halten, konnte auf SMD Bauteile nicht verzichtet werden. Alle Teile mit Ausnahme der Treiberstufen sind SMD-Bauteile. Die Treiber sind als DIP Gehäuse ausgeführt und gesockelt. So kann man im Falle eines Defektes diese ohne Lötarbeiten austauschen. Alle extern zugänglichen Signale wurden auf der Platine herausgeführt. Die digitalen Ein-/Ausgänge sind als 2x5 polige Stiftleiste ausgeführt. Somit kann diese z. B. mit einem 10poligen Flachbandkabel herausführen. Alle anderen Signale (A2D, IIC, SPI) wurden mittels einfachen Stiftleisten verfügbar gemacht. Zudem befinden sich mehrere Testpunkte auf der Platine, an denen sich bei der Inbetriebnahme einfach zugänglich alle Versorgungsspannungen messen lassen. Auf diesem Foto kann man erkennen, wie die kleine Platine rechts zur Befestigung der Schraubklemme dient sowie die Verkabelung mit Flachbandkabeln.

USB IO Expander offen.jpg

Gehäuse

Als Gehäuse kann z. B. wie bereits vorgeschlagen ein TEKO WALL 3 zum Einsatz kommen. Es müssen jedoch z. B. mit einem Dremel Öffnungen für die USB Buchse sowie für die restlichen Ein- und Ausgänge hinein gefräst werden. Eine mögliche Realisierung (die ich gewählt habe) besteht z. B. darin, alle Signale über D-Sub Buchsen herauszuführen. Auf der schmalen Seite des verwendeten Teko Gehäuse, ist gerade genug Platz um nebeneinander sechs D-Sub Buchsen einzubauen. Wenn man welche nimmt, in die man direkt Flachbandkabel einpressen lassen, kann man so ohne großen Aufwand alle Signale nach außen führen. Falls die Variante mit den D-Sub Buchsen gewählt wird, kann z. B. die folgende Vorlage als Beschriftung für das Gehäuse verwendet werden.

USB IO Expander Belegung.png

Software

Firmware im AVR

Allgemeines

Die Firmware ist komplett in C programmiert. Als Compiler kam der gcc zum Einsatz. Die Firmware ist in verschiedene Module unterteilt. Jedes dieser Module ist für eine bestimmte Funktion bestimmt. Da die meisten Module sehr simpel aufgebaut sind, soll hier nur ein grober Überblick über die Funktionsweise gegeben werden. Jede Funktion im Quellcode ist kommentiert, so dass es relativ leicht sein sollte, die Funktionalität nachzuvollziehen.

ShiftRegister Modul

Dieses Modul dient der Ansteuerung der Schieberegister, also dem Einlesen der digitalen Eingänge sowie dem Ausgeben von Werten auf den digitalen Ausgängen. Die Ansteuerung der Schieberegister wird komplett in Software erledigt. Ein Verwenden der Hardware-SPI-Schnittstelle wäre zwar etwas schneller, aber da in diesem Fall die Geschwindigkeit keine Rolle spielt, wurde das SPI-Interface freigehalten.

ADC Modul

Diese Modul stellt Funktion bereit, mit denen man Werte des ADC einlesen kann. Die Read-Funktion blockiert solange, bis der ADC mit dem Einlesevorgang fertig ist. Da auch hier keine hohen Sampleraten erreicht werden sollen, spielt das keine Rolle, so dass ein Abfragen über Interrupts keinen Sinn macht (der AVR würde in der Zwischenzeit sowieso nur warten).

Relais Modul

Dieses sehr simple Modul dient einzig dazu, die 4 Relais anzusteuern. Da der AVR die Relais direkt über Treibertransistoren ansteuert, beschränkt sich die Funktionalität hier auf das setzten bzw löschen von Port-Pins.

SPI Modul

Das SPI-Modul kapselt den Zugriff auf die AVR-interne SPI Schnittstelle. Es erlaubt das senden von Daten sowie die Konfiguration der Schnittstelle. Auch hier blockieren die Sende-Routinen bis der Vorgang beendet ist, da keine hohen Anforderungen an die Geschwindigkeit gestellt werden.

RingBuffer8/16 Modul

Das Ringbuffer Modul steuert keine externe Peripherie, sondern stellt Funktionen zur Verfügung, um einen Ring-Puffer zu verwalten. Ein Ring-Puffer ist eine Struktur die nach dem FIFO-Prinzip arbeitet (First-In-First-Out). Es werden zwei Varianten verwendet, eine die 8 Bit Daten speichert und eine für 16 Bit breite Daten.

Pattern Modul

Dient der Generierung von Mustern am Ausgang, sowie dem Timer-gesteuerten Einlesen der Eingänge. Die Funktionalität ist als Zustandsautomat realisiert. Dieses Modul stellt dem Parser eine einfach zu benutzende Schnittstelle zum Patterngenerator bereit.

Uart Modul

Verwaltet zwei Puffer, um Daten zum PC zu senden bzw. von diesem zu empfangen. Die komplette Sende/Empfangslogik ist durch dieses Modul gekapselt.

Parser Modul

Dies ist der eigentliche Kern der Software. Es verarbeitet die vom PC empfangenen Daten und führt eventuell erhaltene Befehle aus. Die Kernfunktionaliät ist in der Funktion Parser_Process implementiert. Diese wird in einer Endlosschleife aufgerufen und stellt den eigentlichen Parser dar. Zuerst wird geprüft, ob sich im Einganspuffer ein Befehls-Byte befindet. Falls dies der Fall ist, wird im folgenden switch Statement der entsprechende Befehl ausgeführt.

Eigene Erweiterungen

Um dem Parser neue Befehle beizubringen, muss nur in der Funktion Parser_Process() das switch(cmd) Statement nach folgendem Schema erweitert werden:

case CMD_NEW_COMMAND: //entprechenden Befehl einsetzen
{
	if(Uart_DataAvaible(5) //je nach Anzahl der Bytes, die zu einem Befehl gehören, anpassen; hier: warte bis 5 Bytes empfangen wurden
	{
		uint8_t data = Uart_GetByte(); //empfangene Daten in Variable einlesen
		uint8_t data2 = 45;
		Uart_SendByte(data2); //Daten senden

		cmd = CMD_NO_COMMAND; //notwendig damit der Befehl nur einmal ausgeführt wird
	}
}break;

Compilieren

Die Software compiliert mit dem AVR-GCC Compiler (WinAVR 20080610 getestet). Einfach alles in einen Ordner entpacken, und make aufrufen (ein Makefile wird mitgeliefert).

Steuersoftware auf dem PC

Die Software wurde komplett in C++ implementiert und verwendet die Qt Bibliothek. Ursprünglich wurde sie für Windows geschrieben, auf Grund der Plattformunabhängigkeit der Qt Bibliothek sollte sie aber auch unter Linux compilieren, da keine Windows-spezifischen Funktionen verwendet wurden (jedoch nicht getestet). Zusätzlich wurde die FTD2XX.dll Bibliothek von FTDI verwendet, die zur Ansteuerung des verwendeten USB Chips dient. Es wurde hier auf die Verwendung eines virtuellen COM-Ports verzichtet, und stattdessen der FTD2XX Treiber verwendet, da dieser auch unter Linux zur Verfügung steht. Ansonsten hätte eine plattformunabhängige Lösung gefunden werden müssen, um COM Ports zu verwalten. Außerdem vereinfacht die gewählte Lösung die Handhabung des Gerätes, da die Software ohne Auswahl eines COM-Ports das Gerät stets findet. Hier soll nun ein grober Überblick über den Aufbau gegeben werden.

GUI

Die GUI besteht zunächst einmal nur aus einem Hauptfenster, das unten ein Info-Feld sowie Informationen zu Verbindung bereitstellt. Im oberen Bereich befindet sich Fenster, in das dann die verschiedenen Funktionen als eigenständige Tabs integriert werden können. In Version 2 kamen folgende Änderungen hinzu:

Auf der linken Seite befindet sich ein Paneel, über das sich die einzelnen Module auswählen lassen. Dies ist auch über Shortcuts möglich ("Strg+1", für das erste Modul usw). Über die neue Menüleiste am oberen Rand, kann das Gerät reseted werden, die Ansicht konfiguriert werden sowie Informationen zur Softwareversion sowie Hinweise zur Benutzung abgerufen werden.

Pattern
Usb io expander gui pattern.png

Oben rechts befinden sich zwei Buttons, um ein Pattern zu definieren und um den eingebauten Trigger zu konfigurieren. Das Pattern wird auf Wunsch dann am Ausgang ausgegeben. Hierzu dient unten rechts der "Samplen"-Button. Mit den beiden Checkboxen kann ausgewählt werden, ob ein Pattern ausgegeben werden soll ("output") bzw der Eingang gepollt werden soll ("input"). Auch eine Kombination ist möglich. Falls ein Trigger definiert ist, startet die Ein-/Ausgabe erst, falls die Triggerbedinung erfüllt ist.

Die "Anzahl der Samples"-Box wird nur ausgewertet, falls kein Output-Pattern definiert ist. Ansonsten wird die Anzahl der Samples an Hand des definierten Pattern bestimmt.

Die "Speichern" bzw. "Laden" Buttons dienen dazu, die aktuellen Pattern, sowie den Trigger und alle Einstellungen auf der Festplatte zu speichern.


Digitalen Ein-/Ausgänge, Relais und A2D
Usb io expander gui inout.png

Im unteren Bereich kann festgelegt werden, ob die Ein-/Ausgänge automatisch aktualisiert werden sollen (eventuell mit dem Intervall, mit dem die Eingänge abgefragt werden). Ansonsten muss jede Zustandsänderung explizit von Hand angestoßen werden.


SPI-Kommunikation
Usb io expander gui spi.png

Im oberen Bereich kann die SPI-Schnittstelle konfiguriert werden.

Das Datenfeld unten bietet verschiedene Anzeigemodi (Binär, Dezimal, Hex), die mit den Checkboxen ausgewählt werden können. Die zu sendenden Daten werden byteweise binär gewandelt und über die SPI Schnittstelle gesendet. Als Trennzeichen zwischen den Bytes dient ein Leerzeichen.


Servo-Steuerung
Usb io expander gui servo.png

Hierüber können bis zu 8 Servos gleichzeitig gesteuert werden. Mit den Drehreglern im oberen Bereich kann der Winkel jedes Servos einzeln festgelegt werden. Mit der Checkbox unter jedem Regler kann die Richtung des zugehörigen Servos invertiert werden.

Mit den beiden Textfeldern unten rechts wird die Länge der Servo-Impulse festgesetzt. Standardmäßig werden Servos mit Impulsen zwischen 1 und 2 ms angesteuert. Einige Servos erreichen so jedoch nicht ihre Randposition, so dass man die Impulslänge hier korrigieren kann.


USB-Kommunikation

Für die Kommunikation mit dem Gerät ist die Klasse CIOExpanderCommunicationModule zuständig. Diese besitzt mehrere Slots, mittels deren andere Programmteile mitteilen, falls Daten gesendet werden sollen. Über den Empfang von neuen Daten vom Gerät informiert die Klasse mit Hilfe von Signalen.

Die Kommunikation mit dem Gerät wird in einem eigenen Thread abgearbeitet, um währenddessen die GUI nicht zu blockieren. Die Senderoutinen verwenden einen FIFO-Puffer um die Daten vor dem Senden zwischenzuspeichern. Falls ein Befehl eine Antwort erwartet, wird eine Variable vom Typ CUSBCommand in einer Warteschlange gespeichert. Damit kann der Parser jedes empfangene Datenbyte eindeutig einem vorher gesendeten Befehl zuordnen.

Eigene Erweiterungen

Um der Programmoberfläche eigene Tabs hinzuzufügen, muss für jedes neue Tab eine eigene Klasse erstellt werden. Diese muss von CIOExpanderWidget abgeleitet sein. Ein Objekt dieser Klasse muss in CIOExpanderCentralWidget::SetupLayout() instanziert werden:

m_neuesWidget = new CNewTabWidget; //je nach verwendetem Name anpassen

Zusätzlich muss im Konstruktor der neuen Klasse der Konstruktor der Basisklasse CIOExpanderWidget richtig initialisiert werden:

CNewTabWidget::CNewTabWidget()
:CIOExpanderWidget(tr("Name des Tabs"),tr("Name des zugehörigen Icon.png"))
{
}

Ansonsten muss nichts konfiguriert werden, da jedes neu erzeugte Tab-Fenster automatisch alle zugehörigen Einträge sowie Shortcuts in der Menleiste erzeugt.

Die Kommunikation mit CIOExpanderCommunicationModule muss über den Qt internen Signals/Slots Mechanismus abgewickelt werden. Hier zu muss die CIOExpanderCommunicationModule Klasse gegebenefalls um weitere Signale/Slots ergänzt werden.

Um Daten zu senden, muss pro Befehl ein Slot definiert werden, in dem die zu sendenden Daten einfach mit Hilfe des folgenden Code gesendet werden.

	CUSBCommand	cmd(CMD_DUMMY); //das Befehlsbyte
	cmd.setAnswerBytes(4); //dieser Befehl erwartet 4 Byte als Antwort
	cmd << 1; //sende zusätzlich noch Daten mit dem Befehl
	SendCommand(cmd); //sendet den Befehl

Die Verarbeitung von Daten, die über USB empfangen wurden, muss in der Funktion CIOExpanderCommunicationModule::ProcessReceivedData() ergänzt werden.

	switch(cmd) //bereits vorhanden
	{
		case CMD_NEW_COMMAND: //je nach Namen anpassen
		{
			//Hier entsprechende Aktion ausführen
			emit NewCommandSignal(); //zugehöriges Signal emittieren, um GUI zu benachrichtigen
		}break;
	};

Es ist sichergestellt, dass mindestens so viele Bytes empfangen wurden, wie benötigt werden. Die ProcessReceivedData() Funktion wird auch nur aufgerufen, falls wirklich Daten verarbeitet werden sollen.

Compilieren

Um das Programm zu compilieren, wird eine funktionierende Qt Installation auf dem Rechner vorausgesetzt (Version 4.4.0/4.5.0 getestet, eine ältere 4.x Version sollte auch funktionieren). Das Programm wurde - wie die Software für den AVR - mit der Entwicklungsumgebung Codeblocks geschrieben, diese ist aber nicht notwendig, um das Programm zu übersetzen. Das Programm compiliert mit dem gcc Compiler (MinGW) unter Windows, sollte aber auch mit Visual Studio bzw unter Linux compilierbar sein (nicht getestet). Um das Programm zu erstellen muss man nur einmal im Projektordner ein "qmake" ausführen und kann anschließend den Compiliervorgang mit einem "make" starten. In der zip-Datei befindet sich eine QT-Projektdatei (IOExpanderControl.pro). Dort müssen auch bei Änderungen am Programm eventuell neue Sourcedateien hinzugefügt werden. "qmake" erzeugt daraus schließlich das Makefile, mit dem "make" arbeitet. Um das Programm zu starten, muss der FTDI Treiber auf dem Rechner installiert sein. Ansonsten erscheint beim Programmstart ein Fehler wegen einer fehlenden DLL (FTD2XX.dll).

Achtung (nur Windows): Die auf der FTDI Seite erhältliche FTD2XX.lib arbeitet nicht ohne weiteres mit dem GCC-Compiler zusammen, da diese für den Microsoft-Compiler gedacht ist. Diese muss man erst in eine .a Datei konvertieren. Dazu wird das dlltool benötigt (bei MinGW dabei). Man kopiert die FTD2XX.dll sowie die zugehörige .lib und .def Datei (erhältlich bei FTDI) in einen Ordner und tippt folgendes in eine Konsole:

dlltool --input-def FTD2XX.def --dllname FTD2XX.dll --output-lib FTD2XX.a -k

Falls man anschließend compiliert, erhält man wahrscheinlich mehrere Linkerfehler in der Art „undefined Reference to XXX@n“, wobei XXX eine Funktion ist und n eine ganze Zahl. Um hier Abhilfe zu schaffen muss in der FTD2XX.def Datei jedes vorkommen von XXX durch XXX@n ersetzt werden und die .lib Datei erneut konvertiert werden. Dies muss für jeden Linkerfehler wiederholt werden. Eine FTD2XX.a Datei ist bereits im Paket enthalten (Version 3.1.15.0), evtl. kann diese aber mit neueren Treibern nicht mehr verwendet werden. Zumindest mit den in Windows7 integrierten Treibern arbeitet die Datei aber immer noch - am besten also einfach ausprobieren.

Achtung (nur Linux): Der FTD2XX Header ist für Windows gedacht. Auf der FTDI Seite gibt es einen angepassten Header für Linux (im Treiber enthalten). Falls das Programm unter Linux verwendet werden soll, muss natürlich dieser verwendet werden.

Definitionen der Befehle

Grundsätzlich ist jeder Befehl gleich aufgebaut. Das erste Byte kennzeichnet den eigentlichen Befehl, alle anderen (optionalen) Bytes haben bei jedem Befehl eine unterschiedliche Bedeutung. Hier ist eine Übersicht über alle momentan implementierten Befehle:

Funktion 1. Byte 2. Byte 3. Byte 4. Byte 5. Byte 6+ Bytes
Lese ADC Wert 'a' Kanal
Setze Timer Frequenz 'f' Prescaler OCR-Wert
Schreibe Wert auf digitale Ausgänge 'o' Pin 0-7 Pin 8-15
Lese digitale Eingänge 'i'
Schreibe Muster auf digitale Ausgänge 'p' Anzahl Samples Samples Samples Samples
Lese digitale Eingänge wiederholt 's' Anzahl
Kombination aus 's' und 'p' 'x' Anzahl Samples Samples Samples Samples
Setzte Relais Status 'r' Relais Zustand
Sende Daten über SPI 't' Daten
Konfiguriere SPI 'c' SPCR Register SPSR Register
Trigger setzen 'z' Trigger1 Trigger1 Trigger2 Trigger2
Reset 'y'
Servosteuerung 'm' OCR für Timer OCR für Timer OCR für Timer OCR für Timer OCR für Timer
Software Version 'v'

Ein paar Worte zu den verwendeten Bauteilen

Ich habe hier bewusst keine Liste eingestellt, in der die genauen Typbezeichnungen und Menge jedes Bauteils stehen (das macht Eagle sowieso automatisch und den Schaltplan gibt es ja hier zum Download). Bei einigen Teilen bin ich nämlich noch auf der Suche nach der optimalen Variante. Zum einen wären das die beiden Optokoppler. Wie sich herausgestellt hat, ist es gar nicht so einfach, schnelle SMD Typen zu finden. Deshalb habe ich im Moment "nur" Standardtypen verbaut, die jedoch die UART Geschwindigkeit begrenzen. Die Übertragung läuft im Moment nur mit 19,2kBaud. Im Prinzip ist das jedoch ausreichend, da eine Echtzeitdatenübertragung von Anfang an nicht gefordert war (Anmerkung: wie sich mittlerweile herausgestellt hat, reichen die 19200 Baud dicke, da auf Grund der kleinen Datenmengen eine Verzögerung durch die Übertragung kaum bemerkbar ist). Zum anderen habe ich im Moment für den MosFET Q5 (über den der FT232 die Stromversorgung schaltet) einen Typen im TO220 Gehäuse gewählt, der nicht ganz ins Layout passt. Die einzigen Kriterien, die er erfüllen muss, sind bei 5V Gate-Spannung durchzuschalten (Logic-Level p-Kanal Typ) und einen maximalen Strom von mindestens 500mA schalten zu können. Eine Alternative dazu wäre ein FDS4435 im SO-8 Gehäuse. Raum für Verbesserungen bietet auch der DC/DC Wandler (momentan verwendet: SIM2-0505S SIL7 von Reichelt). Dieser liefert zwar eine ziemlich ungenaue Ausgangsspannug (evtl. wie weiter unten beschrieben mit einem zusätzlichen Lastwiderstand nachhelfen), funktioniert aber bis jetzt ohne Probleme.

Inbetriebnahme

Es biete sich an, zuerst den FTDI Chip nebst Peripherie sowie den DC/DC Wandler zu bestücken. So kann die korrekte Spannungsversorgung mit Hilfe der auf der Platine befindlichen Testpunkte geprüft werden. Bei einigen DC/DC Wandlern ist die Leerlaufspannung höher als die angegebene Spannung (gemessen bis zu 7V statt der angegebenen 5V). Unter Last geht sie auf das angegebene Niveau zurück. Deshalb kann es sein, dass man den DC/DC Wandler mit einem zusätzlichen Widerstand belasten muss, um die Spannung in einem verträglichen Bereich zu halten (max 5,5V). Der genaue Wert hängt vom Wandler ab und läst sich am einfachsten durch Ausprobieren herausfinden. Wenn die Spannung OK ist, kann man die restliche Platine gefahrlos bestücken. Wenn die Platine korrekt aufgebaut ist, und man sie über ein USB Kabel mit dem Rechner verbindet, sollte ein USB-serial-Converter erkannt werden. Dann muss mit dem Programm MProg (bei FTDI erhältlich) das EEPROM des FT232R programmiert werden. Die vorzunehmenden Einstellungen kann man hier sehen. Wirklich wichtig sind nur die "Product Description", da die Software an Hand derer das Gerät erkennt, sowie die 500mA und die Auswahl von "Bus Powered". Der "Load D2XX Driver" Schalter hat laut Dokumentation beim FT232R keinen Effekt, anscheinend wird immer sowohl der D2XX als auch der VCP Treiber geladen.

Usb io expander mprog.png

Problembehandlung

FT232

Ich habe beim Testen beobachtet, dass der FTDI-Treiber Probleme macht, falls man eine zu alte Version verwendet. Am sichersten ist es, den neuesten Treiber von der Homepage zu installieren und mit der zugehörigen FTD2XX.lib/FTD2XX.h das Programm zu compilieren. Ansonsten kann es vorkommen, dass während des Betrieb die Verbindung abreißt. Anmerkung: Die bei der Software enthaltene FTD2XX.a Datei scheint mit den neuesten Treibern ohne Probleme zu funktionieren (auch die in Windows7 integrierten). Am besten also ausprobieren und falls hin und wieder eine Meldung erscheint, dass die Verbindung zum Gerät abgebrochen ist, die FTD2XX.a Datei neu erstellen.

AVR

Falls der Controller nach Aufspielen der Software keinen Mucks von sich gibt, wurden eventuell die Fusebits falsch gesetzt. Der Controller muss so eingestellt werden, dass er mit einem externen Quarz arbeitet (kein Oszillator). Die restlichen Fusebits können in der Standardeinstellung belassen werden. Folgendes Bild zeit die Fusebits, wie sie mit AVR Prog eingestellt werden müssen.

Usb io expander fusebits.png

USB Kommunikation

Als erstes sollte man prüfen, ob der FTDI-Treiber in der neuesten Version installiert ist und ob die MProg Einstellungen korrekt sind. Ansonsten noch einmal die Löstellen am FT232R überprüfen (eventuell Lupe?!) bzw kontrollieren ob der Quarz schwingt.

Digitale Ein-/Ausgänge

Eventuell sind die 74AC245 Treiber falsch herum in die Sockel eingesetzt. Sind die Lötstellen an den Schiebregistern (SMD) korrekt?

Version 2

Die mittlerweile online stehende Version 2 weist gegenüber der ersten Version folgende Änderungen auf:

Firmware:

  • Komplett überarbeitete interne Struktur
  • erhöhte Stabilität
  • Code wurde modularer und übersichtlicher gestaltet
  • neuer Befehl um das Gerät zu Reseten
  • es ist möglich die Software Version abzufragen
  • Ansteuerung von bis zu 8 Servos möglich

PC Software:

  • Überarbeitete interne Struktur + übersichtlicherer Code
  • USB Kommunikation überarbeitet: erhöhte Stabilität
  • Ergänzung von neuen Modulen wesentlich vereinfacht
  • Paneel auf der linken Seite ausblendbar (für kleinere Monitore)
  • Infoleiste (einzeilige Statusleiste wie im Browser üblich)
  • Menüleiste
  • Möglichkeit der Ansteuerung von bis zu 8 Servos gleichzeitig mit einstellbarem Impulslängenbereich

Die alte Version steht nicht mehr zum Download bereit, da es keinen Vorteil bringt diese weiterhin einzusetzen. Kombinationen aus alter Firmware/neuer Software bzw. umgekehrt sollten funktionieren (bis auf die Servoansteuerung). Ich hab das allerdings nicht getestet.

Downloads

Links