Durée : 2h. Documents autorisés : notes de cours et documents manuscrits, documents fournis par Mr Trau.
Remarques : Si vous ne savez plus exactement comment écrire une fonction, écrivez juste les instructions qui font ce que je vous demande, comme si tout était dans la seule fonction main. En cas d'informations insuffisantes, vous pouvez faire toute supposition qui vous arrange, à condition qu'elle ne contredise ni ce que j'ai imposé dans le sujet, ni le bon sens.
Ce sujet correspond à un besoin réel, dans une entreprise de la région. Sa production nécessite le remplissage à l'aide d'azote, sous une pression précise, d'une enceinte hyperbare (en clair : récipient supportant les hautes pressions). Auparavant, la pression était réglée manuellement, en actionnant la molette d'un régulateur (dit plus simplement : on ouvre un robinet). L'opérateur tourne la molette (dans le sens trigo) tout en surveillant un manomètre à cadran, jusqu'à ce que la pression désirée soit atteinte. Les produits dans l'enceinte comportant un clapet anti-retour, tout dépassement de la pression prévue entraîne la mise au rebut du lot de produits. Ceci nécessite donc une attention soutenue de l'opérateur, qui pour éviter de dépasser la pression de consigne, ajuste lentement la pression, ce qui ralentit le cycle de production.
Nous avons donc envisagé d'automatiser cette tâche. L'outil de production (la "machine") étant satisfaisant, et vu qu'en recréer une nouvelle, même plus performante, coûterait largement plus que le gain de productivité escompté, il a été décidé de ne pas modifier la "machine" dans son fonctionnement, mais que seule la commande du régulateur se ferait automatiquement. Pour cela, il a suffit d'y installer un moteur pas à pas (et un réducteur), de rajouter un capteur de pression sur l'enceinte, et d'intercaler entre les deux un dispositif de commande : on a choisi d'utiliser un ordinateur (PC), pour son prix (récupéré dans le parc machines de l'entreprise, un modèle un peu ancien suffisant largement), mais aussi pour ses possibilités de traitement, comme on le verra dans la seconde partie.
Le moteur pas à pas est très facile à commander, grâce à son électronique de commande à trois entrées. Ces entrées sont branchées sur un port de sortie du PC à l'adresse 330 (en hexa), sur une carte spécifique. Elles correspondent à :
Les autres bits du port resteront toujours à 0.
Q1.1 : écrivez une fonction qui fasse avancer le moteur d'un pas dans le sens de l'ouverture du régulateur. Son entête sera : void ouvre_1_pas(void)
Ecrivez aussi la fonction ferme_1_pas qui le fait tourner d'un pas dans l'autre sens.
A la sortie de ces deux fonctions, le moteur reste activé.
Q1.2 : Le capteur de pression envoie sa mesure sur une carte d'entrée spécifique (un CAN), qui met la valeur mesurée dans deux ports : les 8 bits de poids faible sont mis sur le port 393 (hexa), les 8 bits de poids fort sur le port 394. Ecrivez une fonction qui lise les deux ports d'entrée et retourne la valeur correspondant à la pression mesurée (donc l'octet de poids faible + 256*l'octet de poids fort). Son entête sera : int mesurer(void)
Q1.3 : Faites le programme complet de commande du dispositif, utilisant les fonctions décrites ci dessus, et répondant au cahier des charges suivant :
l'opérateur entre la valeur correspondant à la pression désirée (scanf), puis à l'appui d'une touche le cycle démarre : on ouvre le régulateur d'un pas à la vitesse maximale, et ce jusqu'à atteindre 90% de la pression désirée. Puis on continue d'ouvrir le régulateur, mais en espaçant chaque impulsion de 10ms jusqu'à atteindre 96% de la valeur désirée, puis on termine en espaçant chaque impulsion de 20ms. On signale à l'écran que la pression est atteinte, et on attend que l'opérateur appuie sur une touche pour remettre le régulateur en position initiale (on peut tourner à la vitesse maximale), il faut exactement autant d'impulsions pour la fermeture que pour l'ouverture. On peut alors désactiver le moteur.
Pour éviter à l'opérateur de donner la valeur de la pression désirée, on préfère qu'il entre un code (référence) pour le type de pièce à produire, votre programme devra trouver la valeur de pression nécessaire. Pour simplifier, on suppose que la référence est un entier strictement positif (dans la réalité c'est une combinaison de chiffres et de lettres). On utilisera pour cela deux tableaux unidimensionnels, le premier s'appelle ref, le second consig. Le nombre de références sera toujours inférieur à 100 et sera stocké dans la variable nbref. Ce sont des variables globales et sont déclarés ainsi :
#define MAX 100 typedef int tableau[MAX]; tableau ref,consig; int nbref;
Le tableau ref contient les références existantes. Exactement en même position, on trouvera dans le tableau consig la consigne de pression correspondant à la référence. Les références ne sont pas triées, mais elles se trouvent dans les nbref premières valeurs du tableau.
On suppose disposer d'une fonction capable de lire les références et consignes sauvées au préalable dans un fichier, et de mettre à jour nbref et les deux tableaux. Cette fonction est écrite dans le fichier "init-ref.h" et son entête est void initialise_tableaux(void). Elle est appelée par la fonction main, dès le début du programme. Vous n'avez donc pas besoin de l'appeler.
Q2.1 : écrivez une fonction qui demande à l'utilisateur une référence, la recherche dans le tableau ref, et s'il la trouve revoie la consigne correspondante. S'il ne la trouve pas, il redemande une référence, et ce jusqu'à ce qu'il obtienne une référence valide. La référence 0 est considérée comme valide : bien que n'étant pas dans le tableau ref, elle correspond aux commandes spéciales, on demande alors à l'opérateur d'entrer la pression désirée, et la fonction retourne directement cette valeur. L'entête de cette fonction est int rech_consigne(void)
En fait, le capteur ne donne pas la valeur exacte, mais proportionnelle à la pression. Après étalonnage du capteur, nous avons pu établir la relation permettant de déterminer la véritable pression : valeur_réelle = (valeur_mesurée - 412) / 6.6
De plus, la lecture de la carte CAN est un peu plus compliquée que ce que j'ai expliqué dans la première partie. En fait, pour effectuer une mesure, il faut en premier lieu sélectionner le canal d'acquisition et déclencher la mesure sur ce canal, ici cela se fait en envoyant la valeur 1 sur le port 390. Puis il faut attendre la fin de l'acquisition, qui sera signalée par la carte qui met le bit de poids faible du port 391 à 1 (les autres bits sont dans un état indéterminé). On peut alors lire la valeur mesurée, comme indiqué dans la question 1.2.
Nous avons également remarqué que la valeur mesurée fluctuait un peu autour de la valeur réelle, le problème a été résolu en faisant 10 lectures d'affilée et en en prenant la moyenne.
Q3.1 : réécrivez la fonction mesurer pour qu'elle retourne la pression réelle, en respectant toutes ces nouvelles conditions.
Q3.2 : par quel chemin, au cœur de l'ordinateur, va transiter l'information qui vient du port 393 jusqu'à ce qu'elle soit stockée en mémoire ?
pour retourner au sommaire des sujets d'examen, cliquez ici
Patrick TRAU, ULP - IPST septembre 2000