Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Le_Pont_V10116 by
Revision 0:8b3c6f593515, committed 2017-06-22
- Comitter:
- CS
- Date:
- Thu Jun 22 09:33:04 2017 +0000
- Commit message:
- V10116 initiale
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Constantes.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,192 @@ +//***********************************************************************************/ +// +// Constantes Pont Bacalan +// +//************************************************************************************/ +#ifndef _CONST_ +#define _CONST_ + +typedef char U8 ; +typedef short S16 ; +typedef unsigned short U16 ; +typedef float F32 ; +typedef int S32 ; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define REG_INPUT_START 0 +#define REG_INPUT_NREGS 260 +#define SLAVE_ID 0x01 + +#define EPSILON 1E-9 + +#define ARRET 0 +#define MONTE 1 +#define DESCEND 2 + +#define MODE_ARRET 0 +#define MODE_MANUEL 1 +#define MODE_AUTOMATIQUE 2 +#define MODE_PARAMETRAGE 3 +#define MODE_ETALONNAGE 4 +#define MODE_ALIGNEMENT 5 + +#define AUCUN 0 +#define DEUX_VITESSES 1 +#define RD_SUIT_RG 2 +#define RG_SUIT_RD 3 +#define CUSTOM 4 + +#define TAILLE_TABLEAU_HAUTEURS 6 + +#define Version_Soft Memoire_S16[1] + +// Boutons +#define BTN_Arret Memoire_S16[120] +#define BTN_Monte Memoire_S16[121] +#define BTN_Descend Memoire_S16[122] +#define BTN_Etalonnage Memoire_S16[140] + + +#define BTN_Monte_RD Memoire_S16[125] +#define BTN_Descend_RD Memoire_S16[126] + +#define BTN_Monte_RG Memoire_S16[130] +#define BTN_Descend_RG Memoire_S16[131] + + +#define BTN_Frein Memoire_S16[141] +#define BTN_Aligne Memoire_S16[142] + +//Temps de scrutation +#define Duree_Boucle_us Memoire_S16[2] +#define Periode_Scrutation_ms Memoire_S16[3] + +//Modes de fonctionnement +#define Mode_Fonctionnement Memoire_S16[15] +#define Mode_Synchro Memoire_S16[16] + +//Informations rive droite +#define Etat_RD Memoire_S16[20] +#define Hauteur_RD Memoire_S16[21] +#define Vitesse_RD Memoire_S16[22] +#define Couple_RD Memoire_S16[23] +#define Acceleration_RD Memoire_S16[24] +#define Mesure_RD Memoire_S16[25] +#define Etat_COM_RD Memoire_S16[26] +#define Compteur_Timeout_RD Memoire_S16[27] +#define Consigne_Vitesse_RD Memoire_S16[28] +#define Consigne_Hauteur_RD Memoire_S16[29] + +#define Hauteur_RD1_mm Memoire_S16[35] +#define Hauteur_RD2_mm Memoire_S16[36] +#define Hauteur_RD1_pts Memoire_S16[37] +#define Hauteur_RD2_pts Memoire_S16[38] + +//Informations rive gauche +#define Etat_RG Memoire_S16[40] +#define Hauteur_RG Memoire_S16[41] +#define Vitesse_RG Memoire_S16[42] +#define Couple_RG Memoire_S16[43] +#define Acceleration_RG Memoire_S16[44] +#define Mesure_RG Memoire_S16[45] +#define Etat_COM_RG Memoire_S16[46] +#define Compteur_Timeout_RG Memoire_S16[47] +#define Consigne_Vitesse_RG Memoire_S16[48] +#define Consigne_Hauteur_RG Memoire_S16[49] + +#define Hauteur_RG1_mm Memoire_S16[55] +#define Hauteur_RG2_mm Memoire_S16[56] +#define Hauteur_RG1_pts Memoire_S16[57] +#define Hauteur_RG2_pts Memoire_S16[58] + +//Informations pont +#define Etat_P Memoire_S16[60] +#define Hauteur_P Memoire_S16[61] +#define Vitesse_P Memoire_S16[62] +#define Couple_P Memoire_S16[63] +#define Acceleration_P Memoire_S16[64] + +#define Consigne_Vitesse_Manu Memoire_S16[67] +#define Consigne_Vitesse_Auto Memoire_S16[68] +#define Consigne_Haute_P Memoire_S16[69] +#define Consigne_Basse_P Memoire_S16[70] + +#define Anticipation_Synchro Memoire_S16[80] +#define KP_Synchro Memoire_S16[81] +#define KI_Synchro Memoire_S16[82] +#define KD_Synchro Memoire_S16[83] + + +#define Hauteur_mini Memoire_S16[100] +#define Hauteur_maxi Memoire_S16[101] +#define Vitesse_mini Memoire_S16[102] +#define Vitesse_maxi Memoire_S16[103] + +#define Ecart_Synchronisation Memoire_S16[110] +#define Defaut_Mineur_Synchro Memoire_S16[111] +#define Defaut_Majeur_Synchro Memoire_S16[112] +#define Defaut_Critique_Synchro Memoire_S16[113] +#define Correction_Synchro Memoire_S16[114] + +//Parametres variateur rive droite +#define Param_Version_RD Memoire_S16[150] +#define Param_Startup_RD Memoire_S16[151] +#define Param_Increment_RD Memoire_S16[152] +#define Param_Seuil_Demarrage_RD Memoire_S16[153] +#define Param_Acceleration_RD Memoire_S16[154] +#define Param_Deceleration_RD Memoire_S16[155] +#define Param_Kpv_RD Memoire_S16[156] +#define Param_Kiv_RD Memoire_S16[157] +#define Param_Kdv_RD Memoire_S16[158] +#define Param_Kav_RD Memoire_S16[159] +#define Param_Consigne_RD Memoire_S16[160] + +//Parametres variateur rive gauche +#define Param_Version_RG Memoire_S16[200] +#define Param_Startup_RG Memoire_S16[201] +#define Param_Increment_RG Memoire_S16[202] +#define Param_Seuil_Demarrage_RG Memoire_S16[203] +#define Param_Acceleration_RG Memoire_S16[204] +#define Param_Deceleration_RG Memoire_S16[205] +#define Param_Kpv_RG Memoire_S16[206] +#define Param_Kiv_RG Memoire_S16[207] +#define Param_Kdv_RG Memoire_S16[208] +#define Param_Kav_RG Memoire_S16[209] +#define Param_Consigne_RG Memoire_S16[210] + +//Commandes de sauvegarde mémoire +#define Sauver_Vers_Flash Memoire_S16[245] + +//Autres paramètres +#define Sauvegarde_automatique Memoire_S16[246] +#define Etalonnage_effectue Memoire_S16[247] +#define Etalonnage_en_cours Memoire_S16[248] +#define RAZ Memoire_S16[249] +#define Mode_Debug Memoire_S16[250] + + +#endif + + + + + + + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Gemma.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,315 @@ +//****************************************************************** +// +// Gemma +// +// Logiciel de gestion des modes de marche et d'arret du Pont Bacalan +// +// +// +//******************************************************************** + +#include "Gemma.h" + +Serial PC3(USBTX, USBRX) ; +// Chronomètre +Timer Chrono_Param ; +AnalogOut Consigne_aout (p18) ; + +U8 No_Parametre ; +S16 *pParametres_Console_RG ; +S16 *pParametres_Console_RD ; + +void vGemma_Init () + { + Chrono_Param.start () ; + pParametres_Console_RG = &Param_Version_RG ; + pParametres_Console_RD = &Param_Version_RD ; + No_Parametre = 0 ; + Consigne_aout.write ( 0.0 ) ; + } + +void vGemma ( Pilote* pRive_Droite , Pilote* pRive_Gauche ) + { + // Fonctionnement des differents modes + PC3.printf("\r\n Mode: %i", Mode_Fonctionnement) ; + if ( Mode_Fonctionnement == MODE_MANUEL ) + // En mode manuel, pas d'action maintenue, les 2 rives sont indépendantes + { + //Raz des parametres de synchronisation + vSynchro_Initialise ( ) ; + + if ( BTN_Monte_RD ) + {// Montée rive droite + if ( ( Hauteur_RD - Hauteur_RG ) < Defaut_Critique_Synchro ) + { + PC3.printf("\t Monte RD") ; + pRive_Droite->Marche ( MODE_MANUEL, MONTE, Hauteur_maxi , Consigne_Vitesse_Manu ) ; + } + BTN_Descend_RD = 0 ; + } + else if ( BTN_Descend_RD ) + {// Descente rive droite + if ( ( Hauteur_RG - Hauteur_RD ) < Defaut_Critique_Synchro ) + { + PC3.printf("\t Descend RD") ; + pRive_Droite->Marche ( MODE_MANUEL, DESCEND, Hauteur_mini , Consigne_Vitesse_Manu ) ; + } + BTN_Monte_RD = 0 ; + } + else + {// Arrêt rive droite + pRive_Droite->Arret() ; + BTN_Descend_RD = 0 ; + BTN_Monte_RD = 0 ; + //PC3.printf("\r\n Arret RD") ; + } + if ( BTN_Monte_RG ) + {// Montée rive gauche + if ( ( Hauteur_RG - Hauteur_RD ) < Defaut_Critique_Synchro ) + { + PC3.printf("\t Monte RG") ; + pRive_Gauche->Marche ( MODE_MANUEL, MONTE, Hauteur_maxi , Consigne_Vitesse_Manu ) ; + Consigne_aout.write ( (F32) Consigne_Vitesse_Manu / V_MAX ) ; + } + BTN_Descend_RG = 0 ; + } + else if ( BTN_Descend_RG ) + {// Descente rive gauche + if ( ( Hauteur_RD - Hauteur_RG ) < Defaut_Critique_Synchro ) + { + PC3.printf("\t Descend RG") ; + pRive_Gauche->Marche ( MODE_MANUEL, DESCEND, Hauteur_mini , Consigne_Vitesse_Manu ) ; + Consigne_aout.write ( (F32) Consigne_Vitesse_Manu / V_MAX ) ; + } + BTN_Monte_RG = 0 ; + } + else + {// Arret rive gauche + pRive_Gauche->Arret() ; + BTN_Monte_RG = 0 ; + BTN_Descend_RG = 0 ; + Consigne_aout.write ( 0.0 ) ; + //PC3.printf("\r\n Arret RG") ; + } + if ( BTN_Frein ) + {// Liberation des freins + if ( !BTN_Monte_RG && !BTN_Descend_RG && !!BTN_Monte_RD && !BTN_Descend_RD ) + { + if (pRive_Gauche->Etat_Frein == SERRE ) pRive_Gauche->Frein( DESSERRE ) ; + if (pRive_Droite->Etat_Frein == SERRE ) pRive_Droite->Frein( DESSERRE ) ; + } + } + else + {// Serrage des freins + if ( !BTN_Monte_RG && !BTN_Descend_RG && !!BTN_Monte_RD && !BTN_Descend_RD ) + { + if (pRive_Gauche->Etat_Frein == DESSERRE ) pRive_Gauche->Frein( SERRE ) ; + if (pRive_Droite->Etat_Frein == DESSERRE ) pRive_Droite->Frein( SERRE ) ; + } + } + } + + else if ( Mode_Fonctionnement == MODE_AUTOMATIQUE ) + {// En mode automatique, les rives sont synchronisées, avec consigne de vitesse et hauteur cible + if ( BTN_Arret ) + {// Arret du pont + BTN_Monte = 0 ; + BTN_Descend = 0 ; + BTN_Arret = 0 ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + Consigne_aout.write ( 0.0 ) ; + + vSynchro_Initialise ( ) ; + + //PC3.printf("\r\n Btn Arret") ; + } + else + {// Vérification de l'ecart de synchronisation: différence de hauteur entre droite et gauche + if ( abs( Hauteur_RD - Hauteur_RG ) > Defaut_Critique_Synchro ) + {// Si l'ecart depasse le seuil critique: on arrete tout! + BTN_Arret = 0 ; + BTN_Descend = 0 ; + BTN_Monte = 0 ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + Consigne_aout.write ( 0.0 ) ; + PC3.printf("\r\n Defaut Critique") ; + } + else if ( BTN_Monte ) + {// Si on est en haut + if ( ( Hauteur_P >= Consigne_Haute_P ) + ||( Hauteur_RD >= Consigne_Haute_P ) + ||( Hauteur_RG >= Consigne_Haute_P ) ) + { + BTN_Monte = 0 ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + PC3.printf("\r\n En Haut") ; + } + else + {// Montée + PC3.printf("\t Monte Auto mode: %i", Mode_Synchro) ; + vSynchronise ( Mode_Synchro , MONTE ) ; + pRive_Droite->Marche ( MODE_AUTOMATIQUE, MONTE, Consigne_Haute_P , Consigne_Vitesse_RD ) ; + pRive_Gauche->Marche ( MODE_AUTOMATIQUE, MONTE, Consigne_Haute_P , Consigne_Vitesse_RG ) ; + Consigne_aout.write ( (F32) Consigne_Vitesse_RG / V_MAX ) ; + } + + BTN_Arret = 0 ; + BTN_Descend = 0 ; + } + else if ( BTN_Descend ) + { + if ( ( Hauteur_P <= Consigne_Basse_P ) + ||( Hauteur_RD <= Consigne_Basse_P ) + ||( Hauteur_RG <= Consigne_Basse_P ) ) + {// Si on est en bas + BTN_Descend = 0 ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + PC3.printf("\r\n En Bas") ; + } + else + {// Descente du pont + PC3.printf("\t Descend Auto") ; + PC3.printf("\t Descend Auto mode: %i", Mode_Synchro) ; + vSynchronise ( Mode_Synchro , DESCEND ) ; + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + + pRive_Droite->Marche ( MODE_AUTOMATIQUE, DESCEND, Consigne_Basse_P , Consigne_Vitesse_RD ) ; + pRive_Gauche->Marche ( MODE_AUTOMATIQUE, DESCEND, Consigne_Basse_P , Consigne_Vitesse_RG ) ; + Consigne_aout.write ( (F32) Consigne_Vitesse_RG / V_MAX ) ; + } + + BTN_Arret = 0 ; + BTN_Monte = 0 ; + } + + else + { + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + Consigne_aout.write ( 0.0 ) ; + } + } + } + else if ( Mode_Fonctionnement == MODE_PARAMETRAGE ) + {// En mode parametrage, + //PC3.printf("\r\n No Param = %i " , No_Parametre) ; + + if ( Chrono_Param.read_ms() > PERIODE_MAJ_PARAM ) + { + Chrono_Param.reset () ; + // Vérifie si le dernier parametre lu est a jour + if ( *(pParametres_Console_RG + No_Parametre ) != (S16) ( pRive_Gauche->Parametres_Vario_S32 [ No_Parametre ] ) ) + {// Sinon, on l'écrit dans le variateur + PC3.printf("\r\n No Param RG= %i - %i " , *(pParametres_Console_RG + No_Parametre ) , pRive_Gauche->Parametres_Vario_S32 [ No_Parametre ] ) ; + pRive_Gauche->Configure ( No_Parametre , (S32) *(pParametres_Console_RG + No_Parametre ) ) ; + } + // Vérifie si le dernier parametre lu est a jour + if ( *(pParametres_Console_RD + No_Parametre ) != (S16) ( pRive_Droite->Parametres_Vario_S32 [ No_Parametre ] ) ) + {// Sinon, on l'écrit dans le variateur + PC3.printf("\r\n No Param RD= %i - %i " , *(pParametres_Console_RD + No_Parametre ) , pRive_Droite->Parametres_Vario_S32 [ No_Parametre ] ) ; + pRive_Droite->Configure ( No_Parametre , (S32) *(pParametres_Console_RD + No_Parametre ) ) ; + } + No_Parametre++ ; + if ( No_Parametre >= NB_PARAM_VARIATEUR ) + { + No_Parametre = 0 ; + } + // Lecture du parametre suivant + pRive_Gauche->Lecture ( No_Parametre ) ; + pRive_Droite->Lecture ( No_Parametre ) ; + + } + + } + else if ( Mode_Fonctionnement == MODE_ETALONNAGE ) + {// Etalonnage + if ( BTN_Etalonnage ) + { + pRive_Droite->Etalonnage (Hauteur_RD1_pts , Hauteur_RD1_mm , Hauteur_RD2_pts , Hauteur_RD2_mm ) ; + pRive_Gauche->Etalonnage (Hauteur_RG1_pts , Hauteur_RG1_mm , Hauteur_RG2_pts , Hauteur_RG2_mm ) ; + BTN_Etalonnage = 0 ; + wait(0.1) ; + } + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + } + + else if ( Mode_Fonctionnement == MODE_ALIGNEMENT ) + { + if ( BTN_Aligne) + {// Alignement des hauteurs de pile pour le mode automatique + if ( abs( Hauteur_RD - Hauteur_RG ) < Defaut_Mineur_Synchro / 2 ) + {// Si l'ecart de hauteur est faible, on arrête tout + BTN_Aligne = 0 ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + PC3.printf("\r\n Aligne") ; + } + else if ( Hauteur_RD > Hauteur_RG ) + {// La pile droite est plus haute + if ( Hauteur_RD > Consigne_Basse_P ) + {// On descend la pile droite + Consigne_Vitesse_RD = Consigne_Vitesse_Manu ; + pRive_Droite->Marche ( MODE_AUTOMATIQUE, DESCEND, Hauteur_RG , Consigne_Vitesse_RD ) ; + } + else + { + pRive_Droite->Arret() ; + } + if ( Hauteur_RG < Consigne_Haute_P ) + {// On monte la pile gauche + Consigne_Vitesse_RG = Consigne_Vitesse_Manu ; + pRive_Gauche->Marche ( MODE_AUTOMATIQUE, MONTE, Hauteur_RD , Consigne_Vitesse_RG ) ; + } + else + { + pRive_Gauche->Arret() ; + } + } + else if ( Hauteur_RD < Hauteur_RG ) + {// La pile gauche est plus haute + if ( Hauteur_RD < Consigne_Haute_P ) + {// On monte la pile droite + Consigne_Vitesse_RD = Consigne_Vitesse_Manu ; + pRive_Droite->Marche ( MODE_AUTOMATIQUE, MONTE, Hauteur_RG , Consigne_Vitesse_RD ) ; + } + else + { + pRive_Droite->Arret() ; + } + if ( Hauteur_RG > Consigne_Basse_P ) + {// On descend la pile gauche + Consigne_Vitesse_RG = Consigne_Vitesse_Manu ; + pRive_Gauche->Marche ( MODE_AUTOMATIQUE, DESCEND, Hauteur_RD , Consigne_Vitesse_RG ) ; + + } + else + { + pRive_Gauche->Arret() ; + } + } + } + else + { + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + } + } + else + // Si le mode est inconnu, mode arret! + { + Mode_Fonctionnement = MODE_ARRET ; + pRive_Droite->Arret() ; + pRive_Gauche->Arret() ; + BTN_Arret = 1 ; + BTN_Monte = 0 ; + BTN_Descend = 0 ; + Consigne_aout.write ( 0.0 ) ; + PC3.printf("\r\n Mode Inconnu") ; + } + } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Gemma.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,26 @@ +//****************************************************************** +// +// Gemma +// +// Logiciel de gestion des modes de marche et d'arret du Pont Bacalan +// +// +// +//******************************************************************** +#ifndef _Gemma_ +#define _Gemma_ + +#include "mbed.h" + +#include "Constantes.h" +#include "Variable.h" +#include "Pilote.h" +#include "Synchronisation.h" + +#define PERIODE_MAJ_PARAM 50 +#define V_MAX 3260 + +extern void vGemma_Init () ; +extern void vGemma ( Pilote* Rive_Droite , Pilote* Rive_Gauche ); + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,263 @@ +/***********************************************************************************/ +// +// Gestion du Modbus +// +//************************************************************************************/ + +#include <mbed.h> +#include "Modbus.h" +#include "Port_Serie.h" + + +//volatile U8 Numero_Ordre_En_Cours_U8 ; +volatile Ordre_Modbus_t Ordres[TAILLE_PILE_ORDRES] ; + + +Serial PC7(USBTX, USBRX) ; + +/************ Initialisation du Modbus ************************/ +void vModbus_Init(int Baudrate) + { + U8 Numero_Ordre_U8 ; + + vPort_Serie_Init( Baudrate ) ; + + for ( Numero_Ordre_U8 = 0 ; Numero_Ordre_U8 < TAILLE_PILE_ORDRES ; Numero_Ordre_U8++ ) + { + // Effacement des ordres + Ordres[Numero_Ordre_U8].Etat_U8 = ARRET ; + Ordres[Numero_Ordre_U8].Nb_Caracteres_Recus_U8 = 0 ; + Ordres[Numero_Ordre_U8].Nb_Caracteres_A_Emettre_U8 = 0 ; + Ordres[Numero_Ordre_U8].Code_Erreur = 0 ; + } + + + PC7.printf("\r\n Modbus : Init ") ; + } + + +/************* Demarrage du Modbus ****************************/ +void vModbus_Start() + { + //Ordres[Numero_Ordre_En_Cours_U8].Etat_U8 = ATTENTE ; + vPort_Serie_Ouvre() ; + //vPort_Serie_Reception ( 0 ) ; + PC7.printf("\r\n Modbus : Start ") ; + } + +static const U8 aucCRCHi[] = { + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40 +}; + +static const U8 aucCRCLo[] = { + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, + 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, + 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, + 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, + 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, + 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, + 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, + 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, + 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, + 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, + 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, + 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, + 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, + 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, + 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, + 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, + 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, + 0x41, 0x81, 0x80, 0x40 +}; + + +U16 CRC16( U8 * pucFrame, U8 usLen ) +{ + U8 ucCRCHi = 0xFF; + U8 ucCRCLo = 0xFF; + int iIndex; + + while( usLen-- ) + { + //PC7.printf("/ %X /", *pucFrame) ; + iIndex = ucCRCLo ^ *( pucFrame++ ); + ucCRCLo = ( U8 )( ucCRCHi ^ aucCRCHi[iIndex] ); + ucCRCHi = aucCRCLo[iIndex]; + } + //PC7.printf("\n\r CRC: %X",(ucCRCHi << 8 | ucCRCLo)) ; + return ( U16 )( ucCRCHi << 8 | ucCRCLo ); +} + +/************* Traitement du Modbus ****************************/ +void vModbus() + { + U8 Numero_Ordre_U8 ; + U16 Valeur_U16 ; + U8 Ordres_Arretes_U8 = 0 ; + U8 Index_CRC_U8 ; + U8 Index_Caractere_U8 ; + U16 Index_Memoire_U16 ; + + for ( Numero_Ordre_U8 = 0 ; Numero_Ordre_U8 < TAILLE_PILE_ORDRES ; Numero_Ordre_U8++ ) + { + + if ( Ordres[Numero_Ordre_U8].Etat_U8 == RECU ) + {// Puisque la trame est complete, on peut la traiter + //PC7.printf("\n\rOrdre : %i recu",Numero_Ordre_U8) ; + if ( Numero_Ordre_U8 < ( TAILLE_PILE_ORDRES - 1 ) ) + {// Enclenche l'ordre suivant + vPort_Serie_Reception ( Numero_Ordre_U8 + 1 ) ; + } + else + {// Enclenche l'ordre 0 + vPort_Serie_Reception ( 0 ) ; + } + // Adresse + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[0] = SLAVE_ID ; + // Fonction + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[1] = Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1] ; + + if (( Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1] == MB_FUNC_READ_HOLDING_REGISTER ) + || ( Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1] == MB_FUNC_READ_INPUT_REGISTER )) + {// Fonction 3 ou 4, Lecture de registres + // Nombre d'octets + //PC7.printf("\n\rOrdre Func: %i",Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1]) ; + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[2] = 2 * Ordres[Numero_Ordre_U8].Trame_Recue_aU8[5] ; + // Registre de départ = Hi * 256 + Lo + Base + Index_Memoire_U16 = REG_INPUT_START + (U16)(Ordres[Numero_Ordre_U8].Trame_Recue_aU8[2]) * 256 + + (U16)Ordres[Numero_Ordre_U8].Trame_Recue_aU8[3] ; + //PC7.printf("\r\n %i :",Index_Memoire_U16) ; + Index_Caractere_U8 = 0 ; + while ( Index_Caractere_U8 < Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[2] ) + { + // Octet de poids fort du registre + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_Caractere_U8 + 3] = (U8) (Memoire_S16 [ Index_Memoire_U16 ] >> 8 ) ; + // Octet de poids faible + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_Caractere_U8 + 4] = (U8) ( Memoire_S16 [ Index_Memoire_U16 ] & 0xFF ) ; + //PC7.printf("/ %X / %X /",Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_Caractere_U8 + 3],Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_Caractere_U8 + 4]) ; + Index_Caractere_U8 = Index_Caractere_U8 + 2 ; + Index_Memoire_U16++ ; + } + + // Calcul de la position du CRC + Index_CRC_U8 = 3 + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[2] ; + // Calcul du CRC + Valeur_U16 = CRC16 ( (U8 *) &(Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[0]) , Index_CRC_U8 ) ; + + // CRC Poids fort + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_CRC_U8 ] = (U8) ( Valeur_U16 & 0xFF ) ; + // CRC Poids faible + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_CRC_U8 + 1 ] = (U8) ( Valeur_U16 >> 8 ) ; + // Longueur de trame à emettre + Ordres[Numero_Ordre_U8].Nb_Caracteres_A_Emettre_U8 = Index_CRC_U8 + 2 ; + } + else if ( Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1] == MB_FUNC_WRITE_MULTIPLE_REGISTERS ) + {// Fonction 16 (0x10) écriture multiple + //PC7.printf("\n\rOrdre Func: %i",Ordres[Numero_Ordre_U8].Trame_Recue_aU8[1]) ; + // Registre de départ poids fort + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[2] = Ordres[Numero_Ordre_U8].Trame_Recue_aU8[2] ; + // Registre de départ poids faible + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[3] = Ordres[Numero_Ordre_U8].Trame_Recue_aU8[3] ; + // Nombre de registres poids fort + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[4] = Ordres[Numero_Ordre_U8].Trame_Recue_aU8[4] ; + // Nombre de registres poids faible + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[5] = Ordres[Numero_Ordre_U8].Trame_Recue_aU8[5] ; + + // Registre de départ = Hi * 256 + Lo + Base + Index_Memoire_U16 = REG_INPUT_START + (U16)(Ordres[Numero_Ordre_U8].Trame_Recue_aU8[2]) * 256 + + (U16)Ordres[Numero_Ordre_U8].Trame_Recue_aU8[3] ; + Index_Caractere_U8 = 0 ; + while ( Index_Caractere_U8 < Ordres[Numero_Ordre_U8].Trame_Recue_aU8[6] ) + { + // Ecriture des registres + Memoire_S16 [ Index_Memoire_U16 ] = (S16) (Ordres[Numero_Ordre_U8].Trame_Recue_aU8[ 7 + Index_Caractere_U8 ]) * 256 + + (S16) Ordres[Numero_Ordre_U8].Trame_Recue_aU8[ 8 + Index_Caractere_U8 ]; + Index_Caractere_U8 = Index_Caractere_U8 + 2 ; + Index_Memoire_U16++ ; + + } + // Calcul du CRC + Valeur_U16 = CRC16 ( (U8 *) &(Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[0]) , 6 ) ; + // Calcul de la position du CRC + Index_CRC_U8 = 6 ; + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_CRC_U8] = (U8) ( Valeur_U16 & 0xFF ) ; + Ordres[Numero_Ordre_U8].Trame_Reponse_aU8[ Index_CRC_U8 + 1 ] = (U8) ( Valeur_U16 >> 8 ); + // Longueur de trame à emettre + Ordres[Numero_Ordre_U8].Nb_Caracteres_A_Emettre_U8 = 8 ; + } + // La trame de réponse est terminée + Ordres[Numero_Ordre_U8].Etat_U8 = TRAITE ; + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,TRAITE) ; + // Lancement de l'émission de la réponse + vPort_Serie_Emission ( Numero_Ordre_U8 ) ; + } + + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == FIN ) + {// La réponse est émise, cloture l'ordre + Ordres[Numero_Ordre_U8].Etat_U8 = ARRET ; + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,FIN) ; + } + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == EMISSION ) + {// L'emission de la réponse n'est pas terminée, re-essaie + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,EMISSION) ; + vPort_Serie_Emission ( Numero_Ordre_U8 ); + } + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == ARRET ) + {// Compte les ordres arretés + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,ARRET) ; + Ordres_Arretes_U8++ ; + } + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == RECEPTION ) + {// Controle si les temps ne sont pas dépassés + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,RECEPTION) ; + //Ordres[Numero_Ordre_U8].Etat_U8 = cControle_Reception( Numero_Ordre_U8 ); + } + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == ATTENTE ) + {// Controle si les temps ne sont pas dépassés + //PC7.printf("\n\rOrdre %i Etat: %i",Numero_Ordre_U8,ATTENTE) ; + } + else if ( Ordres[Numero_Ordre_U8].Etat_U8 == TIMEOUT ) + {// Les temps sont dépassés + Ordres[Numero_Ordre_U8].Etat_U8 = ARRET; + } + //PC7.printf("\r\n Modbus : %i \t %i \r\n",Numero_Ordre_U8,Ordres[Numero_Ordre_U8].Etat_U8 ); + } + if (Ordres_Arretes_U8 >= TAILLE_PILE_ORDRES ) + {// Si tous les ordres sont arretés, le prochain aura l'index 0 + vPort_Serie_Reception ( 0 ) ; + } + } + + extern void vModbus_Stop() + { + } + extern void vModbus_Reset() + { + } + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modbus.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,96 @@ +/*******************************************************************/ +/* */ +/* Modbus */ +/* */ +/* Gestion de la liaison Modbus esclave */ +/* */ +/* */ +/*******************************************************************/ +#ifndef _MODBUS_ +#define _MODBUS_ + +#include "mbed.h" +#include <Serial.h> + +#include "Constantes.h" +#include "Variable.h" + +#include "time.h" + + + +/***** Etats **********/ +#define ARRET 0 +#define ATTENTE 1 +#define RECEPTION 2 +#define RECU 3 +#define TRAITE 4 +#define EMISSION 5 +#define FIN 6 +#define ERREUR 7 +#define TIMEOUT 8 + +/* ----------------------- Defines ------------------------------------------*/ +#define MB_ADDRESSE_BROADCAST ( 0 ) /*! Modbus adresse de broadcast */ +#define MB_ADDRESSE_MIN ( 1 ) /*! Smallest possible slave address. */ +#define MB_ADDRESSE_MAX ( 247 ) /*! Biggest possible slave address. */ +#define MB_FUNC_NONE ( 0 ) +#define MB_FUNC_READ_COILS ( 1 ) +#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 ) +#define MB_FUNC_WRITE_SINGLE_COIL ( 5 ) +#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 ) +#define MB_FUNC_READ_HOLDING_REGISTER ( 3 ) +#define MB_FUNC_READ_INPUT_REGISTER ( 4 ) +#define MB_FUNC_WRITE_REGISTER ( 6 ) +#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 ) +#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 ) +#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 ) +#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 ) +#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 ) +#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 ) +#define MB_FUNC_ERROR ( 128 ) +/* ----------------------- Type definitions ---------------------------------*/ + typedef enum +{ + MB_EX_NONE = 0x00, + MB_EX_ILLEGAL_FUNCTION = 0x01, + MB_EX_ILLEGAL_DATA_ADDRESS = 0x02, + MB_EX_ILLEGAL_DATA_VALUE = 0x03, + MB_EX_SLAVE_DEVICE_FAILURE = 0x04, + MB_EX_ACKNOWLEDGE = 0x05, + MB_EX_SLAVE_BUSY = 0x06, + MB_EX_MEMORY_PARITY_ERROR = 0x08, + MB_EX_GATEWAY_PATH_FAILED = 0x0A, + MB_EX_GATEWAY_TGT_FAILED = 0x0B +} Code_Erreur_t ; + +#define TAILLE_MESSAGE_MAXI 20 + +typedef struct + { + U8 Etat_U8 ; + U8 Code_Erreur ; + U8 Trame_Recue_aU8 [TAILLE_MESSAGE_MAXI] ; + U8 Nb_Caracteres_Recus_U8 ; + U8 Trame_Reponse_aU8 [TAILLE_MESSAGE_MAXI] ; + U8 Nb_Caracteres_A_Emettre_U8 ; + } Ordre_Modbus_t ; + +#define TAILLE_PILE_ORDRES 5 + + + extern volatile Ordre_Modbus_t Ordres[TAILLE_PILE_ORDRES] ; + + + + extern void vModbus_Init(int Baudrate) ; + extern void vModbus_Start() ; + extern void vModbus_Stop() ; + extern void vModbus_Reset() ; + extern void vModbus() ; + + + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pilote.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,568 @@ +/*******************************************************************/ +/* */ +/* Pilote */ +/* */ +/* Objet de pilotage de variateur */ +/* */ +/* */ +/*******************************************************************/ + + +#include "Pilote.h" + +Serial PC2(USBTX, USBRX) ; +/** Class Pilote +* +*/ + + Pilote::Pilote ( S16 Id ) + { + Hauteur_Cible = 0 ; + Etat_Deplacement = ARRET ; + Chaine_A_Emettre[0] = 0 ; + pReception = &Chaine_Recue[0] ; + Nb_Caracteres_Recus = 0 ; + Statut_Ordre_En_Cours = AUCUN ; + + Parametres_Vario_S32 [ VERSION ] = 100 ; + Parametres_Vario_S32 [ STARTUP ] = 500 ; + Parametres_Vario_S32 [ INCREMENT ] = 20 ; + Parametres_Vario_S32 [ SEUIL_DEMARRAGE ] = 10 ; + Parametres_Vario_S32 [ ACCELERATION ] = 20 ; + Parametres_Vario_S32 [ DECELERATION ] = 20 ; + Parametres_Vario_S32 [ KPV ] = 1000 ; + Parametres_Vario_S32 [ KIV ] = 100 ; + Parametres_Vario_S32 [ KDV ] = 0 ; + Parametres_Vario_S32 [ KA ] = 1000 ; + Parametres_Vario_S32 [ CONSIGNE ] = 1500 ; + + }; + + +/*******************************************************************/ +/* */ +/* Init */ +/* */ +/* Initialisation de l'objet de pilotage de variateur */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Init ( int Baudrates , int bits , int Stop ) + { + U8 Index ; + // Initialisation du port série + pPort->baud ( Baudrates ); + pPort->format ( bits , Serial::None , Stop ) ; + + while ( pPort->readable() ) + { + // Réception des caractères pour vider le buffer + Index = pPort->getc() ; + } + // RAZ des chaines recues et à emettre + for ( Index=0 ; Index < LONGUEUR_CHAINE_EMISSION ; Index++ ) + { + Chaine_A_Emettre[Index] = 0 ; + } + for ( Index=0 ; Index < LONGUEUR_CHAINE_RECEPTION ; Index++ ) + { + Chaine_Recue[Index] = 0 ; + } + + Chrono_Pilote.start() ; + Chrono_Arret.start() ; + Debut_Emission_ms = Chrono_Pilote.read_ms () ; + COM_OK = TRUE ; + Compteur_Timeout = 0 ; + Dernier_Ordre_Confirme = ORDRE_ARRET ; + Etat_Deplacement = ARRET ; + + } + +/*******************************************************************/ +/* */ +/* Marche */ +/* */ +/* Ordre de marche automatique */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Marche ( U8 Mode, U8 Sens, S16 Hauteur , S16 Consigne_Vitesse ) + { + F32 Valeur_F32 ; + + // Construction de la trame de marche + Chaine_A_Emettre[0] = 0x02 ; + + if ( Sens == MONTE ) + { + Chaine_A_Emettre [1] = ORDRE_MONTE ; // M + Etat_Deplacement = MONTE ; + } + else + { + Chaine_A_Emettre [1] = ORDRE_DESCEND ; // D + Etat_Deplacement = DESCEND ; + } + + if ( Consigne_Vitesse > Vitesse_maxi ) + { + Consigne_Vitesse = Vitesse_maxi ; + } + else if ( Consigne_Vitesse < 0 ) + { + Consigne_Vitesse = 0 ; + } + Chaine_A_Emettre [2] = Consigne_Vitesse / 256 ; // Poids fort + Chaine_A_Emettre [3] = Consigne_Vitesse % 256 ; // Poids faible + + if ( Hauteur > Hauteur_maxi ) + { + Hauteur = Hauteur_maxi ; + } + else if ( Hauteur < Hauteur_mini ) + { + Hauteur = Hauteur_mini ; + } + + Hauteur_Cible = Hauteur ; + + //Calcul de la mesure à atteindre + Valeur_F32 = ( (F32) Hauteur - MM_Offset ) / MM_par_Points ; + + Chaine_A_Emettre [4] = (S16)Valeur_F32 / 256 ; // Poids fort + Chaine_A_Emettre [5] = (S16)Valeur_F32 % 256 ; // Poids faible + + Chaine_A_Emettre [6] = 0x03 ; + Chaine_A_Emettre [7] = 0x00 ; + + if( Statut_Ordre_En_Cours != ATTENTE ) + { + Ordre_En_Cours = Chaine_A_Emettre [1] ; + Emission ( &Chaine_A_Emettre [0] , 7 ) ; + Statut_Ordre_En_Cours = ATTENTE ; + + } + } + +/*******************************************************************/ +/* */ +/* Arret */ +/* */ +/* Ordre d'arret */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Arret (void) + { + Chaine_A_Emettre[0] = 0x02 ; + Chaine_A_Emettre[1] = ORDRE_ARRET ; + Chaine_A_Emettre[2] = 0x03 ; + Chaine_A_Emettre[3] = 0x00 ; + + //PC2.printf("\r\n Chrono %i: %i ms COM: %i \r\n" ,Id, Chrono_Arret.read_ms() , COM_OK ) ; + + if ( ( Dernier_Ordre_Confirme == ORDRE_ARRET ) + && ( Chrono_Arret.read_ms() > DELAI_COMMANDE_ARRET_ms ) + || ( Ordre_En_Cours != ORDRE_ARRET ) + || ( Statut_Ordre_En_Cours == DEFAUT )) + { + Chrono_Arret.reset() ; + Emission ( &Chaine_A_Emettre [0] , 3 ) ; + Etat_Deplacement = ARRET ; + Statut_Ordre_En_Cours = ATTENTE ; + Ordre_En_Cours = Chaine_A_Emettre [1] ; + } + else + { + //PC2.printf("\r\n Chrono %i: %i ms Ordre: %i \r\n" ,Id, Chrono_Arret.read_ms() , Ordre_En_Cours ) ; + } + + } +/*******************************************************************/ +/* */ +/* Etalonnage */ +/* */ +/* Ordre d'étalonnage de hauteur */ +/* */ +/* */ +/*******************************************************************/ + // Etalonnage de hauteur + void Pilote::Etalonnage (S16 Points1, S16 Hauteur1 , S16 Points2 , S16 Hauteur2 ) + { + F32 Valeur_F32 ; + + Valeur_F32 = (F32) ( Points2 - Points1 ) ; + + if ( abs( Valeur_F32 ) > EPSILON ) + { + MM_par_Points = (F32) ( Hauteur2 - Hauteur1 ) / Valeur_F32 ; + } + else + { + MM_par_Points = 0.0 ; + } + + MM_Offset = (F32)Hauteur1 - MM_par_Points * (F32)Points1 ; + + //PC2.printf("\r\n MM par pts %i: %f \r\n" ,Id, MM_par_Points) ; + //PC2.printf("\r\n Offset %i: %f \r\n" ,Id,MM_Offset) ; + + } +/*******************************************************************/ +/* */ +/* Frein */ +/* */ +/* Ordre d'activation du frein */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Frein ( U8 Etat ) + { + Chaine_A_Emettre[0] = 0x02 ; + Chaine_A_Emettre[1] = ORDRE_FREIN ; + Chaine_A_Emettre[2] = Etat ; + Chaine_A_Emettre[3] = 0x03 ; + Chaine_A_Emettre[4] = 0x00 ; + + if( Statut_Ordre_En_Cours != ATTENTE ) + { + Ordre_En_Cours = Chaine_A_Emettre [1] ; + Emission ( &Chaine_A_Emettre [0] , 4 ) ; + Statut_Ordre_En_Cours = ATTENTE ; + Etat_Frein = Etat ; + } + } +/*******************************************************************/ +/* */ +/* Lecture */ +/* */ +/* Ordre de lecture d'un parametre de variateur */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Lecture ( U16 Num_Parametre ) + { + Chaine_A_Emettre[0] = 0x02 ; + Chaine_A_Emettre[1] = ORDRE_LECTURE ; + Chaine_A_Emettre[2] = Num_Parametre ; + Chaine_A_Emettre[3] = 0x03 ; + Chaine_A_Emettre[4] = 0x00 ; + + if( Statut_Ordre_En_Cours != ATTENTE ) + { + Ordre_En_Cours = Chaine_A_Emettre [1] ; + Emission ( &Chaine_A_Emettre [0] , 4 ) ; + Statut_Ordre_En_Cours = ATTENTE ; + + } + } +/*******************************************************************/ +/* */ +/* Configure */ +/* */ +/* Ordre de configuration d'un parametre variateur */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Configure ( U16 Num_Parametre , S32 Valeur_S32 ) + { + + Chaine_A_Emettre[0] = 0x02 ; + Chaine_A_Emettre[1] = ORDRE_CONFIGURE ; + Chaine_A_Emettre[2] = Num_Parametre ; + Chaine_A_Emettre[6] = (U8)( Valeur_S32 & 0x000000FF) ; + Valeur_S32 = Valeur_S32 >> 8 ; + Chaine_A_Emettre[5] = (U8)( Valeur_S32 & 0x000000FF) ; + Valeur_S32 = Valeur_S32 >> 8 ; + Chaine_A_Emettre[4] = (U8)( Valeur_S32 & 0x000000FF) ; + Valeur_S32 = Valeur_S32 >> 8 ; + Chaine_A_Emettre[3] = (U8)( Valeur_S32 & 0x000000FF) ; + Chaine_A_Emettre[7] = 0x03 ; + Chaine_A_Emettre[8] = 0x00 ; + + if( Statut_Ordre_En_Cours != ATTENTE ) + { + Ordre_En_Cours = Chaine_A_Emettre [1] ; + Emission ( &Chaine_A_Emettre [0] , 8 ) ; + Statut_Ordre_En_Cours = ATTENTE ; + + } + } +/*******************************************************************/ +/* */ +/* Emission */ +/* */ +/* Emission d'une trame vers le variateur */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Emission ( U8 *pChaine , U8 Longueur ) + { + U8 Index = 0 ; + + if ( pPort->writeable() ) + { + // Mesure du timeout + Debut_Emission_ms = Chrono_Pilote.read_ms() ; + + while ( Index < Longueur ) + { + pPort->putc( *pChaine ) ; + //PC2.printf("\r\n %i: %i \r\n" ,Id, *pChaine) ; + pChaine++ ; + Index++ ; + } + } + else + { + PC2.printf("\r\n %i: Bloque \r\n" ,Id) ; + } + + } +/*******************************************************************/ +/* */ +/* Reception */ +/* */ +/* Reception de la reponse du variateur */ +/* */ +/* */ +/*******************************************************************/ + void Pilote::Reception ( void ) + { + U8 Index1 = 0 ; + U8 Index2 = 0 ; + S16 Valeur_S16 ; + S32 Valeur_S32 ; + U8 *pChaine ; + + while ( pPort->readable() ) + { + // Réception des caractères si il y en a + *pReception = pPort->getc() ; + //PC2.printf("\r\n %i",*pReception ) ; + pReception++ ; + Nb_Caracteres_Recus++ ; + } + + pChaine = &Chaine_Recue[0] ; + + // La plus petite trame comporte 3 caractères + if ( Nb_Caracteres_Recus > 2 ) + { + while ( *pChaine != 0x02 ) + { + // Recherche d'un début de trame: STX = 0x02 + if ( Index2 == Nb_Caracteres_Recus ) + { + // Pas de début de trame, on ecrase les caractères reçus et on s'en va! + pReception = &Chaine_Recue[0] ; + Nb_Caracteres_Recus = 0 ; + //PC2.printf("\r\n Poubelle %i \r\n" ,Id) ; + return ; + } + pChaine++ ; + Index2++ ; + } + /**********************************************************************************/ + // Ordre d'arret + if ( *(pChaine+1) == ORDRE_ARRET ) + { + //PC2.printf("\r\n Ordre d'Arret %i\r\n" ,Id) ; + if ( Nb_Caracteres_Recus < ( Index2 + 4 ) ) + { + // Trame incomplete, on reviendra + //PC2.printf("\r\n Arret incomplet %i \r\n" ,Id) ; + return ; + } + // Vérifie le caractere de fin de trame + if ( *(pChaine+4) == 0x03 ) + { + // Trame OK, on efface + //PC2.printf("\r\n Arret OK %i\r\n" ,Id) ; + // On lit la mesure + Valeur_S16 = (S16)(*(pChaine+2) ) * 256 + (S16)(*(pChaine+3)) ; + Mesure_Courante = ( Mesure_Courante + Valeur_S16 ) / 2 ; + + // Calcule la hauteur en mm + Valeur_S16= (S16)((F32) Mesure_Courante * MM_par_Points + MM_Offset ) ; + + if ( ( Valeur_S16 > Hauteur_mini ) + && ( Valeur_S16 < Hauteur_maxi ) ) + { + Hauteur_Courante = ( Valeur_S16 + Hauteur_Courante ) / 2 ; + } + Vitesse_Courante = 0 ; + // On recale la trame réponse + Index2 = Index2 + 5 ; + + if ( Ordre_En_Cours == ORDRE_ARRET ) + { + Statut_Ordre_En_Cours = VALIDE ; + Fin_Reception_ms = Chrono_Pilote.read_ms() ; + Dernier_Ordre_Confirme = ORDRE_ARRET ; + COM_OK = TRUE ; + } + } + } + /***************************************************************************************/ + // Ordre de mouvement automatique + else if ( ( *(pChaine+1) == ORDRE_DESCEND ) + ||( *(pChaine+1) == ORDRE_MONTE ) ) + { + //PC2.printf("\r\n Ordre de mouvement %i\r\n",Id ) ; + if ( Nb_Caracteres_Recus < ( Index2 + 6 ) ) + { + // Trame incomplete, on reviendra + //PC2.printf("\r\n Mouvement Incomplet %i \r\n",Id ) ; + return ; + } + // Vérifie le caractere de fin de trame + if ( *(pChaine+6) == 0x03 ) + { + // Trame OK, on lit la vitesse + Valeur_S16= (S16) (*(pChaine+2)) * 256 + (S16) (*(pChaine+3)) ; + Vitesse_Courante = ( Valeur_S16 + Vitesse_Courante ) / 2 ; + // et la mesure + Valeur_S16 = (S16) (*(pChaine+4)) * 256 + (S16) (*(pChaine+5)) ; + Mesure_Courante = ( Mesure_Courante + Valeur_S16 ) / 2 ; + + // Calcule la hauteur en mm + Valeur_S16 = (S16)((F32) Mesure_Courante * MM_par_Points + MM_Offset ) ; + if ( ( Valeur_S16 > Hauteur_mini ) + && ( Valeur_S16 < Hauteur_maxi ) ) + { + Hauteur_Courante = ( Valeur_S16 + Hauteur_Courante ) / 2 ; + } + + + // On recale la trame réponse + Index2 = Index2 + 7 ; + //PC2.printf("\r\n Ordre de mouvement %i OK\r\n",Id ) ; + + if ( Ordre_En_Cours == *(pChaine+1) ) + { + Statut_Ordre_En_Cours = VALIDE ; + Fin_Reception_ms = Chrono_Pilote.read_ms() ; + COM_OK = TRUE ; + Dernier_Ordre_Confirme = Ordre_En_Cours ; + } + } + } + /**********************************************************************************/ + // Ordre de frein + if ( *(pChaine+1) == ORDRE_FREIN ) + { + //PC2.printf("\r\n Ordre Frein %i\r\n" ,Id) ; + if ( Nb_Caracteres_Recus < ( Index2 + 2 ) ) + { + // Trame incomplete, on reviendra + //PC2.printf("\r\n Frein incomplet %i \r\n" ,Id) ; + return ; + } + // Vérifie le caractere de fin de trame + if ( *(pChaine+2) == 0x03 ) + { + // Trame OK + //PC2.printf("\r\n Frein OK %i\r\n" ,Id) ; + // On recale la trame réponse + Index2 = Index2 + 3 ; + + if ( Ordre_En_Cours == ORDRE_FREIN ) + { + Statut_Ordre_En_Cours = VALIDE ; + Fin_Reception_ms = Chrono_Pilote.read_ms() ; + Dernier_Ordre_Confirme = ORDRE_FREIN ; + COM_OK = TRUE ; + } + } + } + /**********************************************************************************/ + // Ordre de lecture parametre + if ( *(pChaine+1) == ORDRE_LECTURE ) + { + //PC2.printf("\r\n Ordre Frein %i\r\n" ,Id) ; + if ( Nb_Caracteres_Recus < ( Index2 + 7 ) ) + { + // Trame incomplete, on reviendra + //PC2.printf("\r\n Frein incomplet %i \r\n" ,Id) ; + return ; + } + // Vérifie le caractere de fin de trame + if ( *(pChaine+7) == 0x03 ) + { + // Trame OK + //PC2.printf("\r\n Frein OK %i\r\n" ,Id) ; + // Lecture du parametre + Valeur_S32 = (S32) (*(pChaine+3)) * 256 + (S32) (*(pChaine+4)) ; + Valeur_S32 = Valeur_S32 * 256 + (S32) (*(pChaine+5)) ; + Parametres_Vario_S32[*(pChaine+2)] = Valeur_S32 * 256 + (S32) (*(pChaine+6)) ; + // On recale la trame réponse + Index2 = Index2 + 8 ; + + if ( Ordre_En_Cours == ORDRE_LECTURE ) + { + Statut_Ordre_En_Cours = VALIDE ; + Fin_Reception_ms = Chrono_Pilote.read_ms() ; + Dernier_Ordre_Confirme = ORDRE_LECTURE ; + COM_OK = TRUE ; + } + } + } + /**********************************************************************************/ + // Ordre de configuration parametre + if ( *(pChaine+1) == ORDRE_CONFIGURE ) + { + //PC2.printf("\r\n Ordre Frein %i\r\n" ,Id) ; + if ( Nb_Caracteres_Recus < ( Index2 + 3 ) ) + { + // Trame incomplete, on reviendra + //PC2.printf("\r\n Frein incomplet %i \r\n" ,Id) ; + return ; + } + // Vérifie le caractere de fin de trame + if ( *(pChaine+3) == 0x03 ) + { + // Trame OK + //PC2.printf("\r\n Ecriture OK %i\r\n" ,Id) ; + // Ecriture du parametre + // On recale la trame réponse + Index2 = Index2 + 4 ; + + if ( Ordre_En_Cours == ORDRE_CONFIGURE ) + { + Statut_Ordre_En_Cours = VALIDE ; + Fin_Reception_ms = Chrono_Pilote.read_ms() ; + Dernier_Ordre_Confirme = ORDRE_CONFIGURE ; + COM_OK = TRUE ; + } + } + } + /**********************************************************************************/ + // La trame est traitée, on réaligne le reste des caracteres recus + Index1 = 0 ; + while ( Index2 < Nb_Caracteres_Recus ) + { + Chaine_Recue [ Index1 ] = Chaine_Recue [ Index2 ] ; + Chaine_Recue [ Index2 ] = 0 ; + //PC2.printf("\t %i:%i",Index1,Chaine_Recue [ Index1 ]); + Index1++ ; + Index2++ ; + + } + Nb_Caracteres_Recus = Index1 ; + pReception = &Chaine_Recue[Nb_Caracteres_Recus] ; + } + // Gestion du timeout + if ( Statut_Ordre_En_Cours == ATTENTE ) + { + if ( ( Chrono_Pilote.read_ms() - Debut_Emission_ms ) > TIMEOUT_RECEPTION_ms ) + { + Statut_Ordre_En_Cours = DEFAUT ; + Compteur_Timeout++ ; + COM_OK = FALSE ; + //PC2.printf("\n\r *********** Timeout : %i - %i \n\r",Id,Compteur_Timeout); + } + } + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Pilote.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,153 @@ +/*******************************************************************/ +/* */ +/* Pilote */ +/* */ +/* Objet de pilotage de variateur */ +/* */ +/* */ +/*******************************************************************/ +#ifndef _PILOTE_ +#define _PILOTE_ + +#include "mbed.h" +#include <Serial.h> +#include "Constantes.h" +#include "Variable.h" +#include "time.h" + +// Etat des ordres variateur +#define AUCUN 0 +#define ATTENTE 1 +#define VALIDE 2 +#define DEFAUT 3 + +// Ordres variateur +#define ORDRE_AUCUN 0x0 +#define ORDRE_ARRET 0x41 +#define ORDRE_MONTE 0x4D +#define ORDRE_DESCEND 0x44 +#define ORDRE_FREIN 0x46 +#define ORDRE_LECTURE 0x4C +#define ORDRE_CONFIGURE 0x43 + +// Parametres variateur +#define NB_PARAM_VARIATEUR 15 +#define VERSION 0x00 +#define STARTUP 0x01 +#define INCREMENT 0x02 +#define SEUIL_DEMARRAGE 0x03 +#define ACCELERATION 0x04 +#define DECELERATION 0x05 +#define KPV 0x06 +#define KIV 0x07 +#define KDV 0x08 +#define KA 0x09 +#define CONSIGNE 0x0A +#define ETAT_EL 0x0B +#define ETAT_SL 0x0C + +// Etats du frein du moteur +#define SERRE 0 +#define DESSERRE 1 + +#define LONGUEUR_CHAINE_EMISSION 100 +#define LONGUEUR_CHAINE_RECEPTION 100 + +#define TIMEOUT_RECEPTION_ms 200 +#define DELAI_COMMANDE_ARRET_ms 500 + +/** Class Pilote +* Pilotage de variateur de pile de pont via liaison série et protocole 3R +*/ +class Pilote +{ +public: + /** Constructeur + * @param Id : Identifiant de l'instance + */ + Pilote ( S16 Id); + + /** Initialise et ouvre le port série + * @param Baudrates : Vitesse de la liaison série + * @param bits : Bits de données + * @param Stop : Bits de stop + */ + void Init ( int Baudrates, int bits, int Stop) ; + /** Ordre de marche de la pile + * @param Mode : Mode de fonctionnement + * @param Sens : Sens de déplacement + * @param Hauteur : Hauteur cible (mm) + * @param Vitesse : Consigne de vitesse (tr/min) + */ + void Marche ( U8 Mode, U8 Sens, S16 Hauteur, S16 Vitesse ) ; + /** Ordre d'arret de la pile + */ + void Arret (void) ; + /** Commande manuelle du frein + * @param Etat : Etat du frein {SERRE,DESSERRE} + */ + void Frein ( U8 Etat ) ; + /** Lecture d'un parametre du variateur + * @param Num_Parametre : numéro du parametre à lire + */ + void Lecture ( U16 Num_Parametre ) ; + /** Configuration d'un parametre du variateur + * @param Num_Parametre : numéro du parametre à configurer + * @param Valeur : nouvelle valeur du parametre + */ + void Configure ( U16 Num_Parametre , S32 Valeur ) ; + /** Etalonnage de hauteur de la pile + * @param Points1 : Hauteur en points de la mesure basse + * @param Hauteur1 : Hauteur en mm de la mesure basse + * @param Points2 : Hauteur en points de la mesure haute + * @param Hauteur2 : Hauteur en mm de la mesure haute + */ + void Etalonnage (S16 Points1, S16 Hauteur1 , S16 Points2 , S16 Hauteur2 ) ; + /** Reception de la réponse du variateur + */ + void Reception ( void ) ; + + /**Pointeur du port série*/ + Serial* pPort ; + /**Hauteur courante de la pile (mm)*/ + S16 Hauteur_Courante ; + /**Vitesse courante de la pile*/ + S16 Vitesse_Courante ; + ///Hauteur de la pile (pts) + S16 Mesure_Courante ; + ///Hauteur cible du mouvement en cours (mm) + S16 Hauteur_Cible ; + ///Identifiant de l'instance + S16 Id ; + ///Compteur de timeouts de la liaison série + S16 Compteur_Timeout ; + ///Deplacement en cours (ARRET, MONTE, DESCEND) + U8 Etat_Deplacement ; + ///Etat de la commande manuelle de frein (SERRE, DESSERRE) + U8 Etat_Frein ; + ///Etat de la liaison série + U8 COM_OK ; + ///Tableau de paramètres du variateur + S32 Parametres_Vario_S32[NB_PARAM_VARIATEUR] ; + +private: + void Emission ( U8 *pChaine , U8 Longueur ) ; + U8 Chaine_A_Emettre[LONGUEUR_CHAINE_EMISSION] ; + U8 Chaine_Recue[LONGUEUR_CHAINE_RECEPTION] ; + Timer Chrono_Pilote ; + Timer Chrono_Arret ; + U8 *pEmission ; + U8 *pReception ; + U8 Nb_Caracteres_Recus ; + U8 Statut_Ordre_En_Cours ; + U8 Ordre_En_Cours ; + U8 Dernier_Ordre_Confirme ; + F32 MM_par_Points ; + F32 MM_Offset ; + int Debut_Emission_ms ; + int Fin_Reception_ms ; + int Age_Ordre_Arret_ms ; + +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Port_Serie.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,247 @@ +/*******************************************************************/ +/* */ +/* Port Série */ +/* */ +/* Gestion du port série par interruption */ +/* */ +/* */ +/*******************************************************************/ + +#include "mbed.h" +#include "Port_Serie.h" +#include "Modbus.h" + +Serial RS(p28 , p27) ; +Serial PC8(USBTX, USBRX) ; +Timer Chrono_Serie ; + +volatile U8 Buffer_Emission_U8[TAILLE_BUFFER_EMISSION] ; +volatile U8 Pointeur_Emission_U8 ; +volatile U8 Nb_Caracteres_A_Emettre_U8 ; +volatile U8 Buffer_Reception_U8[TAILLE_BUFFER_RECEPTION] ; +volatile U8 Pointeur_Reception_U8 ; +volatile U8 Nb_Caracteres_Attendus ; +volatile U8 Numero_Ordre_En_Reception_U8 ; +volatile U8 Numero_Ordre_En_Emission_U8 ; +volatile U8 Index ; +volatile S32 Date_Dernier_Caractere_S32 ; +volatile S32 Temps_alloue_Reception_S32 ; +static S32 Temps_alloue_Caractere_S32 ; + +/******* Réception sous interruption ***************************/ +void iReception_Serie () + { + U8 Car ; + // Si premier caractere recu, enclenche le chrono + if ( Pointeur_Reception_U8 == 0 ) + { + //Chrono_Serie.start() ; + } + // Si il y a des caractères dans le buffer + while ( RS.readable() ) + {// Réception d'un caractère + Car=RS.getc(); + Buffer_Reception_U8 [ Pointeur_Reception_U8 ] = Car ; + //RS.putc(Car) ; + Pointeur_Reception_U8++ ; + } + if ( ( Pointeur_Reception_U8 > 0 ) + &&( Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 == ATTENTE ) ) + {// Si au moins un caractère recu, la réception est en cours + Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = RECEPTION ; + } + //PC8.printf("\r\n Serie : Reception %s ", &Buffer_Reception_U8 [0]) ; + + //Date_Dernier_Caractere_S32 = Chrono_Serie.read_us() ; + // Analyse de la trame + if ( ( Buffer_Reception_U8 [ 0 ] == SLAVE_ID ) + || ( Buffer_Reception_U8 [ 0 ] == MB_ADDRESSE_BROADCAST ) ) + {// Adresse de l'esclave, ou Adresse de broadcast + //PC8.printf("\r\n Serie : Adresse %i ", Buffer_Reception_U8 [0]) ; + if ( Pointeur_Reception_U8 >= 6 ) + { + //PC8.printf("\r\n Serie : Func %i ", Buffer_Reception_U8 [1]) ; + if (( Buffer_Reception_U8 [ 1 ] == MB_FUNC_READ_HOLDING_REGISTER ) + ||( Buffer_Reception_U8 [ 1 ] == MB_FUNC_READ_INPUT_REGISTER )) + {// Fonction 3 ou 4, Lecture de registres + Nb_Caracteres_Attendus = 8 ; + //PC8.printf("\r\n Serie : Func %i ", Buffer_Reception_U8 [1]) ; + } + else if ( Buffer_Reception_U8 [ 1 ] == MB_FUNC_WRITE_MULTIPLE_REGISTERS ) + {// Fonction 16 (0x10), écriture de registres + Nb_Caracteres_Attendus = 9 + Buffer_Reception_U8 [ 5 ] * 2 ; + } + } + + if ( Pointeur_Reception_U8 >= Nb_Caracteres_Attendus ) + { + // On a recu une trame complète + //PC8.printf("\r\n Serie : trame %d complete %d / %d",Numero_Ordre_En_Reception_U8,Pointeur_Reception_U8,Nb_Caracteres_Attendus) ; + + Index = 0 ; + //Chrono_Serie.stop() ; + while( Index < Pointeur_Reception_U8 ) + {// Copie la trame dans l'ordre en cours de réception + Ordres[Numero_Ordre_En_Reception_U8].Trame_Recue_aU8[Index] = Buffer_Reception_U8 [ Index ] ; + Index++ ; + } + // Nombre de caractères de l'ordre + Ordres[Numero_Ordre_En_Reception_U8].Nb_Caracteres_Recus_U8 = Pointeur_Reception_U8 ; + // Fin de réception + Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = RECU ; + + } + + } + else + { + // Le message n'est pas pour nous, on purge le buffer + Pointeur_Reception_U8 = 0 ; + Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = ATTENTE ; + Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ; + //Chrono_Serie.stop() ; + PC8.printf("\r\n Serie : pas pour nous %i ",Buffer_Reception_U8 [ 1 ]) ; + } + + } +/************ Enclenchement de la réception *****************/ +void vPort_Serie_Reception ( U8 Numero_Ordre_U8 ) + { + if ( (Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 != RECEPTION ) + && (Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 != ATTENTE )) + {// La réception en cours est terminée + if ( ( Ordres[Numero_Ordre_U8].Etat_U8 == RECU ) + ||( Ordres[Numero_Ordre_U8].Etat_U8 == TRAITE ) + ||( Ordres[Numero_Ordre_U8].Etat_U8 == ARRET ) ) + {// L'ordre est pret à être recu + Numero_Ordre_En_Reception_U8 = Numero_Ordre_U8 ; + Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = ATTENTE ; + Pointeur_Reception_U8 = 0 ; + Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ; + //PC8.printf("\r\n Debut reception %i Etat %i ",Numero_Ordre_En_Reception_U8,Ordres[Numero_Ordre_En_Reception_U8].Etat_U8) ; + } + //PC8.printf("\r\n Reception1 %i Etat %i ",Numero_Ordre_U8,Ordres[Numero_Ordre_U8].Etat_U8) ; + } + //PC8.printf("\r\n Reception2 %i Etat %i ",Numero_Ordre_En_Reception_U8,Ordres[Numero_Ordre_En_Reception_U8].Etat_U8) ; + } +/************ Emission de la trame ************************/ +void iEmission ( void ) + { + // Si le buffer n'est pas saturé et qu'il reste des caractères à émettre + while ( ( Pointeur_Emission_U8 < Nb_Caracteres_A_Emettre_U8 ) ) + {// Emission d'un caractère + RS.putc( (U8) Buffer_Emission_U8[ Pointeur_Emission_U8 ] ) ; + Pointeur_Emission_U8++ ; + //PC8.printf("\r\n Serie : Emission %i ", Buffer_Emission_U8[ Pointeur_Emission_U8-1 ]) ; + } + if ( Pointeur_Emission_U8 >= Nb_Caracteres_A_Emettre_U8 ) + {// Tous les caractères sont émis, cloture l'émission + Ordres[Numero_Ordre_En_Emission_U8].Etat_U8 = FIN ; + Pointeur_Emission_U8 = 0 ; + Nb_Caracteres_A_Emettre_U8 = 0 ; + } + else + {// Le buffer est saturé, on reviendra plus tard + + } + } +/************ Emission de la réponse ************************/ +void vPort_Serie_Emission ( U8 Numero_Ordre_U8 ) + { + U8 Index_U8 ; + + + if (Ordres[Numero_Ordre_En_Emission_U8].Etat_U8 != EMISSION ) + {// L'émission en cours est terminée + if (Ordres[Numero_Ordre_U8].Etat_U8 == TRAITE ) + {// L'ordre est pret à être émis + Ordres[Numero_Ordre_U8].Etat_U8 = EMISSION ; + Numero_Ordre_En_Emission_U8 = Numero_Ordre_U8 ; + Nb_Caracteres_A_Emettre_U8 = Ordres[Numero_Ordre_U8].Nb_Caracteres_A_Emettre_U8 ; + Index_U8 = 0 ; + // Copie la trame dans le buffer + while( Index_U8 < Nb_Caracteres_A_Emettre_U8 ) + { + Buffer_Emission_U8 [ Index_U8 ] = Ordres[Numero_Ordre_U8].Trame_Reponse_aU8 [Index_U8] ; + Index_U8++ ; + } + Pointeur_Emission_U8 = 0 ; + } + + //PC8.printf("\r\n Serie : Emission %i : %i/%i",Numero_Ordre_En_Emission_U8, Pointeur_Emission_U8,Nb_Caracteres_A_Emettre_U8) ; + } + // Emission de la trame + iEmission() ; + } +/************ Initialisation du Port ************************/ +void vPort_Serie_Init(int Baudrate) + { + // Initialisation du port RS + RS.baud(Baudrate) ; + // Purge des buffers + for ( Pointeur_Emission_U8 = 0 ; Pointeur_Emission_U8 < TAILLE_BUFFER_EMISSION ; Pointeur_Emission_U8++ ) + { + Buffer_Emission_U8[Pointeur_Emission_U8] = 0 ; + } + for ( Pointeur_Reception_U8 = 0 ; Pointeur_Reception_U8 < TAILLE_BUFFER_RECEPTION ; Pointeur_Reception_U8++ ) + { + Buffer_Reception_U8[Pointeur_Reception_U8] = 0 ; + } + + Pointeur_Emission_U8 = 0 ; + Pointeur_Reception_U8 = 0 ; + Numero_Ordre_En_Reception_U8 = 0 ; + Numero_Ordre_En_Emission_U8 = 0 ; + //PC8.printf("\r\n Serie : Init %i ", Baudrate) ; + // Temps alloué pour 1 caractere = 10bits / Baudrate x 1E6 us + Temps_alloue_Caractere_S32 = 10000000 / Baudrate * 3 ; + } + +/************ Ouverture du port Série **********************/ +void vPort_Serie_Ouvre(void) + { + // Purge du buffer de réception + while( RS.readable() ) + { + Buffer_Reception_U8[0] = RS.getc() ; + } + Buffer_Reception_U8[0] = 0 ; + + vPort_Serie_Reception ( 0 ) ; + RS.attach (&iReception_Serie , RS.RxIrq) ; + + //RS.printf ("Debut") ; + //PC8.printf("\r\n Serie : Attach ") ; + + } + +/************ Controle de réception **********************/ +U8 cControle_Reception( U8 Numero_Ordre_U8 ) + {/* + if ( Numero_Ordre_U8 != Numero_Ordre_En_Reception_U8 ) + {// La réception est arrétée + //Chrono_Serie.stop() ; + return ( ARRET ) ; + } + if ( Chrono_Serie.read_us() > ( Temps_alloue_Caractere_S32 * Nb_Caracteres_Attendus ) ) + {// Dépassement du temps alloué + //Chrono_Serie.stop() ; + Numero_Ordre_En_Reception_U8++ ; + Pointeur_Reception_U8 = 0 ; + Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ; + + return ( TIMEOUT ) ; + }*/ + return ( RECEPTION ) ; + } + +/************ Fermeture du port Série **********************/ +void vPort_Serie_Ferme( void ) + { + //RS.detach() ; + } + +/************ Cloture du port Série **********************/ +void vPort_Serie_Cloture( void ) + { + } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Port_Serie.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,33 @@ +/*******************************************************************/ +/* */ +/* Port Série */ +/* */ +/* Gestion du port série par interruption */ +/* */ +/* */ +/*******************************************************************/ +#ifndef _PORT_SERIE_ +#define _PORT_SERIE_ + +#include "mbed.h" +#include <Serial.h> + +#include "Constantes.h" +#include "Variable.h" + +#include "time.h" + +#define TAILLE_BUFFER_EMISSION 128 +#define TAILLE_BUFFER_RECEPTION 128 + + + +extern void vPort_Serie_Init(int Baudrate) ; +extern void vPort_Serie_Ouvre( void ) ; +extern void vPort_Serie_Ferme( void ) ; +extern void vPort_Serie_Cloture( void ) ; +extern void vPort_Serie_Emission ( U8 Numero_Ordre_U8 ) ; +extern U8 cControle_Reception( U8 Numero_Ordre_U8 ) ; +extern void vPort_Serie_Reception ( U8 Numero_Ordre_U8 ) ; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synchronisation.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,155 @@ +/*******************************************************************/ +/* */ +/* Synchronisation */ +/* */ +/* Procédures de synchronisation des piles du pont Bacalan */ +/* */ +/* Creation : 3R MONTAUBAN */ +/*******************************************************************/ + +#include "Synchronisation.h" + +S16 Ecart_Synchro_Avant ; +F32 Cumul_Ecarts_Synchro_F32 ; +F32 Correction_Synchro_F32 ; + +/** void vSynchro_Initialise ( void ) +* Procédure appelée à chaque mise en route en mode automatique (synchronisé) +*/ +void vSynchro_Initialise ( void ) + {// Initialisation des variables de synchronisation + Ecart_Synchro_Avant = 0 ; + Cumul_Ecarts_Synchro_F32 = 0.0 ; + Correction_Synchro_F32 = (F32) Correction_Synchro ; + } + +void vSynchronise ( U8 Mode_Synchronisation, U8 Sens ) + { + F32 Correction_F32 ; + + switch ( Mode_Synchronisation ) + { + case CUSTOM : + { + // Ecrivez ici votre code personnalisé pour la synchronisation des piles du pont + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + break ; + } + case DEUX_VITESSES : + { + // Calcul de l'écart de synchronisation + Ecart_Synchronisation = ( Hauteur_RD - Hauteur_RG + Ecart_Synchro_Avant ) / 2 ; + Ecart_Synchro_Avant = Ecart_Synchronisation ; + + if ( abs( Ecart_Synchronisation ) < Defaut_Mineur_Synchro ) + {// Pas d'écart de synchronisation significatif: meme vitesse pour les 2 rives + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + } + + else if ( Sens == MONTE ) + {// Le pont monte, et l'ecart de synchronisation nécessite une correction de vitesse + if ( Ecart_Synchronisation > Defaut_Majeur_Synchro ) + {// Montée et Hauteur_RD > Hauteur_RG + Consigne_Vitesse_RD = (S16)( (F32)Consigne_Vitesse_Auto * Correction_Synchro_F32 / 100.0 ) ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + } + else if ( Ecart_Synchronisation < -Defaut_Majeur_Synchro ) + {// Montée et Hauteur_RD < Hauteur_RG + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = (S16)( (F32)Consigne_Vitesse_Auto * Correction_Synchro_F32 / 100.0 ) ; + } + + } + else if ( Sens == DESCEND ) + {// Le pont descend, et l'ecart de synchronisation nécessite une correction de vitesse + if ( Ecart_Synchronisation > Defaut_Majeur_Synchro ) + {// Descente et Hauteur_RD > Hauteur_RG + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = (S16)( (F32)Consigne_Vitesse_Auto * Correction_Synchro_F32 / 100.0 ) ; + } + else if ( Ecart_Synchronisation < (-Defaut_Majeur_Synchro) ) + {// Descente et Hauteur_RD < Hauteur_RG + Consigne_Vitesse_RD = (S16)( (F32)Consigne_Vitesse_Auto * Correction_Synchro_F32 / 100.0 ) ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + } + } + break ; + } + + case RD_SUIT_RG : + { + // Calcul de l'écart de synchronisation + if ( Sens == MONTE ) + { + Ecart_Synchronisation = ( Hauteur_RG - Hauteur_RD + Ecart_Synchro_Avant ) / 2 ; + } + else + { + Ecart_Synchronisation = ( Hauteur_RD - Hauteur_RG + Ecart_Synchro_Avant ) / 2 ; + } + Cumul_Ecarts_Synchro_F32 = Cumul_Ecarts_Synchro_F32 + (F32) Ecart_Synchronisation ; + + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + + // Anticipation + Correction_F32 = (F32) Consigne_Vitesse_Auto * (F32) Anticipation_Synchro / 100.0 ; + + // Proportionnel + Correction_F32 = Correction_F32 + (F32) KP_Synchro * (F32) Ecart_Synchronisation / 100.0 ; + + // Intégral + Correction_F32 = Correction_F32 + (F32) KI_Synchro * (F32) Cumul_Ecarts_Synchro_F32 / 100.0 ; + + // Dérivé + Correction_F32 = Correction_F32 + (F32) KD_Synchro * ( (F32) Ecart_Synchronisation - (F32) Ecart_Synchro_Avant ) / 100.0 ; + + Consigne_Vitesse_RD = (S16) Correction_F32 ; + + Ecart_Synchro_Avant = Ecart_Synchronisation ; + break ; + } + + case RG_SUIT_RD : + { + // Calcul de l'écart de synchronisation + if ( Sens == MONTE ) + { + Ecart_Synchronisation = ( Hauteur_RD - Hauteur_RG + Ecart_Synchro_Avant ) / 2 ; + } + else + { + Ecart_Synchronisation = ( Hauteur_RG - Hauteur_RD + Ecart_Synchro_Avant ) / 2 ; + } + + Cumul_Ecarts_Synchro_F32 = Cumul_Ecarts_Synchro_F32 + (F32) Ecart_Synchronisation ; + + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + + // Anticipation + Correction_F32 = (F32) Consigne_Vitesse_Auto * (F32) Anticipation_Synchro / 100.0 ; + + // Proportionnel + Correction_F32 = Correction_F32 + (F32) KP_Synchro * (F32) Ecart_Synchronisation / 100.0 ; + + // Intégral + Correction_F32 = Correction_F32 + (F32) KI_Synchro * (F32) Cumul_Ecarts_Synchro_F32 / 100.0 ; + + // Dérivé + Correction_F32 = Correction_F32 + (F32) KD_Synchro * ( (F32) Ecart_Synchronisation - (F32) Ecart_Synchro_Avant ) / 100.0 ; + + Consigne_Vitesse_RG = (S16) Correction_F32 ; + + Ecart_Synchro_Avant = Ecart_Synchronisation ; + break ; + } + case AUCUN : + default : + { + // Pas de correction de vitesse pour la synchronisation + Consigne_Vitesse_RD = Consigne_Vitesse_Auto ; + Consigne_Vitesse_RG = Consigne_Vitesse_Auto ; + } + } + } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Synchronisation.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,40 @@ +/*******************************************************************/ +/* */ +/* Synchronisation */ +/* */ +/* Procédures de synchronisation des piles du pont Bacalan */ +/* */ +/* */ +/*******************************************************************/ +#ifndef _SYNCHRO_ +#define _SYNCHRO_ + +#include "mbed.h" +#include "Constantes.h" +#include "Variable.h" + + + +/** void vSynchronise ( U8 Mode_Synchronisation, U8 Sens ) +* Procédure appelée à chaque cycle (100ms) pour corriger la vitesse des piles en fonction de leur hauteur +* @param <Mode_Synchronisation> Mode choisi par l'utilisateur +* CUSTOM : votre procedure de synchronisation est utilisée +* DEUX_VITESSES : La pile en avance passe en vitesse lente pour se laisser rattraper +* AUCUN : La consigne de vitesse est constante pour les 2 piles +* +* @param <Sens> Sens du déplacement +* MONTE +* DESCEND +* +* Utilise les variables: +* Consigne_Vitesse_Auto Consigne de vitesse demandé par l'utilisateur (tr/min) +* Consigne_Vitesse_RD Consigne de vitesse calculée pour la rive droite (tr/min) +* Consigne_Vitesse_RG Consigne de vitesse calculée pour la rive gauche (tr/min) +* Hauteur_RG Hauteur de la pile gauche (mm) +* Hauteur_RD Hauteur de la pile droite (mm) +*/ +extern void vSynchronise ( U8 Mode_Synchronisation, U8 Sens ) ; +extern void vSynchro_Initialise ( void ) ; + + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Variable.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,114 @@ +//***********************************************************************************/ +// +// Variables globales du Pont Bacalan +// +//************************************************************************************/ + +#include <mbed.h> +#include "Constantes.h" + +int i, j; + + + +U16 usRegInputStart = REG_INPUT_START; +S16 Memoire_S16[REG_INPUT_NREGS]; + +//**************************************************************************** +// +// Initialisation des variables +// +//**************************************************************************** +bool Init_Variables(void) + { + // Initialise some registers + for (i = 0; i < REG_INPUT_NREGS; i++) + { + Memoire_S16[i] = 0; + } + + //Paramètres Memoire + Sauvegarde_automatique = 0; + Etalonnage_effectue = 0; + Sauver_Vers_Flash =0; + Etalonnage_en_cours=0; + + RAZ =0; + + Mode_Debug = 1; + Periode_Scrutation_ms = 100 ; // 0.1s + + Mode_Fonctionnement = MODE_ARRET ; + Mode_Synchro = RD_SUIT_RG ; + + BTN_Arret = 1 ; + BTN_Monte = 0 ; + BTN_Descend = 0 ; + + BTN_Descend_RD = 0 ; + BTN_Monte_RD = 0 ; + + BTN_Monte_RG = 0 ; + BTN_Descend_RG = 0 ; + + Consigne_Vitesse_Auto = 2500 ; + Consigne_Vitesse_Manu = 1500 ; + Consigne_Haute_P = 450 ; + Consigne_Basse_P= 5 ; + + + Hauteur_mini = -10 ; + Hauteur_maxi = 470 ; + Vitesse_mini = 0 ; + Vitesse_maxi = 4000 ; + + // Synchronisation + Defaut_Mineur_Synchro = 5 ; + Defaut_Majeur_Synchro = 10 ; + Defaut_Critique_Synchro = 35 ; + Correction_Synchro = 90 ; + Anticipation_Synchro = 100 ; + KP_Synchro = 2000 ; + KI_Synchro = 100 ; + KD_Synchro = 0 ; + + + // Etalonnage + Hauteur_RD1_mm = 0 ; //0 + Hauteur_RD2_mm = 400 ; //500 + Hauteur_RD1_pts = 80 ; //100 + Hauteur_RD2_pts = 2600 ; //3400 + Hauteur_RG1_mm = 0 ; //0 + Hauteur_RG2_mm = 400 ; //500 + Hauteur_RG1_pts = 80 ; //100 + Hauteur_RG2_pts = 2600 ; //3400 + + // Parametres variateur + Param_Version_RD = 100 ; + Param_Startup_RD = 1000 ; + Param_Increment_RD = 50 ; + Param_Seuil_Demarrage_RD = 500 ; + Param_Acceleration_RD = 20 ; + Param_Deceleration_RD = 20 ; + Param_Kpv_RD = 1000 ; + Param_Kiv_RD = 200 ; + Param_Kdv_RD = 0 ; + Param_Kav_RD = 1000 ; + Param_Consigne_RD = 1500 ; + + //Parametres variateur rive gauche + Param_Version_RG = 100 ; + Param_Startup_RG = 1000 ; + Param_Increment_RG = 50 ; + Param_Seuil_Demarrage_RG = 500 ; + Param_Acceleration_RG = 20 ; + Param_Deceleration_RG = 20 ; + Param_Kpv_RG = 1000 ; + Param_Kiv_RG = 200 ; + Param_Kdv_RG = 0 ; + Param_Kav_RG = 1000 ; + Param_Consigne_RG = 1500 ; + + return (1); + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Variable.h Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,32 @@ +//***********************************************************************************/ +// +// Variables globales du thermocube +// +//************************************************************************************/ +#ifndef _VAR_ +#define _VAR_ + +#include <mbed.h> +#include "Constantes.h" +//#include "mb.h" +#include "time.h" + + +extern int i,j ; + + + +extern float Coefficient; + +//extern S16 Mode_Fonctionnement; + +extern U16 usRegInputStart ; +extern S16 Memoire_S16[REG_INPUT_NREGS]; + +extern bool Init_Variables (void); +extern void Init_Mode_Libre(); + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,152 @@ +//****************************************************************** +// +// Pont Bacalan +// +// Logiciel de pilotage du Pont Bacalan: +// - Afficheur Modbus autonome via RS422 4 fils +// - 2 variateur en RS422 4 fils +// - ? sorties logiques +// - ? entrées logiques +// +// +//******************************************************************** + +#include "mbed.h" + +#include "Constantes.h" +#include "Variable.h" +#include "Pilote.h" +#include "Modbus.h" +#include "Synchronisation.h" +#include "Gemma.h" + + +#define VERSION_SOFT 10116 + +// Objet liaison série sur USB pour mode debug +Serial PC1(USBTX, USBRX) ; + +// Objet liaison série vers les variateurs +Serial VAR_RD (p13, p14) ; +Serial VAR_RG (p9, p10) ; + +// Objet pilote, de gestion du dialogue avec les variateurs +Pilote Rive_Droite (1) ; +Pilote Rive_Gauche (2) ; + +// Chronomètre +Timer Chrono ; + +int main() + { + + int debut_boucle_us; + int fin_boucle_us; + int Duree_us; + + F32 Valeur_F32 ; + F32 Hauteur_Avant_F32 [TAILLE_TABLEAU_HAUTEURS] ; + F32 Vitesse_Avant_F32 = 0.0 ; + + S16 Index ; + + // Initialisation du Modbus + vModbus_Init(115200) ; + vModbus_Start() ; + + //Initialisation des variables + Init_Variables(); + Version_Soft = VERSION_SOFT ; + + Index = 0 ; + while ( Index < TAILLE_TABLEAU_HAUTEURS ) + { + Hauteur_Avant_F32 [ Index] = 0.0 ; + Index++ ; + } + + // Initialisation des pilotes de varialeur + Rive_Droite.pPort = &VAR_RD ; + Rive_Gauche.pPort = &VAR_RG ; + + Rive_Droite.Init ( 115200 , 8 , 1 ) ; + Rive_Droite.Id = 1 ; + Rive_Gauche.Init ( 115200 , 8 , 1 ) ; + Rive_Gauche.Id = 2 ; + + Rive_Droite.Etalonnage (Hauteur_RD1_pts , Hauteur_RD1_mm , Hauteur_RD2_pts , Hauteur_RD2_mm ) ; + Rive_Gauche.Etalonnage (Hauteur_RG1_pts , Hauteur_RG1_mm , Hauteur_RG2_pts , Hauteur_RG2_mm ) ; + + //Ininialise_Rampes () ; + //Affiche_Motif ( 0 ) ; + + // Initialisation du Gemma + vGemma_Init () ; + + Chrono.start() ; + + while (true) + { + // Lecture du temps en début de boucle + debut_boucle_us = 0;//Chrono.read_us() ; + Chrono.reset(); + fin_boucle_us = debut_boucle_us + (int)Periode_Scrutation_ms * 1000.0 ; + + // Gestion du Modbus + vModbus() ; + + // Gestion du mode de fonctionnement + vGemma ( &Rive_Droite , &Rive_Gauche ) ; + + // Gestion de l'eclairage des rampes + //vRampe_RGB () ; + + // Duree de la boucle en µs + Duree_us = Chrono.read_us() - debut_boucle_us ; + Duree_Boucle_us = (S16)( Duree_us ) ; + + //PC1.printf("\r\n Duree : %d \r\n",Duree_us) ; + //PC1.printf("\r\n Duree : %d / %X \r\n",Duree_us,Duree_Boucle_us); + + while( Chrono.read_us() < fin_boucle_us ) + { + Rive_Droite.Reception () ; + Rive_Gauche.Reception () ; + vModbus() ; + wait_us(200) ; + } + + + // Traitement des réponses des variateurs + Mesure_RD = Rive_Droite.Mesure_Courante ; + Vitesse_RD = Rive_Droite.Vitesse_Courante ; + Hauteur_RD = Rive_Droite.Hauteur_Courante ; + Etat_COM_RD = Rive_Droite.COM_OK ; + Compteur_Timeout_RD = Rive_Droite.Compteur_Timeout ; + PC1.printf("\r\n RD : %i \t %i \t %i \t %i\r\n",Mesure_RD,Hauteur_RD,Vitesse_RD,Compteur_Timeout_RD); + + Mesure_RG = Rive_Gauche.Mesure_Courante ; + Vitesse_RG = Rive_Gauche.Vitesse_Courante ; + Hauteur_RG = Rive_Gauche.Hauteur_Courante ; + Etat_COM_RG = Rive_Gauche.COM_OK ; + Compteur_Timeout_RG = Rive_Gauche.Compteur_Timeout ; + PC1.printf("\r\n RG : %i \t %i \t %i \t %i\r\n",Mesure_RG,Hauteur_RG,Vitesse_RG,Compteur_Timeout_RG); + + Hauteur_P = ( Hauteur_RD + Hauteur_RG ) / 2 ; + Ecart_Synchronisation = Hauteur_RD - Hauteur_RG ; + //PC1.printf("\r\n Hauteur P : %i \r\n",Hauteur_P); + //PC1.printf("0") ; + + //Valeur_F32 = (F32)Hauteur_P - Hauteur_Avant_F32 [ TAILLE_TABLEAU_HAUTEURS - 1 ] ; + Valeur_F32 = (F32) ( Vitesse_RG + Vitesse_RD ) / 2.0 ; + Valeur_F32 = Valeur_F32 * 19.5 * 3.14156 / 100.0 ; + Valeur_F32 = ( Vitesse_Avant_F32 + Valeur_F32 ) / 2.0 ; + Vitesse_Avant_F32 = Valeur_F32 ; + Vitesse_P = (S16) Valeur_F32 ; + + } + + } + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Jun 22 09:33:04 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89 \ No newline at end of file