1. Introduction
Les expériences de commande ou de contrôle de processus réels à laide dun ordinateur exigent dabord une liaison convenable de lordinateur avec le monde extérieur. Un programme doit être en mesure de récupérer des informations à lextérieur et de transmettre des signaux de commande à des appareils extérieurs. Les informations traitées peuvent se présenter sous forme binaire et ne connaître que deux états, « oui » ou « non » (0 ou 1), ou comme grandeurs analogiques (grandeurs aux variations continues).
Louverture indispensable sur le monde extérieur est offerte par des interfaces (également appelées jonctions, ports : le traducteur de ce manuel utilisera indifféremment « interface » et « port »). Les formes de ports qui se sont imposées dans lindustrie pour les PC sont les suivantes :
cartes dextension enfichées dans lordinateur. Si les vitesses de travail quelles permettent sont très élevées, elles réclament un certain investissement ;
des ports standard relient le PC à des circuits dinterface externes. Les interfaces à linterface sérielle RS232, relativement bon marché, en sont des exemples banals ;
des interfaces dotées de leur propre processeur effectuent des tâches, pratiquement sans échanges de données avec le PC. Lutilisateur doit toutefois savoir (ou apprendre à) programmer ces systèmes ;
les interfaces de toute façon présentes sur les PC, à savoir : les ports sériels, parallèle (habituellement occupé par limprimante) et, assez fréquemment, de jeu (joystick) peuvent sexploiter directement. Elles rendent ainsi superflu tout matériel supplémentaire dans de nombreuses applications.
Les expériences élémentaires peuvent utiliser directement les interfaces présentes. Il est possible de câbler sur un port sériel des diodes électroluminescentes ou des interrupteurs, sans autres composants, et de réaliser ainsi de nombreux projets intéressants. Le port parallèle offre un plus grand nombre de lignes, adressables directement, et par lesquelles les transmissions sont relativement plus rapides.
Des circuits supplémentaires simples permettent de saffranchir de nombreuses contraintes. Les détections et mesures de tensions ne réclament que peu de composants supplémentaires, si vous ne mettez pas laccent sur la rapidité et pouvez compter sur des programmes un peu plus compliqués. Sans grands frais, vous pouvez également envisager des projets demandant de nombreuses lignes dentrée et de sortie.
Les procédés que présente ce livre fonctionnent, en général, avec peu de matériel mais des programmes qui demandent un peu plus de temps de calcul. Le lecteur doit avoir lexpérience dun langage de programmation et des connaissances de base en électronique. Les circuits présentés sont, le plus souvent, si simples quune platine dexpérimentation suffit à leur montage. Tous les projets proposés sont complets et directement reproductibles. Ils peuvent, de plus, servir de base à dautres développements dont les procédés, plus compliqués, demanderont parfois le recours à certains instruments de mesure. Les lecteurs intéressés devraient, par exemple, disposer dun oscilloscope (et savoir sen servir).
Les langages de programmation quutilise ce livre pour le système dexploitation Windows 95 (ou 98) sont Visual Basic et Delphi 4. Les exemples de programme sont quasiment tous reproduits sur le CD-ROM.
1.1. PORT.DLL
Windows pose de sérieux problèmes daccès aux ports du PC. Pour les résoudre, nous utilisons ici une bibliothèque de liaisons dynamiques ou DLL (bibliothèque de sous-programmes) universelle, programmée en Delphi 3. Les DLL remplissent les fonctions dune extension de langage pour différents langages de programmation. La DLL mise au point spécialement pour ce livre, PORT.DLL est sur le CD-ROM. Copiez la dans le répertoire System de Windows où les programmes iront la chercher. A défaut, vous pouvez la copier dans le répertoire du programme .EXE dont vous souhaitez lexécution.
PORT.DLL remplit les tâches suivantes :
ouvertures de ports ;
transferts sériels de données ;
accès aux lignes de ports ;
entrées/sorties de port ;
chronomètre de précision à la milliseconde ;
chronomètre pour tranches de temps en microsecondes ;
accès à la carte son ;
entrées du port de jeu.
Des systèmes de programmation très différents peuvent utiliser la DLL : ses fonctions sont évidemment accessibles aux langages de programmation de ce manuel mais également à des programmes rédigés en C. Des programmes mis au point sur un système sexportent ainsi facilement vers dautres. La DLL peut, de plus, répondre aux appels de macros de Word ou dExcel (reportez-vous à la section 1.2 et au chapitre 14 pour plus dinformations sur ces possibilités).
En principe, Windows accède aux composants matériels par lintermédiaire de pilotes (driver). La mise au point dune DLL générale pour accéder à certains périphériques soppose quelque peu à cette façon de voir. Un pilote relève toujours dun périphérique particulier. Rien nest prévu ici pour de petites expériences matérielles. La mise au point dun pilote demande toutefois trop dinvestissement et ne concerne pratiquement que des entreprises dune certaine envergure.
Sous DOS, chaque langage de programmation proposait son instruction de port (INP et OUT sous GWBASIC ; PORT[..] dans Turbo Pascal), qui donnait un accès direct à lensemble du matériel du PC. Windows 3.1 laissait encore une certaine latitude et le programmeur pouvait sans trop de peine contourner les limites imposées. La première version de Delphi possédait toujours lantique instruction PORT.
Les choses ne sont plus si évidentes sous Windows 95. Visual Basic 5 noffre plus, directement, de possibilité daccès général aux ports. A partir de Delphi 3, les accès directs aux adresses de port ne sont plus permis quen assembleur (code Inline). Ce code est utilisé par la DLL pour restituer à Visual Basic un accès général. Le système dexploitation ne se laisse cependant pas contourner purement et simplement : avant dintervenir comme on le souhaite sur un matériel, par exemple, le port dont il relève doit être déclaré en bonne et due forme.
Windows NT enfin semble condamner définitivement les tentatives des amateurs intéressés par le matériel. Le système est conçu, sécurité oblige, pour en interdire tout accès direct. Ne reste que la voie réglementaire, par pilotes interposés. Le matériel en général devrait alors être adressé par lintermédiaire du port sériel. Tous les accès sont ici possibles, puisquils nutilisent pas daccès aux ports mais des routines réglementaires du système.
Insistons sur le fait que ce livre traite avant tout dexpérimentation avec les interfaces (ou ports) de PC. Les programmes présentés ont été mis au point sous Windows95 et Windows98 avec des systèmes à 32 bits (Visual Basic 6 et Delphi 4). Un programme peut ne pas tourner sur certains ordinateurs, si linstallation de son port présente, par exemple, quelques différences avec ce que le programmeur a prévu. Ne parlons pas de futures versions de Windows, qui peuvent encore traiter différemment les accès aux ports. Si vous tentez, sur ces bases, de mettre au point des applications professionnelles, vous risquez fort de devoir fuir sur une île déserte pour échapper aux agressions dutilisateurs frustrés!
1.2. Appels de DLL dans Visual Basic 6
Nous verrons ici, sur un exemple simple, sans matériel supplémentaire, les principes de base dutilisation dune DLL. Le haut-parleur du PC est attaqué par des composants que des instructions de port peuvent commander. Nous disposons ici soit dune minuterie (timer) pour émettre un son dune fréquence déterminée, soit dune ligne de sortie du circuit PIO 8255 du PC. Il suffit, pour produire des sons ici, de successions rapides de mises hors et sous tension dune ligne. Cette expérience a deux objectifs : nous permettre de voir comment lier une DLL et comment Windows traite le facteur temps.
Nous commandons le haut-parleur par le bit 1 du port B du 8255. Le composant occupe des adresses qui commencent à 60h (96 décimal) dans le domaine des entrées et sorties du PC. Le port B y a ladresse 97. Le format d'écriture est toujours de 8 bits et mobilise simultanément huit lignes. Nous ne souhaitons toutefois modifier que la deuxième ligne (bit 1) et le port B du PIO commande beaucoup dautres choses. Nous commencerons par lire le port de façon à nen modifier quun bit. Si vous ne comprenez pas très bien ce que nous disons ici, ne vous inquiétez pas. Le programme est sur le CD-ROM et les interventions sur les interfaces avec lextérieur sont, pour lessentiel, beaucoup plus simples.
La DLL propose deux fonctions daccès spéciales aux adresses de port du PC :
OutPort adr, dat émission de données à une adresse
InPort adr lecture de données à une adresse d'entrée/sortie
Dans Visual Basic, OutPort peut se lier comme Sub (procédure), mais InPort doit se lier comme fonction. Chaque élément dune DLL est déclaré par linstruction DECLARE. Les transmissions de données entre Visual Basic et la DLL ne peuvent fonctionner convenablement quà laide du mot ByVal, cest-à-dire comme valeurs et non par lintermédiaire dune adresse de référence (par défaut). Le système dexploitation 32 bits Windows95/98 tient compte de la casse (il distingue les capitales et les minuscules) des déclarations. Toutes les fonctions de la DLL sont en capitales, ce que doit respecter le programme appelant. Les déclarations trouvent place dans un module propre (Module1.bas), ajouté au projet SON.
Figure 1.1. Projet son.
Declare Sub OUTPORT Lib "PORT.DLL" (ByVal Adr As Integer, ByVal Dat As Integer)
Declare Function INPORT Lib "PORT.DLL" (ByVal Adr As Integer) As Integer
Declare Sub DELAY Lib "PORT.DLL" (ByVal Temps As Integer)
Programme 1.1. Les déclarations de Module1.bas.
Lensemble du projet dispose maintenant de InPort et OutPort. La procédure Delay est déclarée par la même occasion pour être utilisée un peu plus bas. Une première émission est produite dans une boucle rapide de 100 impulsions rectangulaires à destination du haut-parleur, qui doit alors faire entendre un son. Les émissions vers le port de linstruction OutPort sont soumises à des manipulations de bits par des fonctions logiques AND et OR, qui permettent de ne modifier quune ligne du port à la fois après lecture par linstruction InPort. Ces fonctions seront également expliquées plus loin.
Le programme utilise une formule simple faite dun seul bouton « Son ». La ligne du haut-parleur est mise 100 fois alternativement sous tension puis hors tension. Un PC cadencé à 200 MHz ne produira pas de son sans temporisations supplémentaires. Ces temporisations sont produites par des boucles de comptage à 10 000.
Figure 1.2. Fenêtre de programme.
Private Sub Command1_Click()
For n = 1 To 100
OUTPORT 97, (INPORT(97) Or 2)
For t = 1 To 10000: Next t
OUTPORT 97, (INPORT(97) And 253)
For t = 1 To 10000: Next t
Next n
End Sub
Programme 1.2. Emission sonore par le haut-parleur (SON.FRM).
Si lon clique sur le bouton, le haut-parleur se fait effectivement entendre. La hauteur du son dépend de lordinateur sur lequel tourne le programme. Le son nest pas très clair, il est même franchement « crasseux ». Cela tient à la façon dont Windows gère le temps.
Les temporisations définies par les boucles ne peuvent pas être dégale durée du fait que Windows traite le programme tout en vaquant à ses autres affaires : il soccupe de tout à la fois, des demandes de la souris ou dautres processus en cours. On dit de Windows quil ne fonctionne pas en temps réel, quil nest donc pas possible avec ce système dexploitation de gérer fiablement des processus très rapides. Ce nest quune question de point de vue : tout dépend de la rapidité et de la fiabilité souhaitées. Il est certain que des signaux sonores produits avec la technique de notre exemple ne peuvent pas être propres.
Les boucles de comptage ne sont en tout cas pas les seuls outils de temporisation possibles. Windows fournit de meilleurs moyens de régler des retards de quelques millisecondes. La fonction Delay de la DLL y donne accès. Delay permet daméliorer sensiblement les émissions sonores. La fréquence du signal de sortie ne peut malheureusement pas dépasser 500 Hz, si lon change létat du port une fois par milliseconde.
Private Sub Command1_Click()
For n = 1 To 100
OUTPORT 97, (INPORT(97) Or 2)
DELAY 1
OUTPORT 97, (INPORT(97) And 253)
DELAY 1
Next n
End Sub
Programme 1.3. Émission dun son à laide de Delay (Son2.frm).
Le son produit est de meilleure qualité, bien quencore impur comparé à un pur produit électronique. Des améliorations sont encore possibles à laide de la procédure RealTime (true) de la DLL (nous le verrons à la section 3.2) mais le résultat obtenu donne déjà une première idée de ce que Windows peut offrir « en temps réel ». Nous pourrions effectuer des recherches plus précises à loscilloscope, mais le programme ne sy prête guère, un programme sadressant à une ligne de port sériel COM, par exemple, y serait plus propice.
La DLL, en sus dune fonction Delay permettant daccéder à la milliseconde, offre également des temporisations réglables par pas de lordre de la microseconde. Cette temporisation fait aussi appel en interne à Windows.
Il est préférable de déclarer les appels de DLL dans un module externe BASIC, PORTS.BAS. Nous pourrons insérer par la suite ce module dans tout projet qui utilisera ces déclarations. Le programmeur accède ainsi à toutes les fonctions de la DLL, sans avoir à se préoccuper des conventions exactes des déclarations. Il transmet le fichier PORT.DLL avec le programme compilé (.exe) quil faut ensuite copier dans le répertoire de Windows ou celui du programme exécutable.
Declare Function OPENCOM Lib "Port" (ByVal A$) As Integer
Declare Sub CLOSECOM Lib "Port" ()
....
Declare Sub SOUNDCAPIN Lib "Port" ()
Declare Sub SOUNDCAPOUT Lib "Port" ()
Programme 1.4. Le module PORTS.BAS avec les déclarations à VB5.
Il est possible de déclarer les fonctions DLL dans VBA (la version de Visual Basic livrée avec Office de Microsoft®). Les expériences de ce manuel peuvent donc en principe seffectuer avec Word ou Excel. Les programmes se lancent ensuite comme macro à partir de lapplication. A partir des versions 7 de Word et Excel, les déclarations sont celles de Visual Basic 5. Lexemple suivant de production dun son par le haut-parleur du PC a été programmé sous Word 97. Le chapitre 14 vous donnera dautres exemples de programmation en VBA.
Figure 1.3. Exemple de macro dans Word 97.
Word 97 permet également lutilisation dobjets UserForm avec des éléments de commande personnalisés dans ses macros. « Declare » doit être précédé du mot-clé « Private ». Les fonctions et procédures sont de même formées à laide de « Private ».
1.3. Appels de DLL par Delphi
Sous Delphi 4, nous accédons également aux ports par lintermédiaire de PORT.DLL. Le premier exemple reprend le problème précédent de la production dun son par le haut-parleur du PC. Le programme propose deux boutons, le premier (Son1) sonne à laide dune boucle de comptage, le second (Son2) travaille avec Delay.
Figure 1.4. Premier programme avec Delphi.
Les extensions de DLL sont déclarées comme des procédures et des fonctions normales, dans la même unité, et contiennent, au lieu dun code de programme, la référence à la DLL externe. Les mots-clé « stdcall » et « external » règlent la transmission des paramètres à la DLL et sont décisifs.
Le choix du type des variables transmises est également important. Sur ce point, notons que les différentes versions de Delphi présentent entre elles des incompatibilités pour certains types dentiers. Vous ne pourrez pas toujours utiliser sous Delphi 4 un texte source Delphi 3 et réciproquement. Les types Word (16 bits non signés) et DWord (32 bits non signés) ainsi que les Real sont, en revanche, tout à fait compatibles.
Dans Delphi, le nom de lunité à proprement parler (*.pas) doit être différent de celui du projet (*.dpr). Ce manuel ajoutera donc un P pour « Projet » au nom du fichier projet. Le projet SON1.DPR relève en conséquence de lunité SON1.PAS. La compilation produit dabord le programme exécutable SON1P.EXE, que nous renommons SON1.EXE sur le CD.
unit Son1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Son1: TButton; Son2: TButton;
procedure Son1Click(Sender: TObject);
procedure Son2Click(Sender: TObject);
end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure OUTPORT (adr: Word; Valeur: Word); stdcall; external 'PORT.dll';
function INPORT (adr: Word):Integer; stdcall; external 'PORT.DLL';
procedure DELAY (ms: Word); stdcall; external 'PORT.DLL';
procedure TForm1.Son1Click(Sender: TObject);
var n, t: Integer;
begin
For n := 1 to 100 do begin
OutPort (97, (InPort (97) OR 2));
For t := 1 to 10000 Do;
OutPort (97, (InPort (97) AND 253));
For t := 1 to 10000 Do;
end;
end;
procedure TForm1.Son2Click(Sender: TObject);
var n: Integer;
begin
For n := 1 to 100 do begin
OutPort (97, (InPort (97) OR 2));
Delay (1);
OutPort (97, (InPort (97) AND 253));
Delay (1);
end;
end;
end.
Programme 1.5. Emission dun son dans Delphi (Son1.pas).
Si la temporisation est réalisée par une boucle de comptage, la première chose que nous remarquons est la vitesse dexécution, dix fois plus élevée dans lensemble quavec Visual Basic. Une boucle de comptage jusquà 10 000 sur un PC cadencé à 200 MHz nous donne une fréquence de quelque 5 kHz. Sur un ordinateur encore plus rapide, le son est à peine audible, tant sa fréquence est élevée.
Beaucoup dapplications sont affectées à des tâches dont le déroulement, fonction du temps, doit être indépendant de lordinateur sur lequel elles tournent. La procédure Delay permet en principe à un programme de se comporter de la même façon par rapport au temps, quel que soit lenvironnement. Lorsque vous cliquez sur le bouton Son2, vous obtenez un son de 500 Hz, dont la programmation sappuie sur Delay.
Il est également judicieux sous Delphi de rassembler toutes les déclarations de la DLL dans un module propre, qui prend ici la forme dune unité. Lunité PORTINC.PAS (PORTINC.DCU, après compilation) peut alors être intégrée dans un autre projet, sans que le programmeur ait à soccuper à nouveau des différentes conventions de déclaration.
unit PORTINC;
interface
uses windows;
const THEDLL='PORT.DLL';
Function OPENCOM(S:PCHAR):Integer;stdcall; external THEDLL;
Procedure RTS(d:WORD);stdcall; external THEDLL;
....
Procedure SOUNDCAPIN; stdcall; external THEDLL;
Procedure SOUNDCAPOUT; stdcall; external THEDLL;
implementation
end.
Programme 1.6. Les déclarations pour PORT.DLL dans le fichier PORTINC.PAS. |