Piloter des relais depuis Linux

Comme nous l'avons vu dans le précédent numéro, il est possible de contrôler des appareils depuis le port parallèle du PC (machine à café). Dans l'article présent, nous pousserons plus loin l'expérience. Nous allons créer un montage permettant de contrôler 8 appareils et écrire le logiciel permettant de le mettre en oeuvre.

LE PORT PARALLELE

Parmi tous les ports présents sur un PC, le plus simple à utiliser est le port parallèle. Celui-ci accueille habituellement une imprimante ou un périphérique comme un lecteur Zip ou un scanner. Sur un PC, vous pouvez disposer au maximum de trois ports parallèles. Dans la plupart des cas, un seul est présent sur la machine à l'adresse 0x378 sous le nom /dev/lp1. Dans le cas où trois ports seraient présents nommés lp0, lp1 et lp2, les adresses seront respectivement 0x3bc, 0x378 et 0x278.

Coté matériel, un port parallèle est composé de 25 broches. Les broches 2 à 9 correspondent aux 8 bits de l'octet écrit à l'adresse du port (figure 1). La masse est présente sur les broches 18 et 25. En se basant sur ces informations, il est aisé de programmer ce port comme nous allons le voir plus loin.

 
Fig.1
Broche 2 3 4 5 6 7 8 9
Position 1 2 3 4 5 6 7 8
Valeur 1 2 4 8 16 32 64 128

 

LE MONTAGE

Le problème principal que pose le port parallèle est la faiblesse du courant présent lorsqu'une broche est activée. Il est donc hors de question d'y relier directement un relais. De plus, le retour de courant de la bobine du relais risquerait d'endommager le contrôleur du port. La solution consiste donc à utiliser un transistor qui fera office de vanne. Dans le montage proposé en figure 2, nous relions le transistor 2N2222A à la broche du port parallèle par l'intermédiaire d'une résistance de 4.7 KiloOhm. De cette manière, lorsque la broche sera active, le transistor laissera passer le courant destiné au relais.

Note : n'oubliez pas de placer la diode afin d'empêcher le courant d'aller à la masse en passant au travers du transistor, sinon celui-ci sera, immédiatement détruit.

Le choix du relais est également très important. Votre préférence devra se porter sur des relais acceptant une tension en entrée comprise entre 5 et 12 Volts. La tension et l'ampérage en sortie devraient être choisis en fonction de l'appareil que vous désirez contrôler.

PROGRAMMATION DU PORT

En principe, programmer le port d'un PC revient à écrire un ou plusieurs octets à la ou les adresses du port. Dans la réalité, il faut prendre quelques mesures préventives pour autoriser votre programme à accéder au port.

Dans un premier temps, il faut inclure les headers adéquates :

#include <stdio.h>

#include <asm/io.h>

#include <unistd.h>

Puis nous définissons BASEPORT avec l'adresse du port à utiliser :

#define BASEPORT 0x378

Ensuite nous pouvons commencer notre programme :

int main(void)

{

unsigned int i=1; // compteur pour l'accès aux relais

unsigned int r=1; //compteur pour le numéro du relais

/*Cette ligne permet de demander un accès au port, si l'accès est refusé le programme se termine avec une erreur*/

if(ioperm(BASEPORT,3,1)){perror(“ioperm”);exit(1);}

/*Comme il n'y a pas eu d'erreur, nous pouvons entrer dans une boucle qui activera puis désactivera les huit relais les uns après les autres*/

while(r<9)

{

usleep(300000); //attendre

outb(i,BASEPORT); //on envoie la valeur de i sur 0x378

printf(“Relais %d : ON\n”, r); //on affiche que le

relais n° r est allumé

usleep(300000); //attendre

outb(0,BASEPORT); //on envoie 0 sur 0x378

printf(“Relais %d : OFF\n”, r); //on affiche que le

relais n° r est éteint

i=i*2; //on double la valeur de i pour accéder au prochain relais

r++; //on incrémente le numéro du relais

}

return(0);

}

Ce programme sera compilé avec l'option d'optimisation -O ou -O2 par la ligne :

gcc relais.c -orelais -O

Une fois lancé, le programme enverra successivement les valeurs 1, 2, 4, 8, 16, 32, 64, 128 à l'adresse 0x378. Ceci aura pour effet d'activer une à une les broches de 2 à 9 du port parallèle. Attention : pour lancer le programme, vous devez être root.

Pour activer plusieurs broches en même tant, il vous suffira d'additionner les valeurs entre elles et de les écrire à l'adresse du port. Exemple pour activer les broches 2, 5, 6, on écrit la valeur 25 (1+8+16) à 0x378.

PROGRAMMATION SOUS X

Un programme sous Xwindow est toujours plus sympathique et moins rebutant à utiliser. Nous allons donc écrire un nouveau programme utilisant la bibliothèque GTK.

#include <gtk/gtk.h>

#include <stdio.h>

#include <unistd.h>

#include <asm/io.h>

#define BASEPORT 0x378 /*Définition de l'adresse du port parallèle*/

void callback (GtkWidget *widget, gpointer *data)

{

/*Effacement de l'écran*/

}

void delete_event (GtkWidget *widget, GdkEvent *event, gpointer *data)

{

/*Fin de travail*/

gtk_main_quit();

}

void tictic (GtkWidget *widget, gpointer *data) //Fonction de test des relais

{

unsigned int i=1;

unsigned int r=1;

while(r<9)

{

usleep(300000); //attendre

outb(i,BASEPORT); //on envoi la valeur de i sur 0x378

printf(“Relais %d : ON\n”, r); //on affiche que le relais n° r est allumé

usleep(300000); //attendre

outb(0,BASEPORT); //on envoi 0 sur 0x378

printf(“Relais %d : OFF\n”, r); //on affiche que le relais n° r est éteint

i=i*2; //on double la valeur de i pour accéder au prochain relais

r++; //on incrémente le numéro du relais

}

}

int main (int argc, char *argv[])

{

GtkWidget *window; //définition de la fenêtre

GtkWidget *button; //définition de bouton

GtkWidget *table; //définition de la table

/*Initialisation du port parallèle*/

if(ioperm(BASEPORT,3,1)){perror(“ioperm”);exit(1);}

gtk_init(&argc, &argv); //initialisation de GTK

/*Création de la fenêtre principale*/

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

/*Définition du titre de la fenêtre*/

gtk_window_set_title(GTK_WINDOW(window), “Contrôle Relais”);

/*Définition de la fonction en cas de fermeture de la fenêtre*/

gtk_signal_connect(GTK_OBJECT(window), “delete_event”,

GTK_SIGNAL_FUNC(delete_event, NULL);

/*Définition de la largeur de la bordure de fenêtre*/

gtk_container_border_width(GTK_CONTAINER(window),20);

/*Création d'une boîte pour accueillir les boutons*/

table=gtk_table_new(2,2,TRUE);

/*Ajout de la boîte dans la fenêtre*/

gtk_container_add(GTK_CONTAINER(window), table);

/*Création du bouton RAZ*/

button=gtk_button_new_with_label(“R.A.Z.”);

/*Définition de la fonction à lancer quand on clique*/

gtk_signal_connect(GTK_OBJECT(button), “clicked”,

GTK_SIGNAL_FUNC(callback), (gpointer) “button 1");

/*Ajout du bouton dans la boîte*/

gtk_table_attach_default(GTK_TABLE(table), button, 0, 1, 0, 1);

/*Affichage du bouton*/

gtk_widget_show(button);

/*Création d'un autre bouton selon le même principe*/

button=gtk_button_new_with_label(“ Test Relais ”);

gtk_signal_connect(GTK_OBJECT(button), “clicked”,

GTK_SIGNAL_FUNC(tictic), (gpointer) “button 2");

gtk_table_attach_default(GTK_TABLE(table), button, 1, 2, 0, 1);

gtk_widget_show(button);

/*Création d'un autre bouton selon le même principe*/

button=gtk_button_new_with_label(“Quitter”);

gtk_signal_connect(GTK_OBJECT(button), “clicked”,

GTK_SIGNAL_FUNC(delete_event), (gpointer) “button 3");

gtk_table_attach_default(GTK_TABLE(table), button, 0, 2, 1, 2);

gtk_widget_show(button);

/*Affichage de la boite*/

gtk_widget_show(table);

/*Affichage de la fenêtre*/

gtk_widget_show(window);

/*Appel de la fonction principale GTK*/

gtk_main();

return(0);

}

Notre programme, une fois compilé devrait afficher la fenêtre donnée en figure 3. Un clic sur le bouton "Test Relais" devrait avoir le même effet que notre premier programme. Le bouton "R.A.Z." sert à effacer l'écran du terminal depuis lequel le programme est lancé. Enfin, le bouton "Quitter" sert à... quitter le programme.

CONCLUSION

Cet article a pour but de constituer un point de départ pour vos applications. Nous avons vu comment envoyer des ordres aux relais et comment créer une application de pilotage. A vous à présent de l'adapter à vos besoins en interfaçant des appareils et en programmant une application adéquate. N'hésitez pas à nous faire part de vos réalisations... n


© Copyright 2000 Diamond Editions/Linux magazine France. - Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1or any later version published by the Free Software Foundation; A copy of the license is included in the section entitled "GNU Free Documentation License".