Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
1
Université du Québec à Chicoutimi Module d’ingénierie
Programme : Génie électrique.
Projet de synthèse en ingénierie 6GIN555
Rapport final
Projet d’amélioration de l’outil de réadaptation A.M.E.
Présenté par :
Frédérick Morin
Benoît Côté
Pour :
Martin Gravel C.E.M.E.
Le 23 avril 2010
Coordonnateur : Jacques Paradis
Conseiller : Hung Tien Bui
2
Table des matières I. Introduction ................................................................................................................. 6
II. Présentation du projet ................................................................................................. 7
II.1 Description de l’entreprise .................................................................................. 7
II.2 Description de l’équipe de travail ....................................................................... 8
II.3 Problématique et état de l’art relié au projet ....................................................... 9
II.4 Objectifs généraux et spécifiques du projet ........................................................ 9
III. Aspects techniques et éléments de conception relatifs au projet .............................. 10
III.1. Méthodologie utilisée .............................................................................. 10
III.2. Éléments de conception ........................................................................... 14
III.2.a. Acquisition de données....................................................................... 14
III.2.b. Cellule de charge ................................................................................ 14
III.2.c. SPI logiciel ......................................................................................... 21
� Fonction d’initialisation du port SPI 2 ................................................ 22
� Fonction d’envoi du port SPI 2............................................................ 23
� Fonction de réception du port SPI 2 .................................................... 24
III.2.d. Capteur EMG ..................................................................................... 26
III.2.e. Routine de communication avec le variateur de vitesse ..................... 31
� Configuration ....................................................................................... 31
� Architecture de la transmission de donnée .......................................... 32
� Validation des données ........................................................................ 34
� Conversion et traitement de la valeur reçue ou envoyée ..................... 35
Approbation du rapport final pour diffusion
Nom du conseiller : Hung Tien Bui ing.
Date : 23 avril 2010
Signature :
3
� Résumé des étapes d’envoi .................................................................. 36
� Architecture de la réception de donnée ............................................... 36
� Résumé des étapes d’envoi .................................................................. 36
� Gestion des erreurs de commande ....................................................... 37
III.2.f. Architecture du programme ................................................................ 38
� Initialisation et étapes préliminaires à l’utilisation .............................. 38
� Routine d’asservissement en fonctionnement normal ......................... 43
III.2.g. Interface d’opération .......................................................................... 46
IV. Bilan des activités ..................................................................................................... 53
IV.1 Arrimage formation pratique/universitaire ................................................... 53
IV.2 Travail d’équipe ............................................................................................ 55
IV.3 Respect de l’échéancier................................................................................. 56
IV.4 Analyse et discussion .................................................................................... 58
V. Conclusion et recommandations ............................................................................... 60
VI. Bibliographie............................................................................................................. 62
Annexe A : Nouvelle approche ......................................................................................... 66
Annexe B : Plans électriques ............................................................................................ 69
Annexe C : Programmation
4
Liste des figures :
Figure 1 : Circuit de développement MicroChip .............................................................. 11
Figure 2 : Amplificateur Myoscan branché sur une triode. .............................................. 12
Figure 3 : Logique du programme .................................................................................... 13
Figure 4 : Localisation de la cellule de charge.................................................................. 14
Figure 5 : Cellule de charge et sa configuration ............................................................... 15
Figure 6 : Représentation du système de forces de l’appareil........................................... 16
Figure 7 : Représentation de la puce électronique de conversion AD7798 ...................... 18
Figure 8 : Représentation de la séquence de transfert de l’AD7798................................. 19
Figure 9 : Schématisation de la configuration du convertisseur de la cellule ................... 21
Figure 10 : Initialisation du port SPI 2.............................................................................. 22
Figure 11 : Structure du temporisateur 1 du dsPIC30f4011 ............................................. 23
Figure 12 : Fonction d’envoi du port SPI 2 ...................................................................... 23
Figure 13 : Fonction de réception du port SPI 2 ............................................................... 24
Figure 14 : Triode musculaire ........................................................................................... 26
Figure 15 : Amplificateur RMS et son signal de sortie .................................................... 26
Figure 16 : Configuration des deux registres nécessaires à la communication série SPI . 28
Figure 17 : Séquence à suivre pour une conversion et un transfert adéquat ..................... 28
Figure 18 : Schématisation du branchement entre le microcontrôleur et l’AD7680 ........ 29
Figure 19 : Séquence de conversion des données provenant de l’AD7680 ...................... 30
Figure 20 : Identification du port de communication série sur le variateur de vitesse ..... 31
Figure 21 : Routine de contrôle principale ....................................................................... 38
Figure 22 : Séquence d’initialisation du microcontrôleur................................................. 39
Figure 23 : Séquence d’initialisation de la machine ......................................................... 40
Figure 24: Séquence de réception des consignes provenant de l’interface de contrôle. ... 41
Figure 25: Séquence de positionnement du bras à l’angle initial ..................................... 42
Figure 26: Séquence d’asservissement de la vitesse du moteur. ...................................... 43
Figure 27: Interface d’opération. ...................................................................................... 46
Figure 28: Boucle de l’interface d’opération. ................................................................... 47
Figure 29: Consigne d’angle initial de l’interface. ........................................................... 48
Figure 30: Consigne de charge. ........................................................................................ 48
5
Figure 31: Consigne de l’EMG et valeur isométrique. ..................................................... 49
Figure 32: Control de l’entraînement. ............................................................................... 49
Figure 33: Affichage du graphique de l’EMG. ................................................................. 51
Figure 34: Affichage du graphique de l’EMG à partir du fichier Entraînement.xls ......... 51
Figure 35: Paramètre du port RS-232 et remise à zéro ..................................................... 52
Figure 36: Affichage des valeurs reçues et converties en temps réel. .............................. 52
Figure 37 : Diagramme de Gantt de la planification du projet ......................................... 56
Figure 38 : Schéma du bras de A.M.E. avec la force appliquée ....................................... 66
Liste des tableaux :
Tableau 1: Configuration du port série ............................................................................. 31
Tableau 2: Valeur décimale de certains caractères ASCII................................................ 34
Tableau 3 : Comparaison du prix des équipements .......................................................... 59
6
I. Introduction
L’équipe du Centre d’Ergonomie et de Mieux Être (C.E.M.E) s’apprête à
commercialiser A.M.E. (appareil multifonctionnel d’entraînement), un
équipement d’entraînement révolutionnaire permettant d’accélérer la
réhabilitation des personnes blessées au travail. Il existe présentement un
prototype de l’appareil qui a servi à démontrer et valider avec succès le
fonctionnement de celui-ci.
Avant de commercialiser A.M.E., plusieurs parties de l’appareil doivent être
améliorées afin d’augmenter les performances et diminuer les coûts de
production. En effet, le prototype est très efficace pour la réhabilitation, mais si
l’équipement est soumis à des mouvements rapides, pour l’entraînement en force
par exemple, l’efficacité de l’appareil diminue. De plus, le système permettant le
contrôle de l’équipement est très coûteux et donc pourrait limiter la clientèle pour
cet équipement. De façon générale, le but du projet est donc de réduire les coûts
de production de l’équipement ainsi que d’améliorer ses performances en termes
de temps de réaction.
7
II. Présentation du projet
II.1 Description de l’entreprise
CEME intervient dans les problématiques liées à la santé et la sécurité au travail
de la main-d’œuvre, et ce, dans tous les secteurs de l'activité économique.
Adoptant une approche multidisciplinaire, globale et intégrée face aux
problématiques qui lui sont présentées, leurs consultants s'appuient sur les toutes
nouvelles technologies et leur vaste expérience du milieu de travail pour identifier
les situations à risque et pour concevoir les correctifs à apporter.
Selon la nature et la complexité des problématiques rencontrées, CEME peut faire
appel à l'une ou l'autre, ou encore à plusieurs des expertises suivantes :
ergonomes, éducateurs physiques, ergothérapeutes, kinésiologues,
physiothérapeutes, médecins, ingénieurs, designers industriels, etc. 1
1 http://www.ceme.qc.ca/Questceque.htm
8
II.2 Description de l’équipe de travail
� Équipe de travail :
Benoît Côté,
Frédérick Morin
� Support technique externe :
Le Centre de Production Automatisé (CPA)
� Support technique interne :
Richard Martin
Francis Deschenes
� Superviseur (conseiller) :
Hung-Tien Bui
� Promoteur :
Martin Gravel (Président de la compagnie C.E.M.E.)
9
II.3 Problématique et état de l’art relié au projet
L’appareil multifonctionnel d’entraînement a été conçu pour la réadaptation
physique. Cet appareil doit donc être performant, mais, surtout fiable et
sécuritaire afin de ne pas aggraver l’état de l’utilisateur.
Il existe un équipement qui peut se comparer en partie avec A.M.E. Cet
équipement, Ikarus de la compagnie BFMC, permet l’entraînement et la
réhabilitation des membres supérieurs avec une rétroaction sur la charge.
Là où A.M.E. révolutionne ce type d’équipement, c’est dans la rétroaction
musculaire. La rétroaction au niveau de la charge permet de simuler la charge
voulue et la rétroaction musculaire permet d’ajuster la charge en fonction du seuil
de tolérance maximal du patient. De cette façon, le patient peut compléter un
mouvement sans surpasser l’effort que le muscle peut fournir et par le fait même
éviter de rallonger le temps de réadaptation du muscle.
II.4 Objectifs généraux et spécifiques du projet
L’objectif principal du projet était de faire la démonstration que le contrôle du
système pouvait être pris en charge par un microcontrôleur. Il s’agissait, en autre,
de réviser l’asservissement des moteurs simulant la charge, les systèmes
d’acquisitions de données et de calculs qui se font actuellement sur automate et
ordinateur. De plus, les modifications devaient favoriser la mise en marché du
produit et permettre son adaptation pour différentes applications futures.
10
III. Aspects techniques et éléments de conception relatifs au
projet
III.1. Méthodologie utilisée
Il a été déterminé que le variateur de vitesse du moteur actuel serait conservé pour
le contrôle de la vitesse et l’asservissement de celui-ci. La communication entre le
variateur et le système de contrôle s’effectuerait à l’aide d’une communication
série RS-232. La facilité d’utilisation de ce protocole de communication a
fortement influencé la décision du protocole à utiliser. Il a été déterminé que, pour
l’affectation présente du variateur, la vitesse de communication série serait
suffisante. En effet, la vitesse de communication du port série est de 38400 bauds.
Pour réaliser l’asservissement de la machine, une chaîne de caractères de 368 à
592 bits doit être envoyée au variateur de vitesse. Donc, il est possible d’affirmer
que le rafraîchissement de l’asservissement pourra se faire entre 50 et 103 fois par
seconde. Avec cette vitesse de communication, est possible d’obtenir des
performances équivalentes à celles du prototype déjà en fonction.
Le contrôleur utilisé pour le traitement des données et le contrôle de l’équipement
sera une carte électronique de développement ayant comme unité de traitement un
microcontrôleur DSPic (Microchip). La carte de développement possède déjà des
entrées/sorties numériques et analogiques, des entrées/sorties pour différents
protocoles de communication dont ceux nécessaires au bon fonctionnement du
système et un afficheur LCD.
11
Figure 1 : Circuit de développement MicroChip
Pour communiquer avec les composantes externes du système, deux circuits
contenant des convertisseurs analogiques à numérique ont été développés pour
transférer les signaux analogiques provenant de la cellule de charge et du capteur
électromyogramme (EMG). Ces interfaces communiquent via un port série SPI et
possèdent des convertisseurs analogiques à numérique choisis spécialement pour
chacune des deux applications.
Pour l’acquisition des signaux électriques provenant du système musculaire
humain, un amplificateur conçu par une compagnie spécialisée dans la fabrication
d’équipements biomédicaux sera mis à l’essai et utilisé sur le nouveau prototype.
Cet amplificateur se branche directement sur la triode qui est collée sur le bras du
patient (figure 2). Le signal de sortie de cet amplificateur est une valeur
analogique efficace amplifiée du signal envoyé par le corps humain lors d’une
contraction musculaire.
12
Figure 2 : Amplificateur Myoscan branché sur une triode.
Trois routines de communication ont été développées pour les deux protocoles
séries utilisés. La première routine utilise le module SPI intégré du
microcontrôleur et permet de transférer les données du convertisseur analogique à
numérique du EMG. La deuxième routine de communication est un port SPI
émulé permettant cette fois d’obtenir les valeurs provenant du convertisseur de la
cellule de charge. Une troisième routine utilisant le module de communication
RS-232 du circuit de développement permet de transmettre les consignes et de
recevoir les valeurs du variateur de vitesse. Les liens entre les différents modules
sont présentés à la figure 3
Un autre segment de programmation a été réalisé pour permettre la
communication entre le microcontrôleur et l’interface graphique de l’ordinateur.
Le module intégré de communication du dsPIC sera utilisé pour l’envoi et la
réception des informations. Un module de communication UART/USB permet de
faire le lien entre le microcontrôleur et l’ordinateur.
Par la suite, pour le contrôle de la charge, une routine d’asservissement de vitesse
des moteurs a été conçue. Cette routine permet un contrôle de vitesse en fonction
de la charge perçu sur la poignée. Cette routine permet aussi un ajustement de
consigne de charge en fonction des données recueillies par l’EMG.
13
Il est aussi important de mentionner que beaucoup d’envois de données vers
l’interface de contrôle sont faits dans l’asservissement. Donc toutes les données
converties et recueillies sont traitées dans cette routine.
Figure 3 : Logique du programme
Le dernier segment de programmation développé a été la routine principale. Cette
routine est simple et permet au système de s’initialiser et de prendre sa position de
départ, initialement entrée dans l’interface de contrôle. Elle permet aussi de faire
appel, de manière séquentielle, aux nombreuses routines précédemment
développées, c'est-à-dire les conversions et les traitements de données.
Finalement, des essais ont été faits sur l’équipement pour implanter et valider tous
les systèmes développés lors du projet. Ces essais ont permis d’optimiser le
fonctionnement et atteindre au maximum les objectifs fixés lors de l’élaboration
du plan de travail.
14
III.2. Éléments de conception
III.2.a. Acquisition de données
Toutes les données externes nécessaires au fonctionnement de l’appareil de
réadaptation sont de types analogiques. Le microcontrôleur possède des entrées
analogiques à digitale, mais pour des raisons de précision, ceux-ci n’ont pas été
utilisés. Il a donc été nécessaire de concevoir des interfaces d’acquisitions qui
convertissent les signaux analogiques en numérique. Au total, deux interfaces
utilisant chacune des composantes de conversion spécifiques ont été conçues.
III.2.b. Cellule de charge
La première interface sert à la conversion des signaux de la cellule de charge. La
cellule de charge est une composante du système servant à mesurer la force
appliquée sur le bras de l’appareil. Elle est fixée directement au bas du bras à
l’endroit où se trouvent les poignées. Le positionnement de la cellule permet donc
une lecture de la force appliquée sur le bras de l’appareil en temps réel.
Figure 4 : Localisation de la cellule de charge.
15
La cellule utilisée présentement sur l’équipement est composée de quatre jauges
de contraintes dans une configuration de pont de Wheatstone (figure 5) et possède
une capacité maximale de 30 KG. Le pont possède un facteur nominal de sortie de
2 mV/V par rapport à sa source d’alimentation qui est de 5Vcc. La plage de sortie
sera donc de -10 mV à +10 mV où -10 mV correspond à un poids de 30 KG dans
une direction et +10 mV correspond a 30 KG dans l’autre direction. Pour trouver
cette plage de sortie, il faut multiplier le facteur nominal de sortie par la tension
appliquée au pont. La tension de sortie du pont est donnée par la formule
suivante : 2
3 20
3 4 1 2
EX
R RV V
R R R R
= − •
+ +
Figure 5 : Cellule de charge et sa configuration
En se basant sur le facteur nominal de sortie, il est possible de déterminer la
relation qui existe entre la charge appliquée et la tension à la sortie. La cellule
donnera donc une différence de potentiel à la sortie de :
[ ]
[ ]0 _
2 5Facteur de sortie V
0.333Capacité de la Cellule 30
CCEX
KG
mVV
mVVV
KG KG
• •
= = =
2 ftp://ftp.ni.com/pub/branches/france/mesures_courantes_2.pdf
16
Il est nécessaire de convertir cette valeur représentant une tension pour chaque
kilogramme en tension pour une force équivalente à une masse statique de X
kilogrammes. Le but visé étant de simuler une masse de types poulie (figure 6), il
est donc nécessaire d’effectuer cette conversion afin d’obtenir la valeur voulue.
Comme il est démontré dans la figure suivante, la force à appliquer sur la cellule
sera l’équivalent de la force d’attraction terrestre appliquée sur une masse X. 3
Figure 6 : Représentation du système de forces de l’appareil.
Le gain actuel donne une relation entre une masse simulée et la tension de sortie
de la cellule de charge. Cependant, il est impossible de mesurer directement la
masse, et donc le système doit donc utiliser la force appliquée à la cellule de
charge pour en déduire une masse. Puisque la force est égale à (masse x
accélérations) et que l’accélération terrestre est de 9.81 m/s², il faut ensuite diviser
le potentiel aux bornes de la cellule de charge par 9.81. Cette valeur peut être
trouvée de la manière suivante :
Dû à la force d’attraction terrestre, la force générée par un poids sera de 9.81N/Kg
[ ]
( ) [ ]2 29.81 1 9.81 9.81gravitation
F mA N
m mA F Kg N
s s
=
= → = =
i
3 Mécanique de l’ingénieur : STATIQUE, Traduction et adaptation de Engineering Mechanics,
STATICS, Vol.1, 3e édition, version SI, par J.L. Meriam et L.G. Kraige
17
Puisque le système donne 0.33mV/Kg la tension de sortie sera 0.03398mV/ N de
force.
0_
0 _0_
_
0.3333
0.33330.03398
9.81
KG
KGN
PAR KILO
mVV
KG
mVV mVKG
VNF N
KG
=
= = =
C’est avec le signal de sortie de la cellule de charge qu’il sera possible de donner
une consigne de vitesse au moteur pour le maintien de la force simulée.
Cependant, puisque le signal de sortie de la cellule de charge est analogique et que
le microcontrôleur effectue un traitement de type numérique, une interface a été
créée incluant un convertisseur analogique à numérique. Ce convertisseur a été
choisi en fonction de la tâche à accomplir. En effet, après plusieurs recherches, le
choix s’est arrêté sur un convertisseur fabriqué par la compagnie Analog Device
qui possède les caractéristiques voulues. 4 Ce circuit permet une conversion de
son entrée analogique en une sortie numérique de 16 bits. Puisque la vitesse du
signal est très lente et qu’une grande précision est requise, le type de convertisseur
qui est le mieux adapté aux besoins de l’appareil est de type sigma-delta. La
valeur de sortie est stockée dans un registre interne des circuits intégrés et peut-
être transférée via un port série sous le protocole SPI.
Pour effectuer le transfert entre le convertisseur et le microcontrôleur, une routine
de communication ainsi qu’un programme d’acquisition ont été développés et mis
à l’essai. Le microcontrôleur possède un port intégré permettant le transfert de
données via port série SPI. Toutefois, ce port de communication ne sera pas utilisé
pour le transfert de données entre le convertisseur de la cellule de charge et le
microcontrôleur pour des raisons d’incompatibilité. Il est habituellement possible
d’utiliser le port SPI pour communiquer avec plusieurs composantes possédant ce
protocole de transfert de données. 4 http://www.analog.com/static/imported-files/data_sheets/AD7798_7799.pdf
18
Cependant, dans le cas du projet, les deux convertisseurs utilisés ne
fonctionneront pas aux mêmes vitesses en plus de ne pas posséder les mêmes
protocoles de transfert. En effet, le circuit intégré de conversion AD7798 transfère
les données converties via sa sortie DOUT/RDY illustrée à la figure 7, à des
vitesses de 4.17 à 470 Hz qui sont nettement inférieures au convertisseur de
l’EMG.
Figure 7 : Représentation de la puce électronique de conversion AD7798
Le problème est que lorsque le circuit intégré est en conversion, la sortie devient
‘1’ (5Vcc) jusqu’à ce que la conversion se termine. Deux convertisseurs
analogiques à numérique pourrait théoriquement communiquer par le même port
SPI, mais vu la caractéristique du convertisseur AD7798, le bus SPI devient
inutilisable pendant la conversion. Les données provenant alors du convertisseur
EMG deviennent donc erronées entre chaque conversion de l’AD7798. Les deux
convertisseurs devaient donc être utilisés avec deux ports SPI séparés. Toutefois,
le microcontrôleur utilisé ne possède qu’un seul port SPI. Pour résoudre ce
problème, une routine simulant un port SPI a été programmée dans le
microcontrôleur. Des entrées/sorties logiques génériques du microcontrôleur ont
été utilisées pour le transfert. Cette routine a été programmée en suivant une
logique de transfert spécifique au convertisseur choisi.
19
Cette logique est très importante pour le bon fonctionnement du système, car les
spécifications du constructeur de la puce doivent être suivies pour un transfert de
donnée précise et sans perte d’information. Cette logique de programmation s’est
faite en se basant sur la figure 8, illustrant la séquence temporelle à utiliser lors du
transfert. Comme la figure le démontre, le transfert s’effectue en synchronisation
avec une d’horloge passant du mode repos (5vcc) à actif (0Vcc). Cette horloge
doit être envoyée à la puce sur l’entrée SCLK pendant que l’entrée CS��� est
sélectionnée, c'est-à-dire pendant qu’elle est égale à 0 (0Vcc).
Figure 8 : Représentation de la séquence de transfert de l’AD7798
L’AD7798 doit être configuré avant d’être utilisé. Comme la figure 9 le démontre,
une structure bien précise de transmission et de réception doit être respectée afin
de bien communiquer avec le convertisseur. La fiche technique du constructeur
explique et énumère les différentes configurations possibles ainsi que la manière
de les effectuer.
20
Pour procéder à la configuration, il est nécessaire d’envoyer différents groupes de
données d’une longueur de huit bits. Chacun de ces groupes de données doit être
synchronisé avec l’horloge, car le convertisseur fait l’acquisition de chacun des
bits sur un cycle d’horloge. Un premier groupe de données d’une longueur de huit
bits doit être envoyé pour déterminer l’adresse du registre interne de la puce à
modifier ou lire, suivi d’un groupe d’une longueur de seize bits servant à
configurer le registre. Entre chacun de ces envois, l’entrée CS doit être maintenue
à 0 (0Vcc).
La dernière configuration qui doit être envoyée est une configuration permettant à
la puce d’effectuer des conversions continues à la vitesse sélectionnée. Après que
cette configuration soit terminée, il n’est plus nécessaire d’utiliser l’entrée de la
puce. En effet, la sortie de celle-ci deviendra 0 (0Vcc) à chaque fois qu’une
conversion sera terminée et une série de seize horloges devra être envoyée à la
puce à ce moment à une vitesse pouvant aller jusqu’à 1Mhz pour transférer les
données.
21
Pour simplifier l’explication, seulement les configurations utilisées sont
énumérées ci-dessous.
Figure 9 : Schématisation de la configuration du convertisseur de la cellule
III.2.c. SPI logiciel
Afin de communiquer avec la cellule de charge, un deuxième port SPI était requis.
Comme le dsPic30f4011 ne possède qu’un seul port SPI intégré, il était nécessaire
d’en concevoir un deuxième entièrement programmé.
22
� Fonction d’initialisation du port SPI 2
La première fonction consiste à initialiser et à configurer le
temporisateur 1 (figure 10). Ce temporisateur est utilisé pour
synchroniser la transmission des données.
Cette fonction débute en configurant les paramètres du
temporisateur. Comme le temporisateur utilise l’horloge
interne pour incrémenter le temps, il est possible de réduire le
nombre de cycles d’horloge en utilisant une mise à l’échelle
(Prescaler). Ce paramètre permet d’envoyer une impulsion à
tous les 1, 8, 64, ou 256 cycles d’horloge (figure 11). Pour le
SPI 2, la mise à l’échelle a été ajustée à 1. Ensuite un
compteur permet de relever le nombre d’impulsions envoyé
par le «Prescaler». Lorsque la valeur du compteur atteint la
valeur voulue (période «Pr1»), le drapeau signale la fin de la
temporisation. Le compteur se réinitialise et change l’état de la
sortie de l’horloge du port SPI 2. Un cycle d’horloge SPI 2
nécessite donc deux périodes complètes du temporisateur 1.
Figure 10 : Initialisation du port SPI 2
La valeur de la fréquence de l’horloge du SPI2 est donc définie par la formule
suivante, où la période est de 6 :
( ) ( )2
Pr 1 Période
Ps=Valeur du Prescaler
Fosc=Fréquence du cris ta l
8 / 4 7.328 8 / 4/ 2 / 2 1.22
P r1 1 6os c
SP I
f M Hzf M Hz
P s
=
• • = = =
• •
23
Finalement, le mode d’interruption est désactivé, le temporisateur est désactivé
(en attente) et la valeur du drapeau est initialisée à la valeur 0.
Figure 11 : Structure du temporisateur 1 du dsPIC30f4011
� Fonction d’envoi du port SPI 2
La fonction d’envoi du port SPI 2 permet d’envoyer
un mot binaire d’une longueur déterminée (figure 13).
L’appel de la fonction TXLoadC (mot,longueur)
débute en activant et en faisant la mise à zéro du
temporisateur 1. La première valeur du mot binaire
est immédiatement appliquée à la sortie du port SPI 2.
La boucle attend alors le drapeau du temporisateur 1.
Lorsque que le drapeau signale que le temps est
atteint, la valeur de la sortie de l’horloge du SPI 2
passe de 1 vers 0. La valeur de sortie du SPI 2 change
de valeur seulement après deux changements d’état
(un cycle d’horloge complet).
Figure 12 : Fonction d’envoi du port SPI 2
24
Il est important de noter que la valeur de la sortie du port SPI 2 est rafraîchie sur
le front descendant du signal d’horloge du port SPI 2. Finalement, un compteur
permet de vérifier si la longueur du mot est atteinte. Si la longueur du mot est
atteinte, la transmission est terminée. Sinon, la séquence attend de nouveau le
drapeau du temporisateur1.
� Fonction de réception du port SPI 2
La fonction de réception du port SPI 2
(figure 13) permet de recevoir un mot de
16 bits. La fonction débute par la remise à
zéro du temporisateur 1 et son activation.
Ensuite le programme attend le drapeau du
temporisateur. Lorsque le drapeau s’active,
la valeur appliquée à l’entrée du port SPI 2
est enregistrée dans le registre de réception
à tous les cycles d’horloge.
Il est donc important de noter que la
sauvegarde de l’état de l’entrée du port SPI
2 se fait sur le front montant du cycle de
l’horloge.
Figure 13 : Fonction de réception du port SPI 2
25
Un compteur permet de détecter la fin du mot à enregistrer. Si la réception n’est
pas terminée, le cycle attend de nouveau le drapeau du temporisateur. Pour le bon
fonctionnement de la puce, il est nécessaire de construire une interface possédant
les alimentations nécessaires et la filtration adéquate des entrées et sorties. Pour ce
faire, une lecture approfondie de la fiche technique du convertisseur AD7798
permet la conception d’un circuit permettant un fonctionnement optimal de
l’équipement.5 Dans cette fiche, tous les niveaux de tensions d’alimentation et les
valeurs de composantes pour les filtres sont mentionnés selon les fréquences et
types de signaux traités. Le circuit développé est illustré en annexe de ce
document.
5 http://www.analog.com/static/imported-files/data_sheets/AD7798_7799.pdf
26
III.2.d. Capteur EMG
Dans le système proposé, il existe une deuxième interface qui sert à la conversion
des signaux provenant des contractions musculaires. Ces signaux sont captés avec
une triode qui est collée sur la peau comme illustrée à la figure 14.
Figure 14 : Triode musculaire
Les signaux à la sortie de la triode sont de l’ordre du micro volt. L’utilisation d’un
appareil servant à amplifier le signal musculaire sera donc nécessaire pour le
traitement des signaux. La compagnie qui fabrique ce système est Thought
Technology Ltd et le numéro de produit de l’amplificateur est le MyoScan-Pro
(SA9401M). Cet amplificateur se branche directement sur la triode ce qui a pour
impact d’amplifier un signal ayant beaucoup moins de bruits parasites. Le signal
de sortie de cet amplificateur sera de l’ordre du millivolt jusqu’au volt ce qui
facilitera le traitement. En plus d’amplifier le signal, cet appareil le traite et envoie
sa valeur efficace à la sortie, ce qui est très avantageux pour l’application
présente. L’amplificateur et un exemple de la forme de son signal de sortie sont
illustrés à la figure 15.
Figure 15 : Amplificateur RMS et son signal de sortie
27
Au début de chaque séance, un essai préliminaire est effectué sur chaque patient
pour déterminer la force maximale que celui-ci est capable de fournir. Le signal
émis par les muscles est ensuite enregistré et un seuil maximal est déterminé pour
une bonne réadaptation. Ce seuil représente environ 30% de la force maximale
précédemment enregistrée.
Par la suite, le patient commence à faire les mouvements prescrits et à chaque fois
que les signaux musculaires émis sont supérieurs au maximum déterminé, la
consigne de charge diminuera jusqu’à ce que les signaux musculaires passent en
dessous du seuil établi. Comme les signaux à traiter sont de types analogiques, ils
doivent être convertis en signaux numériques pour être traités dans le
microcontrôleur. Pour ce faire, une interface semblable à l’interface de la cellule
de charge a été conçue. Cependant, le circuit intégré servant à la conversion est
différent, car les seuils de tension sont différents. Après plusieurs recherches, le
choix s’est arrêté sur un convertisseur fabriqué par la compagnie Analog Device
qui possède des caractéristiques désirées pour cette application. 6 Tout comme le
circuit intégré de la cellule de charge, celui-ci permet une conversion de son
entrée analogique en une sortie numérique de 16 bits. La conversion se fait avec
une horloge externe et les données sont transférées au microcontrôleur par port
SPI.
Suite à la lecture des documents technique du convertisseur AD7680, il a été
possible de concevoir un circuit permettant la filtration adéquate des entrées
sorties tout en optimisant la précision de l’acquisition de données. Le transfert de
données entre le circuit intégré de conversion de l’EMG et le microcontrôleur se
fait par communication série SPI. Cette fois-ci, le port interne du microcontrôleur
est utilisé. Ce port série nécessite une configuration de plusieurs registres internes
qui déterminent la vitesse de transfert, le type d’horloge à utiliser et la longueur
des données lors du transfert. Les configurations des registres nécessaires pour
6 http://www.analog.com/static/imported-files/Data_Sheets/AD7680.pdf
28
l’application présente sont illustrées dans la figure 16 (se référer à la fiche
technique du manufacturier pour la description détaillée de chacun des registres)7.
Figure 16 : Configuration des deux registres nécessaires à la communication série SPI
Cette configuration du microcontrôleur assigne au port SPI une vitesse d’horloge
de transfert de 3.685 MHz, configure le microcontrôleur en mode maître et
assigne la longueur des données transférées à huit bits. Cette configuration permet
aussi d’ajuster les paramètres de l’horloge pour qu’ils soient compatibles avec le
convertisseur. La figure 17 démontre la séquence à suivre pour que la puce
effectue une conversion adéquate sans perte de données.
Figure 17 : Séquence à suivre pour une conversion et un transfert adéquat
Comme il est illustré, pour effectuer une conversion adéquate, le convertisseur
nécessite un envoi de 24 cycles d’horloges consécutifs pendant que son sélecteur
(CS���) est à 0 (0Vcc). Puisque la communication à l’intérieur du microcontrôleur a
été configurée pour envoyer et recevoir huit bits à la fois, les données reçues par
le microcontrôleur sont donc trois caractères de cette longueur.
7 http://www.analog.com/static/imported-files/Data_Sheets/AD7680.pdf
29
Pour démarrer l’horloge, une donnée quelconque doit être écrite dans le registre
tampon (SPI1BUF) du microcontrôleur. Celui-ci démarrera ensuite l’horloge de
communication (SCK1) et transmettra ce qui est à l’intérieur du registre tampon
sur son bus de sortie (SDO1). Cependant, pour cette application, le bus de
transmission série n’est pas utilisé. En effet, seul le bus d’entrée (SDI1) est utilisé
par le microcontrôleur puisque le convertisseur analogique à numérique utilisé ne
nécessite aucune configuration ou envoi de consigne. Celui-ci nécessite seulement
un envoi de 24 cycles d’horloge consécutif.
La conversion se fait durant les quatre premiers cycles d’horloges, les 16 autres
cycles permettront le transfert des données significatives de la conversion pour
ensuite se terminer par un envoi de quatre zéros par le convertisseur à la fin de la
communication. La figure 18 illustre le branchement entre l’AD7682 et le
« CPU ».
Figure 18 : Schématisation du branchement entre le microcontrôleur et l’AD76808
8 http://www.analog.com/static/imported-files/Data_Sheets/AD7680.pdf
30
Une séquence a donc été programmée à l’intérieur du microcontrôleur pour la
réception des trois caractères qui, après un traitement mathématique et leurs
recombinaisons, donnent une seule valeur sur 16 bits.
Pour effectuer la recombinaison des trois caractères, il a été nécessaire de faire des
déplacements dans les caractères reçus pour ensuite les additionner ensemble.
Cette manipulation est illustrée dans la figure 19.
Figure 19 : Séquence de conversion des données provenant de l’AD7680
31
III.2.e. Routine de communication avec le variateur de vitesse
Le variateur de vitesse Allen Bradley Ultra 3000 possède un port de
communication RS-232 permettant la configuration et le contrôle de l’appareil
(figure 20). Toute l’information est contenue dans la publication de Rockwell
Automation 2098-RM003A-EN-P. 9
Figure 20 : Identification du port de communication série sur le variateur de vitesse
� Configuration
La communication du variateur de vitesse RS-232 se fait sous la configuration
suivante :
Tableau 1: Configuration du port série
Vitesse de transfert : 38400 bauds
Parité : aucune
Stop bits : 1
Nombre de bits : 8
Contrôle du flux: aucun
9 http://samplecode.rockwellautomation.com/idc/groups/literature/documents/rm/20 98-rm003_-en-p.pdf
32
La configuration des paramètres de communication UART du dsPic30F4011 a dû
être effectuée à l’intérieur du programme afin de permettre la communication
entre le contrôleur et le variateur de vitesse.
� Architecture de la transmission de donnée
L’architecture de communication est basée sur l’envoi d’une série de caractères
ASCII (8bits) permettant de spécifier le numéro du variateur, l’action à effectuer
(lecture, écriture), le paramètre à accéder (ex. vitesse, position, courant…), la
valeur à envoyer (16 à 32 bits) et la validation des caractères envoyés ou reçus
(Checksum). La communication est amorcée en envoyant le caractère (:) et se
termine par un Retour de chariot. Une donnée typique se trouve sous la forme
suivante :
« : NN PPP A VVVVVVVV CC <cr> »
(:) Initialisation de la communication
(NN) : Adresse du variateur de vitesse
(PPP) : Paramètre à lire ou à écrire
(A): Commande lecture, écriture
(VVVVVVVV): Valeur de lecture ou d’écriture
(CC) : Valeur des deux derniers caractères du ‘Checksum’
<cr> : Retour de chariot (Fin de la communication)
La valeur des caractères est envoyée sous la forme de caractères ASCII. Chaque
caractère numérique peut prendre des valeurs de 0 à F en hexadécimal.
Le numéro du variateur est égal à 0 pour l’utilisation du servomoteur du côté
gauche de l’appareil. Pour communiquer avec le variateur du côté droit, il suffit
de remplacer l’adresse par 1. Pour les essais de ce projet seulement le côté gauche
est utilisé donc l’adresse restera égale à 0.
33
« : 00 PPP A VVVVVVVV CC <cr> »
Les paramètres du variateur sont définis de 000 à FFF. Par exemple pour
modifier le paramètre de la consigne de vitesse, l’adresse est égale à 0x06D.
« : 00 06D A VVVVVVVV CC <cr> »
Les commandes valides pour l’adresse 0x06D sont les suivantes :
0x0 : Lire la valeur dans le variateur de vitesse
0x1 : Écrire la valeur dans le variateur de vitesse
0x8: Lire la valeur minimum dans le variateur de vitesse
0x9 : Lire la valeur maximum dans le variateur de vitesse
« : 00 06D 1 VVVVVVVV CC <cr> »
La valeur pouvant être envoyée vers le variateur de vitesse est de 0x0000000 à
0xFFFFFFFF. Cette valeur représente la consigne de vitesse du variateur en
comptes/seconde.
Ex. :
65535
1 Révolution par minute (RPM) = 8000 Comptes/minute
1 Révolution par minute (RPM) = 155 Comptes/seconde
65535422.8 Rpm
155
h DFFFF =
=
« : 00 06D 1 0000FFFF CC <cr> »
34
� Validation des données
Afin de vérifier l’intégrité de la chaîne de caractères, un algorithme calcule la
SOMME DES DONNÉES (checksum). Ce calcul consiste à faire l’addition de la
valeur décimale de chaque caractère après l’initialisation de la communication.
Ensuite la valeur de la somme est soustraite de 256 et le résultat est converti en
hexadécimal
(256 )ASCII hexadecimal− ⇒∑
Ex. : « : 00 06D 1 0000FFFF CC <cr> »
Tableau 2: Valeur décimale de certains caractères ASCII
Caractère ASCII Valeur décimale
0 48
1 49
6 54
D 68
F 70
(256 )
(48 48 48 54 68 49 48 48 48 48 70 70 70 70)
787
256 787 531
531
d
d d d
d h
ASCII hexadecimal
ASCII
ASCII
FFFFFDED
− ⇒
= + + + + + + + + + + + + +
=
− = −
− →
∑∑∑
Les deux derniers caractères de la réponse hexadécimale forment le ‘checksum’ et
doivent être envoyés vers le variateur de vitesse. Dans le cas de l’exemple
précédant la valeur du “CheckSum” sera ED. Un exemple est présenté à la page
168 du document 2098-RM003A-EN-P de Rockwell automation. 10
« : 00 06D 1 0000FFFF ED <cr> »
10 http://samplecode.rockwellautomation.com/idc/groups/literature/documents/rm/20 98-rm003_-en-p.pdf
35
� Conversion et traitement de la valeur reçue ou envoyée
L’asservissement de la vitesse du bras permet d’ajuster la charge simulée sur la
poignée. La valeur de la vitesse est calculée par le contrôleur et est écrite dans un
registre de 32 bits. Afin d’isoler chaque caractère hexadécimal du mot de 32 bits,
il suffit d’utiliser la fonction de décalage « shift register » permettant d’isoler
chaque groupe de 4 bits du groupe de 32bits. Chaque caractère hexadécimal isolé
est converti en code ASCII 11 et ensuite envoyé dans l’emplacement de la valeur
à écrire.
Ex. : 0000FFFF (hexadécimal) = 00000000000000001111111111111111 (binaire)
b
b
1111
0000 0h
h
F→
→
Pour convertir la valeur hexadécimale de �� en code ASCII il
suffit d’ajouter 37� pour les valeurs de A à F et 30� de 0 à 9.
F +37 =46
0 +30 =30 h h h
h h h
La valeur correspondante obtenue sera F et 0 en code ASCII.
« : 00 06D 1 0000FFFF ED <cr> »
Finalement, une routine permet d’envoyer un caractère à la fois la chaîne de
caractère qui a été construite dans la séquence. Cette routine transmet tous les
caractères jusqu’à ce qu’elle rencontre la fin de la chaîne. De plus si la
communication est occupée, la routine attend avant d’envoyer un autre caractère.
Ceci permet d’éviter des erreurs d’écrasement de données.
11 http://www.asciitable.com/
36
� Résumé des étapes d’envoi
1- Inscription des paramètres dans la chaîne de caractère (Adresse, paramètre et
commande).
2- Conversion de la valeur à envoyer en caractère ASCII et inscription de ces
caractères dans la chaîne.
3- Calcul du ‘checksum’ et inscription de ces caractères dans la chaîne.
4- Envoi de la chaîne de caractères.
� Architecture de la réception de donnée
Le principe de réception est basé sur la même architecture que celle utilisée pour
la transmission. La différence se situe dans la partie commande où il suffit
d’inscrire la demande de lecture.
« : NN PPP 0 VVVVVVVV CC <cr> »
Il faut donc envoyer une chaîne semblable à une commande d’écriture à la
différence près que la zone allouée à la valeur à envoyer n’est pas transmise.
« : NN PPP A ________ CC <cr>
Il suffira ensuite de recevoir la réponse avec une routine de réception qui fera les
étapes inverses de l’envoi et enregistrera la valeur voulue dans le registre spécifié.
� Résumé des étapes d’envoi
1- Réception caractère par caractère (ASCII)
2- Calcul du ‘Checksum’ et vérification de la concordance des données
3- Conversion des caractères ASCII de la valeur envoyée en mots de 32bits.
37
� Gestion des erreurs de commande
Lorsqu’une commande de lecture ou d’écriture est envoyée au variateur de
vitesse, une série de code d’erreur peut être renvoyée par le variateur.
Par exemple, les réponses d’erreur possibles pour une commande à l’adresse
0x06D sont les suivantes :
0x04 = Valeur en dessous du minimum
0x08 = Code de fonction invalide
Pour chaque commande il existe des codes d’erreur qui lui sont associés. Il faut
donc s’assurer que la valeur envoyée soit valide, car présentement aucune boucle
n’a été programmée pour détecter les erreurs à la suite d’une commande.
38
III.2.f. Architecture du programme
� Initialisation et étapes préliminaires à l’utilisation
Le programme principal (figure 21) est
constitué de trois parties : l’initialisation
du microcontrôleur, l’initialisation de la
machine et l’asservissement de la vitesse.
Lorsque l’initialisation du contrôleur et
de la machine a été effectuée, le système
attend la consigne de démarrer
l’entraînement. La consigne provient de
l’interface de l’opérateur lorsque le client
est bien positionné et prêt à commencer
l’entraînement.
Pour terminer l’entraînement, l’opérateur
doit appuyer sur le bouton « Arrêt » de la
console d’opération.
Figure 21 : Routine de contrôle principale
39
L’initialisation du microcontrôleur consiste à
configurer et activer les périphériques utilisés
dans le contrôle de la machine (figure 22).
Dans l’ordre l’initialisation des « UART»
(Universal Synchronous & Asynchronous
Receiver Transmitter), permet de spécifier les
paramètres de communication tels que la vitesse,
la parité, le nombre de bits d’arrêt ainsi que la
configuration des interruptions générées par la
transmission ou la réception.
Figure 22 : Séquence d’initialisation du microcontrôleur.
Ensuite, il faut initialiser le port SPI 1 pour ajuster le type d’horloge utilisé et la
vitesse de communication. Pour le port SPI 2, il s’agit d’un port émulé, il faut
donc initialiser le temporisateur utilisé pour la communication ainsi que les
entrées et sorties dédiées pour transmettre et recevoir les signaux de l’échange de
donnée. Une fois les ports de communication initialisés et configurés, il faut
assigner la fonction de chacun des ports A, B, C, D, E, utilisés soit en entrée ou en
sortie et définir leurs valeurs initiales.
Lorsque l’initialisation des périphériques internes au microcontrôleur est
terminée, il faut ensuite procéder à l’initialisation des périphériques externes. Le
convertisseur A/D de la cellule de charge est donc configuré pour effectuer la
conversion à la vitesse voulue et de façon à envoyer des données en continu.
INITIALISATION DU
MICROCONTROLLEUR
INITIALISATION DU UART1
INITIALISATION DU UART2
INITIALISATION DU SPI 1
INITIALISATION DU TEMPORISATEUR #1
(SPI2)
INITIALISATION DES ENTRÉES / SORTIES
INITIALISATION DU A/D 2
INITIALISATION DU VARIATEUR DE VITESSE
40
Finalement, une configuration initiale est envoyée au variateur de vitesse pour
l’activer en mode asservissement de vitesse avec une consigne initiale de 0 RPM.
INITIALISATION DE LA
MACHINE
POSITIONNEMENT DU BRAS À LA CONSIGNE DE
L’INTERFACE LECTURE DE LA CONSIGNE DE FORCE DE L’INTERFACE
LECTURE DU SEUIL MAXIMAL DE FORCE DU
CLIENT (EMG)
CALCUL DU SEUIL DE 30%EMG MAX.
ATTENTE
CONSIGNE ANGULAIRE OK =0
CONSIGNE ANGULAIRE OK =1
ATTENTE
CONSIGNE CHARGE OK =0
CONSIGNE CHARGEOK=1
LECTURE DE LA CELLULE DE CHARGE
SAUVEGARDE DU ZÉRO DE LA CELLULE DE CHARGE
MAX EMG =1
LECTURE EMG
MAX EMG=0
Figure 23 : Séquence d’initialisation de la machine
L’initialisation de la machine vise à ajuster les paramètres qui sont propres au
client qui utilise la machine (figure 23).
La première étape consiste à ajuster l’angle de départ auquel le client débute son
exercice. L’angle est défini par l’entraîneur et doit être entré dans la console
d’opération. À la réception de cette consigne par le microcontrôleur, elle doit être
traitée, car cette consigne est en ASCII représentant un nombre décimal et de
longueur pouvant varier d’un à quatre caractères. En plus, pour indiquer que la
consigne est celle qui est attendue, elle est précédée d’une lettre indicatrice.
41
Une routine à l’intérieur du microcontrôleur a donc été développée pour ramener
cette valeur en hexadécimale sur 16 bits, ce qui permet le traitement de celle-ci. Il
est possible de visualiser les étapes de transformation de la variable dans la figure
24, qui servira pour toutes les réceptions de consigne.
Figure 24: Séquence de réception des consignes provenant de l’interface de contrôle.
Une fois la consigne inscrite, il faut activer la fonction de positionnement pour
que le bras mécanique de l’appareil se positionne à l’angle inscrit. Cette fonction
est en fait une boucle qui envoie une vitesse lente au variateur de vitesse et envoie
ensuite des consignes de lecture de position en boucle ce qui permet de savoir la
position du bras en continu. La routine se termine lorsque la position est atteinte.
À ce moment, une consigne de vitesse ZÉRO est inscrite dans le variateur de
vitesse ce qui arrête le bras à la position désirée. La séquence de cette routine est
illustrée à la figure 25.
42
Figure 25: Séquence de positionnement du bras à l’angle initial
La deuxième étape est l’envoi de la consigne de charge. Cette valeur doit être
inscrite dans la console d’opération et envoyée en appuyant sur le bouton « ok ».
Cette valeur sera utilisée comme consigne de charge initiale et traitée de la même
manière que la consigne d’angle initial décrit précédemment.
La dernière étape consiste à déterminer le seuil maximal musculaire du client. Le
servomoteur ayant une consigne de vitesse de 0 RPM ne permet donc aucun
mouvement de rotation du bras mécanique. Le client doit ensuite forcer au
maximum de ses capacités contre le bras mécanique et relâcher. Cette étape doit
être faite sous la supervision d’un spécialiste afin d’éviter tout risque de blessures.
Pendant ce temps le microcontrôleur enregistre la valeur maximale lue par
l’EMG. En appuyant par la suite sur le bouton « Max. EMG» le programme
enregistre cette valeur et détermine le seuil de 30% que l’utilisateur ne devra pas
dépasser lors de l’exercice.
43
� Routine d’asservissement en fonctionnement normal
Figure 26: Séquence d’asservissement de la vitesse du moteur.
L’asservissement de la vitesse (figure 26) permet de varier la force que le client
applique sur la cellule de charge. En accélérant dans le même sens que
l’utilisateur la charge simulée sera diminuée tandis qu’une décélération la fera
augmenter. Toutefois, le seuil de 30% de l’EMG reste prioritaire sur la consigne
de charge. En effet, une fois la lecture de la cellule de charge effectuée, une
lecture de l’EMG permet de vérifier que le seuil de 30% n’a pas été dépassé.
Advenant le cas, le système diminuera la consigne de la charge afin de rétablir
une valeur d’EMG inférieure ou égale à 30%. La diminution de la consigne sera
proportionnelle au dépassement du seuil de 30 % :
[ ]%
_ 30%100%
_ 30%
D Dépassement
EMG SeuilD
Seuil
∆ =
−• = ∆
44
Avec le pourcentage de dépassement, il est possible ensuite de calculer la
nouvelle consigne de charge de l’appareil.
[ ]
( )nouvelle actuelle actuelle
SpF Consigneforce N
SpF SpF SpF D
=
= − • ∆
Ensuite, la mesure de la force appliquée permet de calculer la différence avec la
consigne de charge.
[ ]Différence de force
Consigne actuel
F N
F F F
∆ =
∆ = −
Les nouvelles consignes de vitesse et d’accélération sont ensuite déterminées en
fonction de F∆ .
[ ]
( )
2
2min
min min
Consigne de vitesse Compte/seconde
Consigne d'accélération Compte/seconde
Accélération minimum Compte/seconde
correction
actuelle correction
SpV
SpA
A
SpA A A F Gain
SpV V F Gain Facteur
=
=
=
= + • ∆ •
= ± ∆ • •( )correction
La valeur de la consigne d’accélération (SpA) varie donc entre une valeur
d’accélération minimale jusqu'à une valeur proportionnelle à l’erreur entre la
consigne et la force appliquée.
La valeur de la consigne de vitesse (SpV) dépend du type d’erreur sur la consigne
de charge. Si la valeur actuelle est inférieure à la consigne, il y aura une correction
négative sur la vitesse et inversement dans le cas d’une valeur actuelle supérieure
à la consigne.
45
Lorsque les nouvelles valeurs ont été déterminées, elles sont envoyées au
variateur de vitesse pour appliquer la correction. Une fois les nouvelles consignes
envoyées au variateur de vitesse, le programme envoie la valeur de position
angulaire, d’EMG et de cellule de charge vers l’interface.
Afin d’accélérer au maximum la vitesse de la boucle d’asservissement, la gestion
des positions de fin de course est gérée par le variateur de vitesse. De cette
manière, le programme dans le microcontrôleur n’aura plus besoin de recevoir les
données de position pour détecter les limites de position.
Lors du positionnement initial du bras, la première position est enregistrée comme
valeur minimale. Ensuite, la valeur maximale est calculée soit 90 degrés de plus
que la valeur minimale. Ces deux valeurs sont envoyées au variateur de vitesse
pour la détection de la fin de course.
Finalement, une comparaison à l’intérieur du variateur de vitesse permet d’activer
deux sorties sur le variateur de vitesse. L’activation des sorties permet d’alimenter
deux entrées du microcontrôleur informant que la fin de course est atteinte. Les
deux entrées permettent de signaler la fin de la course du bras, de commander
l’arrêt du moteur et de changer le sens du mouvement.
46
III.2.g. Interface d’opération
Figure 27: Interface d’opération.
Dans le cadre du projet, l’interface d’opération permettra d’opérer la machine
seulement en flexion du bras gauche.
Le fonctionnement de l’interface se divise en deux parties. La première est une
boucle séquentielle qui permet de rafraîchir les valeurs de l’interface à chaque
milliseconde (Figure 28). La deuxième est une fonction de réception qui s’active
en présence d’un événement permettant de recevoir les données envoyées par le
microcontrôleur.
47
Les données acquises de l’EMG, de la cellule de charge et de la position angulaire
sont affichées sur les trois graphiques de l’interface (figure 27). Les valeurs des
données sont rafraîchies lorsque la consigne du temporisateur de l’interface atteint
le temps désiré, soit 1mS.
Figure 28: Boucle de l’interface d’opération.
L’étape 0 consiste à envoyer la valeur de la position initiale en degré vers le
microcontrôleur. Le bouton « Dem » de l’interface permet d’aller à l’étape 0. Le
bouton « Ok » apparaît à droite de la boîte où peut être entrée la valeur de l’angle
initial (figure 29).
48
Le bouton « ARR » permet d’arrêter l’interface en fermant le port RS-232 et la
feuille Excel en cours. Un témoin (1/0) à droite du bouton « ARR » permet de
vérifier l’état de l’interface.
Figure 29: Consigne d’angle initial de l’interface.
Après avoir entré la consigne initiale de position angulaire, le bouton « Ok »
permet d’ouvrir le port de communication RS-232 et d’envoyer une chaîne de
caractères ASCII représentant la consigne angulaire. Par exemple, si la consigne
est 10 degrés, les caractères envoyés seront « :G10Z ». Les deux points permettent
de marquer le début de la chaîne, le «G» permet de spécifier l’angle initial, la
valeur « 10 » est la consigne et le « Z » représente la fin de la chaîne. Une fois
l’envoi des caractères terminé le port de communication est refermé, le
programme passe à l’étape 1 et le bouton « Ok » est masqué.
Figure 30: Consigne de charge.
L’étape 1 consiste à envoyer la consigne de la charge. Le bouton « Ok » est
affiché à droite de la consigne de charge. Un message clignotant est aussi affiché,
pour signaler qu’il ne faut pas toucher la poignée à cette étape. Ceci est dû à la
remise à zéro de la valeur lue à la cellule de charge. En appuyant sur le bouton
« Ok » le bouton est masqué et la valeur de la consigne est envoyée par RS-232.
Par exemple, pour une consigne de 10Kg, le message sera «:L10Z».
49
L’architecture est la même que pour la consigne angulaire sauf pour le « L» qui
spécifie la consigne de charge.
Figure 31: Consigne de l’EMG et valeur isométrique.
L’étape trois consiste tout d’abord à faire un test isométrique permettant d’obtenir
le seuil maximum lu par l’électromyogramme. À cette étape, la valeur de
l’électromyogramme est affichée en temps réel dans la case «ACT» pour valeur
actuelle. L’utilisateur peut donc forcer à quelque reprise contre le bras de
l’appareil de l’opérateur peut ensuite écrire la valeur maximale lue dans la case
«SP» afin de spécifier le maximum obtenu. Le bouton « Max EMG » est affiché
lorsque la séquence est à l’étape 3. En appuyant sur le bouton, celui-ci devient
masqué et permet d’envoyer la chaîne de caractère de la consigne de l’EMG. Par
exemple si la consigne est de 1000µV, le message envoyé sera «:S1000Z». Le
«S» permettra de spécifier la consigne de l’EMG au microcontrôleur.
Figure 32: Control de l’entraînement.
L’étape 4 peut débuter lorsque le bouton «DEM» est enfoncé. En appuyant sur le
bouton «ARR», l’entraînement est arrêté et l’interface attend le démarrage pour
continuer. Afin de transmettre la consigne d’arrêt ou de démarrage de
l’entraînement, les consignes «:ONNZ» (démarrage) et «:OFFZ» (arrêt) sont
envoyées au microcontrôleur. Pendant l’entraînement, l’interface permet de
visualiser les valeurs de la cellule de charge, de l’EMG et de la position angulaire.
50
Les valeurs affichées sont les valeurs qui sont contenues dans la mémoire tampon
de la réception RS-232, donc les dernières valeurs reçues en provenance du
microcontrôleur. La mémoire tampon contient 30 caractères ASCII et la chaîne de
caractères à recevoir est de 14 caractères. La chaîne de caractères est constituée
des valeurs hexadécimales de la position angulaire, de l’EMG et de la cellule de
charge de la façon suivante «:AAAAEEEELLLLZ». Le «:» définit le début de la
chaîne et le «Z» la fin. Les valeurs AAAA, EEEE ou LLLL sont les valeurs
hexadécimales de 0 à FFFF. Une détection du «:» et un compteur permettent de
localiser la chaîne de caractères de la mémoire tampon. Il faut par la suite
convertir les caractères ASCII en un nombre décimal. Chaque caractère ASCII
est converti en sa valeur décimale, soit 48 pour un «0» ASCII à 70 pour un «F». Il
suffit ensuite de ramener la valeur en hexadécimal et de faire la somme de chaque
caractère.
Par exemple : «1», «A», «2», «F» en décimal
( )
( )
( )
( )
( ) ( ) ( )
1 49 49 48 1
A 65 65 65 10 10
2 50 50 48 2
F 70 70 65 10 15
1 4096 10 256 2 16 15 6703
1A2F 6703
Val
→ → − =
→ → − + =
→ → − =
→ → − + =
= • + • + • + =
=
Une fois la valeur convertie, il suffit de l’afficher dans l’interface et d’enregistrer
les valeurs dans Excel. Afin d’avoir un graphique ayant un affichage précis,
l’image de fond a été dessinée avec une précision de un pixel. Le format de
l’image est de 1200X800 pixels et les divisions verticales sont à tous les 100
pixels. Chaque rafraîchissement avance le pointeur dans l’image de un pixel.
Selon le temps de rafraîchissement, il est possible de ramener les échantillons
dans le temps. De la même façon, les valeurs affichées dans les graphiques seront
donc des %, kg ou degré ramenées sur 267 pixels. Lorsque la valeur du pointeur
en X atteint 1200 pixels, l’image est réinitialisée pour effacer les graphiques.
51
Pour faciliter la comparaison des données avec celles recueillies avec le prototype,
un enregistrement Excel permet de sauvegarder toutes les données affichées
durant toute la durée de l’exercice.
L’enregistrement dans un fichier nommé «Entraînement.xls» débute automatique
lorsque l’entraînement démarre. Ce fichier est sauvegardé lors de l’arrêt de
l’exercice. À chaque fois que le pointeur du graphique atteint 1200 pixels,
l’enregistrement Excel change de colonne. Ceci permet donc d’afficher facilement
un graphique de 1200 échantillons de l’EMG de la cellule de charge et de la
position angulaire
Figure 33: Affichage du graphique de l’EMG.
Figure 34: Affichage du graphique de l’EMG à partir du fichier Entraînement.xls
Comme le démontrent les figures 33 et 34, il est possible de vérifier la
concordance des valeurs enregistrées dans le tableau Excel.
-10
0
10
20
30
40
50
0 50 100 150 200 250 300 350 400
52
Afin de vérifier l’interface, des valeurs aléatoires ont été envoyées par RS-232. La
seconde partie du programme est une fonction qui se déclenche lorsque le port
RS-232 reçoit 24 caractères. À ce moment une copie de la mémoire tampon est
transférée dans un registre afin d’être traitée dans la routine principale. La
fonction de réception est active seulement à l’étape 2 pour obtenir la valeur en
isométrie et à l’étape 3 pour le rafraîchissement de l’affichage.
Figure 35: Paramètre du port RS-232 et remise à zéro
Plusieurs fonctions ont été programmées afin de faciliter les essais. Pour
configurer le nom du port RS-232, une case permet de la spécifier pour le bon
fonctionnement de l’interface. Ensuite, un bouton remis à zéro permet de
réinitialiser l’interface à l’étape initiale en tout temps (Figure 35). Des affichages
permettant de visualiser la valeur actuelle des graphiques en temps réel ont été
ajoutés afin d’obtenir rapidement la valeur affichée (Figure 36_1). Ensuite pour
diagnostiquer la communication les valeurs du tampon de réception sont affichées
en temps réel (figure 36_3) ainsi que les caractères ASCII détectés dans la chaîne
de caractères (Figure 36_4).
Finalement, l’affichage du temps de
rafraîchissement (figure 36_2) représente le temps
nécessité par le programme du microcontrôleur pour
effectuer un cycle complet de l’asservissement.
Cette valeur est affichée en milliseconde et permet
de mesurer la performance de la boucle.
Figure 36: Affichage des valeurs reçues et converties en temps réel.
53
IV. Bilan des activités
IV.1 Arrimage formation pratique/universitaire
Lors de la réalisation du projet, de nombreuses notions techniques et
mathématiques ont été nécessaires pour le bon déroulement de celui-ci. En effet,
des cours tels que Système à Microprocesseur, Systèmes digitaux, Introduction
aux Ordinateurs, Dynamique des Systèmes II, Électronique I et Électronique II
ont permis d’acquérir les connaissances de base nécessaire au bon déroulement du
projet.
Les cours tels que système à Microprocesseur, Systèmes digitaux et Introduction
aux Ordinateurs ont été très utiles pour développer le programme de contrôle du
système fonctionnant sur microcontrôleur. Par la suite, les notions acquises dans
les cours de Dynamique des Systèmes II, Électronique I et Électronique II ont
permis de comprendre de nombreuse notion sur la stabilité des systèmes et le
traitement des signaux.
Le projet a quant à lui permis d’approfondir de nombreuses notions qui ont été
apprises plus tard au cours de la formation. Effectivement, une étude approfondie
des systèmes de conversions analogiques à numériques a été nécessaire et très
utile. Subséquemment, le développement d’une interface de contrôle a nécessité
l’apprentissage du programme Visual Studio et du langage de programmation
Visual Basic. Finalement, le projet en général permet d’appliquer de nombreuses
notions apprises au long de la formation et de comprendre l’utilité de celles-ci.
Il est à noter que la matière des cours tels que Signaux et Système, Traitement
numérique des Signaux et Système asservi aurait pu être très utile pour le
développement de l’appareil. Cependant, il était difficile de faire le lien entre les
notions théoriques de ces cours et leurs applications dans ce projet.
54
Finalement, les cours optionnels comme Interface et Instrumentation ainsi que
Conception de Systèmes digitaux sont des cours très appliqués qui auraient pu
apporter des techniques de conception utiles au développement du système.
Cependant, le projet était déjà très avancé lorsque nous avons assisté à ces cours,
il a donc été impossible de bénéficier de ces connaissances durant le projet.
55
IV.2 Travail d’équipe
Dans la première moitié du projet, l’appareil A.M.E résidait dans les locaux de
l’entreprise et était utilisé pour la réadaptation physique. Ensuite, dans la
deuxième partie du projet, la machine a été transférée dans l’aile des humanités de
l’UQAC pour une étude sur plusieurs personnes afin de valider les performances
de l’appareil au niveau physiologique.
Afin de ne pas interférer avec l’utilisation de la machine, il fallait bien planifier
les moments où allaient être effectuées les interventions sur l’équipement. De
plus, comme l’équipement était utilisé fréquemment, il fallait s’assurer de
remettre A.M.E. dans sa condition initiale après chaque intervention.
Le projet a donc permis de mieux coordonner les interventions de façon à ne pas
compromettre l’utilisation normale de l’appareil avec l’utilisation de l’agenda en
ligne de Google.
Puisque la première version de l’équipement a été conçue par le CPA, il fallait
fréquemment entrer en contact avec eux afin d’obtenir de l’information technique
sur certains composants. De plus, certains des équipements étaient accessibles via
le laboratoire du Cégep de Jonquière et ont pu nous permettre de faire plusieurs
essais avec le variateur de vitesse. De cette, façon il était possible d’effectuer des
essais sécuritaires et sans utiliser du temps d’opération de A.M.E.
Cette particularité du projet a permis d’apprendre à utiliser les ressources
disponibles afin de faciliter le développement de l’équipement.
Finalement, l’interaction avec l’ensemble des participants, soient le CEME, le
CPA , les techniciens et notre conseiller, a permis tout au long du projet de
vérifier et corriger les hypothèses qui ont été avancées.
56
IV.3 Respect de l’échéancier
Figure 37 : Diagramme de Gantt de la planification du projet
57
L’échéancier a été respecté pour la majorité des tâches à effectuer. Toutefois,
certains points ont été plus longs que prévu.
La calibration et l’essai de la cellule de charge ont duré une semaine de plus que
le délai prévu dû à des problèmes de configuration du circuit intégré. Ensuite, dû à
une particularité du convertisseur de la cellule de charge, un port de
communication SPI virtuel a dû être programmé. Cette étape supplémentaire a
ajouté un délai au niveau du développement de l’acquisition de la cellule de
charge.
La conception de l’interface d’essai a aussi été un peu plus longue que prévu. En
effet, la programmation avec Visual Studio 2008 a nécessité un temps
d’adaptation afin de maîtriser les fonctions et l’environnement du programme. De
plus, pour faciliter le diagnostic du programme durant le projet, l’interface a été
modifiée et adaptée tout au long du projet. Finalement, pour permettre l’affichage
des valeurs en temps réel, il a fallu optimiser la communication RS-232 afin de
maximiser le rafraîchissement des valeurs affichées.
La fin du projet était prévue pour le début du mois de mars 2010. Afin d’obtenir
les résultats voulus, il a été possible de prolonger la période d’évaluation des
performances du processeur versus celles de l’automate d’un mois c'est-à-dire
jusqu’au début avril 2010. Les résultats qui auraient été obtenus à la fin du mois
de mars auraient été satisfaisants, toutefois l’étude a été prolongée afin d’obtenir
le meilleur fonctionnement possible. Cette période a permis de faire quelques
correctifs au niveau du contrôle de l’appareil et d’optimiser l’asservissement du
système.
58
IV.4 Analyse et discussion
Après analyse du projet de façon générale, il est possible d’affirmer que celui-ci
s’est bien déroulé. Cependant, dû à une limitation causée par la vitesse de
communication entre le variateur de vitesse et l’unité centrale, il n’a pas été
possible d’utiliser les pleines performances de l’unité de calcul. Il sera donc
primordial dans la continuité du développement de l’appareil d’utiliser un
protocole de communication beaucoup plus rapide capable d’exploiter les
performances du système de contrôle à son maximum.
Un élément qui risque de devenir une faiblesse après l’amélioration de la vitesse
de communication énumérée précédemment est le convertisseur
analogique/numérique servant à faire la conversion des signaux provenant de la
cellule de charge. En effet, lors des essais effectués sur le système, il a été
possible de constater que la vitesse de conversion théorique de cet élément semble
difficile à atteindre si l’on désire une grande précision.
Un élément très important du projet est le remplacement du Myotrac par un
amplificateur EMG situé directement sur la triode. Ceci permet d’effectuer le
traitement des signaux musculaires directement à la source. En effet, cet
équipement permet de réduire les coûts de production de l’équipement en plus de
permettre au microcontrôleur d’effectuer le traitement des données. Cela a eu
pour effet d’éliminer la boucle de traitement qui était longue et qui pouvait ainsi
amener des délais de traitement et des réponses lentes du système.
Finalement, la vitesse de traitement du microcontrôleur est très élevée et permet
d’effectuer tous les calculs nécessaires au bon fonctionnement de l’appareil.
L’optimisation de la communication au niveau du variateur de vitesse permettra
d’utiliser le microcontrôleur à son plein potentiel et ceci amènera par le fait même
une meilleure réaction du système. De plus, le coût de cette composante est
minime si on la compare au système de contrôle existant.
59
Effectivement, il est possible de réduire le coût de l’unité de calcul par un facteur
de 20 pour une vitesse de traitement supérieure, tel qu’illustré dans le tableau 3.
Tableau 3 : Comparaison du prix des équipements
Prototype actuel Nouvelle Approche Processeur CompactLogix L43
3 656,18 $ Carte de développement dsPic (Microchip)
150 $
Carte de conversion pour cellule de charge
1 782,50 $ Convertisseur de la cellule de charge (A/D)
70 $
MyTrac 1 700 $ Convertisseur de l’EMG (A/D)
70 $
MyoScanPro 400 $
Total 7138,68$ Total 690$
60
V. Conclusion et recommandations
L’objectif du projet était de réévaluer les choix qui ont été faits dans le premier
prototype et de modifier le système pour améliorer les performances et réduire les
coûts. Les objectifs du projet ont pratiquement tous été atteints puisque le système
a présentement un fonctionnement comparable au prototype existant. De plus, les
coûts reliés au système de contrôle et à l’acquisition des signaux musculaires sont
grandement réduits.
La raison pour laquelle il n’a pas été possible d’obtenir un système possédant une
réponse plus rapide que le système existant est le protocole de communication
utilisé entre le variateur de vitesse et le microcontrôleur. Effectivement, ce
protocole a été choisi pour sa compatibilité avec le variateur de vitesse et le temps
limité pour la réalisation du projet. Il aurait été possible d’utiliser la
communication SERCOS, qui est un protocole sur fibre optique et qui est
présentement utilisée sur le prototype, mais il aurait été impossible de respecter le
temps alloué au projet si le support de la communication SERCOS avait été
ajouté. Il serait donc important d’étudier ce point pour le développement futur et
aussi, de faire une étude complète de la réaction du système bras/moteur pour
déterminer son temps de réaction et sa capacité à réagir à des mouvements
brusques.
Pour ce qui est du traitement des signaux de la cellule de charge, il serait peut-être
avantageux d’effectuer une amplification du signal directement à la sortie de la
cellule de charge. Effectivement, cela aurait pour effet de diminuer l’influence des
équipements environnants sur les signaux de la cellule. De plus, une fois amplifié,
il serait possible de faire la conversion analogique/numérique des signaux avec le
convertisseur intégré au microcontrôleur qui est plus rapide que le convertisseur
présentement utilisé.
61
Ensuite, le système actuel utilise un asservissement de vitesse pour simuler la
charge ressentie. En considérant une approche plus près de la physique réelle,
l’utilisation de consignes d’accélération pourrait probablement augmenter la
précision de l’asservissement et ainsi, diminuer le temps de réaction de
l’équipement.
Finalement, après une étude du travail accompli, il est possible de conclure que
les objectifs initiaux du projet ont été respectés et que le projet est maintenant
terminé.
62
VI. Bibliographie
CEME, Qu’est que c’est, 1 page , 2002, Consultants en ergonomie et en mieux-être
http://www.ceme.qc.ca/Questceque.htm
Consulté le 14 avril 2010.
AB, Ultra3000 Digital servo drive, 180 pages, 2004, Rockwell Automation
http://literature.rockwellautomation.com/idc/groups/literature/documents/in/2098-
in003_-en-p.pdf
Consulté le 10 octobre 2009.
AB, Ultra 3000 Digital servo drive, 180 pages, 2004, Rockwell Automation
http://literature.rockwellautomation.com/idc/groups/literature/documents/in/2098-
in005_-en-p.pdf
Consulté le 13 octobre 2009.
LINAK, Actuateur linéaire, 1 page, 2010, Linear actuator technologie
http://www.linak.com/Products/?id2=2
Consulté le 12 octobre 2009.
AB, Tl serie servo motor, 24 pages, 2005, Allen Bradley
http://literature.rockwellautomation.com/idc/groups/literature/documents/in/tl-
in001_-en-p.pdf
Consulté le 13 octobre 2009.
AB, Compact Logix Controller, 36 pages, 2008, Allen Bradley
http://literature.rockwellautomation.com/idc/groups/literature/documents/in/1768-
in004_-en-p.pdf
Consulté le 13 octobre 2009.
63
AB, 1768 Compact Logix Controller, 132 pages, 2008, Allen Bradley
http://literature.rockwellautomation.com/idc/groups/literature/documents/um/1768-
um001_-en-p.pdf
Consulté le 13 octobre 2009.
Oméga, Cellule de charge, 1 page, 2002, Oméga.ca
http://www.omega.ca/manuals/default_FRRR.asp?s=j
Consulté le 19 octobre 2009.
Vishay, Cellule de charge, 6 pages, 2002, Vishay Intertechnology
http://www.vishay.com/docs/49408/tedea-h.pdf
Consulté le 20 octobre 2009.
Thought technology, Cellule de charge, 23 pages, 2003, Thought technology
http://www.thoughttechnology.com/pdf/manuals/MAR900-
01%20SEMG%20applied%20to%20psychophysiology.pdf
Consulté le 15 octobre 2009.
Thought technology, Myotrac Infiniti, 56 pages, 2006, Thought technology
http://bio-medical.com/support/pdf/CONTISUITE.pdf
Consulté le 23 octobre 2009.
Thought technology, Myotrac Infiniti (user guide), 57 pages, 2005, Thought technology
http://www.thoughttechnology.com/pdf/manuals/SA9810%20Rev%204%20.pdf
Consulté le 25 octobre 2009.
Thought technology, MyoScan, 1 pages, 2010, Thought technology
http://www.thoughttechnology.com/gbfsensors.htm
Consulté le 25 octobre 2009.
64
AB, PLCenter_Surplus, 1 page, 2010, Allen Bradley
http://www.plccenter.com/buy/ALLEN+BRADLEY/2098DSD020X
Consulté le 15 octobre 2009.
MC, Compiler C30, 1 page, 2009, Microchip
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=14
06&dDocName=en535363
Consulté le 29 octobre 2009.
MC, Carte de développement, 1 page, 2009, Microchip
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=14
06&dDocName=en023561
Consulté le 29 octobre 2009.
EFPGA, EZ1CUSB - Altera Cyclone FPGA, 1 page, 2009, Easy_FPGA
http://www.easyfpga.com/
Consulté le 17 octobre 2009.
OTTech, FPGA USB Boards- ZestSC2, 1 page, 2009, Orange tree technologie
http://www.easyfpga.com/
Consulté le 11 octobre 2009.
SemiFluid, PIC18F2550 USB HID Oscilloscope, 1 page, 2009, SemiFluid
http://www.semifluid.com/?p=24#more-24
Consulté le 13 octobre 2009.
MC, dsPic30f4011, 1 page, 2009, Microchip
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010337
Consulté le 13 octobre 2009.
65
TI, TLC2270 amplifier, 1 page, 2009, Texas Instrument
http://focus.ti.com/lit/ds/symlink/tlc2274.pdf
Consulté le 13 octobre 2009.
ONSEMI, Diodes MRA4003T3, 4 pages, 2004, ON semiconductor
http://www.onsemi.com/pub_link/Collateral/MRA4003T3-D.PDF
Consulté le 13 octobre 2009.
BFMC, CTT IKARUS, 1 page, 2009, BioFeedbackMotorControl
http://www.bfmc.de/produkte_direkt_eng.html
Consulté le 13 octobre 2009.
66
Annexe A : Nouvelle approche
Afin d’obtenir un contrôle qui s’approche au maximum des équations de la
physique, il serait possible de faire l’asservissement de la charge simulée en
faisant des corrections d’accélération durant le mouvement.
[ ]
[ ]
[ ]
2
2
Force appliquée
Masse
ccélération m/s
_ ang = Accélération angulaire cnt/s
F N
m Kg
A A
A
F mA N
=
=
=
=
Figure 38 : Schéma du bras de A.M.E. avec la force appliquée
Afin d’obtenir la valeur de la masse simulée (m), la force (F) appliquée doit être
mesurée ainsi que la hauteur (H) ou la poignée est positionnée. De plus,
l’accélération (A) angulaire du moteur devra être mesurée par le variateur de
vitesse.
Avec ces valeurs, il sera possible de déterminer la masse simulée par le système.
L’accélération (A) qui est mesurée par le variateur de vitesse est une accélération
angulaire, il faut donc la convertir pour avoir l’accélération à la hauteur de la
poignée.
( )
[ ]
2
2
22
Accélération angulaire /
1 tour du moteur = 8000 cnt
1 1 /8000 360 0.045
Accélération au niveau de la poignée m/s
2m/s 0.045
360
poignée
poignée
A cnt s
Cnt cnt cnt
A
cntA A H m
s cnt
π
=
= ° = °
=
° = °
i
i i i
H
F
A_ang
67
Lorsque l’accélération de la poignée est connue, il suffit d’utiliser la formule
suivante pour déterminer la masse simulée.
[ ]Kgpoignée
Fm
A=
Lorsque la masse simulée a été obtenue, il est possible de la comparer avec la
consigne et de calculer la correction à effectuer.
[ ]
[ ]
[ ][ ]
[ ]
% = Correction [%]
_ = Consigne de charge kg
Charge mesurée N
_
9.81
% 100% _
C
Sp load
load
load NSp load kg
N
kgC
Sp load kg
=
−
= •
Avec le pourcentage de correction, il sera ensuite possible de calculer la nouvelle
consigne d’accélération permettant d’obtenir la charge simulée voulue.
[ ]
( )( )
2
2
_ = Consigne d'accélération [ / ]
_ = Accélération réelle /
% Correction %
_ _ _ %
Sp A m s
A reel m s
C
Sp A A reel A reel C
=
= + •
68
La nouvelle consigne d’accélération aura donc une variation proportionnelle à
l’écart entre la charge et la consigne de charge. Afin de conserver l’appareil
sécuritaire, il sera important de spécifier une valeur maximum pour l’accélération
et la vitesse.
Finalement, pour permettre un contrôle en accélération avec le variateur de
vitesse existant, il faudra que le système n’atteigne jamais sa consigne de vitesse
pour conserver une variation de l’accélération. Donc ceci implique qu’à chaque
cycle de l’asservissement, il faudra ajuster la vitesse (positive ou négative) afin
d’accélérer ou de décélérer en plus d’envoyer la grandeur de l’accélération
voulue.
Il est à noter que la nouvelle consigne d’accélération (Sp_ A) devra être convertie
en accélération angulaire pour être envoyée au variateur de vitesse.
69
Annexe B : Plans électriques
Annexe C : Programme du microcontrôleur et de l’interface
1C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
'***********************************************************************************************************
'Declaration des variables'********************************************************************************************
***************Public Class Form1 Dim Temp As String = 0 Dim ExcelACT As Boolean = 0 Dim A As Char = "A" Dim CAR As Char = "Z" Dim ZERO As Char = "0" Dim X1 As Integer = 5 Dim Y1 As Integer = 264 Dim X2 As Integer = 5 Dim Y2 As Integer = 264 Dim Y3 As Integer = 530 Dim Y4 As Integer = 530 Dim Y5 As Integer = 796 Dim Y6 As Integer = 796 Dim Y7 As Integer = 264 Dim Y8 As Integer = 530 Dim Y9 As Integer = 796 Dim Y10 As Integer = 264 Dim Y11 As Integer = 530 Dim Y12 As Integer = 796
Dim fin As String = Chr(13) '<CR> Dim ONN As String = "ONN" Dim OFF As String = "OFF" Dim str As String = Chr(58) ': Dim FF As String = Chr(12) 'NP Dim RX_T_1 As Integer = 0 Dim temp1 As Integer = 0 Dim count As Long = 1 Dim MyXL As Object Dim XL_File As String Dim NomP As String Dim RX() As Integer = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} Dim PTR As Integer = 0 Dim RXVAL As String = 0 Dim RX_temp As Integer = 0 Dim RX_temp1 As Integer = 0 Dim PRX As Integer = 0 Dim POT() As Integer = {0, 0, 0, 0} Dim EMG() As Integer = {0, 0, 0, 0} Dim LOADC() As Integer = {0, 0, 0, 0} Dim ANG() As Integer = {0, 0, 0, 0} Dim TMRFRESH() As Integer = {0, 0, 0, 0} Dim TMRFRESH_val As Double = 0.0 Dim SPCHARGE() As Integer = {0, 0, 0, 0} Dim SPCHARGE_val As Integer = 0 Dim RXtemp() As Char = {A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A} Dim RXstat As Integer = 0 Dim EN_DIS As Boolean = False Dim Etape As Integer = 0 Dim ANG_STAT_OK As Boolean = False Dim EMG_STAT_OK As Boolean = False Dim CHRG_STAT_OK As Boolean = False Dim TR_STATUS As Boolean = False Dim R1 As Integer = 1 Dim R2 As Integer = 2 Dim R3 As Integer = 3 Dim CNT As Integer = 0 Dim flash As Integer = 0 Dim Maximum_emg() As Char = {ZERO, ZERO, ZERO, ZERO}
2C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
Dim Maximum_emgint() As Integer = {0, 0, 0, 0} Dim Maximum_emgVAL As Integer = 0 Dim CntEmgREF = 0 Dim emgTemp = 0 '****************************************************************************************
********************** 'Bouton DEM de l'interface (ouvre le port de communication et demarre l'interface) '****************************************************************************************
********************** Private Sub ComActive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ComActive.Click EN_DIS = True SerialPort1.PortName = COMNAME.Text 'Ouvre le port du nom
entree dans la case COMNAME SerialPort1.Open() INTERF_STAT.BackColor = Color.Lime 'Change la couleur du
status en vert (Active) INTERF_STAT.Text = 1 INTERF_STAT.Refresh() End Sub
'**************************************************************************************************************
'Bouton ARR de l'interface (Ferme le port de communication, la feuille excel et l'interface)
'**************************************************************************************************************
Private Sub COMDESACTIVE_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles COMDESACTIVE.Click
EN_DIS = False INTERF_STAT.BackColor = Color.Red 'Change la couleur du
status en rouge (Desactive) INTERF_STAT.Text = 0 INTERF_STAT.Refresh() SerialPort1.Close() 'Ferme le port rs232 If ExcelACT = True Then MyXL.Quit() 'Ferme la feuille Excel End If Close() 'Ferme l'interface End Sub
'**************************************************************************************************************
'Boucle principale, s'active sur l'evenement du temporisateur Timer1 (1mS) '****************************************************************************************
********************** Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Timer1.Tick
'*******Declaration des variables:************** Dim Graph As Graphics = PictureBox1.CreateGraphics Dim temp As Integer = 0 Dim temp1 As Integer = 0 Dim Val1 As Integer = 0 Dim Val2 As Integer = 0 Dim A As Integer = 0 Dim B As Integer = 0 Dim C As Integer = 0 Dim D As Integer = 0 Dim M As Integer = 0 Dim F As Integer = 0 Dim G As Integer = 0 Dim H As Integer = 0 Dim I As Integer = 0 Dim J As Integer = 0 Dim K As Integer = 0
3C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
Dim L As Integer = 0 Dim Q As Integer = 0 Dim N As Integer = 0 Dim O As Integer = 0 Dim P As Integer = 0 Dim U As Integer = 0 Dim R As Integer = 0 Dim S As Integer = 0 Dim T As Integer = 0 Dim CNT As Integer = 0 Dim rece As Integer = 0
If EN_DIS = True Then 'Activation de l'interface
'------------------------------------------------------------------------------------------------------------------------
'------------------------------------------------------------------------------------------------------------------------
If Etape = 0 Then 'Configuration de l'angle de depart
ANG_OK.Visible = True 'Affichage du bouton ok (pour envoyer lorsque pret)
ANG_OK.Refresh() If ANG_STAT_OK Then 'Bouton ok appuye ANG_OK.Visible = False 'Masquer le bouton ok ANG_OK.Refresh() SerialPort1.Write(str) 'Envoyer la valeur de la
angulaire de depart SerialPort1.Write("G") SerialPort1.WriteLine(ANG_SP.Value.ToString) SerialPort1.Write(fin) Etape = Etape + 1 'Etape suivante ANG_STAT_OK = 0 End If End If '--------------------------------------------------------------------------------
----------------------------------------- '--------------------------------------------------------------------------------
----------------------------------------- If Etape = 1 Then 'Configuration de la
consigne de charge CRG_OK.Visible = True CRG_OK.Refresh()
warn1.Visible = True 'Affichage clignotant (Ne pas toucher la poignee)
If flash < 20 Then warn1.BackColor = Color.Yellow warn1.Refresh() flash = flash + 1 Else warn1.BackColor = Color.Gainsboro warn1.Refresh() flash = flash + 1 End If
If flash > 40 Then flash = 0 End If
If CHRG_STAT_OK = True Then 'Affichage du bouton ok (pour envoyer lorsque pret)
CRG_OK.Visible = False 'Masquer le bouton ok CRG_OK.Refresh() warn1.Visible = False 'Masquer l'avertissement warn1.Refresh() SerialPort1.Write(str) 'Envoyer la valeur de la
4C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
consigne de charge SerialPort1.Write("L") SerialPort1.WriteLine(CHRG_SP.Value.ToString) SerialPort1.Write(fin) Etape = Etape + 1 'Etape suivante CHRG_STAT_OK = False End If End If '--------------------------------------------------------------------------------
----------------------------------------- '--------------------------------------------------------------------------------
----------------------------------------- If Etape = 2 Then 'Configuration du seuil
EMG MAX_EMG.Visible = True 'Affichage du MAX EMG
(pour envoyer lorsque pret) MAX_EMG.Refresh() act.Visible = True 'Affichage en temps reel
de l'EMG act.Refresh() SP_emg_TAG.Visible = True SP_emg_TAG.Refresh() ACT_EMG.Visible = True ACT_EMG.Refresh() EMG_SP.Visible = True EMG_SP.Refresh()
'-------------------------------------Détection de la chaine de caractère reçu (EMG)------------------------------------
PTR = 0 While PTR < 22 RX_temp = Convert.ToInt16(RXtemp(PTR)) TextBox1.Text = RXtemp If RX_temp = 90 Then '(CR)=13 z=90 Fin de la
transmission If CNT = 20 Then 'Vérification de la
longueur de la chaine recu
EMG(0) = RX(4) 'Mise à jour de la valeur du EMG
EMG(1) = RX(5) EMG(2) = RX(6) EMG(3) = RX(7)
PTR = 22 'EXIT WHILE End If End If
If rece = 1 Then RX(CNT) = RX_temp CNT = CNT + 1 End If
If CNT = 21 Then PTR = 22 End If
PTR = PTR + 1
If RX_temp = 58 Then '(:) Debut de la transmission
CNT = 0 rece = 1 End If
End While
'-----------------------------------------Conversion Ascii vers Hexa EMG-------------------------------------------
5C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
If EMG(0) < 58 Then A = EMG(0) - 48 Else A = (EMG(0) - 65) + 10 End If If EMG(1) < 58 Then B = EMG(1) - 48 Else B = (EMG(1) - 65) + 10 End If If EMG(2) < 58 Then C = EMG(2) - 48 Else C = (EMG(2) - 65) + 10 End If If EMG(3) < 58 Then D = EMG(3) - 48 Else D = (EMG(3) - 65) + 10 End If
'----------------------------------------------------Diagnose RX EMG------------------------------
TextBox2.Text = A 'Affichage des valeurs recu pour diagnostique
TextBox3.Text = B TextBox4.Text = C TextBox5.Text = D
'----------------------------------------------------------------------------------------------------------
temp = ((A * 4096) + (B * 256) + (C * 16) + D) 'Calcul EMG temp1 = (temp / 65536) * 5000 'Conversion pour table
excel 0 à 5000 uV EMG
CntEmgREF = CntEmgREF + 1 'Affichage de la valeur la plus grande
If temp1 > emgTemp Then emgTemp = temp1 End If
If CntEmgREF = 10 Then 'Rafraichissment de la valeur 1/10 pour la voir passer
ACT_EMG.Text = (emgTemp).ToString CntEmgREF = 0 emgTemp = 0 End If
If EMG_STAT_OK = True Then 'Bouton MAX_EMG détecté MAX_EMG.Visible = False 'Masquer bouton MAX_EMG MAX_EMG.Refresh() SerialPort1.Write(str) 'Envoiyer la valeur
MAX_EMG par RS232 SerialPort1.Write("S") SerialPort1.WriteLine(EMG_SP.Text) SerialPort1.Write(fin) Etape = Etape + 1 'Étape suivante act.Visible = False act.Refresh() ACT_EMG.Visible = False ACT_EMG.Refresh() EMG_STAT_OK = False
PTR = 0 XL_File = "C:\Entrainement.xls" 'Création de la feuille
Excel
6C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
NomP = "Entrainement" MyXL = CreateObject("Excel.Application") MyXL.Workbooks.Add() MyXL.Worksheets(1).Name = NomP ExcelACT = True DEM_TR.Visible = True DEM_TR.Refresh() ARR_TR.Visible = True ARR_TR.Refresh() TR_TAG.Visible = True TR_TAG.Refresh() TR_STAT.Visible = True TR_STAT.Refresh() End If End If '--------------------------------------------------------------------------------
----------------------------------------- '--------------------------------------------------------------------------------
----------------------------------------- If Etape = 3 Then 'Demarrage de l'entrainement If TR_STATUS = True Then
'-------------------------------------Détection de la chaine de caractère reçu------------------------------------
PTR = 0 While PTR < 22 RX_temp = Convert.ToInt16(RXtemp(PTR))
If RX_temp = 90 Then 'z=90 Fin de la transmission
If CNT = 20 Then 'Vérification de la longueur de la chaine recu
EMG(0) = RX(4) 'Mise à jour de la valeur du EMG
EMG(1) = RX(5) EMG(2) = RX(6) EMG(3) = RX(7)
LOADC(0) = RX(0) 'Mise à jour de la valeur du LOAD
LOADC(1) = RX(1) LOADC(2) = RX(2) LOADC(3) = RX(3)
ANG(0) = RX(8) 'Mise à jour de la valeur du ANG
ANG(1) = RX(9) ANG(2) = RX(10) ANG(3) = RX(11)
TMRFRESH(0) = RX(12) 'Mise à jour du temp de rafraichissement
TMRFRESH(1) = RX(13) TMRFRESH(2) = RX(14) TMRFRESH(3) = RX(15)
SPCHARGE(0) = RX(16) 'Mise à jour du temp de Consigne Load
SPCHARGE(1) = RX(17) SPCHARGE(2) = RX(18) SPCHARGE(3) = RX(19)
PTR = 22 'EXIT WHILE End If End If
If rece = 1 Then 'Compte du nombre de caractère reçu
7C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
RX(CNT) = RX_temp CNT = CNT + 1 End If
If CNT = 21 Then 'Force la fin de chaine reçu
PTR = 22 End If
PTR = PTR + 1
If RX_temp = 58 Then '(:) Debut de la transmission
CNT = 0 rece = 1 End If
End While
TextBox1.Text = RXtemp 'Affichage de la valeur reçu (diagnostic)
'-----------------------------------------Conversion Ascii vers Hexa EMG-------------------------------------------
If EMG(0) < 58 Then A = EMG(0) - 48 Else A = (EMG(0) - 65) + 10 End If If EMG(1) < 58 Then B = EMG(1) - 48 Else B = (EMG(1) - 65) + 10 End If If EMG(2) < 58 Then C = EMG(2) - 48 Else C = (EMG(2) - 65) + 10 End If If EMG(3) < 58 Then D = EMG(3) - 48 Else D = (EMG(3) - 65) + 10 End If '----------------------------------------Conversion Ascii vers Hexa load
cell--------------------------------------- If LOADC(0) < 58 Then M = LOADC(0) - 48 Else M = (LOADC(0) - 65) + 10 End If If LOADC(1) < 58 Then F = LOADC(1) - 48 Else F = (LOADC(1) - 65) + 10 End If If LOADC(2) < 58 Then G = LOADC(2) - 48 Else G = (LOADC(2) - 65) + 10 End If If LOADC(3) < 58 Then H = LOADC(3) - 48 Else H = (LOADC(3) - 65) + 10 End If
'----------------------------------------Conversion Ascii vers Hexa ANG ---------------------------------------
8C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
If ANG(0) < 58 Then I = ANG(0) - 48 Else I = (ANG(0) - 65) + 10 End If If ANG(1) < 58 Then J = ANG(1) - 48 Else J = (ANG(1) - 65) + 10 End If If ANG(2) < 58 Then K = ANG(2) - 48 Else K = (ANG(2) - 65) + 10 End If If ANG(3) < 58 Then L = ANG(3) - 48 Else L = (ANG(3) - 65) + 10 End If
'----------------------------------------Conversion Ascii vers Hexa Refresh ---------------------------------------
If TMRFRESH(0) < 58 Then Q = TMRFRESH(0) - 48 Else Q = (TMRFRESH(0) - 65) + 10 End If If TMRFRESH(1) < 58 Then N = TMRFRESH(1) - 48 Else N = (TMRFRESH(1) - 65) + 10 End If If TMRFRESH(2) < 58 Then O = TMRFRESH(2) - 48 Else O = (TMRFRESH(2) - 65) + 10 End If If TMRFRESH(3) < 58 Then P = TMRFRESH(3) - 48 Else P = (TMRFRESH(3) - 65) + 10 End If
TMRFRESH_val = ((((Q * 4096) + (N * 256) + (O * 16) + P)) / 100) 'Calcul TMRFRESH
RefreshLBL.Text = TMRFRESH_val.ToString 'Affichage du temps de rafraichissement
'----------------------------------------Conversion Ascii vers Consigne Load ---------------------------------------
If SPCHARGE(0) < 58 Then U = SPCHARGE(0) - 48 Else U = (SPCHARGE(0) - 65) + 10 End If If SPCHARGE(1) < 58 Then R = SPCHARGE(1) - 48 Else R = (SPCHARGE(1) - 65) + 10 End If If SPCHARGE(2) < 58 Then S = SPCHARGE(2) - 48 Else S = (SPCHARGE(2) - 65) + 10 End If If SPCHARGE(3) < 58 Then T = SPCHARGE(3) - 48 Else
9C:\Users\Ben\Desktop\Ecole_2\Projet de ... de progrès\Jacques Paradis\Code_Interface.vb
T = (SPCHARGE(3) - 65) + 10 End If
SPCHARGE_val = ((U * 4096) + (R * 256) + (S * 16) + T) 'Calcul Consigne charge g
'----------------------------------------------------Diagnose RX EMG TextBox2.Text = A TextBox3.Text = B TextBox4.Text = C TextBox5.Text = D '----------------------------------------------------Diagnose RX LOADC TextBox9.Text = M TextBox8.Text = F TextBox7.Text = G TextBox6.Text = H '----------------------------------------------------Diagnose RX Ang TextBox13.Text = I TextBox12.Text = J TextBox11.Text = K TextBox10.Text = L '------------------------------------------------------------------------
---------------------------------- temp = ((A * 4096) + (B * 256) + (C * 16) + D) 'Calcul EMG temp1 = (temp / 65536) * 5000 'Conversion pour
table excel 0 à 5000uV EMG emgstatval.Text = ((temp1 / Maximum_emgVAL) * 100) temp = ((temp1 / Maximum_emgVAL) * 264) 'Calcul de la
position Y en pixel MyXL.Worksheets(NomP).Cells(count, R1) = temp1 Y2 = (264 - temp) Y7 = (264 - (((Maximum_emgVAL * 0.3) / Maximum_emgVAL) * 264)) 'Calcul de
la consigne EMG 30%
temp = ((M * 4096) + (F * 256) + (G * 16) + H) 'Calcul Load temp1 = (temp) 'Calcul Load pour
table excel 0 à 30000 g crgstatval.Text = temp1 temp = (temp1 / 30000) * 264 'Calcul de la
position Y en pixel MyXL.Worksheets(NomP).Cells(count, R2) = temp1 Y4 = (530 - temp) Y8 = (530 - ((SPCHARGE_val / 30000) * 264)) 'Calcul de la
consigne de Charge
temp = ((I * 4096) + (J * 256) + (K * 16) + L) 'Calcul Ang angstatval.Text = temp temp1 = (temp / 90) * 264 'Calcul de la
position Y en pixel MyXL.Worksheets(NomP).Cells(count, R3) = temp 'Calcul angulaire
table excel 0 à 100 deg Y6 = (796 - temp1) X2 = X1 + 1 'Incrémentation de la
position en X en pixel
Graph.DrawLine(Pens.Red, X1, Y1, X2, Y2) 'Dessiner les trois courbes à l'écran point (x1,y1) vers (x2,y2)
Graph.DrawLine(Pens.Red, X1, Y7, X2, Y10) 'Dessiner les SP Graph.DrawLine(Pens.Red, X1, Y7 + 1, X2, Y10 + 1) 'Dessiner les
SP Graph.DrawLine(Pens.Red, X1, Y7 + 2, X2, Y10 + 2) 'Dessiner les
SP
Graph.DrawLine(Pens.Green, X1, Y3, X2, Y4) Graph.DrawLine(Pens.Red, X1, Y8, X2, Y11) 'Dessiner les SP Graph.DrawLine(Pens.Red, X1, Y8 + 1, X2, Y11 + 1) 'Dessiner les
SP
10C:\Users\Ben\Desktop\Ecole_2\Projet de ...de progrès\Jacques Paradis\Code_Interface.vb
Graph.DrawLine(Pens.Red, X1, Y8 + 2, X2, Y11 + 2) 'Dessiner les SP
Graph.DrawLine(Pens.Blue, X1, Y5, X2, Y6)
Y5 = Y6 'Enregistrement de la valeur actuelle
Y3 = Y4 Y1 = Y2 X1 = X2
Y10 = Y7 'Enregistrement de la valeur actuelle
Y11 = Y8
If X1 > 1200 Then 'Rafraichissement de l'écran en fin d'image X=1200
X1 = 5 PictureBox1.Refresh() End If count = count + 1 'Compteur du nombre
de pixel parcouru en X If count > 1200 Then 'Changement de
colonne de la table excel pour chaque fin de page. count = 1 R1 = R1 + 4 R2 = R2 + 4 R3 = R3 + 4 End If End If End If End If End Sub
'***********************************************************************************************************
'Boucle de récéption de données du port RS232 '****************************************************************************************
******************* Private Sub dataRX(ByVal sender As System.Object, ByVal e As System.IO.Ports.
SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived If EN_DIS = True Then RXtemp = SerialPort1.ReadExisting.ToCharArray SerialPort1.DiscardInBuffer() End If End Sub
'***********************************************************************************************************
'Détection du bouton ANG_OK (Angle initial) '****************************************************************************************
******************* Private Sub ANG_OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ANG_OK.Click ANG_STAT_OK = True End Sub
'***********************************************************************************************************
'Détection du bouton CRC_OK (Consigne de charge) '****************************************************************************************
******************* Private Sub CRG_OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles CRG_OK.Click CHRG_STAT_OK = True End Sub
11C:\Users\Ben\Desktop\Ecole_2\Projet de ...de progrès\Jacques Paradis\Code_Interface.vb
'***********************************************************************************************************
'Détection du bouton MAX_EMG (Maximum du seuil EMG) '****************************************************************************************
******************* Private Sub MAX_EMG_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MAX_EMG.Click Dim cnt As Integer = 0 Dim EMG_LENGTH As Integer = EMG_SP.TextLength EMG_STAT_OK = True Maximum_emg = EMG_SP.Text.ToCharArray
For cnt = 1 To EMG_LENGTH Maximum_emgint(EMG_LENGTH - (cnt)) = Convert.ToInt16(Maximum_emg(cnt - 1)) Next
For cnt = (EMG_LENGTH + 1) To 4 Maximum_emgint(cnt - 1) = 48 Next
'Permet d'afficher la consigne de l'emg 30% de MAX EMG '----------------------------------------Conversion Ascii vers Decimal --------------
--------------------- Maximum_emgVAL = (((Maximum_emgint(3) - 48) * 1000) + ((Maximum_emgint(2) - 48) *
100) + ((Maximum_emgint(1) - 48) * 10) + (Maximum_emgint(0) - 48)) 'Calcul EMG
End Sub
'***********************************************************************************************************
'Détection du bouton DEM_ENT (Démarrer entrainement) '****************************************************************************************
*******************
Private Sub DEM_TR_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DEM_TR.Click
TR_STAT.BackColor = Color.Lime 'Change la couleur du status de l'entrainement (vert)
TR_STAT.Text = 1 TR_STAT.Refresh() SerialPort1.Write(str) 'Envoie la valeur ONN
(Démarrage de l'entrainement) SerialPort1.Write(ONN) SerialPort1.WriteLine(fin) TR_STATUS = 1 End Sub
'***********************************************************************************************************
'Détection du bouton ARR_ENT (Arrêt de l'entrainement) '****************************************************************************************
*******************
Private Sub ARR_TR_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ARR_TR.Click
TR_STATUS = 0 TR_STAT.BackColor = Color.Red 'Change la couleur du
status de l'entrainement (rouge) TR_STAT.Text = 0 TR_STAT.Refresh() SerialPort1.Write(str) 'Envoie la valeur OFF
(Arrêt de l'entrainement) SerialPort1.Write(OFF) SerialPort1.WriteLine(fin) End Sub
'***********************************************************************************************************
'Détection du bouton Remise à zéro (Redémarrage de l'entraînement)
12C:\Users\Ben\Desktop\Ecole_2\Projet de ...de progrès\Jacques Paradis\Code_Interface.vb
'***********************************************************************************************************
Private Sub Reset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Reset.Click
If EN_DIS = 1 Then 'Arrêt de l'interface SerialPort1.Write(str) SerialPort1.Write(OFF) 'Envoie la valeur OFF
(Arrêt de l'entrainement) SerialPort1.WriteLine(fin) SerialPort1.Close() End If
Etape = 0 'Retour à l'étape 0 et réinitialisation des affichages
DEM_TR.Visible = False DEM_TR.Refresh() ARR_TR.Visible = False ARR_TR.Refresh() TR_TAG.Visible = False TR_TAG.Refresh() TR_STAT.Visible = False TR_STAT.Refresh() act.Visible = False act.Refresh() ACT_EMG.Visible = False ACT_EMG.Refresh() ANG_OK.Visible = False ANG_OK.Refresh() CRG_OK.Visible = False CRG_OK.Refresh() MAX_EMG.Visible = False MAX_EMG.Refresh() act.Visible = False act.Refresh() SP_emg_TAG.Visible = False SP_emg_TAG.Refresh() warn1.Visible = False warn1.Refresh()
Dim X1 As Integer = 5 'Réinitialisation des variables
Dim Y1 As Integer = 264 Dim X2 As Integer = 5 Dim Y2 As Integer = 264 Dim Y3 As Integer = 530 Dim Y4 As Integer = 530 Dim Y5 As Integer = 796 Dim Y6 As Integer = 796 Dim Y7 As Integer = 264 Dim Y8 As Integer = 530 Dim Y9 As Integer = 796 Dim Y10 As Integer = 264 Dim Y11 As Integer = 530 Dim Y12 As Integer = 796 PictureBox1.Refresh() End Sub
End Class
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Asservissement(1).c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À REÇU******************************************************************************************************/
extern Envoi_Vitess_drive(signed long ADRES);extern Envoi_Accel_drive(signed long ADRES2);extern Convert_to_hex_Drive(unsigned char caractere2[]);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS ACCESSIBLE DANS TOUT LE PROGRAMME*****************************************************************************************************/extern WriteUART_to_RS232(void);extern RXLoadC(void); //Get Loadc Valueextern INIT_ADs_SPI(void); //Get EMG Valueextern AffCONSIGNE(void);extern ZERO_VITESSE (void);
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/
extern unsigned int LCSPIRX; //Valeur recu Load Cellextern unsigned int EMG; //Valeur recu EMGextern unsigned int Consigne_load_Hexa; //Valeur de la consigne de chargeextern unsigned int Consigne_seuil_Hexa; //Valeur de la consigne du seuilextern unsigned int start_load; //Application de la force initialextern unsigned int up_down; //Sens de l'exerciceextern unsigned int RS;extern unsigned int ZERO_LOAD;extern unsigned int STAT_RECEI;extern unsigned int Reel_pos_Read; extern unsigned int POSI;extern unsigned int SP_load;extern unsigned int RXsel;extern unsigned int x;
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME ET UTILISÉ DANS CELUI-CI*****************************************************************************************************/extern unsigned char ReceivedData[];extern unsigned char PositionData[];extern unsigned char Read_speed_ASCII[];
/**************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 4 294 967 295)**************************************************************************************************************/extern unsigned long Seuil_Trente_Hexa; //Valeur de 30% du seuil
/*************************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (-2 147 483 648 À 2 147 483 647)*************************************************************************************************************************/extern signed long Read_speed_Calc;extern signed long Coco;extern signed long Diff_Hexa_Calc;extern signed long Zero_Speed;extern signed long SP_vit;extern signed long Accel_Val_MIN; extern signed long Acceleration; extern signed long Vit_act;
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Asservissement(1).c
/*************************************************************************************************************************DÉCLARATION DES VARIABLES EN POINT FLOTTANT (1.17549*10e-38 À 8.5*10e37)*************************************************************************************************************************/extern float depass; //Depassement de la valeur seuil de l'emg en %extern float SP_EMG;extern float Delta_force;extern float facteur; //cnt/sec; //Facteur de correction du systeme (0.007136 tr/N*s * 2000)extern float EMG_CORR_GAIN;extern float LOAD_CORR_GAIN;extern float ACCEL_GAIN;extern float LOAD;extern float tempload = 0;
/*****************************************************************************************************DÉCLARATION DES FONCTIONS DE DÉLAI*****************************************************************************************************/
extern Delay5ms (int);extern Delay5us (int);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS RELIÉES SEULEMENT SUR CETTE FEUILLE*****************************************************************************************************/
void convert_load(void);void Asservi(void);
/******************************ENTRÉE DANS LA ROUTINE DE CONVERSION DE LA VALEUR DE LA CHARGE***************************************
CETTE ROUTINE PERMET DE CONVERTR LES DONNÉE PROVENANT DE LA CELLULE DE CHARGE. LES DONNÉES ARRIVE EN BINAIRE VIA LE POR SPI ET DOIVENT ÊTRE TRAITÉES POUR REPRÉSENTER UNE VRAI VALEUR DE CHARGE.
***********************************************************************************************************************************/
void convert_load(void){
if(up_down==1) //30Kg = 10mV = 0.33333333mV / Kg{
if (LCSPIRX>=ZERO_LOAD) //Si valeur lu est plus grande ou égale à 0x8000
{LOAD=(LCSPIRX-ZERO_LOAD)*3.5763; //0.004768mV/Div (pour 10mV la
plage est de 2097 division) POUR GAIN DE 16
if (LOAD > 10000){
LOAD =10000;} //0.0023842mV/Div (pour 10mV la
plage est de 4194 division) POUR GAIN DE 32}
//(0.004768(mV/div)/.333333(mV/Kg))*1000(g/Kg) =14.304(g/Div) POUR GAIN DE 16
//0.0023842mV/Div/.333333(mV/Kg))*1000(g/Kg) =7.152629(g/Div) POUR GAIN DE 32else //Si valeur lu est plus grande
que 0x8000{LOAD = 0x0000;}
}
else
{if (LCSPIRX<ZERO_LOAD) //Si valeur lu est plus PETITE ou
égale à 0x8000
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Asservissement(1).c
{LOAD=(ZERO_LOAD-LCSPIRX)*3.5763; //0.004768mV/Div (pour 10mV la
plage est de 2097 division) POUR GAIN DE 16//0.0023842mV/Div (pour 10mV la
plage est de 4194 division) POUR GAIN DE 32if (LOAD > 10000){
LOAD =10000;}
//(0.002384(mV/div)/.333333(mV/Kg))*1000(g/Kg) =14.304(g/Div) POUR GAIN DE 1
}
else //Si valeur lu est plus petite que 0x8000
{LOAD = 0x0000;}
}
}/*************************************ENTRÉE DANS LA ROUTINE D'ASSERVISSEMENT******************************************************
CETTE ROUTINE PERMET LE CONTRÔLE DU SYSTÈME, C'EST À DIRE QU'ELLE EFFECTUE LES CALCULS NÉCESSAIRES POUR DÉTERMINER LES VITESSES ET ACCELLÉRATION À ENVOYER AU VARIATEUR DE VITESSSE POUR LE MAINTIENT DE LA CHARGE RÉEL LE PLUS PRÈS POSSIBLE DE LA CONSIGNE.
***********************************************************************************************************************************/void Asservi(void){
float EMG_CALC = 0;
if(!PORTBbits.RB5) //Lecture de la cellule de charge LORSQUE LE A/D EST PRÈS
{RXLoadC(); //APPEL DE LA
FONCTION DE LECURE DU A/Dconvert_load(); //APPEL À LA FONCTION
DE CONVERSION DES DONNÉES RECU PAR LA CELLULE EN VALEUR DE CHARGE RÉEL }
if(!PORTBbits.RB5) //Lecture de la cellule de charge LORSQUE LE A/D EST PRÈS
{RXLoadC(); //APPEL DE LA
FONCTION DE LECURE DU A/Dconvert_load(); //APPEL À LA FONCTION
DE CONVERSION DES DONNÉES RECU PAR LA CELLULE EN VALEUR DE CHARGE RÉEL }INIT_ADs_SPI(); //APPEL DE LA
FONCTION DE Lecture de l'EMG
EMG_CALC = EMG; //TRANSFERT DE LA DONNÉE ENTIÈRE EN DONNÉE POINT FLOTTANT POUR TRAITEMENT
if(EMG_CALC>SP_EMG) //Ajustement de la charge en fonction DU SEUIL EMG (30% DU MAX)
{depass=(((EMG_CALC-SP_EMG)/SP_EMG) * EMG_CORR_GAIN);SP_load=(SP_load-(depass*SP_load));
}else
{SP_load=SP_load; //SI PAS DE
DÉPASSEMENT, LA CONSIGNE DE CHARGE NE CHANGE PAS}
RXsel=0; //REMISE DES POINTEUR
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Asservissement(1).c
À ZÉRO AVANT DE CONTINUER LE PROGRAMMEReel_pos_Read=0;RS =0;
Read_speed(); //APPEL DE LA ROUTINE QUI EFFECTUE LA LECTURE DE LA VITESSE ACTUELLE DU MOTEUR DANS LE VARIATEUR DE VITESSE
while(!RS); //ATTENTE QUE LA VITESSE SOIT ENTRÉE
for(x=0;x<8;x++){Read_speed_ASCII[x]=ReceivedData[x+6]; //Transfert de la
vitesse ASCII en ASCII 8 caractère pour convertion}
Convert_to_hex_Drive(Read_speed_ASCII); //Convertion de la vitesse ASCII en vitesse Hexadecimale
Vit_act = Read_speed_Calc; //TRANSFERT DE VARIABLE SERVANT SEULEMENT POUR LE TRAITEMENT
if(up_down==1) //SI LE SYSTÈME EST EN MONTER, FAIRE UN COMPLÉMENT À DEUX SUR LA VITESSE AVANT DE LA TRAITER
{Vit_act=(0xFFFFFFFF-(Vit_act-1)); //Complement a 2}
if(LOAD<SP_load) //Ajustement de la vitesse du moteur en fonction de la consigne de la charge, SI LA VALEUR ACTUELLE EST SOUS LA CONSIGNE
{Delta_force=(SP_load-LOAD);SP_vit=(Vit_act-(Delta_force*facteur*LOAD_CORR_GAIN));
if(SP_vit<=0) //SI LA CONSIGNE DE VITESSE EST EN DESSOUS DE ZÉRO, LA METTRE À ZÉRO POUR ÉVITER LES OSCILLATIONS
{ZERO_VITESSE(); //APPEL DE LA
FONCTION QUI ENVOI UNE CONSIGNE DE VITESSE ZÉRO AU VARIATEUR DE VITESSE}else
{Envoi_Vitess_drive(SP_vit); //Envoi de la
nouvelle consigne de vitesseWriteUART_to_RS232();Delay5us(1200);
}}
else //Ajustement de la vitesse du moteur en fonction de la consigne de la charge, SI LA VALEUR ACTUELLE EST AU DESSUS DE LA CONSIGNE
{Delta_force=(LOAD-SP_load);SP_vit=(Vit_act+(Delta_force*facteur*LOAD_CORR_GAIN));
if(SP_vit>=0x00061A80) //Detection de vitesse ZERO
{Envoi_Vitess_drive(0x00061A80); //SI LA CONSIGNE DE
VITESSE EST EN DESSUS DE CE SEUIL, LA METTRE À CE SEUIL LA CONSIGNE DE VITESSE}else
{Envoi_Vitess_drive(SP_vit); //Envoi de la
nouvelle consigne de vitesseWriteUART_to_RS232();Delay5us(1200);
}}
Acceleration = (Accel_Val_MIN+(Delta_force*facteur*ACCEL_GAIN)); //TRAITEMENT
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Asservissement(1).c
DE LA CONSIGNE D'ACCÉLÉRATIONEnvoi_Accel_drive(Acceleration); //ENVOI DE LA NOUVELLE VALEUR
D'ACCÉLÉRATIONWriteUART_to_RS232();Delay5us(1500);
AffCell(); //ROUTINE DE TRANSFERT DES
DONNÉES DE LA CELLULE DANS VARIABLE DE TANSFERT ASCIIAffEMG(); //ROUTINE DE TRANSFERT DES
DONNÉES DE L'EMG DANS VARIABLE DE TANSFERT ASCIIAffPOSI(); //ROUTINE DE TRANSFERT DES
DONNÉES DE LA POSITION DANS VARIABLE DE TANSFERT ASCIIAffCONSIGNE(); //ROUTINE DE TRANSFERT DES
DONNÉES DE LA CONSIGNE DE CHARGE DANS VARIABLE DE TANSFERT ASCIIWriteUART2_to_RS232();
}
5
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Communication_SPI.c
/*; © 2005 Microchip Technology Inc.;; Microchip Technology Inc. (“Microchip”) licenses this software to you; solely for use with Microchip dsPIC® digital signal controller; products. The software is owned by Microchip and is protected under; applicable copyright laws. All rights reserved.;; SOFTWARE IS PROVIDED “AS IS.” MICROCHIP EXPRESSLY DISCLAIMS ANY; WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A; PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP; BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL; DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF; PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS; BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),; ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.;;;FILE DESCRIPTION:; This file provides low-leve SPI drivers to interface to the 30F2011; that controls the text-based 4-bit parallel LCD on the dsPICDEM2; development board.;;REVISION HISTORY:; $Log: SPI_for_LCD.c,v $; Revision 1.1.1.1 2005/06/06 09:16:45 VasukiH; First release of software;;*/
//Pre-Processor Directives:#include <p30fxxxx.h>#include "system.h"#include "spi.h"
/*****************************************************************************************************DÉCLARATION DES FONCTIONS DE DÉLAI*****************************************************************************************************/
extern Delay5ms (int);extern Delay5us (int);
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME ET UTILISÉ SUR CETTE FEUILLE*****************************************************************************************************/extern unsigned char Status[];extern unsigned char aff[];
/*****************************************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME ET UTILISÉS SUR CETTE FEUILLE (0 À 65535)*****************************************************************************************************************************/extern unsigned int EMG;extern unsigned int EMG1;extern unsigned int EMG2;extern unsigned int EMG3;extern unsigned int TAMPON;
/*****************************************************************************************************DÉCLARATION ROUTINE UTILISÉES DANS CETTE FEUILLE*****************************************************************************************************/void READ_SPI1BUF(void);void INIT_ADs_SPI(void);void SPI_Init(void);
/*****************************************************************************************************DÉCLARATION ROUTINE UTILISÉES QUI RECOIVENT ET RENVOIT DES VARIABLES DANS CETTE FEUILLE
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Communication_SPI.c
*****************************************************************************************************/unsigned int LSBYTE(unsigned int);unsigned int CSBYTE(unsigned int);unsigned int MSBYTE(unsigned int);
/*-----------------------------------------------------------------------------------------------------------------INITIALISER La Com SPI-------------------------------------------------------------------------------------------------------------------*/void SPI_Init(void){ SPI1STAT = 0x0000; SPI1CON = 0x0021; //Set the SPI1 module to 8-bit Master mode IFS0bits.SPI1IF = 0; //Clear the SPI1 Interrupt Flag IEC0bits.SPI1IE = 0; //SPI1 ISR processing is not enabled. //SPI1 will be used in polling-mode SPI1STATbits.SPIEN = 1; //Turn on the SPI1 module}/*-----------------------------------------------------------------------------------------------------------------EFFECTUER LACOMMUNICATION AVEC LE ADs EMG-------------------------------------------------------------------------------------------------------------------*/void INIT_ADs_SPI(void){
unsigned int msbytev;unsigned int csbytev;unsigned int lsbytev;
LATBbits.LATB4 = 0; //SORTIE PERMETTANT DE SÉLECTIONNER LE CONVERTISSEUR DE L'EMG (EN FONCTION)
TAMPON = SPI1BUF; //VARIABLE PERMETTANT DE VIDER LE "BUFFER" SPI
msbytev = MSBYTE(0x0000); //DÉMARRER LA COMMUNICATION SPI POUR RECEVOIR LE MOST SIGNIFIANT BYTE
csbytev = CSBYTE(0x0000); //DÉMARRER LA COMMUNICATION SPI POUR RECEVOIR LE CENTER BYTE
lsbytev = LSBYTE(0x0000); //DÉMARRER LA COMMUNICATION SPI POUR RECEVOIR LE LESS SIGNIFIANT BYTE
Delay5us (1);LATBbits.LATB4 = 1; //SORTIE PERMETTANT DE SÉLECTIONNER LE CONVERTISSEUR DE L'EMG
(HORS FONCTION)
/*****************************************************Traitement des données EMG pour les mettre sur 16 bits*****************************************************/ msbytev = msbytev << 12;msbytev = msbytev & 0xF000;
csbytev = csbytev << 4;csbytev = csbytev & 0x0FF0;
lsbytev = lsbytev >> 4;lsbytev = lsbytev & 0x000F;
EMG = lsbytev + csbytev + msbytev;
}/*-----------------------------------------------------------------------------------------------------------------LECTURE DU MSBYTE-------------------------------------------------------------------------------------------------------------------*/unsigned int MSBYTE(unsigned int TEMP1){
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Communication_SPI.c
SPI1BUF = TEMP1;while (!SPI1STATbits.SPIRBF);return SPI1BUF;
}/*-----------------------------------------------------------------------------------------------------------------LECTURE DU CSBYTE-------------------------------------------------------------------------------------------------------------------*/unsigned int CSBYTE(unsigned int TEMP3){
SPI1BUF = TEMP3;while (!SPI1STATbits.SPIRBF);return SPI1BUF;
}/*-----------------------------------------------------------------------------------------------------------------LECTURE DU LSBYTE-------------------------------------------------------------------------------------------------------------------*/unsigned int LSBYTE(unsigned int TEMP2){
SPI1BUF = TEMP2;while (!SPI1STATbits.SPIRBF);return SPI1BUF;
}
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
//Pre-Processor Directives:#include <p30f4011.h>#include "system.h"
/*****************************************************************************************************DÉCLARATION DES FONCTIONS ACCESSIBLE DANS TOUT LE PROGRAMME*****************************************************************************************************/extern WriteUART1(unsigned int data);extern WriteUART_to_RS232(void);
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/extern unsigned int cons_ang_stat;extern unsigned int cons_load_stat;extern unsigned int cons_seuil_stat;extern unsigned int First_pos_Read;extern unsigned int Long;extern unsigned int STAT_RECEI;extern unsigned int Posi_init;extern unsigned int Consigne_seuil_Hexa;extern unsigned int Consigne_load_Hexa;extern unsigned int Reel_pos_Read; extern unsigned int RS;extern unsigned int up_down;extern unsigned int j; extern unsigned int l; extern unsigned int TimeScan;extern unsigned int SP_load;
/*************************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (-32768 À 32767)**************************************************************************************************************/extern signed int Potentiometer;extern signed int EMG;extern signed int EMG1;extern signed int EMG2;extern signed int EMG3;extern signed int LCSPIRX;extern signed int POSI;
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME ET UTILISÉ DANS CETTE FEUILLE*****************************************************************************************************/extern unsigned char Status[];extern unsigned char DisplayData[];extern unsigned char Donnee_DEC[];extern unsigned char Donnee_HEX[];extern unsigned char REFRESHVAL[];extern unsigned char consigne_posi[];extern unsigned char consigne_load[];extern unsigned char consigne_seuil[];extern unsigned char REELPosition[];extern unsigned char Read_speed_ASCII[];
/**************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 4 294 967 295)**************************************************************************************************************/extern unsigned long Consigne_ang_Hexa;extern unsigned long Zero_Speed;extern unsigned long Consigne_Pulse;
/*************************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (-2 147 483 648 À 2 147 483 647)
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
*************************************************************************************************************************/extern signed long Donnee_Hexa_Calc;extern signed long Zero_Hexa_Calc;extern signed long Reel_Hexa_Calc;extern signed long Diff_Hexa_Calc;extern signed long Read_speed_Calc;extern signed long TEMP_DEEEEEE;
/*************************************************************************************************************************DÉCLARATION DES VARIABLES EN POINT FLOTTANT (1.17549*10e-38 À 8.5*10e37)*************************************************************************************************************************/extern float LOAD;
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À REÇU******************************************************************************************************/
void Convert_to_hex(unsigned char caractere[]);void Convert_to_hex_Drive(unsigned char caractere2[]);void Consigne_Char(unsigned char caractere1[]);void Reel_Pulse_Posi(unsigned char caractere3[]);void Convert_Angle_Pulse(unsigned long ANGLE);void Envoi_Vitess_drive(signed long ADRES);void Envoi_Accel_drive(signed long ADRES2);void soft_overtravel_positif (signed long ADRES3);void soft_overtravel_negatif (signed long ADRES4);void soft_overtravel_pos_limit (signed long ADRES5);void soft_overtravel_neg_limit (signed long ADRES6);void MINIMUM_POSI(signed long ADRES7);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS UTILISÉS SUR CETTE FEUILLE *****************************************************************************************************/void AffCell(void);void AffEMG(void);void AffPOSI(void);void AffREFRESH(void);void AffCONSIGNE(void);void Checksum(void);void Checksum_LONG(void);
//**************************************************************************************************************************//Envoi de la charge réel à l'interface//**************************************************************************************************************************void AffCell(void){ //unsigned int val = LCSPIRX;
unsigned int val = LOAD;unsigned int tmp = 0x0000;
tmp= val & 0x000F;
if (tmp<=9){ tmp+=0x30;}
else {
tmp+=0x37; }
REFRESHVAL[4]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
if (tmp<=9) { tmp+=0x30;}
else { tmp+=0x37;}REFRESHVAL[3]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9){ tmp+=0x30;}
else {tmp+=0x37;
} REFRESHVAL[2] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{ tmp+=0x37;
} REFRESHVAL[1]=tmp;
REFRESHVAL[21]=0x5A;REFRESHVAL[22]=0x00;
}
//**************************************************************************************************************************//Envoi des données EMG à l'interface//**************************************************************************************************************************void AffEMG(void){ unsigned int val = EMG;
unsigned int tmp = 0x0000;
//Conv char0
tmp= val & 0x000F; if (tmp<=9)
{tmp+=0x30;}
else{
tmp+=0x37; }
REFRESHVAL[8]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) { tmp+=0x30;}
else
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
{ tmp+=0x37;}REFRESHVAL[7]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) { tmp+=0x30;}
else{ tmp+=0x37;
} REFRESHVAL[6] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{ tmp+=0x37;}
REFRESHVAL[5]=tmp;
REFRESHVAL[21]=0x5A;REFRESHVAL[22]=0x00;
}
//**************************************************************************************************************************//Envoi de la position à l'interface//**************************************************************************************************************************void AffPOSI(void){ unsigned int val = POSI;
unsigned int tmp = 0x0000;
//Conv char0
tmp= val & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{
tmp+=0x37;}
REFRESHVAL[12]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9){ tmp+=0x30;}
else { tmp+=0x37;}REFRESHVAL[11]=tmp;
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) { tmp+=0x30;}
else{ tmp+=0x37;
} REFRESHVAL[10] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{ tmp+=0x37;}
REFRESHVAL[9]=tmp;
REFRESHVAL[21]=0x5A;REFRESHVAL[22]=0x00;
}
//**************************************************************************************************************************//Envoi du time-scan à l'interface//**************************************************************************************************************************void AffREFRESH(void){ unsigned int val = TimeScan;
unsigned int tmp = 0x0000;
//Conv char0
tmp= val & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{
tmp+=0x37;}
REFRESHVAL[16]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9){ tmp+=0x30;}
else { tmp+=0x37;}REFRESHVAL[15]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) { tmp+=0x30;
5
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
} else
{ tmp+=0x37;
} REFRESHVAL[14] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{ tmp+=0x37;}
REFRESHVAL[13]=tmp;
REFRESHVAL[21]=0x5A;REFRESHVAL[22]=0x00;
}
//**************************************************************************************************************************//Envoi de la consigne de charge à l'interface//**************************************************************************************************************************void AffCONSIGNE(void){ unsigned int val = SP_load;
unsigned int tmp = 0x0000;
//Conv char0
tmp= val & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{
tmp+=0x37;}
REFRESHVAL[20]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9){ tmp+=0x30;}
else { tmp+=0x37;}REFRESHVAL[19]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) { tmp+=0x30;}
else{ tmp+=0x37;
}
6
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
REFRESHVAL[18] =tmp; //Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
{ tmp+=0x30;}
else{ tmp+=0x37;}
REFRESHVAL[17]=tmp;
REFRESHVAL[21]=0x5A;REFRESHVAL[22]=0x00;
}
//**************************************************************************************************************************//Envoi de la vitesse au variateur de vitesse//**************************************************************************************************************************void Envoi_Vitess_drive(signed long ADRES){
signed long val=0; signed long tmp;
val = ADRES;
//REV COMPLEMENT A 2 DE LA CONSIGNEif (up_down==1)
{val=(0xFFFFFFFF-val)+1;}
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x36; // Caractère ASCII "6" >>Adresse du régistre dans la driveDisplayData[5] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) tmp+=0x30;
7
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
else tmp+=0x37;
DisplayData[12] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;
}
//**************************************************************************************************************************//Imposition de la position minimum d'arret//**************************************************************************************************************************
void MINIMUM_POSI(signed long ADRES7){
signed long val=0;signed long tmp;
8
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
val = ADRES7;val = (0xFFFFFFFF-val)+1;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x31; // Caractère ASCII "1" >>Adresse du régistre dans la driveDisplayData[4] = 0x35; // Caractère ASCII "5" >>Adresse du régistre dans la driveDisplayData[5] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Position mINIMALEDisplayData[7] = 0x30; //0 DisplayData[8] = 0x31; //1
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[16]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[15]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[14] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[13]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[12]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
9
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
DisplayData[11]=tmp;
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[9]=tmp;
Checksum_LONG();DisplayData[19]=0x0D;DisplayData[20]=0x00;
}
//**************************************************************************************************************************//ENVOIE DE LA RAMPE D'ACCÉLÉRATION//**************************************************************************************************************************void Envoi_Accel_drive(signed long ADRES2){
signed long val=0;signed long tmp;
val = ADRES2;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x36; // Caractère ASCII "6" >>Adresse du régistre dans la driveDisplayData[5] = 0x45; // Caractère ASCII "E" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
10
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[12] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;//DisplayData[19]=0x00;
}
//**************************************************************************************************************************//Envoie des consignes des limites Soft travels POSITIVES//**************************************************************************************************************************void soft_overtravel_positif (signed long ADRES3){
11
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
signed long val=0;signed long tmp;
val = ADRES3;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la driveDisplayData[5] = 0x38; // Caractère ASCII "8" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[12] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
12
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;//DisplayData[19]=0x00;
}
//**************************************************************************************************************************//Envoie des consignes des limites Soft travels NEGATIVES//**************************************************************************************************************************void soft_overtravel_negatif (signed long ADRES4){
signed long val=0;signed long tmp;
val = ADRES4;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la driveDisplayData[5] = 0x39; // Caractère ASCII "9" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
13
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[12] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;//DisplayData[19]=0x00;
}
//**************************************************************************************************************************//Envoie des consignes des distances limites Soft travels POSITIVES//**************************************************************************************************************************void soft_overtravel_pos_limit (signed long ADRES5){
signed long val=0;
14
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
signed long tmp;
val = ADRES5;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la driveDisplayData[5] = 0x41; // Caractère ASCII "A" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[12] =tmp;
//Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
15
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;//DisplayData[19]=0x00;
}
//**************************************************************************************************************************//Envoie des consignes des distances limites Soft travels NÉGATIVES//**************************************************************************************************************************void soft_overtravel_neg_limit (signed long ADRES6){
signed long val=0;signed long tmp;
val = ADRES6;
DisplayData[0] = 0x3A; // Caractère ASCII ":"DisplayData[1] = 0x30; // Caractère ASCII "0" >>Adresse de la driveDisplayData[2] = 0x30; // Caractère ASCII "0" >>Adresse de la drive
DisplayData[3] = 0x30; // Caractère ASCII "0" >>Adresse du régistre dans la driveDisplayData[4] = 0x44; // Caractère ASCII "D" >>Adresse du régistre dans la driveDisplayData[5] = 0x42; // Caractère ASCII "B" >>Adresse du régistre dans la drive
DisplayData[6] = 0x31; // Caractère ASCII "1" >>Fonction écrire dans le régistre sélectionné
//Conv char0 tmp= val & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[14]=tmp;
//Conv char1tmp= val>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[13]=tmp;
//Conv char2 tmp= val>>8 & 0x000F;
if (tmp<=9)
16
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
tmp+=0x30; else
tmp+=0x37;
DisplayData[12] =tmp; //Conv char3
tmp= val>>12 & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[11]=tmp;
//Conv char4 tmp=val >>16 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[10]=tmp;
//Conv char5 tmp=val >>20 & 0x000F;
if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[9]=tmp;
//Conv char6 tmp=val >>24 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[8]=tmp;
//Conv char7 tmp=val >>28 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[7]=tmp;
Checksum();
DisplayData[17]=0x0D;DisplayData[18]=0x00;
}
//**************************************************************************************************************************//Conversion des caractères ASCII représentant des décimales en binaire //**************************************************************************************************************************void Convert_to_hex(unsigned char caractere[]){ unsigned long val=0;
unsigned int c,d,e=0;unsigned int
17
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
tmp0=0x0000,tmp1=0x0000,tmp2=0x0000,tmp3=0x0000,tmp4=0x0000,tmp5=0x0000,tmp6=0x0000,tmp7=0x0000;unsigned int temp=0x0000;
for(c=0;c<4;c++){
Donnee_DEC[c] = caractere[c]-48;}
tmp0 = Donnee_DEC[3];
tmp1 = Donnee_DEC[2];
tmp2 = Donnee_DEC[1];
tmp3 = Donnee_DEC[0];
Donnee_Hexa_Calc = tmp0 + (tmp1*10) + (tmp2*100) + (tmp3*1000);
if(cons_ang_stat==1){
Consigne_ang_Hexa = Donnee_Hexa_Calc;}
if(cons_load_stat==1){
Consigne_load_Hexa = Donnee_Hexa_Calc;}
if(cons_seuil_stat==1){
Consigne_seuil_Hexa = Donnee_Hexa_Calc;Consigne_seuil_Hexa =(Consigne_seuil_Hexa*13.107); //65535/5000;
}
}
//***********************************************************************************************************//Routine de conversion de la position du variateur de vitesse et la Vitesse du variateur de vitesse//***********************************************************************************************************void Convert_to_hex_Drive(unsigned char caractere2[]){ signed long val=0;
signed int c,d,e=0;signed long
tmp0=0x00000000,tmp1=0x00000000,tmp2=0x00000000,tmp3=0x00000000,tmp4=0x00000000,tmp5=0x00000000,tmp6=0x00000000,tmp7=0x00000000;
signed long temp=0x00000000;
for(c=0;c<8;c++){
if (caractere2[c] > 0x40){
Donnee_HEX[c] = caractere2[c]-55;}else
{Donnee_HEX[c] = caractere2[c]-48;
}}
tmp0 = Donnee_HEX[7]; //tmp0 = (tmp0 && 0x0000000F);
tmp0 = (tmp0);
tmp1 = Donnee_HEX[6];//tmp1 = (tmp1 << 4) && 0x000000F0;
18
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
tmp1 = (tmp1 << 4);
tmp2 = Donnee_HEX[5];//tmp2 = (tmp2 << 8) && 0x00000F00;tmp2 = (tmp2 << 8);
tmp3 = Donnee_HEX[4];//tmp3 = (tmp3 << 12) && 0x0000F000;tmp3 = (tmp3 << 12);
tmp4 = Donnee_HEX[3];//tmp4 = (tmp4 << 16) && 0x000F0000;tmp4 = (tmp4 << 16);
tmp5 = Donnee_HEX[2];//tmp5 = (tmp5 << 20) && 0x00F00000;tmp5 = (tmp5 << 20);
tmp6 = Donnee_HEX[1];//tmp6 = (tmp6 << 24) && 0x0F000000;tmp6 = (tmp6 << 24);
tmp7 = Donnee_HEX[0];//tmp7 = (tmp7 << 28) && 0xF0000000;tmp7 = (tmp7 << 28);
Donnee_Hexa_Calc = tmp0 + tmp1 + tmp2 + tmp3 + tmp4 + tmp5 + tmp6 + tmp7;
if(First_pos_Read==1){
Zero_Hexa_Calc = Donnee_Hexa_Calc;}
if(Reel_pos_Read==1){
Reel_Hexa_Calc = Donnee_Hexa_Calc;}
if(RS==1){
Read_speed_Calc = Donnee_Hexa_Calc;RS=0;
}
}
//***********************************************************************************************************//Conversion de l'angle de degré à pulses //***********************************************************************************************************void Convert_Angle_Pulse(unsigned long ANGLE){
signed long Temp = 0;
Temp = ANGLE;Consigne_Pulse = (Temp * 800000)/360; // Transformation de la consigne angulaire en
consigne Nbre de pulse
}
//***********************************************************************************************************//Consigne Char Function://Mettre la longueur de la consigne sur quatre caractères//***********************************************************************************************************void Consigne_Char(unsigned char caractere1[]){
unsigned int d = 0;
19
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
Long = Long-1;if(caractere1[0]==0x47) // Permet de négliger les deux points{
for(d=0;d<Long;d++){consigne_posi[3-d]=caractere1[Long-d]; // Mettre la consigne dans la variable
consigne_posi}Long=0;
}
if(caractere1[0]==0x4C){
for(d=0;d<Long;d++){consigne_load[3-d]=caractere1[Long-d]; // Mettre la consigne dans la variable
consigne_load}Long=0;
}if(caractere1[0]==0x53){
for(d=0;d<Long;d++){consigne_seuil[3-d]=caractere1[Long-d]; // Mettre la consigne dans la variable
consigne_seuil}Long=0;
}}
//***********************************************************************************************************//Convertion De plage de la position://***********************************************************************************************************void Reel_Pulse_Posi(unsigned char caractere3[]){
unsigned int c = 0;signed long tpm_zero = 0;
for(c=0;c<8;c++){
REELPosition[c]=caractere3[c+6]; // Position actuelle = position initiale}
Reel_pos_Read = 1;
Convert_to_hex_Drive(REELPosition); // Conversion de la donnée ASCII de position en donnée Hexadécimale(Position_Hexa_Calc)
STAT_RECEI = 0;Reel_pos_Read=0;
Diff_Hexa_Calc = Reel_Hexa_Calc - Zero_Hexa_Calc;
if (Diff_Hexa_Calc < 0){
Diff_Hexa_Calc = (0xFFFFFFFF - (Diff_Hexa_Calc - 1));}
}
//***********************************************************************************************************
20
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
//Checksum() Function://Fonction permettant de faire le calcul du Checksum afin de valider les données transmises POUR 18 CARACTÈRES.//***********************************************************************************************************void Checksum(void){int l;int CS=0;int sum=0;int tmp=0;//DisplayData[] = ":DDFFFfVVVVVVVVCC";
for (l=1; l<15; l++){sum = sum + DisplayData[l];}
CS=256-sum;
//Conv CS1 tmp= CS & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[16] = tmp;
//Conv CS0tmp= CS>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[15] = tmp;
}
//***********************************************************************************************************//Checksum() Function://Fonction permettant de faire le calcul du Checksum afin de valider les données transmises POUR 20 CARACTÈRES.//***********************************************************************************************************void Checksum_LONG(void){int h;int Ch=0;int sum=0;int tmp=0;//DisplayData[] = ":DDFFFfVVVVVVVVCC";
for (h=1; h<17; h++){sum = sum+ DisplayData[h];}
Ch=256-sum;
//Conv CS1 tmp= Ch & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[18] = tmp;
//Conv CS0tmp= Ch>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
21
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\ConvertRoutines.c
else tmp+=0x37;
DisplayData[17] = tmp;
}
22
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Delay.s
;Symbol/Literal/Immediate Operand Definitions:
;".equ" directives are similar to "#define" pre-processor directives in C
.equ NANOSEC125, 2 ;125ns approx = 2*TCY at 14.7 MIPS
.equ MICROSEC, 8*NANOSEC125 ;8*125ns =1us
.equ MILLISEC, 1000*MICROSEC ;1000*1us = 1000*8*125ns = 1ms
;Global Declarations for Functions and variables:
.global _Delay5us
.global _Delay5ms
.global _Delay125ns
;Code Sections:
;Code sections are named ".text"
.section .text
_Delay5us:
;Function Prototype for C:
; void Delay5us(int Count)
; Note: "_" prefixed to the function name is not used when calling the
; function from a C file.
; Function Execution Time when Count=1 is 5 microseconds at 14.74 MIPS
;
push w1 ;Store w1 on to stack
mov #MICROSEC, w1 ;w1 = MICROSEC
dec w1, w1 ;w1 = w1 - 1
bra nz, $-2 ;If w1 != 0 then Branch to previous instruction
dec w0, w0 ;else w0 = w0 - 1
bra nz, $-8 ;If w0 != 0 then Branch back 4 instructions
pop w1 ;else restore w1 from stack
return ;Return to calling routine
_Delay5ms:
;Function Prototype for C:
; void Delay5ms(int Count)
; Note: "_" prefixed to the function name is not used when calling the
; function from a C file.
; Function Execution Time when Count=1 is 5 milliseconds at 14.74 MIPS
push w1 ;Store w1 on to stack
mov #MILLISEC, w1 ;w1 = MILLISEC
dec w1, w1 ;w1 = w1 - 1
bra nz, $-2 ;If w1 != 0 then Branch to previous instruction
dec w0, w0 ;else w0 = w0 - 1
bra nz, $-8 ;If w0 != 0 then Branch back 4 instructions
pop w1 ;else restore w1 from stack
return ;Return to calling routine
.end ;End of File
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/extern unsigned int RXsel;extern unsigned int PTR;extern unsigned int RS;
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME *****************************************************************************************************/extern unsigned char DisplayData[];
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE reçu******************************************************************************************************/
extern putsUART1(unsigned int *buffer);extern WriteUART1(unsigned int data);extern WriteUART_to_RS232(void);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS DE DÉLAI*****************************************************************************************************/extern Delay5ms (int);extern Delay5us (int);
/*****************************************************************************************************DÉCLARATION DES FONCTION ACCESSIBLE SEULEMENT SUR CETTE FEUILLE*****************************************************************************************************/void ZERO_VITESSE (void);void GetPosition (void);void Checksum2(void);void Reset_fault (void);void SP_VITESSE_MODE (void);void Drive_Enable (void);void Drive_Disable (void);void Read_speed (void);void Drive_init (void);void Max_speed (void);void Accel (void);void Decel (void);void disable_accel_limit (void);void soft_overtravel (void);void Define_Home (void);void Position_Compar_Init (void);void Digital_Output (void);
/*****************************************************************************************************INITIALISATION DE LA ROUTINE D'INITIALISATION DU VARIATEUR DE VITESSE*****************************************************************************************************/void Drive_init (void) //Fonction permettant d'acquiter une faute sur le variateur de vitesse{
//Drive_Disable();Reset_fault();//Max_speed();Drive_Disable();Delay5ms(1000);Drive_Enable();Define_Home();
}
//*****************************************************************************************************************************//Définir la position initiale du système//*****************************************************************************************************************************
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
void Define_Home (void){
DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Adresse de HomingDisplayData[3] = 0x30; //0 DisplayData[4] = 0x37; //7 DisplayData[5] = 0x31; //1
//Ecrire 1 pour imposer la position actuelleDisplayData[6] = 0x31; //1
//CheckSumDisplayData[7] = 0x44; //D DisplayData[8] = 0x37; //7
//Carriage returnDisplayData[9] = 0x0D; //<CR>DisplayData[10] = 0x00; //0
WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
}
//************************************************************//Mettre la fonction d'overtravel en fonction//************************************************************void soft_overtravel (void){
DisplayData[0] = 0x3A; //: //: DisplayData[1] = 0x30; //0 //0 DisplayData[2] = 0x30; //0 //0
//Drive OVERTRAVEL ENABLEDisplayData[3] = 0x30; //0 //0 DisplayData[4] = 0x44; //D //D DisplayData[5] = 0x44; //D //D
//EcrireDisplayData[6] = 0x31; //1 //1
//METTRE EN FONCTIONDisplayData[7] = 0x30; //0 //0 DisplayData[8] = 0x30; //1 //0
//CheckSumDisplayData[9] = 0x35; //5 //5DisplayData[10] = 0x37; //6 //7
//Carriage returnDisplayData[11] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[12] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
}
//************************************************************//Mettre HORS FONCTION LES LIMITES D'ACCÉLÉRATION//************************************************************void disable_accel_limit (void){
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//Max speedDisplayData[3] = 0x30; //0DisplayData[4] = 0x41; //ADisplayData[5] = 0x39; //9
//EcrireDisplayData[6] = 0x31; //1
//DataDisplayData[7] = 0x30; //0DisplayData[8] = 0x30; //0
//CheckSumDisplayData[9] = 0x36; //6DisplayData[10] = 0x35; //5
//Carriage returnDisplayData[11] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[12] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232(); Delay5ms(2);
}
//************************************************************////************************************************************void Accel (void){
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Max speedDisplayData[3] = 0x30; //0DisplayData[4] = 0x35; //5DisplayData[5] = 0x46; //F
//EcrireDisplayData[6] = 0x31; //1
//Max speedDisplayData[7] = 0x30; //0DisplayData[8] = 0x30; //0DisplayData[9] = 0x31; //1DisplayData[10] = 0x33; //3
DisplayData[11] = 0x38; //8DisplayData[12] = 0x38; //8DisplayData[13] = 0x30; //0DisplayData[14] = 0x30; //0
//CheckSumDisplayData[15] = 0x30; //3DisplayData[16] = 0x33; //0
//Carriage returnDisplayData[17] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[18] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232(); Delay5ms(2);
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
}
//************************************************************////************************************************************void Decel (void){
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Max speedDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x30; //0
//EcrireDisplayData[6] = 0x31; //1
//consigne de decelDisplayData[7] = 0x33; //3DisplayData[8] = 0x46; //FDisplayData[9] = 0x46; //FDisplayData[10] = 0x46; //F
DisplayData[11] = 0x46; //FDisplayData[12] = 0x46; //FDisplayData[13] = 0x46; //FDisplayData[14] = 0x46; //F
//CheckSumDisplayData[15] = 0x42; //BDisplayData[16] = 0x43; //C
//Carriage returnDisplayData[17] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[18] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232(); Delay5ms(2);
}
//************************************************************////************************************************************void Max_speed (void) //Fonction permettant d'acquiter une faute sur le variateur de vitesse{
// :00038fddddcc<cr> //((((16378 CNT/SEC)*60SEC)/8000)=122rpm = 0X7A
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Max speedDisplayData[3] = 0x30; //0DisplayData[4] = 0x33; //3DisplayData[5] = 0x38; //8
//EcrireDisplayData[6] = 0x31; //1
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//Max speedDisplayData[7] = 0x30; //0 0DisplayData[8] = 0x42; //0 B BB8E8 = 3000RPM maxDisplayData[9] = 0x42; //0 BDisplayData[10] = 0x38; //0 8
//CheckSumDisplayData[11] = 0x45; //1 EDisplayData[12] = 0x38; //4 8
//Carriage returnDisplayData[13] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[14] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232(); Delay5ms(2);
}
//************************************************************//FAIRE UNE REMISE À ZÉRO DES ERREURS DANS LE VARIATEUR//************************************************************void Reset_fault (void) //Fonction permettant d'acquiter une faute sur le variateur de vitesse{
// :0006F1C3<cr>
//Drive Fault resetDisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Drive RESETDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x46; //F
//EcrireDisplayData[6] = 0x31; //1
//CheckSumDisplayData[7] = 0x43; //CDisplayData[8] = 0x33; //3
//Carriage returnDisplayData[9] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[10] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232();//Delay5us(1200); Delay5ms(2);
//************************************************************//METTRE LE VARIATEUR DE VITESSE EN CONSIGNE DE VITESSE//************************************************************
//Drive ADRESSDisplayData[0] = 0x3A; //: //: DisplayData[1] = 0x30; //0 //0 DisplayData[2] = 0x30; //0 //0
//Drive velocity preset modeDisplayData[3] = 0x30; //0 //0DisplayData[4] = 0x36; //6 //6DisplayData[5] = 0x31; //1 //1
5
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//EcrireDisplayData[6] = 0x31; //1 //1
//Preset velocity modeDisplayData[7] = 0x30; //0 //0DisplayData[8] = 0x31; //1 //0
//CheckSumDisplayData[9] = 0x37; //7 //7 DisplayData[10] = 0x37; //7 //8
//Carriage returnDisplayData[11] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[12] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);//Delay5us(700);
}
//************************************************************//METTRE LE VARIATEUR DE VITESSE EN CONSIGNE DE VITESSE//************************************************************void SP_VITESSE_MODE (void) //Fonction permettant de mettre la drive en asservissement de vitesse{
// :0006110177<cr>
//Drive ADRESSDisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Drive velocity preset modeDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x31; //1
//EcrireDisplayData[6] = 0x31; //1
//Preset velocity modeDisplayData[7] = 0x30; //0DisplayData[8] = 0x31; //1
//CheckSumDisplayData[9] = 0x37; //7DisplayData[10] = 0x37; //7
//Carriage returnDisplayData[11] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[12] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UART
}
//************************************************************//METTRE LE VARIATEUR DE VITESSE EN MODE FONCTIONNEMENT//************************************************************void Drive_Enable (void) //Fonction permettant d'activer le variateur de vitesse{
//Drive ADRESSDisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
6
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//Drive Enable/DisableDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x42; //B
//EcrireDisplayData[6] = 0x31; //1
//Enable DriveDisplayData[7] = 0x30; //0DisplayData[8] = 0x31; //1
//CheckSumDisplayData[9] = 0x36; //6DisplayData[10] = 0x36; //6
//Carriage returnDisplayData[11] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[12] = 0x00; //0
//Envoi de la commandeWriteUART_to_RS232();Delay5ms(2);
}
//************************************************************//METTRE LE VARIATEUR DE VITESSE HORS FONCTION//************************************************************void Drive_Disable (void) //Fonction permettant de désactiver le variateur de vitesse{
// :0006B10067<cr>
//Drive ADRESSDisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Drive Enable/DisableDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x42; //B
//EcrireDisplayData[6] = 0x31; //1
//Disable DriveDisplayData[7] = 0x30; //0DisplayData[8] = 0x30; //0
//CheckSumDisplayData[9] = 0x36; //6DisplayData[10] = 0x37; //7
//Carriage returnDisplayData[11] = 0x0D;
//Arret de la transmission rs-232DisplayData[12] = 0x00;
//Envoi de la commandeWriteUART_to_RS232(); Delay5ms(2);
}
//************************************************************//ENVOIE D'UNE CONSIGNE DE LECTURE AU VARIATEUR DE VITESSE//************************************************************void Read_speed (void) //Fonction permettant d'obtenir la vitesse actuelle
7
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
{
// :aa085fddddddddcc<cr>
//Drive ADRESSDisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Drive Enable/DisableDisplayData[3] = 0x30; //0DisplayData[4] = 0x38; //8DisplayData[5] = 0x35; //5
//LectureDisplayData[6] = 0x30; //0
//CheckSumDisplayData[7] = 0x44; //DDisplayData[8] = 0x33; //3
//Carriage returnDisplayData[9] = 0x0D;
//Arret de la transmission rs-232DisplayData[10] = 0x00;
//Envoi de la commandeWriteUART_to_RS232();
}
//************************************************************************//Lecture de position et insertion dans PositionData//************************************************************************void GetPosition(void){unsigned int i;
// :aa07Efcc<cr>
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
DisplayData[3] = 0x30; //0DisplayData[4] = 0x37; //7DisplayData[5] = 0x45; //E
//Lire la valeurDisplayData[6] = 0x30; //0
//CheckSumDisplayData[7] = 0x43; //CDisplayData[8] = 0x34; //4
//Carriage return DisplayData[9] = 0x0D; //<CR>
//Arret de la transmission rs-232
DisplayData[10] = 0x00; //0WriteUART_to_RS232(); //Envoi la serie de caractere par
RS-232
PTR=0; //Initialise le pointeur de la reception sur 0
RXsel=1; //Envoi la reception vers PositionData
}
void Position_Compar_Init (void)
8
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
{
//************************************************************//Imposer la limite minimale et maximale de dépassement//*********************************************************************************//************************************************************//MAXIMUM---------------------------------------------------------------------
DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x31; //1 DisplayData[4] = 0x35; //5 DisplayData[5] = 0x44; //D
//EcrireDisplayData[6] = 0x31; //1
//Position maximaleDisplayData[7] = 0x30; //0 DisplayData[8] = 0x30; //0
//POSITIONDisplayData[9] = 0x46; //FDisplayData[10] = 0x46; //F DisplayData[11] = 0x46; //FDisplayData[12] = 0x43; //CDisplayData[13] = 0x46; //FDisplayData[14] = 0x32; //2DisplayData[15] = 0x43; //CDisplayData[16] = 0x30; //0
//CheckSumDisplayData[17] = 0x36; //6DisplayData[18] = 0x35; //5
//Carriage returnDisplayData[19] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[20] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
/*
//MINIMUM------------------------------------------------------------DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x31; //1 DisplayData[4] = 0x35; //5 DisplayData[5] = 0x44; //D
//EcrireDisplayData[6] = 0x31; //1
//Position mINIMALEDisplayData[7] = 0x30; //0 DisplayData[8] = 0x31; //1
//POSITIONDisplayData[9] = 0x46; //FDisplayData[10] = 0x46; //F DisplayData[11] = 0x46; //FDisplayData[12] = 0x46; //FDisplayData[13] = 0x41; //D //E //ADisplayData[14] = 0x39; //8 //A //9
9
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
DisplayData[15] = 0x33; //F //4 //3DisplayData[16] = 0x32; //0 //D //2
//CheckSumDisplayData[17] = 0x36; //5 //4 //6DisplayData[18] = 0x44; //A //E //D
//Carriage returnDisplayData[19] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[20] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
*/
//TYPE DE COMPARAISON ARRAY_00------------------------------------------------------------DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x31; //1 DisplayData[4] = 0x35; //5 DisplayData[5] = 0x45; //E
//EcrireDisplayData[6] = 0x31; //1
//ARRAY Position 1DisplayData[7] = 0x30; //0 DisplayData[8] = 0x30; //0
//POSITION Less thanDisplayData[9] = 0x30; //0DisplayData[10] = 0x31; //1
//CheckSumDisplayData[11] = 0x30; //0DisplayData[12] = 0x33; //3
//Carriage returnDisplayData[13] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[14] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
//TYPE DE COMPARAISON ARRAY_01------------------------------------------------------------DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x31; //1 DisplayData[4] = 0x35; //5 DisplayData[5] = 0x45; //E
//EcrireDisplayData[6] = 0x31; //1
//ARRAY Position 1DisplayData[7] = 0x30; //0 DisplayData[8] = 0x31; //1
//POSITION Greater thanDisplayData[9] = 0x30; //0DisplayData[10] = 0x30; //0
10
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//CheckSumDisplayData[11] = 0x30; //0DisplayData[12] = 0x33; //3
//Carriage returnDisplayData[13] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[14] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
}
void Digital_Output (void){
//************************************************************//Imposer les fonctions des sortie digitales//*********************************************************************************//************************************************************//FONCTION COMPARAISON1---------------------------------------------------------------------
DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x30; //0 DisplayData[4] = 0x43; //C DisplayData[5] = 0x45; //E
//EcrireDisplayData[6] = 0x31; //1
//Position maximaleDisplayData[7] = 0x30; //0 DisplayData[8] = 0x30; //0
//FONCTION DisplayData[9] = 0x30; //0DisplayData[10] = 0x30; //0 DisplayData[11] = 0x30; //0DisplayData[12] = 0x30; //0DisplayData[13] = 0x34; //4DisplayData[14] = 0x30; //0DisplayData[15] = 0x30; //0DisplayData[16] = 0x30; //0
//CheckSumDisplayData[17] = 0x44; //DDisplayData[18] = 0x33; //3
//Carriage returnDisplayData[19] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[20] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
//FONCTION COMPARAISON_2---------------------------------------------------------------------DisplayData[0] = 0x3A; //: DisplayData[1] = 0x30; //0 DisplayData[2] = 0x30; //0
//Drive Comparateur de positionDisplayData[3] = 0x30; //0 DisplayData[4] = 0x43; //C DisplayData[5] = 0x45; //E
11
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
//EcrireDisplayData[6] = 0x31; //1
//Position maximaleDisplayData[7] = 0x30; //0 DisplayData[8] = 0x31; //1
//FONCTION DisplayData[9] = 0x30; //0DisplayData[10] = 0x30; //0 DisplayData[11] = 0x30; //0DisplayData[12] = 0x30; //0DisplayData[13] = 0x38; //8DisplayData[14] = 0x30; //0DisplayData[15] = 0x30; //0DisplayData[16] = 0x30; //0
//CheckSumDisplayData[17] = 0x43; //CDisplayData[18] = 0x45; //E
//Carriage returnDisplayData[19] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[20] = 0x00; //0WriteUART_to_RS232(); //Update RS232 via UARTDelay5ms(2);
}
//************************************************************//ENVOI D'UNE CONSIGNE DE VITESSE NULLE AU VARIATEUR DE VITESSE//************************************************************void ZERO_VITESSE (void){
DisplayData[0] = 0x3A; //:DisplayData[1] = 0x30; //0DisplayData[2] = 0x30; //0
//Max speedDisplayData[3] = 0x30; //0DisplayData[4] = 0x36; //6DisplayData[5] = 0x44; //D
//EcrireDisplayData[6] = 0x31; //1
//consigne de VITESSE 0DisplayData[7] = 0x30; //0DisplayData[8] = 0x30; //0DisplayData[9] = 0x30; //0DisplayData[10] = 0x30; //0
DisplayData[11] = 0x30; //0DisplayData[12] = 0x30; //0DisplayData[13] = 0x30; //0DisplayData[14] = 0x30; //0
//CheckSumDisplayData[15] = 0x34; //4DisplayData[16] = 0x35; //5
//Carriage returnDisplayData[17] = 0x0D; //<CR>
//Arret de la transmission rs-232DisplayData[18] = 0x00; //0
//Envoi de la commande
12
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Drive_Command(2).c
WriteUART_to_RS232(); //Delay5ms(1); Delay5us(1200);
}
//************************************************************************//EFFECTUER LE CHECKSUM//************************************************************************void Checksum2(void){int l;int CS=0;int sum=0;int tmp;//DisplayData[] = ":DDFFFfVVVVVVVVCC";
for (l=1; l<15; l++){sum = sum + DisplayData[l];}
CS=256-sum;
//Conv CS1 tmp= CS & 0x000F; if (tmp<=9)
tmp+=0x30; else
tmp+=0x37;
DisplayData[16] = tmp;
//Conv CS0tmp= CS>>4 & 0x000F;
if (tmp<=9) tmp+=0x30;
else tmp+=0x37;
DisplayData[15] = tmp;
}
13
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
#include <p30f4011.h> //"p30fxxxx.h" is a generic header file for dsPIC30F#include "system.h" //"system.h" is a header file defined for this demo //application.
_FOSC(CSW_FSCM_OFF & XT_PLL8); //Run this project using an external crystal //routed via the PLL in 8x multiplier mode //For the 7.3728 MHz crystal we will derive a //throughput of 7.3728e+6*8/4 = 14.74 MIPS(Fcy) //,~67nanoseconds instruction cycle time(Tcy)._FWDT(WDT_OFF); //Turn off the Watch-Dog Timer._FBORPOR(MCLR_EN & PWRT_OFF); //Enable MCLR reset pin and turn off the //power-up timers._FGS(CODE_PROT_OFF); //Disable Code Protection
/*****************************************************************************************************DÉCLARATION DES FONCTIONS ACCESSIBLE DANS TOUT LE PROGRAMME*****************************************************************************************************/extern UART_Init (void);extern UART2_Init (void);extern SPI_Init(void);extern Timer1_Init(void);extern INTx_Init(void);extern INIT_ADs_SPI(void);extern RXLoadC(void);extern SPILCInit(void);extern WriteUART_to_RS232(void);extern WriteUART2_to_RS232(void);extern AffCell(void);extern AffEMG(void);extern AffPOSI(void);extern GetPosition (void);extern WritePosi (void);extern UART_Init2 (void);extern Drive_init(void); extern Accel (void);extern Decel (void);extern disable_accel_limit (void);extern soft_overtravel (void);extern Timer2_Init(void);extern GetTimeScan(void);extern AffREFRESH(void);extern AffCONSIGNE(void);extern Define_Home (void);extern Position_Compar_Init (void);extern Digital_Output (void);extern ZERO_VITESSE (void);extern Asservi (void);extern convert_load(void);
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À ENVOYER******************************************************************************************************/
extern WriteUART1(unsigned int data);extern TXLoadC(unsigned int SPITX,unsigned int length);extern ConfigIntUART2(unsigned int config);extern WriteL_UART2(unsigned char lenght);extern WriteUART2(unsigned int data);extern Convert_to_hex(unsigned char caractere[]);extern Convert_to_hex_Drive(unsigned char caractere2[]);extern Consigne_Char(unsigned char caractere1[]);extern Reel_Pulse_Posi(unsigned char caractere3[]);extern Convert_Angle_Pulse(unsigned long Consigne_ANGLE);extern Envoi_Vitess_drive(signed long ADRES);extern Envoi_Accel_drive(signed long ADRES2);extern soft_overtravel_positif (signed long ADRES3);extern soft_overtravel_negatif (signed long ADRES4);extern soft_overtravel_pos_limit (signed long ADRES5);
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
extern soft_overtravel_neg_limit (signed long ADRES6);extern MINIMUM_POSI(signed long ADRES7);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS DE DÉLAI*****************************************************************************************************/extern Delay5us (int);extern Delay5ms (int);
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME *****************************************************************************************************/extern unsigned char Status[]="0000000000000000000000000000000000";extern unsigned char DisplayData[]=":00000000000000000000 ";extern unsigned char ReceivedData[]="0000000000000000";extern unsigned char PositionData[]="0000000000000000";extern unsigned char ZeroPosition[]="00000000";extern unsigned char REELPosition[]="00000000";extern unsigned char ConsigneVitessePos[]="000000000000000000";extern unsigned char Donnee_DEC[]="0000";extern unsigned char Donnee_HEX[]="00000000";extern unsigned char Donnee_Hexa_AFF[] = "00000000";extern unsigned char Read_speed_ASCII[] = "00000000";extern unsigned char consigne_posi[]="0000";extern unsigned char consigne_load[]="0000";extern unsigned char consigne_seuil[]="0000";extern unsigned char Temporaire1[]="0000";extern unsigned char CONSIGNE[]=":000000";extern unsigned char REFRESHVAL[]=":0000000000000000000000";
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR HUIT BITS NON SIGNÉES ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 255)*****************************************************************************************************/
extern unsigned char send = 0;extern unsigned char TX2REFRESHVAL=0;
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/
extern unsigned int TAMPON = 0x0000;extern unsigned int EMG = 0x0000;extern unsigned int AFF = 0x0000;extern unsigned int POSI = 0x0000;extern unsigned int LCSPIRX = 0x0000;extern unsigned int PTR = 0;extern unsigned int PTR2 = 0;extern unsigned int PosAtt = 0;extern unsigned int RX2PTR=0;extern unsigned int cons_ang_stat=0;extern unsigned int cons_load_stat=0;extern unsigned int cons_seuil_stat=0;extern unsigned int First_pos_Read=0;extern unsigned int Reel_pos_Read=0;extern unsigned int Long=0;extern unsigned int Posi_init = 0;extern unsigned int j=0;extern unsigned int l=0;extern unsigned int x=0;extern unsigned int STAT_RECEI=0;extern unsigned int RS=0; extern unsigned int STOP=0; extern unsigned int START=0; extern unsigned int up_down=1;extern unsigned int start_load=1; extern unsigned int DDD;extern unsigned int ZERO_LOAD=0;extern unsigned int TimeScan = 0x0000;extern unsigned int SP_load = 0x0000;extern unsigned int RXsel = 0;
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
extern unsigned int Consigne_load_Hexa = 0x0000;extern unsigned int Consigne_seuil_Hexa = 0x0000;
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (-32768 À 32767)*****************************************************************************************************/
extern signed int Potentiometer = 0;
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 4 294 967 295)*****************************************************************************************************/
extern unsigned long RX2TEMP=0;extern unsigned long CONSLOAD=0;extern unsigned long Consigne_Pulse = 0;extern unsigned long MAX_Speed=0x00002FFA; // Défénition de la vitesse maximaleextern unsigned long Consigne_ang_Hexa = 0x00000000;extern unsigned long Seuil_Trente_Hexa = 0x00000000;
/*****************************************************************************************************
DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME(-2 147 483 648 À 2 147 483 647)*****************************************************************************************************/
extern signed long SP_vit = 0;extern signed long Donnee_Hexa_Calc = 0x00000000;extern signed long Diff_Hexa_Calc = 0x00000000;extern signed long Reel_Hexa_Calc = 0x00000000;extern signed long Zero_Hexa_Calc = 0x00000000;extern signed long Read_speed_Calc = 0x00000000;extern signed long Posi_Speed = 0x00002FF4;extern signed long Accel_Val_MIN = 0x00001B27; extern signed long Acceleration = 0x00000000; extern signed long Zero_Speed = 0x00000000;extern signed long TEMP_DEEEEEE = 0x00000000;extern signed long soft_positif = 0xFFFFD499;extern signed long soft_negatif = 0xFFFCF2C0;extern signed long positif_limit = 0x000008AE;extern signed long negatif_limit = 0x000008AE;extern signed long Vit_act=0;
/*****************************************************************************************************DÉCLARATION DES VARIABLES EN POINT FLOTTANT (1.17549*10e-38 À 8.5*10e37)*****************************************************************************************************/extern float depass=0; //Depassement de la valeur seuil de l'emg en %extern float SP_EMG = 0x0000;extern float Delta_force = 0;extern float facteur = 7.272; //cnt/sec; //Facteur de correction du systeme (0.007136 tr/N*s * 8000)extern float EMG_CORR_GAIN = 0.025;extern float LOAD_CORR_GAIN = 2;extern float ACCEL_GAIN = 12;extern float LOAD=0;
/*****************************************************************************************************DÉCLARATION DES FONCTION ACCESSIBLE SEULEMENT SUR CETTE FEUILLE*****************************************************************************************************/void main (void);
/***********************************************ENTRÉE DANS LA ROUTINE PRINCIPALE*********************
CETTE ROUTINE EST LE CONTRÔLE PRINCIPALE DU SYSTÈME. ELLE PERMET D'INITIALISER LE VARIATEUR DE VITESSEET DE RECEUILLIR LE CONSIGNES DE FONCTIONNEMENT DE L'APPAREIL. DANS CETTE ROUTINE, BEAUCOUP DE SOUS FONCTIONS DE CONVERSION SONT APPELÉS CE QUI PERMET D'UTILISER LES DIFFÉRENTES VARIABLES LUT PAR LE SYSTÈME. DE PLUS, LA ROUTINE D'ASSERVISSEMENT EST APPELÉ DANS CETTE PARTIE.
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
*****************************************************************************************************/
void main (void){
//**********************************************************************************************//INITIALISATION DE CERTAINES VARIABLE APPLICABLE À LA ROUTINE PRINCIPALE//**********************************************************************************************unsigned char NEW_PAGE = 12;unsigned char NEW_LINE = 10;unsigned char h,tampon, Tata = 0;
unsigned int cr = 0x0D;unsigned int i = 0;unsigned int count = 0;unsigned int cnt = 0;unsigned int c,d,e,f = 0;
signed int CNT_UPD=0;
//**********************************************************************************************//INITIALISATION DES ENTRÉES SORTIES DU SYSTÈME//**********************************************************************************************TRISBbits.TRISB1 = 0; // Configurer la pin RB3 en sortie (1=entrée, 0 = sortie)TRISBbits.TRISB0 = 0; // Configurer la pin RB3 en sortie (1=entrée, 0 = sortie)TRISBbits.TRISB3 = 0; // Configurer la pin RB3 en sortie (1=entrée, 0 = sortie)TRISBbits.TRISB4 = 0; // Configurer la pin RB4 en sortie (1=entrée, 0 = sortie)TRISBbits.TRISB5 = 1; // Configurer la pin RB5 en entrée (1=entrée, 0 = sortie)
TRISEbits.TRISE2 = 0; // Configurer la pin RE2 en sortie (1=entrée, 0 = sortie) TRISEbits.TRISE3 = 0; // Configurer la pin RE3 en sortie (1=entrée, 0 = sortie) TRISEbits.TRISE4 = 1; // Configurer la pin RE4 en entrée (1=entrée, 0 = sortie) TRISEbits.TRISE8 = 1; // Configurer la pin RE8 en entrée (1=entrée, 0 = sortie)
LATBbits.LATB3 = 1; // Mettre la sortie RB3 ONLATBbits.LATB4 = 1; // Mettre la sortie RB4 ONLATBbits.LATB5 = 0; // Mettre l'entrée RB5 OFF LATEbits.LATE3 = 1; // Mettre la sortie RE3 ON LATEbits.LATE2 = 0; // Mettre la sortie RE3 OFF
ADPCFG = 0xFFFF; // After reset all port pins multiplexed // with the A/D converter are configred analog. // We will reconfigure them to be digital // by writing all 1's to the ADPCFG register. // Note: All dsPIC registers are memory mapped. // The address of ADPCFG and other registers // are defined in the device linker script // in your project.Envoi_Vitess_drive(Zero_Speed); // Permet de s'assurer que le variateur de vitesse sera arrêter
// lors du démarrage du systèmeWriteUART_to_RS232();Delay5ms(200);
//**********************************************************************************************//INITIALISATION DE CERTAINS PARAMÈTRES ESSENTIELS AU FONCTIONNEMENT//**********************************************************************************************UART_Init (); //PERMET DE METTRE EN FONCTION LE PÉRIPHÉRIQUE UART1UART2_Init (); //PERMET DE METTRE EN FONCTION LE PÉRIPHÉRIQUE UART2SPI_Init(); //PERMET DE METTRE EN FONCTION LE PÉRIPHÉRIQUE SPITimer1_Init(); //PERMET DE METTRE EN FONCTION LE PÉRIPHÉRIQUE TIMER1Timer2_Init(); //PERMET DE METTRE EN FONCTION LE PÉRIPHÉRIQUE TIMER2SPILCInit(); //PERMET DE METTRE EN FONCTION LE SYSTÈME SOFTWARE SPI DU A/D DE LA
//CELLULE DE CHARGEDrive_init(); //Initialise certains paramètres dans le variateur de vitessedisable_accel_limit(); //Met hors fonction les limite d'accélérationPosition_Compar_Init(); //Met en fonction les comparateurs internes du variateurDigital_Output(); //Met en fonction et assigne certaines sortie du variateur de vitessesoft_overtravel(); //Met les dépassement hors fonction
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
//ADC_Init();Envoi_Accel_drive(Accel_Val_MIN);//Envoi une consigne d'accélération minimum au variateur de vitesseWriteUART_to_RS232();Delay5us(1200);
while (1) // Boucle principale qui se fait à l'infinie {
//**********************************************************************************************//DÉMARRAGE DE L'INITIALISATION DU SYSTÈME (RÉCEPTION CONSIGNES, POSITIONNEMENT INITIALE, ETC.//**********************************************************************************************Drive_Enable(); // Appeler la routine permettant de mettre la Drive en mode RUNDelay5us(1200); // Attendre un délais pour la transmission (2.75ms)Envoi_Vitess_drive(Zero_Speed); // Appeler la routine de convertion HEXA en ASCII de la vitesse
// à la drive, envoie vitesse = 0WriteUART_to_RS232(); // Envoyer la vitesse à la DriveDelay5us(1200); // Attendre un délais pour la transmission (4ms)LATBbits.LATB1 = 1; // LED1 pour test de debug à ON
while (!STAT_RECEI) // Attendre la position actuelle du variateur {GetPosition(); // Lire la position actuelle du moteurDelay5us(1200); // Attendre un délais pour la transmission (2.5ms)}
LATBbits.LATB1 = 0; // LED1 pour test de debug à OFFFirst_pos_Read=1; // Flag pour avertir que la position zéro du variateur est reçu
for(c=0;c<8;c++){
ZeroPosition[c]=PositionData[c+6]; // Position actuelle = position initiale su 8 caractères. } // Ceci permet d'éliminer les caractères servant à idiquer
// l'adresse du régistre lu de la drive.
Convert_to_hex_Drive(ZeroPosition); // Conversion de la donnée ASCII de position en donnée // hexadécimale(Position_Hexa_Calc)
STAT_RECEI = 0; // Remise à zéro du FLAG de réception de positionFirst_pos_Read=0; // Remise à zéro du FLAG de position initiale
LATBbits.LATB1 = 1;while (!cons_ang_stat) // Attendre la consigne de position initiale du variateur{}
Consigne_Char(CONSIGNE); // Convertion de la consigne reçu de nombres de caractère // inconnue en 4 caractères
Convert_to_hex(consigne_posi); // Convertion de la consigne de position initiale ASCII en HEXAcons_ang_stat = 0; // Remise à zéro du FLAG de réception de la consigne angulaire
//Positionnnement du bras à sa position initiale******************************************************//****************************************************************************************************Convert_Angle_Pulse(Consigne_ang_Hexa); // Conversion de la consigne angulaire en nombre de pulse
MINIMUM_POSI(Consigne_Pulse);WriteUART_to_RS232(); // Envoyer la Consigne position minimum à la driveDelay5us(1200);LATBbits.LATB1 = 0; // (fonctionnement de la drive en nombre de pulses)
Envoi_Accel_drive(0x0F000000); // Envoi du consigne d'accélération énorme pour un arrêt brusque WriteUART_to_RS232();Delay5us(2000);
while (!Posi_init) // Faire la boucle tant que la position != à la consigne de position {
Envoi_Vitess_drive(Posi_Speed); // Appeler la routine de convertion HEXA en ASCII de la vitesse à // la drive, envoie vitesse = 12282 cnt/sec
5
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
WriteUART_to_RS232(); // Envoyer la vitesse à la DriveDelay5us(1200); // Attendre un délais pour la transmission (4.5ms)GetPosition(); // Lire la position actuelle du moteurLATBbits.LATB0 = 1;
while (!STAT_RECEI) // Attendre qu'une vitesse soit entrée {}
STAT_RECEI = 0;
Reel_Pulse_Posi(PositionData); // Convertion de la vitesse ASCII en HEXA
if (Diff_Hexa_Calc > Consigne_Pulse)// Vérifier si la position actuel est plus grande que la // consigne de position
{Posi_init = 1;Envoi_Vitess_drive(Zero_Speed); // Arrête le système avec une consigne de vitesse nulleWriteUART_to_RS232();Delay5us(1200);
}}Envoi_Accel_drive(Accel_Val_MIN); // Envoi d'une consigne normale d'accélération pour un
// fonctionnement normaleWriteUART_to_RS232();Delay5us(2000);
LATBbits.LATB0 = 0;
//Réception de la consigne de charge******************************************************************//****************************************************************************************************count = 0;while (!cons_load_stat) // Attendre la consigne de charge initiale du variateur{
if(!PORTBbits.RB5) // Lecture de la cellule de charge{RXLoadC();ZERO_LOAD = LCSPIRX; // Zero de la cellule de charge}
}
count = 0;Consigne_Char(CONSIGNE); // Convertion de la consigne recu en chaine de caractère
// possédant la bonne longueurConvert_to_hex(consigne_load); // Conversion de la chaine de caractère en données hexadécimale
// permettant leur traitementcons_load_stat = 0;SP_load = (Consigne_load_Hexa * 1000); // Transformer la consigne de charge de kilogramme à gramme pour
// une meilleure précision
//Réception de la consigne de seuil EMG***************************************************************//****************************************************************************************************while (!cons_seuil_stat){
INIT_ADs_SPI(); // Effectuer une lecture du capteur EMG
/*************************************************Le système entame la séquence d'affichage une fois par 50 cycles*************************************************/if (i == 50){
AFF = EMG;AffEMG(); // Envoi la valeur lu sur l'EMG dans une variable d'affichageWriteUART2_to_RS232(); // Envoi la donnée à l'affichagei=0;
}
6
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
i++;}
Consigne_Char(CONSIGNE); // Convertion de la consigne recu en chaine de caractère // possédant la bonne longueur
Convert_to_hex(consigne_seuil); // Conversion de la chaine de caractère en données hexadécimale
// permettant leur traitementcons_seuil_stat=0;SP_EMG = (Consigne_seuil_Hexa * 0.3); // Établie le seuil de dépassement à trente pourcent de la
// valeur maximum envoyé
//Démarrage de la routine permettant l'asservissement de l'entraînement*******************************//****************************************************************************************************
while (!START);
while (!STOP) //Entrainement actif jusqu'a ce que le bouton stop sois declanche
{
//EN MONTÉ********************************************************************************//****************************************************************************************
if(up_down==1) //Monter{
/*************************************************Si cette condition est vrai, le système arrête brusquement*************************************************/if(PORTDbits.RD1)
{Envoi_Accel_drive(0x0F000000); //Envoyer une consigne énorme d'accélération
//au variateur de vitesse pour un arrêt brusqueWriteUART_to_RS232();Delay5us(2000);
Envoi_Vitess_drive(Zero_Speed); //Envoi d'une commande de vitesse = 0WriteUART_to_RS232();Delay5ms(60);
Envoi_Accel_drive(Accel_Val_MIN);//Envoyer la consigne initiale d'accélération //pour continuer l'exercice
WriteUART_to_RS232();Delay5us(2000);
up_down=0; //Indiquer que le prochain mouvement //sera en descente
SP_load = (Consigne_load_Hexa*1000);//Remettre la consigne de charge à la valeur//de la consigne initiale
POSI = 0x005A; //Envoyer une position de 90 degré à l'affich//Appel des routine d'envoi de données à l'affichage AffCell();AffEMG();AffPOSI();AffCONSIGNE();WriteUART2_to_RS232();//Fin envoi affichage
}
/*************************************************Le système entame la séquence d'asservissement lorsque la position max n'est pas atteinte*************************************************/
else
{GetTimeScan(); // Appel une fonction permettant de calculer le temps de scan
7
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
AffREFRESH(); // Envoi le temps de scan pour l'affichageWriteUART2_to_RS232();
Asservi();}
}
//EN DESCENTE*****************************************************************************//****************************************************************************************
else
{/*************************************************Si cette condition est vrai, le système arrête brusquement*************************************************/if(PORTDbits.RD2){
Envoi_Accel_drive(0x0F000000); //Envoyer une consigne énorme //d'accélération au variateur de vitesse //pour un arrêt brusque
WriteUART_to_RS232();Delay5us(2000);
Envoi_Vitess_drive(Zero_Speed); //Envoi d'une commande de vitesse = 0WriteUART_to_RS232();Delay5ms(60);
Envoi_Accel_drive(Accel_Val_MIN); //Envoyer la consigne initiale d'accélération//pour continuer l'exercice
WriteUART_to_RS232();Delay5us(2000);
up_down=1; //Indiquer que le prochain mouvement sera en //monté
SP_load = (Consigne_load_Hexa*1000);//Remettre la consigne de charge à la valeur//de la consigne initiale
POSI = 0x0000; //Envoyer une position de 0 degré à //l'affichage
//Appel des routine d'envoi de données à l'affichage AffCell();AffEMG();AffPOSI();AffCONSIGNE();WriteUART2_to_RS232();//Fin envoi affichage
}
/*************************************************Le système entame la séquence d'asservissement lorsque la position min n'est pas atteinte*************************************************/
else
{GetTimeScan(); // Appel une fonction permettant de calculer le temps
// de scan.AffREFRESH(); // Envoi le temps de scan pour l'affichageWriteUART2_to_RS232();
Asservi();}
}}
//ARRÊT DU SYSTÈME************************************************************************//****************************************************************************************Envoi_Vitess_drive(Zero_Speed); // Appeler la routine de convertion HEXA en ASCII de
// la vitesse à la drive, envoie vitesse = 0WriteUART_to_RS232(); // Envoyer la vitesse à la Drive
8
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\Main.c
Delay5ms(2); // Attendre un délais pour la transmission (10ms)LATBbits.LATB0 = 0;}
return 0; }
9
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\SPI_LoadCell.c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"#include "math.h"
/**************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 4 294 967 295)**************************************************************************************************************/extern unsigned int LCSPIRX;
/*****************************************************************************************************DÉCLARATION DES FONCTIONS RELIÉES SEULEMENT SUR CETTE FEUILLE*****************************************************************************************************/
void Timer1_Init(void);void SPILCInit(void);void RXLoadC(void);
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À REÇU******************************************************************************************************/
void TXLoadC(unsigned int SPITX,unsigned int length);
void Timer1_Init(void){ T1CON = 0b0000000000000000; //TCKPS1 Timer1 set up to count on instruction cycle
//edge with 1:1 prescaler applied initially. PR1 = 0x0006; //Period Register, PR1, set to maximum count IFS0bits.T1IF = 0; //Clear the Timer1 Interrupt Flag IEC0bits.T1IE = 0; //Enable Timer1 Interrupt Service Routine
T1CONbits.TON=0; //Stop Timer 1}
/***********************************************ENTRÉE DANS LA ROUTINE D'INITIALISATION*********************************************
CETTE ROUTINE EFFECTUE L'INITIALISATION PRÉLÉMINAIRE DU CONVERTISSEUR ANALOGIQUE À NUMÉRIQUE DE LA CELLULE DE CHARGE
***********************************************************************************************************************************/void SPILCInit(void){
unsigned int CONFIG;//RESET DU ADLATBbits.LATB3 = 0;
TXLoadC(0xFFFF,32); //RESET ADC TXLoadC(0xFFFF,32); //RESET ADC
Delay5us(125); //DELAY 500uS
//CONFIGURAION DU MODE REGISTER
TXLoadC(0x0008,16); //MODE REGISTER//TXLoadC(0x4003,32); //IDLE MODE, 123 Hz,TXLoadC(0x4004,32); //IDLE MODE, 62 Hz,
//TXLoadC(0x4008,32); //IDLE MODE, 19.6 Hz
// CONFIGURAION DU CONFIGURATION REGISTER
TXLoadC(0x0010,16); //CONFIGURATION REGISTER //TXLoadC(0x0410,32); //BUFFER MODE, BIPOLAR, GAIN 16, AN1, ADC input = 39.06 mV
//TXLoadC(0x0510,32); //BUFFER MODE, BIPOLAR, GAIN 32, AN1, ADC input = 39.06 mV
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\SPI_LoadCell.c
TXLoadC(0x0610,32); //BUFFER MODE, BIPOLAR, GAIN 64, AN1, ADC input = 39.06 mV
//CONFIGURAION DU MODE REGISTER
TXLoadC(0x0008,16); //MODE REGISTER//TXLoadC(0x8003,32); //ZERO SCALE CALIBRATION, // Fréquence de convertion =
123 HzTXLoadC(0x8004,32); //ZERO SCALE CALIBRATION, // Fréquence de convertion = 62
Hz //TXLoadC(0x8008,32); //ZERO SCALE CALIBRATION, // Fréquence de convertion = 19.6 Hz
while (PORTBbits.RB5){}
//CONFIGURAION DU MODE REGISTER
TXLoadC(0x0008,16); //CONFIGURATION REGISTER //TXLoadC(0xA003,32); //FULL SCALE CALIBRATION, // Fréquence de convertion = 123 Hz TXLoadC(0xA004,32); //FULL SCALE CALIBRATION, // Fréquence de convertion = 62 Hz //TXLoadC(0xA008,32); //FULL SCALE CALIBRATION, // Fréquence de convertion = 19.6 Hz
while (PORTBbits.RB5){}
// CONFIGURAION DU CONFIGURATION REGISTER
TXLoadC(0x0010,16); //CONFIGURATION REGISTER //TXLoadC(0x0410,32); //Gain = 16, ADC input = 39.06 mV
//TXLoadC(0x0510,32); //Gain = 32, ADC input = 39.06 mV TXLoadC(0x0610,32); //Gain = 64, ADC input = 39.06 mV
//CONFIGURAION DU MODE REGISTER
TXLoadC(0x0008,16); //MODE REGISTER //TXLoadC(0x0003,32); //CONTINUOUS CONVERTION, Fréquence de convertion = 123 Hz
TXLoadC(0x0004,32); //CONTINUOUS CONVERTION, Fréquence de convertion = 62 Hz //TXLoadC(0x0008,32); //CONTINUOUS CONVERTION, Fréquence de convertion = 19.6 Hz
TXLoadC(0x005C,16); //CONTINUOUS CONVERTION}
/***********************************************ENTRÉE DANS LA ROUTINE DE TRANSMISSION*********************************************
ENVOIE DES VARIABLES VOULUES DANS LE CONVERISSEUR
***********************************************************************************************************************************/void TXLoadC(unsigned int SPITX,unsigned int length)
{LATEbits.LATE3 = 1; //Latch bit for RE3 port pin //SPICLKunsigned char COUNT=0;unsigned char COUNT1=0;unsigned char COUNT2=0;
T1CONbits.TON=1;TMR1 = 0x0000;
PR1 = 0x0006;IFS0bits.T1IF=0;
while (!IFS0bits.T1IF)
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\SPI_LoadCell.c
if(((SPITX>>((length/2)-1))&0x0001)==1){LATEbits.LATE2 = 1; //Latch bit for RE2 port pin}else
{LATEbits.LATE2 = 0; //Latch bit for RE2 port pin}
LATEbits.LATE3 = 0; //Latch bit for RE3 port pin //SPICLK
for (COUNT2=0; COUNT2<(length-1); COUNT2++){
T1CONbits.TON=1; TMR1 = 0x0000;
PR1 = 0x0006;IFS0bits.T1IF=0;
while (!IFS0bits.T1IF){}
COUNT1++;if(((SPITX>>(((length/2)-1)-COUNT))&0x0001)==1)
{LATEbits.LATE2 = 1; //Latch bit for RE2 port pin}
else
{LATEbits.LATE2 = 0; //Latch bit for RE2 port pin}
if(PORTEbits.RE3&&(COUNT2<length)){ LATEbits.LATE3 = 0; //Clear bit for RE3 port pin}
else
{LATEbits.LATE3 = 1; //Latch bit for RE3 port pin}
if (COUNT1==2){COUNT++;COUNT1=0;}
}
}
/***********************************************ENTRÉE DANS LA ROUTINE DE TRANSMISSION*********************************************
RÉCEPTION DE LA CHARGE
***********************************************************************************************************************************/void RXLoadC(void){
unsigned char COUNT=0;unsigned char COUNT1=0;unsigned char COUNT2=0;
LATEbits.LATE2 = 0; //Clear Latch bit for RE2 port pin //DATAOUT LATEbits.LATE3 = 0; //Latch bit for RE3 port pin //SPICLK
T1CONbits.TON=1; TMR1 = 0x0000;
PR1 = 0x0006;
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\SPI_LoadCell.c
IFS0bits.T1IF=0; //Start Timer 1 LCSPIRX=0x0000;
for (COUNT2=0; COUNT2<31; COUNT2++){while(!IFS0bits.T1IF)
{}
COUNT1++;
if(PORTEbits.RE3){ LATEbits.LATE3 = 0; //Clear bit for RE3 port pin}
else {LATEbits.LATE3 = 1; //Latch bit for RE3 port pin}
if(PORTEbits.RE4&&(COUNT2<32)&&(COUNT1<2)){ LCSPIRX=LCSPIRX+(1<<(15-COUNT)); }
if (COUNT1==2){COUNT++;COUNT1=0;}
}
}
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\TimeScan(1).c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"#include "math.h"
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/
extern unsigned int TimeScan;
/*****************************************************************************************************DÉCLARATION DES FONCTIONS UTILISÉES SUR CETTE FEUILLE*****************************************************************************************************/void Timer2_Init(void);void GetTimeScan(void);
/*****************************************ENTRÉE DANS LA ROUTINE D'INITIALISATION DES TIMERS***************************************
CETTE ROUTINE PERMET D'INITIALISER LES PARAMÈTRES NÉCÉSSAIRE AU BON FONCTIONNEMENT DES TIMERS
***********************************************************************************************************************************/void Timer2_Init(void){
T2CON = 0b0000000000011000; //TCKPS1 Timer2 set up to count on instruction cycle //0123456789012345 //edge with 1:8 prescaler applied initially. PR2 = 0xFFFF; //Period Register, PR2, set to maximum count PR3 = 0xFFFF; //Period Register, PR3, set to maximum count
TMR3HLD = 0x0000;TMR2 = 0x0000;
IFS0bits.T2IF = 0; //Clear the Timer2 Interrupt Flag IEC0bits.T2IE = 0; //Enable Timer1 Interrupt Service Routine IFS0bits.T3IF = 0; //Clear the Timer3 Interrupt Flag IEC0bits.T3IE = 0; //Enable Timer1 Interrupt Service Routine
T2CONbits.TON = 0; //Stop Timer 2}
/********************************ENTRÉE DANS LA ROUTINE QUI CALCUL LE TEMPS DE SCAN DE CHAQUE BOUCLE********************************
CETTE ROUTIME PERMET LE CALCUL DU TEMPS DE SCAN DE CHAQUE BOUCLE EN MILLISECONDE
***********************************************************************************************************************************/void GetTimeScan(void){unsigned long temp1=0;unsigned long temp2=0;float temp3=0;
temp2=TMR2;temp1=TMR3HLD;
//7.3728*8/4 MHz/8 = 1843200Hztemp3 = (temp2*0.0005425); //(1000/1843200 clk/s )=0.0005425 (*1000 (ms))
if(temp3>=65535){TimeScan=0xFFFF;}else
{TimeScan=(temp3*100); //Timescan (XXXX) = temp3 (XX,XX) ms }
PR2 = 0xFFFF; //Period Register, PR2, set to maximum count PR3 = 0xFFFF; //Period Register, PR2, set to maximum count
TMR3HLD = 0x0000;TMR2 = 0x0000;
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\TimeScan(1).c
T2CONbits.TON = 0; //Stop Timer 2 IFS0bits.T3IF = 0; //Clear the Timer3 Interrupt Flag IFS0bits.T2IF = 0; //Clear the Timer2 Interrupt Flag
T2CONbits.TON = 1; //Start Timer 2}
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART_BON.c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"#include <uart.h>
#define BAUDRATE 38400 //Desired Baud Rate#define BRGVAL ((FCY/BAUDRATE)/16)-1 //Formula for U1BRG register //from dsPIC30F Family //Reference Manual
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME ET UTILISÉ DANS CETTE FEUILLE*****************************************************************************************************/extern unsigned char DisplayData[];extern unsigned char ReceivedData[];extern unsigned char PositionData[];
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/extern unsigned int RS;extern unsigned int PTR;extern unsigned int RXsel;extern unsigned int STAT_RECEI;
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À REÇU******************************************************************************************************/
void ConfigIntUART1(unsigned int config);void putsUART1(unsigned int *buffer);void WriteUART1(unsigned int data);void OpenUART1(unsigned int config1,unsigned int config2, unsigned int ubrg);
/*****************************************************************************************************DÉCLARATION DES FONCTIONS UTILISÉS SUR CETTE FEUILLE *****************************************************************************************************/void UART_Init (void);void WriteUART_to_RS232(void);void ReadUART_from_RS232(void);char BusyUART1(void);void CloseUART1(void);
/*****************************************************************************************************DÉCLARATION DES POINTEURS UTILISÉ SUR CETTE FEUILLE*****************************************************************************************************/unsigned int *UARTCharPtr;
/***********************************ENTRÉE DANS LA ROUTINE D'INITIALISATION DU PÉRIFÉRIQUE UART1**************************************
CETTE ROUTIME PERMET D'ENTRER LES PARAMÈTRES ADÉQUATS PERMETTANT LE FONCTIONNEMENT DE LA COMMUNICATION SÉRIE AVEC LE PÉRIFÉRIQUE UART1.
**************************************************************************************************************************************/void UART_Init (void){
unsigned int conf = 2; ConfigIntUART1(conf);
U1MODE = 0x0000; //Clear UART1 registers U1STA = 0x0000; U1MODEbits.ALTIO = 1; //Enable U1ATX and U1ARX
U1MODEbits.UARTEN = 1; //Enable UART1 module U1BRG = BRGVAL; //Load UART1 Baud Rate Generator
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART_BON.c
IFS0bits.U1RXIF = 0; //Clear UART1 Receiver Interrupt Flag IFS0bits.U1TXIF = 0; //Clear UART1 Transmitter Interrupt Flag IEC0bits.U1RXIE = 1; //Enable UART1 Receiver ISR IEC0bits.U1TXIE = 1; //Enable UART1 Transmitter ISR U1STAbits.UTXISEL = 1; //Setup UART1 transmitter to interrupt //when a character is transferred to the //Transmit Shift register and as result, //the transmit buffer becomes empty. U1STAbits.URXISEL =0; //Setup UART1 Receiver to interrupt //when a character is transferred to the //Transmit Shift register and as result, //the transmit buffer becomes empty.
U1STAbits.UTXEN = 1; //Enable UART1 transmitter UARTCharPtr = &DisplayData[0]; //Initialize UARTCharPtr to point //to the first character in the Display buffer
IFS0bits.U1TXIF = 0; //Clear the UART1 transmitter interrupt flagIFS0bits.U1RXIF = 0; //Clear the UART1 Receiver interrupt flag
}
/*****************************************ENTRÉE DANS LA ROUTINE DE TRANSMISSION SÉRIE RS-232***************************************
CETTE ROUTIME PERMET DE TRANMETTRE DES CHAÎNE DE CARACTÈRES AU VARIATEUR DE VITESSE.
***********************************************************************************************************************************/void WriteUART_to_RS232(void){
UARTCharPtr = &DisplayData[0]; //Initialize UARTCharPtr to pointputsUART1(UARTCharPtr);IFS0bits.U1TXIF = 0; //Clear the UART1 transmitter interrupt flag
}
/*********************************************************************** Function Name : ConfigIntUART1 ** Description : This function sets priority for RX,TX interrupt * * and enable/disables the interrupt ** Parameters : unsigned int config enable/disable and priority ** Return Value : None * **********************************************************************/void ConfigIntUART1(unsigned int config){ /* clear IF flags */ _U1RXIF = 0; _U1TXIF = 0;
/* set priority */ _U1RXIP = 0x0007 & config; _U1TXIP = (0x0070 & config) >> 4;
// /* enable/disable interrupt */ _U1RXIE = (0x0008 & config) >> 3; _U1TXIE = (0x0080 & config) >> 7;}
/************************************************************************** Function Name : BusyUART1 ** Description : This returns status whether the transmission ** is in progress or not, by checking Status bit TRMT ** Parameters : None ** Return Value : Info about whether transmission is in progress. **************************************************************************/
char BusyUART1(void){
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART_BON.c
return(!U1STAbits.TRMT);}
//----------------------------------------------------------------------------------------------------------------------------------------/********************************************************************** Function Name : CloseUART1 ** Description : This function disables the UART and clears the ** Interrupt enable & flag bits * * Parameters : None ** Return Value : None * *********************************************************************/
void CloseUART1(void){ U1MODEbits.UARTEN = 0;
IEC0bits.U1RXIE = 0; IEC0bits.U1TXIE = 0;
IFS0bits.U1RXIF = 0; IFS0bits.U1TXIF = 0;}
//----------------------------------------------------------------------------------------------------------------------------------------/**************************************************************************** Function Name : putsUART1 ** Description : This function puts the data string to be transmitted ** into the transmit buffer (till NULL character) ** Parameters : unsigned int * address of the string buffer to be * * transmitted ** Return Value : None ****************************************************************************/
void putsUART1(unsigned int *buffer){ char * temp_ptr = (char *) buffer;
/* LA TRANSMISSION SE FAIT JUSQU'À LA DÉTECTION D'UN CARACTÈRE NULL */
while(*temp_ptr != '\0') { while(U1STAbits.UTXBF); /* wait if the buffer is full */ U1TXREG = *temp_ptr++; /* transfer data byte to TX reg */ } }
//----------------------------------------------------------------------------------------------------------------------------------------/**************************************************************************** Function Name : ReadUART1 ** Description : This function returns the contents of UxRXREG buffer * * Parameters : None ** Return Value : unsigned int value from UxRXREG receive buffer ****************************************************************************/
unsigned int ReadUART1(void){ if(U1MODEbits.PDSEL == 3) return (U1RXREG); else return (U1RXREG & 0xFF);}
//----------------------------------------------------------------------------------------------------------------------------------------/********************************************************************** Function Name : WriteUART1 *
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART_BON.c
* Description : This function writes data into the UxTXREG, ** Parameters : unsigned int data the data to be written ** Return Value : None **********************************************************************/
void WriteUART1(unsigned int data){ while(U1STAbits.UTXBF)
{}
if(U1MODEbits.PDSEL == 3) U1TXREG = data; else
U1TXREG = data & 0xFF;}
//----------------------------------------------------------------------------------------------------------------------------------------//_U1TXInterrupt() is the UART1 Interrupt Service Routine.//The routine must have global scope in order to be an ISR.//The ISR name is the same name provided for the module in the device linker//script.void __attribute__((__interrupt__)) _U1TXInterrupt(void){ IFS0bits.U1TXIF = 0; //Clear the UART1 transmitter interrupt flag}
/*****************************************ENTRÉE DANS LA ROUTINE DE RÉCEPTION SÉRIE RS-232******************************************
CETTE ROUTIME PERMET DE RECEVOIR LES DONNÉES PROVENANT DU VARIATEUR DE VITESSE ET FONCTIONNE EN INTÉRUPTION.
***********************************************************************************************************************************/void __attribute__((__interrupt__)) _U1RXInterrupt(void){unsigned int temp=0;temp=U1RXREG;
if(RXsel==1) //Envoi la valeur recu dans posidata{
if(PTR<16 && temp!=13 && temp!=58){
PositionData[PTR]=temp; PTR=PTR+1;
}
if(PTR==16|| temp==13 || temp==58){
if(temp==13){STAT_RECEI=1;RXsel=0;}
PTR=0;
}}
if(RXsel==0){if(PTR<16 && temp!=13 && temp!=58)
{ ReceivedData[PTR]=temp; PTR=PTR+1;
}
if(PTR==16|| temp==13 || temp==58)
4
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART_BON.c
{
if(temp==13){RS = 1;}
PTR=0;}
}
IFS0bits.U1RXIF = 0; //Clear the UART1 Receiver interrupt flag}
5
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART2.c
///Pre-Processor Directives:#include <p30f4011.h>#include "system.h"#include <uart.h>.
#define BAUDRATE 921600 //Desired Baud Rate#define BRGVAL ((FCY/BAUDRATE)/16)-1 //Formula for U2BRG register //from dsPIC30F Family //Reference Manual
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR SEIZE BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 65535)*****************************************************************************************************/extern unsigned int RX2PTR;extern unsigned int PTR2;extern unsigned int Long;extern unsigned int DDD=0; extern unsigned int START; extern unsigned int STOP; extern unsigned int cons_ang_stat;extern unsigned int cons_load_stat;extern unsigned int cons_seuil_stat;
/**************************************************************************************************************DÉCLARATION DES VARIABLES SUR TRENTE-DEUX BITS NON SIGNÉS ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 4 294 967 295)**************************************************************************************************************/extern unsigned long RX2TEMP;extern unsigned long CONSLOAD;
/*****************************************************************************************************DÉCLARATION DES VARIABLES SUR HUIT BITS NON SIGNÉES ACCESSIBLE DANS TOUT LE PROGRAMME (0 À 255)*****************************************************************************************************/extern unsigned char TX2REFRESHVAL;
/*****************************************************************************************************DÉCLARATION DES CHAINES DE CARACTÈRES DISPONIBLES DANS TOUT LE PROGRAMME ET UTILISÉ DANS CETTE FEUILLE*****************************************************************************************************/extern unsigned char CONSIGNE[];extern unsigned char REFRESHVAL[];extern unsigned char consigne_posi[];extern unsigned char consigne_load[];extern unsigned char consigne_seuil[];extern unsigned char DisplayData[];
/*****************************************************************************************************DÉCLARATION DES FONCTIONS UTILISÉS SUR CETTE FEUILLE *****************************************************************************************************/void WriteUART2_to_RS232(void);void UART2_Init (void);
/******************************************************************************************************
DÉCLARATION DES FONCTIONS ACCESSIBLE PARTOUT DANS LE PROGRAMME AVEC VARIABLE À REÇU******************************************************************************************************/
void ConfigIntUART2(unsigned int config);void WriteUART2(unsigned int data);
/*****************************************************************************************************DÉCLARATION DES POINTEURS UTILISÉ SUR CETTE FEUILLE*****************************************************************************************************/unsigned int *UART2CharPtr;
//----------------------------------------------------------------------------------------------------------------------------------------//Functions//UART_Init() sets up the UART2 for a 8-bit data, No Parity, 1 Stop bit//at 38400 baud with transmitter interrupts enabled
1
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART2.c
//Port Alternate uart1 jumper sur H4 = 1 void UART2_Init (void){
unsigned int conf = 2; ConfigIntUART2(conf);
U2MODE = 0x0000; //Clear UART2 registers U2STA = 0x0000; U2MODEbits.ALTIO = 1; //Enable U2ATX and U2ARX U2MODEbits.UARTEN = 1; //Enable UART2 module U2BRG = BRGVAL; //Load UART2 Baud Rate Generator
IFS1bits.U2RXIF = 0; //Clear UART2 Receiver Interrupt Flag IFS1bits.U2TXIF = 0; //Clear UART2 Transmitter Interrupt Flag IEC1bits.U2RXIE = 1; //Enable UART2 Receiver ISR IEC1bits.U2TXIE = 1; //Enable UART2 Transmitter ISR U2STAbits.UTXISEL = 1; //Setup UART2 transmitter to interrupt //when a character is transferred to the //Transmit Shift register and as result, //the transmit buffer becomes empty. U2STAbits.URXISEL =0; //Setup UART2 Receiver to interrupt //when a character is transferred to the //Transmit Shift register and as result, //the transmit buffer becomes empty.
U2STAbits.UTXEN = 1; //Enable UART2 transmitter IFS1bits.U2TXIF = 0; //Clear the UART2 transmitter interrupt flag
IFS1bits.U2RXIF = 0; //Clear the UART2 Receiver interrupt flag
}//----------------------------------------------------------------------------------------------------------------------------------------/*********************************************************************** Function Name : ConfigIntUART2 ** Description : This function sets priority for RX,TX interrupt * * and enable/disables the interrupt ** Parameters : unsigned int config enable/disable and priority ** Return Value : None * **********************************************************************/void ConfigIntUART2(unsigned int config){ /* clear IF flags */ _U2RXIF = 0; _U2TXIF = 0;
/* set priority */ _U2RXIP = 0x0007 & config; _U2TXIP = (0x0070 & config) >> 4;
// /* enable/disable interrupt */ _U2RXIE = (0x0008 & config) >> 3; _U2TXIE = (0x0080 & config) >> 7;}
/**********************************ENTRÉE DANS LA ROUTINE DE TRANSMISSION SÉRIE RS-232 (INTERFACE)**********************************
CETTE ROUTIME PERMET DE TRANMETTRE DES CHAÎNE DE CARACTÈRES A`L'INTERFACE DE CONTRÔLE.
***********************************************************************************************************************************/void WriteUART2_to_RS232(void){
UART2CharPtr = &REFRESHVAL[0]; //Initialize UARTCharPtr to pointputsUART2(UART2CharPtr);IFS1bits.U2TXIF = 0; //Clear the UART1 transmitter interrupt flag
}
2
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART2.c
/********************************************************************** Function Name : WriteUART2 ** Description : This function writes data into the UxTXREG, ** Parameters : unsigned int data the data to be written ** Return Value : None **********************************************************************/void WriteUART2(unsigned int data){ while(U2STAbits.UTXBF)
{}
if(U2MODEbits.PDSEL == 3) U2TXREG = data; else
U2TXREG = data & 0xFF;}//----------------------------------------------------------------------------------------------------------------------------------------//_U1TXInterrupt() is the UART2 Interrupt Service Routine.//The routine must have global scope in order to be an ISR.//The ISR name is the same name provided for the module in the device linker//script.void __attribute__((__interrupt__)) _U2TXInterrupt(void){ IFS1bits.U2TXIF = 0; //Clear the UART2 transmitter interrupt flag}
/***********************************ENTRÉE DANS LA ROUTINE DE RÉCEPTION SÉRIE RS-232 (INTERFACE)************************************
CETTE ROUTIME PERMET DE RECEVOIR LES DONNÉES PROVENANT DE L'INTERFACE DE CONTRÔLE EN INTÉRUPTION.
***********************************************************************************************************************************/void __attribute__((__interrupt__)) _U2RXInterrupt(void){
unsigned int temp=0;unsigned int d=0;temp=U2RXREG;
if(((PTR2<6) && (temp!=13) && (temp!=58))&&((temp==48) || (temp==49) || (temp==50) || (temp==51) || (temp==52) || (temp==53) || (temp==54) || (temp==55) || (temp==56) || (temp==57) || (temp==71) || (temp==76) || (temp==83) || (temp==70) || (temp==78) ||(temp==79)))
{ CONSIGNE[PTR2]=temp; PTR2=PTR2++;}
if(temp==13) // Longueur ou : ou <cr>{
if(CONSIGNE[0]==0x47) // Permet de négliger les deux points{
cons_ang_stat=1;Long = PTR2;PTR2 = 0;//Long=4-RX2PTR;
}if(CONSIGNE[0]==0x4C){
cons_load_stat=1;Long = PTR2;PTR2 = 0;//Long=4-RX2PTR;
}if(CONSIGNE[0]==0x53){
cons_seuil_stat=1;Long = PTR2;PTR2 = 0;
3
C:\Users\Ben\Desktop\Ecole_2\Projet de conception 5 Crédits\Code final CEME New\Code final CEME\UART2.c
//Long=4-RX2PTR;}if((CONSIGNE[0]==0x4F) && (CONSIGNE[1]==0x4E) && (CONSIGNE[2]==0x4E)){
START = 1;PTR2 = 0;
}if((CONSIGNE[0]==0x4F) && (CONSIGNE[1]==0x46) && (CONSIGNE[2]==0x46)){
STOP = 1;PTR2 = 0;
}
}
if(temp==58){PTR2=0;}
IFS1bits.U2RXIF = 0;}
//**********************************************************************************************************************//putsUART2//**********************************************************************************************************************void putsUART2(unsigned int *buffer2){ char * temp_ptr2 = (char *) buffer2;
/* LA TRANSMISSION SE FAIT JUSQU'À LA DÉTECTION D'UN CARACTÈRE NULL */
while(*temp_ptr2 != '\0') { while(U2STAbits.UTXBF); /* wait if the buffer is full */ U2TXREG = *temp_ptr2++; /* transfer data byte to TX reg */ } }
4