CRAC Team / CRAC-Strat_2019

Dependencies:   CRAC-Strat_2019 SerialHalfDuplex SDFileSystem DISCO-F469NI_portrait liaison_Bluetooth ident_crac

Dependents:   Codeprincipal_2019 CRAC-Strat_2019

Committer:
antbig
Date:
Wed Apr 27 13:05:03 2016 +0000
Revision:
8:0edc7dfb7f7e
Parent:
5:dcd817534b57
Child:
12:14729d584500
D?but des actions du gros robot

Who changed what in which revision?

UserRevisionLine numberNew contents of line
antbig 0:ad97421fb1fb 1 #include "AX12-V2.h"
antbig 0:ad97421fb1fb 2
antbig 0:ad97421fb1fb 3 struct S_AX12 AX12_data[MAX_AX12];//La liste de tous les AX12 du robot possible, aussi bien par CAN que en local
antbig 0:ad97421fb1fb 4
antbig 5:dcd817534b57 5 SerialHalfDuplex AX12_Serial1 = SerialHalfDuplex(p9,p10);
antbig 5:dcd817534b57 6 SerialHalfDuplex AX12_Serial2 = SerialHalfDuplex(p28,p27);
antbig 0:ad97421fb1fb 7
antbig 0:ad97421fb1fb 8 int lastAX12Use = 0;
antbig 0:ad97421fb1fb 9
antbig 1:116040d14164 10 FunctionPointer AX12_CallbackEnd;//Fonction de callback lors de la fin d'un mouvement d'un AX12
antbig 1:116040d14164 11
antbig 0:ad97421fb1fb 12 /****************************************************************************************/
antbig 0:ad97421fb1fb 13 /* FUNCTION NAME: AX12_register */
antbig 0:ad97421fb1fb 14 /* DESCRIPTION : Indiquer qu'un AX12 est connecté à la carte */
antbig 0:ad97421fb1fb 15 /****************************************************************************************/
antbig 5:dcd817534b57 16 void AX12_register(unsigned char id, unsigned char serial, unsigned short speed)
antbig 0:ad97421fb1fb 17 {
antbig 0:ad97421fb1fb 18 int localID = AX12_getLocalID(id);
antbig 8:0edc7dfb7f7e 19
antbig 0:ad97421fb1fb 20 AX12_data[localID].isUsingCAN = 0;//On indique que l'AX12 est connecté localement
antbig 0:ad97421fb1fb 21
antbig 0:ad97421fb1fb 22 if(speed > 0x3FF) speed = 0x3FF;//La vitesse ne doit pas depasser 1023
antbig 0:ad97421fb1fb 23
antbig 8:0edc7dfb7f7e 24 AX12_data[localID].speed = speed;
antbig 8:0edc7dfb7f7e 25 AX12_data[localID].serial = serial;
antbig 8:0edc7dfb7f7e 26 //printf("registering AX12 id: %d local: %d\n",id,localID);
antbig 5:dcd817534b57 27 AX12_Serial1.baud(1000000);//On indique la vitesse de transmission des AX12
antbig 5:dcd817534b57 28 AX12_Serial2.baud(1000000);//On indique la vitesse de transmission des AX12
antbig 0:ad97421fb1fb 29
antbig 0:ad97421fb1fb 30 }
antbig 0:ad97421fb1fb 31
antbig 0:ad97421fb1fb 32 /****************************************************************************************/
antbig 0:ad97421fb1fb 33 /* FUNCTION NAME: AX12_setGoal */
antbig 0:ad97421fb1fb 34 /* DESCRIPTION : Definir la position d'un ax12, !!Ne déclanche pas le mouvement */
antbig 0:ad97421fb1fb 35 /****************************************************************************************/
antbig 0:ad97421fb1fb 36 void AX12_setGoal(unsigned char id, unsigned short goal, unsigned short speed)
antbig 0:ad97421fb1fb 37 {
antbig 0:ad97421fb1fb 38 int localID = AX12_getLocalID(id);//On récupère les info sur l'AX12
antbig 0:ad97421fb1fb 39 CANMessage msgTx=CANMessage();
antbig 0:ad97421fb1fb 40
antbig 0:ad97421fb1fb 41 AX12_data[localID].needToUpdate = 1;
antbig 0:ad97421fb1fb 42 AX12_data[localID].goal = goal;
antbig 0:ad97421fb1fb 43 if(speed > 0x3FF) speed = 0x3FF;//La vitesse ne doit pas depasser 1023
antbig 1:116040d14164 44 if(speed != 0x3FF)
antbig 1:116040d14164 45 AX12_data[localID].speed = speed;
antbig 0:ad97421fb1fb 46
antbig 0:ad97421fb1fb 47 if(AX12_data[localID].isUsingCAN != 0) {//Il faut envoyer la trame CAN car l'AX12 est sur une autre carte
antbig 0:ad97421fb1fb 48 msgTx.id=SERVO_AX12_SETGOAL;
antbig 1:116040d14164 49 msgTx.len=5;
antbig 0:ad97421fb1fb 50 msgTx.format=CANStandard;
antbig 0:ad97421fb1fb 51 msgTx.type=CANData;
antbig 0:ad97421fb1fb 52 // id de l'AX12 sur 1 octet
antbig 0:ad97421fb1fb 53 msgTx.data[0]=(unsigned char)id;
antbig 0:ad97421fb1fb 54 // Position de l'AX12 sur 2 octet
antbig 0:ad97421fb1fb 55 msgTx.data[1]=(unsigned char)goal;
antbig 0:ad97421fb1fb 56 msgTx.data[2]=(unsigned char)(goal>>8);
antbig 0:ad97421fb1fb 57 //Vitesse de l'AX12 sur 2 octet
antbig 1:116040d14164 58 msgTx.data[3]=(unsigned char)AX12_data[localID].speed;
antbig 1:116040d14164 59 msgTx.data[4]=(unsigned char)(AX12_data[localID].speed>>8);
antbig 0:ad97421fb1fb 60
antbig 0:ad97421fb1fb 61 can1.write(msgTx);
antbig 0:ad97421fb1fb 62 }
antbig 0:ad97421fb1fb 63
antbig 0:ad97421fb1fb 64 }
antbig 0:ad97421fb1fb 65
antbig 0:ad97421fb1fb 66 /****************************************************************************************/
antbig 0:ad97421fb1fb 67 /* FUNCTION NAME: AX12_isLocal */
antbig 0:ad97421fb1fb 68 /* DESCRIPTION : Savoir si un AX12 est enregistré sur la carte */
antbig 0:ad97421fb1fb 69 /****************************************************************************************/
antbig 0:ad97421fb1fb 70 unsigned char AX12_isLocal(unsigned char id)
antbig 0:ad97421fb1fb 71 {
antbig 0:ad97421fb1fb 72 int i=0;
antbig 0:ad97421fb1fb 73 for(i=0;i<MAX_AX12;i++)
antbig 0:ad97421fb1fb 74 {
antbig 0:ad97421fb1fb 75 if(AX12_data[i].id == id && AX12_data[i].isUsingCAN == 0) return 1;
antbig 0:ad97421fb1fb 76 }
antbig 0:ad97421fb1fb 77 return 0;
antbig 0:ad97421fb1fb 78 }
antbig 0:ad97421fb1fb 79
antbig 0:ad97421fb1fb 80
antbig 0:ad97421fb1fb 81 /****************************************************************************************/
antbig 0:ad97421fb1fb 82 /* FUNCTION NAME: AX12_getLocalID */
antbig 0:ad97421fb1fb 83 /* DESCRIPTION : Obtenir les info sur un AX12 ou l'initialiser si non présent */
antbig 0:ad97421fb1fb 84 /****************************************************************************************/
antbig 0:ad97421fb1fb 85 int AX12_getLocalID(unsigned char id)
antbig 0:ad97421fb1fb 86 {
antbig 0:ad97421fb1fb 87 int i=0;
antbig 8:0edc7dfb7f7e 88 for(i=0;i<lastAX12Use;i++)
antbig 0:ad97421fb1fb 89 {
antbig 0:ad97421fb1fb 90 if(AX12_data[i].id == id) return i;
antbig 0:ad97421fb1fb 91 }
antbig 0:ad97421fb1fb 92 //Si l'AX12 n'est pas déjà initialisé, on l'initialise
antbig 0:ad97421fb1fb 93 AX12_data[lastAX12Use].id = id;//
antbig 0:ad97421fb1fb 94 AX12_data[lastAX12Use].goal = 0;//
antbig 0:ad97421fb1fb 95 AX12_data[lastAX12Use].speed = 0x320;//
antbig 0:ad97421fb1fb 96 AX12_data[lastAX12Use].isUsingCAN = 1;//Indique qu'il faut envoyer le message via CAN
antbig 0:ad97421fb1fb 97 AX12_data[lastAX12Use].needToUpdate = 0;//
antbig 0:ad97421fb1fb 98 lastAX12Use++;
antbig 0:ad97421fb1fb 99 return lastAX12Use-1;
antbig 0:ad97421fb1fb 100 }
antbig 0:ad97421fb1fb 101
antbig 0:ad97421fb1fb 102 /****************************************************************************************/
antbig 1:116040d14164 103 /* FUNCTION NAME: AX12_notifyCANEnd */
antbig 1:116040d14164 104 /* DESCRIPTION : indiquer qu'un mouvement d'AX12 CAN est terminé */
antbig 1:116040d14164 105 /****************************************************************************************/
antbig 1:116040d14164 106 void AX12_notifyCANEnd(unsigned char id)
antbig 1:116040d14164 107 {
antbig 1:116040d14164 108 if(waitingAckFrom == SERVO_AX12_DONE) {
antbig 1:116040d14164 109 waitingAckFrom = 0;
antbig 1:116040d14164 110 waitingAckID = 0;
antbig 1:116040d14164 111 }
antbig 1:116040d14164 112 }
antbig 1:116040d14164 113
antbig 1:116040d14164 114 /****************************************************************************************/
antbig 0:ad97421fb1fb 115 /* FUNCTION NAME: AX12_doLoop */
antbig 0:ad97421fb1fb 116 /* DESCRIPTION : Boucle de vérification de la position des AX12 */
antbig 0:ad97421fb1fb 117 /****************************************************************************************/
antbig 0:ad97421fb1fb 118 void AX12_doLoop(void)
antbig 0:ad97421fb1fb 119 {
antbig 1:116040d14164 120 int i=0;
antbig 1:116040d14164 121 CANMessage msgTx=CANMessage();
antbig 1:116040d14164 122
antbig 8:0edc7dfb7f7e 123 for(i=0;i<lastAX12Use;i++)
antbig 1:116040d14164 124 {
antbig 1:116040d14164 125 if(AX12_data[i].isUsingCAN == 0 && AX12_data[i].needCheckMoving == 1)//Il faut vérifier si l'AX12 a terminé de bouger
antbig 1:116040d14164 126 {
antbig 5:dcd817534b57 127 if(AX12_isMoving(i) == 0) {//L'AX12 a terminé de bouger
antbig 1:116040d14164 128 AX12_data[i].needCheckMoving = 0;
antbig 1:116040d14164 129
antbig 1:116040d14164 130 msgTx.id=SERVO_AX12_DONE;
antbig 1:116040d14164 131 msgTx.len=1;
antbig 1:116040d14164 132 msgTx.format=CANStandard;
antbig 1:116040d14164 133 msgTx.type=CANData;
antbig 1:116040d14164 134 // id de l'AX12 sur 1 octet
antbig 1:116040d14164 135 msgTx.data[0]=(unsigned char)AX12_data[i].id;
antbig 1:116040d14164 136 can1.write(msgTx);
antbig 1:116040d14164 137 AX12_notifyCANEnd(AX12_data[i].id);
antbig 1:116040d14164 138 }
antbig 1:116040d14164 139 }
antbig 1:116040d14164 140 }
antbig 0:ad97421fb1fb 141 }
antbig 0:ad97421fb1fb 142
antbig 0:ad97421fb1fb 143 /****************************************************************************************/
antbig 0:ad97421fb1fb 144 /* FUNCTION NAME: AX12_processChange */
antbig 0:ad97421fb1fb 145 /* DESCRIPTION : Permet de prendre en compte les changement d'instruction des AX12 */
antbig 0:ad97421fb1fb 146 /* Début du mouvement à partir de l'appel de cette fonction */
antbig 0:ad97421fb1fb 147 /****************************************************************************************/
antbig 5:dcd817534b57 148 void AX12_processChange(unsigned char fromCan)
antbig 0:ad97421fb1fb 149 {
antbig 0:ad97421fb1fb 150 int i=0;
antbig 0:ad97421fb1fb 151 int dataToSendLength = 0;
antbig 1:116040d14164 152 char dataToSend[100];
antbig 0:ad97421fb1fb 153
antbig 0:ad97421fb1fb 154
antbig 8:0edc7dfb7f7e 155 for(i=0;i<lastAX12Use;i++)
antbig 0:ad97421fb1fb 156 {
antbig 8:0edc7dfb7f7e 157 //printf("checking AX12 id: %d",AX12_data[i].id);
antbig 0:ad97421fb1fb 158 if(AX12_data[i].needToUpdate == 1) //Il faut mettre à jour la position de l'AX12
antbig 0:ad97421fb1fb 159 {
antbig 8:0edc7dfb7f7e 160 //printf(" => update");
antbig 0:ad97421fb1fb 161 if(AX12_data[i].isUsingCAN == 0)//Il faut envoyer la trame en local
antbig 0:ad97421fb1fb 162 {
antbig 8:0edc7dfb7f7e 163 //printf(" local");
antbig 0:ad97421fb1fb 164 if(dataToSendLength == 0)
antbig 1:116040d14164 165 dataToSend[dataToSendLength++] = 4;//length data
antbig 0:ad97421fb1fb 166 dataToSend[dataToSendLength++] = AX12_data[i].id;//ID servo1
antbig 0:ad97421fb1fb 167 dataToSend[dataToSendLength++] = ((1023 * AX12_data[i].goal) / 300) & 0xff;// bottom 8 bits
antbig 1:116040d14164 168 dataToSend[dataToSendLength++] = ((1023 * AX12_data[i].goal) / 300) >> 8; // top 8 bits
antbig 1:116040d14164 169 dataToSend[dataToSendLength++] = (AX12_data[i].speed) & 0xff;// bottom 8 bits
antbig 1:116040d14164 170 dataToSend[dataToSendLength++] = (AX12_data[i].speed) >> 8; // top 8 bits
antbig 1:116040d14164 171 AX12_data[i].needCheckMoving = 1;
antbig 0:ad97421fb1fb 172 }
antbig 0:ad97421fb1fb 173 AX12_data[i].needToUpdate = 0;//Remise à 0 de l'indicatif de mise à jour
antbig 0:ad97421fb1fb 174 }
antbig 8:0edc7dfb7f7e 175 //printf("\n");
antbig 0:ad97421fb1fb 176 }
antbig 5:dcd817534b57 177 if(fromCan == 0)
antbig 5:dcd817534b57 178 SendRawId(SERVO_AX12_PROCESS);//On indique par CAN qu'il faut bouger les AX12
antbig 8:0edc7dfb7f7e 179 //printf("need to send %d data\n",dataToSendLength);
antbig 0:ad97421fb1fb 180 if(dataToSendLength > 0)//Il y a des données à envoyer en local
antbig 0:ad97421fb1fb 181 {
antbig 5:dcd817534b57 182 AX12_syncWrite(AX12_Serial1, AX12_REG_GOAL_POSITION, dataToSendLength, dataToSend);
antbig 8:0edc7dfb7f7e 183 //wait_ms(10);
antbig 5:dcd817534b57 184 AX12_syncWrite(AX12_Serial2, AX12_REG_GOAL_POSITION, dataToSendLength, dataToSend);
antbig 0:ad97421fb1fb 185 }
antbig 0:ad97421fb1fb 186
antbig 0:ad97421fb1fb 187 }
antbig 0:ad97421fb1fb 188
antbig 0:ad97421fb1fb 189 /****************************************************************************************/
antbig 1:116040d14164 190 /* FUNCTION NAME: AX12_isMoving */
antbig 1:116040d14164 191 /* DESCRIPTION : Fonction pour savoir si un AX12 local est entrain de bouger */
antbig 1:116040d14164 192 /****************************************************************************************/
antbig 1:116040d14164 193 int AX12_isMoving(unsigned char id)
antbig 1:116040d14164 194 {
antbig 1:116040d14164 195 char data[1];
antbig 5:dcd817534b57 196 if(AX12_data[id].serial == 0)
antbig 5:dcd817534b57 197 AX12_read(AX12_Serial1,AX12_data[id].id,AX12_REG_MOVING,1,data);
antbig 5:dcd817534b57 198 else
antbig 5:dcd817534b57 199 AX12_read(AX12_Serial2,AX12_data[id].id,AX12_REG_MOVING,1,data);
antbig 1:116040d14164 200 return(data[0]);
antbig 1:116040d14164 201 }
antbig 1:116040d14164 202
antbig 1:116040d14164 203 /****************************************************************************************/
antbig 0:ad97421fb1fb 204 /* FUNCTION NAME: AX12_syncWrite */
antbig 0:ad97421fb1fb 205 /* DESCRIPTION : Fonction pour envoyer des trames aux AX12 en mode syncWrite */
antbig 0:ad97421fb1fb 206 /****************************************************************************************/
antbig 5:dcd817534b57 207 int AX12_syncWrite(SerialHalfDuplex& AX12_Serial, int start, int bytes, char* data)
antbig 0:ad97421fb1fb 208 {
antbig 0:ad97421fb1fb 209 //0 : 0xff
antbig 0:ad97421fb1fb 210 //1 : 0xff
antbig 0:ad97421fb1fb 211 //2 : ID de l'AX12 ou 0xFE pour le broadcast
antbig 0:ad97421fb1fb 212 //3 : Length => longueur de la trame
antbig 0:ad97421fb1fb 213 //4 : Intruction(write) => id de l'instruction 0x83 pour le syncwrite
antbig 0:ad97421fb1fb 214 //5 : Address => addresse du registre à modifier
antbig 0:ad97421fb1fb 215 //6+ : Data => les données à transmettre
antbig 0:ad97421fb1fb 216 //last : Checksum
antbig 0:ad97421fb1fb 217 int ID = 0xFE;//Toujours 0xFE dans le cas d'un broadcast
antbig 0:ad97421fb1fb 218
antbig 0:ad97421fb1fb 219 char TxBuf[60];
antbig 0:ad97421fb1fb 220 char sum = 0;
antbig 0:ad97421fb1fb 221
antbig 0:ad97421fb1fb 222 int timeout_transmit = 0;
antbig 0:ad97421fb1fb 223 int i = 0;
antbig 8:0edc7dfb7f7e 224 //printf("Start sending moving trame\n");
antbig 0:ad97421fb1fb 225 // Build the TxPacket first in RAM, then we'll send in one go
antbig 0:ad97421fb1fb 226
antbig 0:ad97421fb1fb 227 TxBuf[0] = 0xff;
antbig 0:ad97421fb1fb 228 TxBuf[1] = 0xff;
antbig 0:ad97421fb1fb 229
antbig 0:ad97421fb1fb 230 // ID
antbig 0:ad97421fb1fb 231 TxBuf[2] = ID;
antbig 0:ad97421fb1fb 232 sum += TxBuf[2];
antbig 0:ad97421fb1fb 233
antbig 0:ad97421fb1fb 234 // packet Length
antbig 0:ad97421fb1fb 235 TxBuf[3] = 3+bytes;
antbig 0:ad97421fb1fb 236 sum += TxBuf[3];
antbig 0:ad97421fb1fb 237
antbig 0:ad97421fb1fb 238
antbig 0:ad97421fb1fb 239 // Instruction
antbig 0:ad97421fb1fb 240 TxBuf[4]=0x83;//toujours 0x83 dans le cas d'un syncwrite
antbig 0:ad97421fb1fb 241 sum += TxBuf[4];
antbig 0:ad97421fb1fb 242
antbig 0:ad97421fb1fb 243
antbig 0:ad97421fb1fb 244 // Start Address
antbig 0:ad97421fb1fb 245 TxBuf[5] = start;//addresse du registre à modifier
antbig 0:ad97421fb1fb 246 sum += TxBuf[5];
antbig 0:ad97421fb1fb 247
antbig 0:ad97421fb1fb 248 // data
antbig 0:ad97421fb1fb 249 for (char i=0; i<bytes ; i++) {
antbig 0:ad97421fb1fb 250 TxBuf[6+i] = data[i];
antbig 0:ad97421fb1fb 251 sum += TxBuf[6+i];
antbig 8:0edc7dfb7f7e 252 //printf(" Data : 0x%x\n",TxBuf[6+i]);
antbig 0:ad97421fb1fb 253 }
antbig 0:ad97421fb1fb 254
antbig 0:ad97421fb1fb 255 // checksum
antbig 0:ad97421fb1fb 256 TxBuf[6+bytes] = 0xFF - sum;
antbig 0:ad97421fb1fb 257
antbig 0:ad97421fb1fb 258
antbig 0:ad97421fb1fb 259 /* Transmission de la trame construite precedemment dans le tableau TxBuf
antbig 0:ad97421fb1fb 260 */
antbig 0:ad97421fb1fb 261 while ((timeout_transmit<100) && (i < (7+bytes))) {
antbig 0:ad97421fb1fb 262 if (AX12_Serial.writeable()) {
antbig 0:ad97421fb1fb 263 AX12_Serial.putc(TxBuf[i]);
antbig 0:ad97421fb1fb 264 i++;
antbig 0:ad97421fb1fb 265 timeout_transmit = 0;
antbig 0:ad97421fb1fb 266 } else timeout_transmit++;
antbig 0:ad97421fb1fb 267 }
antbig 0:ad97421fb1fb 268
antbig 0:ad97421fb1fb 269 if (timeout_transmit == 100 ) { // dans le cas d'une sortie en timeout pour ne pas rester bloquer !
antbig 0:ad97421fb1fb 270 return(-1);
antbig 0:ad97421fb1fb 271 }
antbig 0:ad97421fb1fb 272
antbig 0:ad97421fb1fb 273 // Wait for data to transmit
antbig 0:ad97421fb1fb 274 wait (0.005);
antbig 0:ad97421fb1fb 275 return(0);//OK trame envoyé
antbig 0:ad97421fb1fb 276 }
antbig 0:ad97421fb1fb 277
antbig 0:ad97421fb1fb 278 /****************************************************************************************/
antbig 0:ad97421fb1fb 279 /* FUNCTION NAME: AX12_write */
antbig 0:ad97421fb1fb 280 /* DESCRIPTION : Fonction pour envoyer des trames aux AX12 */
antbig 0:ad97421fb1fb 281 /****************************************************************************************/
antbig 5:dcd817534b57 282 int AX12_write(SerialHalfDuplex& AX12_Serial, int ID, int start, int bytes, char* data, int flag)
antbig 0:ad97421fb1fb 283 {
antbig 0:ad97421fb1fb 284 // 0xff, 0xff, ID, Length, Intruction(write), Address, Param(s), Checksum
antbig 5:dcd817534b57 285 // = AX12_Serial1;
antbig 0:ad97421fb1fb 286 char TxBuf[16];
antbig 0:ad97421fb1fb 287 char sum = 0;
antbig 0:ad97421fb1fb 288 char Status[6];
antbig 0:ad97421fb1fb 289
antbig 0:ad97421fb1fb 290 int timeout = 0;
antbig 0:ad97421fb1fb 291 int plen = 0;
antbig 0:ad97421fb1fb 292 int flag_out = 0;
antbig 0:ad97421fb1fb 293 int timeout_transmit = 0;
antbig 0:ad97421fb1fb 294 int i = 0;
antbig 0:ad97421fb1fb 295 /*int poubelle = 0;
antbig 0:ad97421fb1fb 296 int count = 0;
antbig 0:ad97421fb1fb 297 char vidage[50];*/
antbig 0:ad97421fb1fb 298
antbig 0:ad97421fb1fb 299 typedef enum {Header1, Header2, ident, length, erreur, checksum} type_etat;
antbig 0:ad97421fb1fb 300 type_etat etat = Header1;
antbig 0:ad97421fb1fb 301
antbig 0:ad97421fb1fb 302 // Build the TxPacket first in RAM, then we'll send in one go
antbig 0:ad97421fb1fb 303 TxBuf[0] = 0xff;
antbig 0:ad97421fb1fb 304 TxBuf[1] = 0xff;
antbig 0:ad97421fb1fb 305
antbig 0:ad97421fb1fb 306 // ID
antbig 0:ad97421fb1fb 307 TxBuf[2] = ID;
antbig 0:ad97421fb1fb 308 sum += TxBuf[2];
antbig 0:ad97421fb1fb 309
antbig 0:ad97421fb1fb 310 // packet Length
antbig 0:ad97421fb1fb 311 TxBuf[3] = 3+bytes;
antbig 0:ad97421fb1fb 312 sum += TxBuf[3];
antbig 0:ad97421fb1fb 313
antbig 0:ad97421fb1fb 314 // Instruction
antbig 0:ad97421fb1fb 315 if (flag == 1) {
antbig 0:ad97421fb1fb 316 TxBuf[4]=0x04;
antbig 0:ad97421fb1fb 317 sum += TxBuf[4];
antbig 0:ad97421fb1fb 318 } else {
antbig 0:ad97421fb1fb 319 TxBuf[4]=0x03;
antbig 0:ad97421fb1fb 320 sum += TxBuf[4];
antbig 0:ad97421fb1fb 321 }
antbig 0:ad97421fb1fb 322
antbig 0:ad97421fb1fb 323 // Start Address
antbig 0:ad97421fb1fb 324 TxBuf[5] = start;
antbig 0:ad97421fb1fb 325 sum += TxBuf[5];
antbig 0:ad97421fb1fb 326
antbig 0:ad97421fb1fb 327
antbig 0:ad97421fb1fb 328 // data
antbig 0:ad97421fb1fb 329 for (char i=0; i<bytes ; i++) {
antbig 0:ad97421fb1fb 330 TxBuf[6+i] = data[i];
antbig 0:ad97421fb1fb 331 sum += TxBuf[6+i];
antbig 0:ad97421fb1fb 332 }
antbig 0:ad97421fb1fb 333
antbig 0:ad97421fb1fb 334 // checksum
antbig 0:ad97421fb1fb 335 TxBuf[6+bytes] = 0xFF - sum;
antbig 0:ad97421fb1fb 336
antbig 0:ad97421fb1fb 337
antbig 0:ad97421fb1fb 338
antbig 0:ad97421fb1fb 339 /* Transmission de la trame construite precedemment dans le tableau TxBuf
antbig 0:ad97421fb1fb 340 */
antbig 0:ad97421fb1fb 341 while ((timeout_transmit<100) && (i < (7+bytes))) {
antbig 0:ad97421fb1fb 342 if (AX12_Serial.writeable()) {
antbig 0:ad97421fb1fb 343 AX12_Serial.putc(TxBuf[i]);
antbig 0:ad97421fb1fb 344 i++;
antbig 0:ad97421fb1fb 345 timeout_transmit = 0;
antbig 0:ad97421fb1fb 346 } else timeout_transmit++;
antbig 0:ad97421fb1fb 347 }
antbig 0:ad97421fb1fb 348
antbig 0:ad97421fb1fb 349 if (timeout_transmit == 100 ) { // dans le cas d'une sortie en timeout pour ne pas rester bloquer !
antbig 0:ad97421fb1fb 350 return(-1);
antbig 0:ad97421fb1fb 351 }
antbig 0:ad97421fb1fb 352 /* Transmission effectuée on va ensuite récuperer la trame de retour renvoyer par le servomoteur
antbig 0:ad97421fb1fb 353 */
antbig 0:ad97421fb1fb 354
antbig 0:ad97421fb1fb 355
antbig 0:ad97421fb1fb 356 // Wait for data to transmit
antbig 0:ad97421fb1fb 357 wait (0.005);
antbig 0:ad97421fb1fb 358
antbig 0:ad97421fb1fb 359 // make sure we have a valid return
antbig 0:ad97421fb1fb 360 Status[4]=0x00;
antbig 0:ad97421fb1fb 361
antbig 0:ad97421fb1fb 362 // we'll only get a reply if it was not broadcast
antbig 0:ad97421fb1fb 363 if (ID!=0xFE) {
antbig 0:ad97421fb1fb 364
antbig 0:ad97421fb1fb 365
antbig 0:ad97421fb1fb 366 /* Partie de reception de la trame de retour
antbig 0:ad97421fb1fb 367 */
antbig 0:ad97421fb1fb 368 while ((flag_out != 1) && (timeout < MAX_TIMEOUT)) {
antbig 0:ad97421fb1fb 369 // Les differents etats de l'automate on été créés au debut de la fonction write !
antbig 0:ad97421fb1fb 370 switch (etat) {
antbig 0:ad97421fb1fb 371 case Header1:
antbig 0:ad97421fb1fb 372 if (AX12_Serial.readable()) { // reception du premier Header ( 0xFF )
antbig 0:ad97421fb1fb 373 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 374 timeout = 0;
antbig 0:ad97421fb1fb 375 if (Status[plen] == 0xFF ) {
antbig 0:ad97421fb1fb 376 etat = Header2;
antbig 0:ad97421fb1fb 377 plen++;
antbig 0:ad97421fb1fb 378
antbig 0:ad97421fb1fb 379 } else etat = Header1;
antbig 0:ad97421fb1fb 380 } else timeout++;
antbig 0:ad97421fb1fb 381 break;
antbig 0:ad97421fb1fb 382
antbig 0:ad97421fb1fb 383
antbig 0:ad97421fb1fb 384 case Header2:
antbig 0:ad97421fb1fb 385 if (AX12_Serial.readable()) { // reception du second Header ( 0xFF )
antbig 0:ad97421fb1fb 386 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 387 timeout = 0;
antbig 0:ad97421fb1fb 388 if (Status[plen] == 0xFF ) {
antbig 0:ad97421fb1fb 389 etat = ident;
antbig 0:ad97421fb1fb 390 plen++;
antbig 0:ad97421fb1fb 391 } else {
antbig 0:ad97421fb1fb 392 etat = Header1;
antbig 0:ad97421fb1fb 393 plen = 0;
antbig 0:ad97421fb1fb 394 }
antbig 0:ad97421fb1fb 395 } else timeout++;
antbig 0:ad97421fb1fb 396 break;
antbig 0:ad97421fb1fb 397
antbig 0:ad97421fb1fb 398 case ident:
antbig 0:ad97421fb1fb 399 if (AX12_Serial.readable()) { // reception de l'octet correspondant à l'ID du servomoteur
antbig 0:ad97421fb1fb 400 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 401 timeout = 0;
antbig 0:ad97421fb1fb 402 if (Status[plen] == ID ) {
antbig 0:ad97421fb1fb 403 etat = length;
antbig 0:ad97421fb1fb 404 plen++;
antbig 0:ad97421fb1fb 405 } else {
antbig 0:ad97421fb1fb 406 etat = Header1;
antbig 0:ad97421fb1fb 407 plen = 0;
antbig 0:ad97421fb1fb 408 }
antbig 0:ad97421fb1fb 409 } else timeout++;
antbig 0:ad97421fb1fb 410 break;
antbig 0:ad97421fb1fb 411
antbig 0:ad97421fb1fb 412 case length:
antbig 0:ad97421fb1fb 413 if (AX12_Serial.readable()) { // reception de l'octet correspondant à la taille ( taille = 2 + nombre de paramètres )
antbig 0:ad97421fb1fb 414 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 415 timeout = 0;
antbig 0:ad97421fb1fb 416 if (Status[plen] == 2 ) { // dans la trame de retour d'un write il n'y a pas de paramètre la taille vaudra donc 2!!
antbig 0:ad97421fb1fb 417 etat = erreur;
antbig 0:ad97421fb1fb 418 plen++;
antbig 0:ad97421fb1fb 419 } else {
antbig 0:ad97421fb1fb 420 etat = Header1;
antbig 0:ad97421fb1fb 421 plen = 0;
antbig 0:ad97421fb1fb 422 }
antbig 0:ad97421fb1fb 423 } else timeout++;
antbig 0:ad97421fb1fb 424 break;
antbig 0:ad97421fb1fb 425
antbig 0:ad97421fb1fb 426 case erreur:
antbig 0:ad97421fb1fb 427 if (AX12_Serial.readable()) { //reception de l'octet correspondant au code d'erreurs eventuels ( 0 = pas d'erreur )
antbig 0:ad97421fb1fb 428 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 429 timeout = 0;
antbig 0:ad97421fb1fb 430 plen++;
antbig 0:ad97421fb1fb 431 etat = checksum;
antbig 0:ad97421fb1fb 432 } else timeout++;
antbig 0:ad97421fb1fb 433
antbig 0:ad97421fb1fb 434 case checksum:
antbig 0:ad97421fb1fb 435 if (AX12_Serial.readable()) { // recpetion du dernier octet ( Checksum ) >>> checksum = NOT ( ID + length ) >>>> dans le cas de la reception d'un write
antbig 0:ad97421fb1fb 436 Status[plen] = AX12_Serial.getc();
antbig 0:ad97421fb1fb 437 timeout = 0;
antbig 0:ad97421fb1fb 438 flag_out = 1;
antbig 0:ad97421fb1fb 439 etat = Header1;
antbig 0:ad97421fb1fb 440 } else timeout++;
antbig 0:ad97421fb1fb 441 break;
antbig 0:ad97421fb1fb 442 }
antbig 0:ad97421fb1fb 443 }
antbig 0:ad97421fb1fb 444
antbig 0:ad97421fb1fb 445 if (timeout == MAX_TIMEOUT ) { // 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
antbig 0:ad97421fb1fb 446 return(-1);
antbig 0:ad97421fb1fb 447 }
antbig 0:ad97421fb1fb 448
antbig 0:ad97421fb1fb 449 // Build the TxPacket first in RAM, then we'll send in one go
antbig 0:ad97421fb1fb 450 }
antbig 0:ad97421fb1fb 451
antbig 0:ad97421fb1fb 452 return(Status[4]); // retourne le code d'erreur ( octect 5 de la trame de retour )
antbig 0:ad97421fb1fb 453 }
antbig 1:116040d14164 454
antbig 1:116040d14164 455
antbig 1:116040d14164 456 /****************************************************************************************/
antbig 1:116040d14164 457 /* FUNCTION NAME: AX12_read */
antbig 1:116040d14164 458 /* DESCRIPTION : Lire des données dans un registre de l'AX12 */
antbig 1:116040d14164 459 /****************************************************************************************/
antbig 5:dcd817534b57 460 int AX12_read(SerialHalfDuplex& AX12_Serial, int ID, int start, int bytes, char* data)
antbig 1:116040d14164 461 {
antbig 1:116040d14164 462
antbig 5:dcd817534b57 463 //SerialHalfDuplex AX12_Serial = AX12_Serial1;
antbig 1:116040d14164 464 char PacketLength = 0x3;
antbig 1:116040d14164 465 char TxBuf[16];
antbig 1:116040d14164 466 char sum = 0;
antbig 1:116040d14164 467 char Status[16];
antbig 1:116040d14164 468
antbig 1:116040d14164 469 int timeout = 0;
antbig 1:116040d14164 470 int plen = 0;
antbig 1:116040d14164 471 int flag_out = 0;
antbig 1:116040d14164 472 int timeout_transmit = 0;
antbig 1:116040d14164 473 int i = 0;
antbig 1:116040d14164 474 int enable = 0;
antbig 1:116040d14164 475 // int poubelle = 0;
antbig 1:116040d14164 476 // int count = 0;
antbig 1:116040d14164 477 // char vidage[50];
antbig 1:116040d14164 478
antbig 1:116040d14164 479 typedef enum {Header1, Header2, ident, length, erreur, reception, checksum} type_etat;
antbig 1:116040d14164 480 type_etat etat = Header1;
antbig 1:116040d14164 481
antbig 1:116040d14164 482 Status[4] = 0xFE; // return code
antbig 1:116040d14164 483
antbig 1:116040d14164 484
antbig 1:116040d14164 485
antbig 1:116040d14164 486
antbig 1:116040d14164 487
antbig 1:116040d14164 488 /*********************************** CREATION DE LA TRAME A EVOYER *****************************************/
antbig 1:116040d14164 489
antbig 1:116040d14164 490
antbig 1:116040d14164 491 // Build the TxPacket first in RAM, then we'll send in one go
antbig 1:116040d14164 492
antbig 1:116040d14164 493 TxBuf[0] = 0xff;
antbig 1:116040d14164 494 TxBuf[1] = 0xff;
antbig 1:116040d14164 495
antbig 1:116040d14164 496 // ID
antbig 1:116040d14164 497 TxBuf[2] = ID;
antbig 1:116040d14164 498 sum += TxBuf[2];
antbig 1:116040d14164 499
antbig 1:116040d14164 500 // Packet Length
antbig 1:116040d14164 501 TxBuf[3] = PacketLength+bytes; // Length = 4 ; 2 + 1 (start) = 1 (bytes)
antbig 1:116040d14164 502 sum += TxBuf[3]; // Accululate the packet sum
antbig 1:116040d14164 503
antbig 1:116040d14164 504
antbig 1:116040d14164 505 // Instruction - Read
antbig 1:116040d14164 506 TxBuf[4] = 0x2;
antbig 1:116040d14164 507 sum += TxBuf[4];
antbig 1:116040d14164 508
antbig 1:116040d14164 509 // Start Address
antbig 1:116040d14164 510 TxBuf[5] = start;
antbig 1:116040d14164 511 sum += TxBuf[5];
antbig 1:116040d14164 512
antbig 1:116040d14164 513 // Bytes to read
antbig 1:116040d14164 514 TxBuf[6] = bytes;
antbig 1:116040d14164 515 sum += TxBuf[6];
antbig 1:116040d14164 516
antbig 1:116040d14164 517 // Checksum
antbig 1:116040d14164 518 TxBuf[7] = 0xFF - sum;
antbig 1:116040d14164 519
antbig 1:116040d14164 520 /********************************************TRAME CONSTRUITE DANS TxBuf***************************************/
antbig 1:116040d14164 521
antbig 1:116040d14164 522
antbig 1:116040d14164 523
antbig 1:116040d14164 524
antbig 1:116040d14164 525 /* Transmission de la trame construite precedemment dans le tableau TxBuf
antbig 1:116040d14164 526 */
antbig 1:116040d14164 527 while ((timeout_transmit<1000) && (i < (7+bytes))) {
antbig 1:116040d14164 528 if (AX12_Serial.writeable()) {
antbig 1:116040d14164 529 AX12_Serial.putc(TxBuf[i]);
antbig 1:116040d14164 530 i++;
antbig 1:116040d14164 531 timeout_transmit = 0;
antbig 1:116040d14164 532 } else timeout_transmit++;
antbig 1:116040d14164 533 }
antbig 1:116040d14164 534
antbig 1:116040d14164 535 if (timeout_transmit == 1000 ) { // dans le cas d'une sortie en timeout pour ne pas rester bloquer !
antbig 1:116040d14164 536 return(-1);
antbig 1:116040d14164 537 }
antbig 1:116040d14164 538 /* Transmission effectuée on va ensuite récuperer la trame de retour renvoyer par le servomoteur
antbig 1:116040d14164 539 */
antbig 1:116040d14164 540 // Wait for the bytes to be transmitted
antbig 1:116040d14164 541 wait (0.001);
antbig 1:116040d14164 542
antbig 1:116040d14164 543 // Skip if the read was to the broadcast address
antbig 1:116040d14164 544 if (ID != 0xFE) {
antbig 1:116040d14164 545
antbig 1:116040d14164 546 /* Partie de reception de la trame de retour
antbig 1:116040d14164 547 */
antbig 1:116040d14164 548 while ((flag_out != 1) && (timeout < (1000*bytes))) {
antbig 1:116040d14164 549 // Les differents etats de l'automate on été créés au debut de la fonction write !
antbig 1:116040d14164 550 switch (etat) {
antbig 1:116040d14164 551 case Header1:
antbig 1:116040d14164 552 if (AX12_Serial.readable()) { // reception du premier Header ( 0xFF )
antbig 1:116040d14164 553 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 554 timeout = 0;
antbig 1:116040d14164 555 if (Status[plen] == 0xFF ) {
antbig 1:116040d14164 556 etat = Header2;
antbig 1:116040d14164 557 plen++;
antbig 1:116040d14164 558
antbig 1:116040d14164 559 } else etat = Header1;
antbig 1:116040d14164 560 } else timeout++;
antbig 1:116040d14164 561 break;
antbig 1:116040d14164 562
antbig 1:116040d14164 563
antbig 1:116040d14164 564 case Header2:
antbig 1:116040d14164 565 if (AX12_Serial.readable()) { // reception du second Header ( 0xFF )
antbig 1:116040d14164 566 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 567 timeout = 0;
antbig 1:116040d14164 568 if (Status[plen] == 0xFF ) {
antbig 1:116040d14164 569 etat = ident;
antbig 1:116040d14164 570 plen++;
antbig 1:116040d14164 571
antbig 1:116040d14164 572 } else if (Status[plen] == ID ) { // PERMET D'EVITER CERTAINES ERREUR LORSQU'ON LIT PLUSIEURS REGISTRES !!!!
antbig 1:116040d14164 573 Status[plen] = 0;
antbig 1:116040d14164 574 plen++;
antbig 1:116040d14164 575 Status[plen] = ID;
antbig 1:116040d14164 576 etat = length;
antbig 1:116040d14164 577 plen++;
antbig 1:116040d14164 578
antbig 1:116040d14164 579 } else {
antbig 1:116040d14164 580
antbig 1:116040d14164 581 etat = Header1;
antbig 1:116040d14164 582 plen = 0;
antbig 1:116040d14164 583 }
antbig 1:116040d14164 584 } else timeout++;
antbig 1:116040d14164 585 break;
antbig 1:116040d14164 586
antbig 1:116040d14164 587 case ident:
antbig 1:116040d14164 588 if (AX12_Serial.readable()) { // reception de l'octet correspondant à l'ID du servomoteur
antbig 1:116040d14164 589 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 590 timeout = 0;
antbig 1:116040d14164 591 if (Status[plen] == ID ) {
antbig 1:116040d14164 592 etat = length;
antbig 1:116040d14164 593 plen++;
antbig 1:116040d14164 594
antbig 1:116040d14164 595 } else {
antbig 1:116040d14164 596 etat = Header1;
antbig 1:116040d14164 597 plen = 0;
antbig 1:116040d14164 598 }
antbig 1:116040d14164 599 } else timeout++;
antbig 1:116040d14164 600 break;
antbig 1:116040d14164 601
antbig 1:116040d14164 602 case length:
antbig 1:116040d14164 603 if (AX12_Serial.readable()) { // reception de l'octet correspondant à la taille ( taille = 2 + nombre de paramètres )
antbig 1:116040d14164 604 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 605 timeout = 0;
antbig 1:116040d14164 606 if (Status[plen] == (bytes+2) ) {
antbig 1:116040d14164 607 etat = erreur;
antbig 1:116040d14164 608 plen++;
antbig 1:116040d14164 609
antbig 1:116040d14164 610 } else {
antbig 1:116040d14164 611 etat = Header1;
antbig 1:116040d14164 612 plen = 0;
antbig 1:116040d14164 613 }
antbig 1:116040d14164 614 } else timeout++;
antbig 1:116040d14164 615 break;
antbig 1:116040d14164 616
antbig 1:116040d14164 617 case erreur:
antbig 1:116040d14164 618 if (AX12_Serial.readable()) { //reception de l'octet correspondant au code d'erreurs eventuels ( 0 = pas d'erreur )
antbig 1:116040d14164 619 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 620 timeout = 0;
antbig 1:116040d14164 621 plen++;
antbig 1:116040d14164 622
antbig 1:116040d14164 623 etat = reception;
antbig 1:116040d14164 624 } else timeout++;
antbig 1:116040d14164 625
antbig 1:116040d14164 626 case reception:
antbig 1:116040d14164 627 while ( enable < bytes ) { // reception du ou des octect(s) de donnés ( suivant la valeur de la variable length )
antbig 1:116040d14164 628 if (AX12_Serial.readable()) {
antbig 1:116040d14164 629 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 630 timeout = 0;
antbig 1:116040d14164 631 plen++;
antbig 1:116040d14164 632 enable++;
antbig 1:116040d14164 633
antbig 1:116040d14164 634 } else timeout++;
antbig 1:116040d14164 635 }
antbig 1:116040d14164 636 etat = checksum;
antbig 1:116040d14164 637 break;
antbig 1:116040d14164 638
antbig 1:116040d14164 639 case checksum:
antbig 1:116040d14164 640 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!!
antbig 1:116040d14164 641 Status[plen] = AX12_Serial.getc();
antbig 1:116040d14164 642 timeout = 0;
antbig 1:116040d14164 643 flag_out = 1;
antbig 1:116040d14164 644 etat = Header1;
antbig 1:116040d14164 645 } else timeout++;
antbig 1:116040d14164 646 break;
antbig 1:116040d14164 647
antbig 1:116040d14164 648 default:
antbig 1:116040d14164 649 break;
antbig 1:116040d14164 650 }
antbig 1:116040d14164 651 }
antbig 1:116040d14164 652
antbig 1:116040d14164 653
antbig 1:116040d14164 654 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
antbig 1:116040d14164 655 return(-1);
antbig 1:116040d14164 656 }
antbig 1:116040d14164 657
antbig 1:116040d14164 658
antbig 1:116040d14164 659 // copie des données dans le tableau data
antbig 1:116040d14164 660 for (int i=0; i < Status[3]-2 ; i++) {
antbig 1:116040d14164 661 data[i] = Status[5+i];
antbig 1:116040d14164 662 }
antbig 1:116040d14164 663
antbig 1:116040d14164 664 } // toute la partie precedente ne s'effectue pas dans le cas d'un appel avec un broadcast ID (ID!=0xFE)
antbig 1:116040d14164 665
antbig 1:116040d14164 666 return(Status[4]); // retourne le code d'erreur ( octect 5 de la trame de retour )
antbig 1:116040d14164 667 }
antbig 1:116040d14164 668
antbig 1:116040d14164 669