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