Logiciels > Code Delphi > Acquisition sur port Joystick

Dernière mise à jour : 15/02/2007

Présentation

Vous trouverez ici un exemple de code Delphi permettant de lire une valeur analogique sur les 4 entrées analogiques d'un port Joystick.

Avertissement

Au moment où j'ai effectué les tests d'accès au port Joystick, je possédais un PC équipé de Win98, qui n'affichait pas d'erreur de type "Violation d'accès" tel que peut en afficher WinNT ou WinXP. Pour les problèmes d'accès au port parallèle sous WinNT et WinXP, je m'en suis sorti grâce à l'utilisation du driver zlportio.sys de Alexandr Zloba. Je ne doute pas un instant que ce même driver zlportio.sys puisse être d'un grand secours pour le port Joystick si ce dernier pose le même genre de problèmes sous NT ou XP.

Cablage sur port Joystick d'un PC

Le port Joystick est composé d'un connecteur DB15, dont le brochage des quatre entrées analogiques et des quatre entrées numériques est indiqué ci-dessous.

Port Joystick PC

Fonctionnement des entrées numériques D0 à D3 et analogique A0 à A3

Pour les entrées numériques D0 à D3, rien de compliqué, il suffit de lire le bit qui correspond aux bornes physiques D0 à D3.
Pour les entrées analogiques A0 à A3, c'est un peu particulier. Elles servent en temps normal à déterminer la résistance d'un potentiomètre de 100K. Après initialisation logicielle, chaque potentiomètre - monté en résistance variable - charge un condensateur de 10 nF ingré dans l'ordinateur. Un comparateur interne bascule dès l'instant où le condensateur voit à ses bornes une tension égale à 2/3 de la tension d'alimentation +5V, et à cet instant même, le condensateur se décharge. Le temps de charge du condensateur (temps qui sépare l'initialisation et le basculement du comparateur) est directement proportionnel à la valeur du potentiomètre, et on déduit donc la position du potentiomètre d'après le temps mis pour charger le condensateur. Comme la charge du condensateur est exponentielle, il convient d'effectuer un petit calcul pour "linéariser" la mesure. Comme ce calcule peut être aisement effectué de façon logicielle, inutile de chercher trop loin côté matériel. Le fait d'utiliser des condensateurs impose un calibrage indépendant pour chaque entrée analogique si l'on veut disposer d'une bonne précision. Notez que l'on peut très simplement remplacer les potentiomètres de 100K par des thermistances CTN de 100K pour lire directement la valeur de températures.

Accès au port Joystick (méthode Assembleur)

J'ai utilisé la procédure d'accès au port suivante. Le port de jeu Joystick n'occupe qu'une seule adresse mémoire, toutes les lignes de données sont lues à cette unique adresse, qui est l'adresse 201 (valeur Hexa).

// joystick


const
JoystickPortBaseAddr = $201;

function JoystickPort_ReadAnalogValues(
BaseAddr: word;
var A1, A2, A3, A4: integer;
TimeOut: integer): boolean;
var
InputValue: byte;
OutputValue: smallint;
A1Stopped, A2Stopped, A3Stopped, A4Stopped: boolean;
t: longint;
begin
A1 := 0;
A2 := 0;
A3 := 0;
A4 := 0;
InputValue := 0;
OutputValue := 0;
t := getTickCount;

// reset counter on joystick port
try
asm
mov dx, BaseAddr
mov ax, OutputValue
out dx, al
end;
except
result := false;
exit;
end;

// read joystick port, in loop for analog values,
try
repeat
asm
mov dx, BaseAddr
in al, dx
mov InputValue, al
end;
A1Stopped := not ((InputValue and 1) = 1);
A2Stopped := not ((InputValue and 2) = 2);
A3Stopped := not ((InputValue and 4) = 4);
A4Stopped := not ((InputValue and 8) = 8);
if not A1Stopped then inc(A1);
if not A2Stopped then inc(A2);
if not A3Stopped then inc(A3);
if not A4Stopped then inc(A4);
until (A1Stopped and A2Stopped and A3Stopped and A4Stopped)
or ((getTickCount - t) > longint(timeout))
except
result := false;
exit;
end;
result := true;
end;

-

Lecture de tensions sur les entrées analogiques A0 à A3

Les entrées analogique ne sont pas à proprement parler des entrées analogiques telles que celles que l'on trouve à l'entrée d'un CAN (Convertisseur Analogique / Numérique). Il est cependant possible de mesurer des tensions externes comprises entre 4V et 30V environ, et ce à peu de frais, voir le schéma ci-dessous.

Joystick Acq Tension

En procédant ainsi, le condensateur interne à l'ordinateur se charge sous une tension externe. Plus cette tension est élevée et plus la valeur de 2/3 de 5V est rapidement atteinte. On peut donc là encore faire une correspondance entre temps de charge et tension mesurée. Un condensateur peut être ajouté en parallèle sur l'entrée pour augmenter le temps de charge et ainsi améliorer la résolution de la mesure pour les tensions élevées. Bien entendu, plus la valeur du condensateur externe est élevée, et plus le temps entre deux mesures devra être grand.
Remarque : cela fait pas mal d'années que j'ai fait ces tests de lecture sur port joystick, et pour être honnête, je n'ai pas tout noté et ne me souviens plus de tout ce que j'ai pû observer. Je me rappelle simplement que ça fonctionnait.

Prototype pour tests acquisition

Côté matériel, difficile de faire plus simple...

acq_donnees_joystick_001a

4 boutons poussoir et quatre potentiomètres ajustables.

Codes source complets

Code à prendre tel quel ! Je n'ai pas le temps actuellement de mettre ça au propre, merci de votre compréhension.
Routines Communication diverses - Code source pour accès aux ports série, port joystick, port parallèle, protocoles GPIB et JBUS.
Exemple 1 de lecture sur port joystick - Logiciel Joystick, pour acquisition Numérique et analogique
Exemple 2 de lecture sur port joystick - ADDatAcq
Exemple 3 de lecture sur port joystick - ADDatAcq 2