CRAC Team / Strategie_13h30

Fork of CRAC-Strat_2017_homologation_gros_rob by CRAC Team

Revision:
1:116040d14164
Parent:
0:ad97421fb1fb
Child:
5:dcd817534b57
--- a/AX12-V2/AX12-V2.cpp	Wed Apr 13 22:04:54 2016 +0000
+++ b/AX12-V2/AX12-V2.cpp	Fri Apr 15 10:49:40 2016 +0000
@@ -6,6 +6,8 @@
 
 int lastAX12Use = 0;
 
+FunctionPointer AX12_CallbackEnd;//Fonction de callback lors de la fin d'un mouvement d'un AX12
+
 /****************************************************************************************/
 /* FUNCTION NAME: AX12_register                                                         */
 /* DESCRIPTION  : Indiquer qu'un AX12 est connecté à la carte                           */
@@ -20,14 +22,14 @@
     if(speed > 0x3FF) speed = 0x3FF;//La vitesse ne doit pas depasser 1023
     
     AX12_data[lastAX12Use].speed = speed;
-    
+    /*
     data[0] = speed & 0xff; // bottom 8 bits
     data[1] = speed >> 8;   // top 8 bits
-    
+    */
     AX12_Serial.baud(1000000);//On indique la vitesse de transmission des AX12
-    
+    /*
     AX12_write(id,AX12_REG_MOVING_SPEED,2,data);
-    
+    */
     
 }
 
@@ -43,12 +45,12 @@
     AX12_data[localID].needToUpdate = 1;
     AX12_data[localID].goal = goal;
     if(speed > 0x3FF) speed = 0x3FF;//La vitesse ne doit pas depasser 1023
-    
-    AX12_data[localID].speed = speed;
+    if(speed != 0x3FF)
+        AX12_data[localID].speed = speed;
     
     if(AX12_data[localID].isUsingCAN != 0) {//Il faut envoyer la trame CAN car l'AX12 est sur une autre carte
         msgTx.id=SERVO_AX12_SETGOAL;
-        msgTx.len=3;
+        msgTx.len=5;
         msgTx.format=CANStandard;
         msgTx.type=CANData;
         // id de l'AX12 sur 1 octet
@@ -57,8 +59,8 @@
         msgTx.data[1]=(unsigned char)goal;
         msgTx.data[2]=(unsigned char)(goal>>8);
         //Vitesse de l'AX12 sur 2 octet
-        msgTx.data[3]=(unsigned char)speed;
-        msgTx.data[4]=(unsigned char)(speed>>8);
+        msgTx.data[3]=(unsigned char)AX12_data[localID].speed;
+        msgTx.data[4]=(unsigned char)(AX12_data[localID].speed>>8);
     
         can1.write(msgTx);
     }
@@ -102,12 +104,44 @@
 }
 
 /****************************************************************************************/
+/* FUNCTION NAME: AX12_notifyCANEnd                                                     */
+/* DESCRIPTION  : indiquer qu'un mouvement d'AX12 CAN est terminé                       */
+/****************************************************************************************/
+void AX12_notifyCANEnd(unsigned char id) 
+{
+    if(waitingAckFrom == SERVO_AX12_DONE) {
+        waitingAckFrom = 0;
+        waitingAckID = 0;
+    }
+}
+
+/****************************************************************************************/
 /* FUNCTION NAME: AX12_doLoop                                                           */
 /* DESCRIPTION  : Boucle de vérification de la position des AX12                        */
 /****************************************************************************************/
 void AX12_doLoop(void)
 {
-    //TODO
+    int i=0;
+    CANMessage msgTx=CANMessage();
+
+    for(i=0;i<MAX_AX12;i++)
+    {
+        if(AX12_data[i].isUsingCAN == 0 && AX12_data[i].needCheckMoving == 1)//Il faut vérifier si l'AX12 a terminé de bouger
+        {
+            if(AX12_isMoving(AX12_data[i].id) == 0) {//L'AX12 a terminé de bouger
+                AX12_data[i].needCheckMoving = 0;
+                
+                msgTx.id=SERVO_AX12_DONE;
+                msgTx.len=1;
+                msgTx.format=CANStandard;
+                msgTx.type=CANData;
+                // id de l'AX12 sur 1 octet
+                msgTx.data[0]=(unsigned char)AX12_data[i].id;
+                can1.write(msgTx);
+                AX12_notifyCANEnd(AX12_data[i].id);
+            }     
+        }
+    } 
 }
 
 /****************************************************************************************/
@@ -119,7 +153,7 @@
 {
     int i=0;
     int dataToSendLength = 0;
-    char dataToSend[50];
+    char dataToSend[100];
 
     
     for(i=0;i<MAX_AX12;i++)
@@ -129,10 +163,13 @@
             if(AX12_data[i].isUsingCAN == 0)//Il faut envoyer la trame en local
             {
                 if(dataToSendLength == 0)
-                    dataToSend[dataToSendLength++] = 2;//length data
+                    dataToSend[dataToSendLength++] = 4;//length data
                 dataToSend[dataToSendLength++] = AX12_data[i].id;//ID servo1
                 dataToSend[dataToSendLength++] = ((1023 * AX12_data[i].goal) / 300) & 0xff;// bottom 8 bits
-                dataToSend[dataToSendLength++] = ((1023 * AX12_data[i].goal) / 300) >> 8;  // top 8 bits                
+                dataToSend[dataToSendLength++] = ((1023 * AX12_data[i].goal) / 300) >> 8;  // top 8 bits      
+                dataToSend[dataToSendLength++] = (AX12_data[i].speed) & 0xff;// bottom 8 bits
+                dataToSend[dataToSendLength++] = (AX12_data[i].speed) >> 8;  // top 8 bits   
+                AX12_data[i].needCheckMoving = 1;         
             }
             AX12_data[i].needToUpdate = 0;//Remise à 0 de l'indicatif de mise à jour
         }
@@ -147,6 +184,17 @@
 }
 
 /****************************************************************************************/
+/* FUNCTION NAME: AX12_isMoving                                                         */
+/* DESCRIPTION  : Fonction pour savoir si un AX12 local est entrain de bouger           */
+/****************************************************************************************/
+int AX12_isMoving(unsigned char id)
+{
+    char data[1];
+    AX12_read(id,AX12_REG_MOVING,1,data);
+    return(data[0]);
+}
+
+/****************************************************************************************/
 /* FUNCTION NAME: AX12_syncWrite                                                        */
 /* DESCRIPTION  : Fonction pour envoyer des trames aux AX12 en mode syncWrite           */
 /****************************************************************************************/
@@ -397,3 +445,219 @@
 
     return(Status[4]); // retourne le code d'erreur ( octect 5 de la trame de retour )
 }
+
+
+/****************************************************************************************/
+/* FUNCTION NAME: AX12_read                                                             */
+/* DESCRIPTION  : Lire des données dans un registre de l'AX12                           */
+/****************************************************************************************/
+int AX12_read(int ID, int start, int bytes, char* data)
+{
+
+
+    char PacketLength = 0x3;
+    char TxBuf[16];
+    char sum = 0;
+    char Status[16];
+
+    int timeout = 0;
+    int plen = 0;
+    int flag_out = 0;
+    int timeout_transmit = 0;
+    int i = 0;
+    int enable = 0;
+//    int poubelle = 0;
+//    int count = 0;
+//    char vidage[50];
+
+    typedef enum {Header1, Header2, ident, length, erreur, reception, checksum} type_etat;
+    type_etat etat = Header1;
+
+    Status[4] = 0xFE; // return code
+
+
+
+
+
+    /*********************************** CREATION DE LA TRAME A EVOYER *****************************************/
+
+
+    // Build the TxPacket first in RAM, then we'll send in one go
+
+    TxBuf[0] = 0xff;
+    TxBuf[1] = 0xff;
+
+    // ID
+    TxBuf[2] = ID;
+    sum += TxBuf[2];
+
+    // Packet Length
+    TxBuf[3] = PacketLength+bytes;    // Length = 4 ; 2 + 1 (start) = 1 (bytes)
+    sum += TxBuf[3];            // Accululate the packet sum
+
+
+    // Instruction - Read
+    TxBuf[4] = 0x2;
+    sum += TxBuf[4];
+
+    // Start Address
+    TxBuf[5] = start;
+    sum += TxBuf[5];
+
+    // Bytes to read
+    TxBuf[6] = bytes;
+    sum += TxBuf[6];
+
+    // Checksum
+    TxBuf[7] = 0xFF - sum;
+
+    /********************************************TRAME CONSTRUITE DANS TxBuf***************************************/
+
+
+
+
+    /* Transmission de la trame construite precedemment dans le tableau TxBuf
+    */
+    while ((timeout_transmit<1000) && (i < (7+bytes))) {
+        if (AX12_Serial.writeable()) {
+            AX12_Serial.putc(TxBuf[i]);
+            i++;
+            timeout_transmit = 0;
+        } else timeout_transmit++;
+    }
+
+    if (timeout_transmit == 1000 ) { // dans le cas d'une sortie en timeout pour ne pas rester bloquer !
+        return(-1);
+    }
+    /* Transmission effectuée on va ensuite récuperer la trame de retour renvoyer par le servomoteur
+    */
+    // Wait for the bytes to be transmitted
+    wait (0.001);
+
+    // Skip if the read was to the broadcast address
+    if (ID != 0xFE) {
+
+        /* Partie de reception de la trame de retour
+        */
+        while ((flag_out != 1) && (timeout < (1000*bytes))) {
+            // Les differents etats de l'automate on été créés au debut de la fonction write !
+            switch (etat) {
+                case Header1:
+                    if (AX12_Serial.readable()) {     // reception du premier Header ( 0xFF )
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        if (Status[plen] == 0xFF ) {
+                            etat = Header2;
+                            plen++;
+
+                        } else etat = Header1;
+                    } else timeout++;
+                    break;
+
+
+                case Header2:
+                    if (AX12_Serial.readable()) {     // reception du second Header ( 0xFF )
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        if (Status[plen] == 0xFF ) {
+                            etat = ident;
+                            plen++;
+
+                        } else if (Status[plen] == ID ) { // PERMET D'EVITER CERTAINES ERREUR LORSQU'ON LIT PLUSIEURS REGISTRES !!!!
+                            Status[plen] = 0;
+                            plen++;
+                            Status[plen] = ID;
+                            etat = length;
+                            plen++;
+
+                        } else {
+
+                            etat = Header1;
+                            plen = 0;
+                        }
+                    } else timeout++;
+                    break;
+
+                case ident:
+                    if (AX12_Serial.readable()) {     // reception de l'octet correspondant à l'ID du servomoteur
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        if (Status[plen] == ID ) {
+                            etat = length;
+                            plen++;
+
+                        } else {
+                            etat = Header1;
+                            plen = 0;
+                        }
+                    } else timeout++;
+                    break;
+
+                case length:
+                    if (AX12_Serial.readable()) {        // reception de l'octet correspondant à la taille ( taille = 2 + nombre de paramètres )
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        if (Status[plen] == (bytes+2) ) {
+                            etat = erreur;
+                            plen++;
+
+                        } else {
+                            etat = Header1;
+                            plen = 0;
+                        }
+                    } else timeout++;
+                    break;
+
+                case erreur:
+                    if (AX12_Serial.readable()) {     //reception de l'octet correspondant au code d'erreurs eventuels ( 0 = pas d'erreur )
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        plen++;
+
+                        etat = reception;
+                    } else timeout++;
+
+                case reception:
+                    while ( enable < bytes ) {     // reception du ou des octect(s) de donnés ( suivant la valeur de la variable length )
+                        if (AX12_Serial.readable()) {
+                            Status[plen] = AX12_Serial.getc();
+                            timeout = 0;
+                            plen++;
+                            enable++;
+
+                        } else timeout++;
+                    }
+                    etat = checksum;
+                    break;
+
+                case checksum:
+                    if (AX12_Serial.readable()) { // reception du dernier octet ( Checksum ) >>> checksum = NOT ( ID + length + somme des données ) >>>> dans le cas d'un retour d'un read!!
+                        Status[plen] = AX12_Serial.getc();
+                        timeout = 0;
+                        flag_out = 1;
+                        etat = Header1;
+                    } else timeout++;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+
+        if (timeout == (1000*bytes) ) { // permet d'afficher si il y a une erreur de timeout et de ne pas rester bloquer si il y a des erreurs de trames
+            return(-1);
+        }
+
+
+        // copie des données dans le tableau data
+        for (int i=0; i < Status[3]-2 ; i++) {
+            data[i] = Status[5+i];
+        }
+
+    } // toute la partie precedente ne s'effectue pas dans le cas d'un appel avec un broadcast ID (ID!=0xFE)
+
+    return(Status[4]);    // retourne le code d'erreur ( octect 5 de la trame de retour )
+}
+
+