Max Bismuth
/
MX28-Scan3D_DB03-IRQ
Scan Mines
Fork of MX28-Scan3D_DB03-IRQ by
main.cpp
- Committer:
- wumzi
- Date:
- 2015-06-03
- Revision:
- 5:a81d551cfffa
- Parent:
- 4:ca5bdb807fa1
File content as of revision 5:a81d551cfffa:
/************************************ * DB le 28/05/2015 MX28-Scan3D_DB05-IRQ * Mesure de luminosité avec adafruit GA1A12S202 : Ok * Codage Accelerometre * Programme final conforme au protocole de communication * Reste à faire : - lecture accéléromètre * - vérification de positions atteintes par servomoteurs * * Pilotage MX-106 (SERVO_VERTICAL) et MX-28 (SERVO_HORIZONTALE) * avec liaison série : Trame Scan3D * &abcdefghij/ début $, fin /, longueur variable * Réception Série par IRQ * Piloter les positions des 2 servomoteurs V et H * Débit = 57142bit/s * * Matrice Led Neopixels * Une seule instance possible avec la classe NeoStrip : * Problème, pour nous il faut 3 voies : panelLed1, panelLed2 et panelLed3 ! * les 2 autres voies "faite à la main" avec les fonctions : * - void writeBitCode1(numMatriceLed) et void writeBitCode0(numMatriceLed) * - void writeMatriceLed(int numMatriceLed, int N, int valRouge, int valVerte, int valBleu) * * Cible : Carte mbed_S3DHQ_2015 *************************************/ #include "mbed.h" #include "MX-28_DefConstantes.h" #include "NeoStrip.h" #define ID_SERVO_VERTICAL 10 // MX-106R #define ID_SERVO_HORIZONTALE 1 // MX-28R #define N1 64 // Nombre de pixels(Led) du panneau Led 1 #define N2 128 // Nombre de pixels(Led) du panneau Led 2 #define N3 128 // Nombre de pixels(Led) du panneau Led 3 #define NBRE_ACK 256 // nombre d'acquisition pour la moyenne sur mesure luminosité #define NBRE_ACQ_ACC 100 // nombre d'acquisition pour la moyenne sur mesure accceleration DigitalOut led01(LED1); DigitalOut led02(LED2); DigitalOut led03(LED3); DigitalOut led04(LED4); DigitalOut dir(p17); DigitalOut laser(p5); DigitalOut panelLed2(p7); DigitalOut panelLed3(p8); AnalogIn mesLux(p20); // Entrée pour mesure de luminosité int valeurLux; short valeurAccX; short valeurAccY; short valeurAccZ; unsigned char numeroOctetRecu=0; char octetRecu; //premier octet reçu char bufferRec[12]; // buffer de réception serialPc Serial serialPc(USBTX, USBRX); // tx, rx, écarté car driver incompatible avec LabVIEW //Serial serialPc(p28, p27); // tx, rx (c'est l'uart2 du LPC1768) Serial uartMX28(p13, p14); // tx, rx pour MX28 (uart1 du LPC1768) //Serial uartMX28(p28, p27); // tx, rx pour MX28 (uart1 du LPC1768) NeoStrip panelLed1(p6, N1); // creation de l'objet panelLed1 cde par p6, N1 Led //NeoStrip panelLed2(p7, N2); // creation de l'objet panelLed2 cde par p7, N2 Led //NeoStrip panelLed3(p8, N3); // creation de l'objet panelLed3 cde par p8, N3 Led I2C i2cLsm303D(p9, p10); // Création objet et affectation SDA1, SCL1 pour l'accéléromètre LSM303D const int addrLsm303D = 0x3C; // adresse du LSM303D avec SDO/SA0=0 //--------------------------------------------------------------------------------------------- // Set Motor gain //------------------------------------------------------------------------------------------------ // Envoi de la trame de pilotage a un servomoteur MX-28 void write (char id, char longueurTrame, char instruction, char param1 = NULL, char param2 = NULL, char param3 = NULL, char param4 = NULL) { char Cks; Cks = ~( id + longueurTrame + instruction + param1 + param2 + param3 + param4); //calcul du checkSum //serialPc.printf("Cks : %d\n", Cks); dir = 1; uartMX28.putc(0xFF); uartMX28.putc(0xFF); uartMX28.putc(id); uartMX28.putc(longueurTrame); uartMX28.putc(instruction); if (longueurTrame >= 3) { uartMX28.putc(param1); } if (longueurTrame >= 4) { uartMX28.putc(param2); } if (longueurTrame >= 5) { uartMX28.putc(param3); } if (longueurTrame >= 6) { uartMX28.putc(param4); } uartMX28.putc(Cks); wait_us(MX28_WAIT_AFTER_WRITE); // Attendre l'envoie complet de la trame. dir = 0; } void setMotorGainSpeed(){ char min = 1; char max = 2; write(ID_SERVO_VERTICAL, 5, MX28_WRITE_DATA, MX28_MOVING_SPEED_L, min, max); write(ID_SERVO_HORIZONTALE, 5, MX28_WRITE_DATA, MX28_MOVING_SPEED_L, min, max); serialPc.printf("gains set\n"); } // Set goal position of engine void setPosition(char id, int goal) { char goal_h = goal >> 8; char goal_l = goal; //serialPc.printf("Goal set : %d %d %d\n", goal, goal_h, goal_l); write(id, 5, MX28_WRITE_DATA, MX28_GOAL_POSITION_L, goal_l, goal_h); } //--------------------------------------------------------------------------------------------- // Lire position d'un servomoteur MX-28 ou MX-106 int lirePositionServo(char idServo) { //Vider le buffer de réception uartMX28 while(uartMX28.readable()) { uartMX28.getc(); } write(idServo, 4, MX28_READ_DATA, MX28_PRESENT_POSITION_L,2); char octetRecuMX[8]; char i=0; int tempoReception=0; while((tempoReception < 1000000)&&(i<8)) { if(uartMX28.readable()) { octetRecuMX[i] = uartMX28.getc(); i++; } tempoReception++; } int valeurLue = octetRecuMX[6] * 256 + octetRecuMX[5]; return valeurLue; } //--------------------------------------------------------------------------------------------- // fonction écriture Bit code 1 et 0 pour matrice Led Neopixels void writeBitCode1(int numMatriceLed) { if(numMatriceLed==2){panelLed2=1;} else{panelLed3=1;} for(int i=0;i<37;i++) {int x = i*i*i; x=x*x;} // pour T1H=700ns if(numMatriceLed==2){panelLed2=0;} else{panelLed3=0;} for(int i=0;i<16;i++) {int x = i*i*i; x=x*x;} // pour T1L= 450ns + 150ns pour exe fonction } void writeBitCode0(int numMatriceLed) { if(numMatriceLed==2){panelLed2=1;} else{panelLed3=1;} for(int i=0;i<15;i++) {int x = i*i*i; x=x*x;} // pour T0H=350ns if(numMatriceLed==2){panelLed2=0;} else{panelLed3=0;} for(int i=0;i<32;i++) {int x = i*i*i; x=x*x;} // pour T0L=650ns+150ns pour exe fonction } //--------------------------------------------------------------------------------------------- // fonction écriture matrice Led Neopixels void writeMatriceLed(int numMatriceLed, int N, int valRouge, int valVerte, int valBleu) { int valeurCouleurVRB = valVerte*65536+valRouge*256+valBleu; for(int i=0;i<N;i++) { int mask_1sur24Bits = 0x800000; for(int j=0;j<24;j++) { if(valeurCouleurVRB & mask_1sur24Bits) { writeBitCode1(numMatriceLed); } else { writeBitCode0(numMatriceLed); } mask_1sur24Bits = mask_1sur24Bits >> 1; } } } // Mesure de la luminosité avec moyenne sur NBRE_ACK int mesureDeLux() { float sommeMesure=0; int valL; for(int i=0; i<NBRE_ACK;i++) { sommeMesure += mesLux; } valL = ((sommeMesure*3.3*1000)/NBRE_ACK); // mesure en mV return valL; } short mesureAcc(char sub) { char dataLu[2]; short valAcc=0; int sommeValAcc=0; for(int i=0; i<NBRE_ACQ_ACC;i++) { dataLu[0]=sub; // OUT_X_L_A ou Y ou Z, registre acc X,Y,Z i2cLsm303D.write(addrLsm303D, dataLu, 1); i2cLsm303D.read(addrLsm303D, dataLu, 1); valAcc = dataLu[0]; dataLu[0]=sub+1; // OUT_X_H_A registre acc X i2cLsm303D.write(addrLsm303D, dataLu, 1); i2cLsm303D.read(addrLsm303D, dataLu, 1); valAcc |= dataLu[0]<<8; sommeValAcc += valAcc; } valAcc = sommeValAcc/NBRE_ACQ_ACC; int val = int (valAcc*2000)/32768; valAcc = val; //prendre la partie entière return valAcc; } //--------------------------------------------------------------------------------------------- // fonction appelée par interruption si réception sur serialPc void receptionPc() { led04 =1; octetRecu = serialPc.getc(); if(octetRecu == '$') { numeroOctetRecu = 0; memset(&bufferRec[0], 0, sizeof(bufferRec)); } else { bufferRec[numeroOctetRecu-1] = octetRecu; ///Debug serialPc.printf("%c",octetRecu); //////// } if(octetRecu == '/') { if ((bufferRec[0] == '0')&&(numeroOctetRecu == 8)) { // si c'est une commande de position MX28+MX106 int b = bufferRec[1] - 0x30; int c = bufferRec[2] - 0x30; int d = bufferRec[3] - 0x30; int e = bufferRec[4] - 0x30; int f = bufferRec[5] - 0x30; int g = bufferRec[6] - 0x30; int anglePositionVerticale = (b * 100) + (c * 10) + d; int valeurPositionVerticale = anglePositionVerticale * 4095 / 360; setPosition(ID_SERVO_VERTICAL, valeurPositionVerticale); int anglePositionHorizontale = (e * 100) + (f * 10) + g; int valeurPositionHorizontale = anglePositionHorizontale * 4095 / 360; wait_us(3200); // Attendre fin de la trame de réponse du Servo Vertical setPosition(ID_SERVO_HORIZONTALE, valeurPositionHorizontale); //Pour Debug //serialPc.printf("idServ = %d \tvaleurPosition = %d\n",ID_SERVO_VERTICAL, valeurPositionVerticale); //serialPc.printf("idServ = %d \tvaleurPosition = %d\n",ID_SERVO_HORIZONTALE, valeurPositionHorizontale); //--Solution simple pour retourner la position mais sans tester "positions demandéess=atteintes" // test positions atteintes à faire wait(1); //pour laisser le temps au moteur de se déplacer, int incr = 0; int valeurLue = lirePositionServo(ID_SERVO_VERTICAL); int valeurAngleVertCentiemeDegres = (valeurLue * 100) * 360/4096; wait(0.2); valeurLue = lirePositionServo(ID_SERVO_HORIZONTALE); int valeurAngleHorizontaleCentiemeDegres = (valeurLue * 100) * 360/4096; /*while ((abs(valeurAngleVertCentiemeDegres - anglePositionVerticale * 100) > 100 || abs(valeurAngleHorizontaleCentiemeDegres - anglePositionHorizontale * 100) > 100) && incr < 60) { wait(1); int valeurLue = lirePositionServo(ID_SERVO_VERTICAL); valeurAngleVertCentiemeDegres = (valeurLue * 100) * 360/4096; wait(0.2); valeurLue = lirePositionServo(ID_SERVO_HORIZONTALE); valeurAngleHorizontaleCentiemeDegres = (valeurLue * 100) * 360/4096; incr++; //pc.printf(" Goal = %d ; Current = %d", goalHoriz, currentPositionHoriz); }*/ bufferRec[0] = '1'; //pour retourner la mesure de la position numeroOctetRecu = 2; //pour retourner la mesure de la position } if ((bufferRec[0] == '1')&&(numeroOctetRecu == 2)) { // si demande de lecture de la position led03 = 1; // indic int valeurLue = lirePositionServo(ID_SERVO_VERTICAL); int valeurAngleVertCentiemeDegres = (valeurLue * 100) * 360/4096; wait(0.2); valeurLue = lirePositionServo(ID_SERVO_HORIZONTALE); int valeurAngleHorizontaleCentiemeDegres = (valeurLue * 100) * 360/4096; serialPc.printf("$OK_moteurs_%0#5d_%0#5d/\n",valeurAngleVertCentiemeDegres, valeurAngleHorizontaleCentiemeDegres); led03 = 0; // } if ((bufferRec[0] == '2')&&(numeroOctetRecu == 3)) { // si c'est une commande Laser if (bufferRec[1] == '1') { //Laser on led02 = 1; // indic commande Laser on laser = 1; serialPc.printf("$OK_laser_1/\n"); } else { //Laser off led02 = 0; // indic commande Laser off laser = 0; serialPc.printf("$OK_laser_0/\n"); } } if ((bufferRec[0] == '3')&&(numeroOctetRecu == 11)) { // si commande panneau led supérieur led03 = 1; // indic commande panneau led supérieur // A terminer int b = bufferRec[1] - 0x30; int c = bufferRec[2] - 0x30; int d = bufferRec[3] - 0x30; int e = bufferRec[4] - 0x30; int f = bufferRec[5] - 0x30; int g = bufferRec[6] - 0x30; int h = bufferRec[7] - 0x30; int i = bufferRec[8] - 0x30; int j = bufferRec[9] - 0x30; int colorLed1 = (b*100+c*10+d)*65536+(e*100+f*10+g)*256+(h*100+i*10+j); panelLed1.clear(); for(int n=0;n<N1;n++) { panelLed1.setPixel(n,colorLed1); } panelLed1.write(); wait(0.2); serialPc.printf("$OK_panneau_1_%c%c%c_%c%c%c_%c%c%c/\n",bufferRec[1],bufferRec[2],bufferRec[3],bufferRec[4],bufferRec[5],bufferRec[6],bufferRec[7],bufferRec[8],bufferRec[9]); led03 = 0; // indic commande panneau led supérieur } if ((bufferRec[0] == '4')&&(numeroOctetRecu == 11)) { // si commande panneau led latéral 1 led03 = 1; // indic commande panneau led int b = bufferRec[1] - 0x30; int c = bufferRec[2] - 0x30; int d = bufferRec[3] - 0x30; int e = bufferRec[4] - 0x30; int f = bufferRec[5] - 0x30; int g = bufferRec[6] - 0x30; int h = bufferRec[7] - 0x30; int i = bufferRec[8] - 0x30; int j = bufferRec[9] - 0x30; int valeurRouge = (b*100+c*10+d); int valeurVerte = (e*100+f*10+g); int valeurBleu = (h*100+i*10+j); writeMatriceLed(2,N2,valeurRouge, valeurVerte, valeurBleu); wait(0.2); serialPc.printf("$OK_panneau_2_%c%c%c_%c%c%c_%c%c%c/\n",bufferRec[1],bufferRec[2],bufferRec[3],bufferRec[4],bufferRec[5],bufferRec[6],bufferRec[7],bufferRec[8],bufferRec[9]); led03 = 0; // indic commande panneau led } if ((bufferRec[0] == '5')&&(numeroOctetRecu == 11)) { // si commande panneau led latéral 2 led03 = 1; // indic commande panneau led int b = bufferRec[1] - 0x30; int c = bufferRec[2] - 0x30; int d = bufferRec[3] - 0x30; int e = bufferRec[4] - 0x30; int f = bufferRec[5] - 0x30; int g = bufferRec[6] - 0x30; int h = bufferRec[7] - 0x30; int i = bufferRec[8] - 0x30; int j = bufferRec[9] - 0x30; int valeurRouge = (b*100+c*10+d); int valeurVerte = (e*100+f*10+g); int valeurBleu = (h*100+i*10+j); writeMatriceLed(3,N3,valeurRouge, valeurVerte, valeurBleu); wait(0.2); serialPc.printf("$OK_panneau_3_%c%c%c_%c%c%c_%c%c%c/\n",bufferRec[1],bufferRec[2],bufferRec[3],bufferRec[4],bufferRec[5],bufferRec[6],bufferRec[7],bufferRec[8],bufferRec[9]); led03 = 0; // indic commande panneau led } if ((bufferRec[0] == '6')&&(numeroOctetRecu == 2)) { // si c'est une demande mesure accéléromètre //LECTURE ET ENVOI des mesures d'accélérations // A Faire serialPc.printf("AccX = %+-0#5d AccY = %+-0#5d AccZ = %+-0#5d\n",valeurAccX,valeurAccY,valeurAccZ); } if ((bufferRec[0] == '7')&&(numeroOctetRecu == 2)) { // si c'est une demande mesure luminosité serialPc.printf("$OK_lumiere_%0#4d/\n",valeurLux); } numeroOctetRecu = 0; } else { numeroOctetRecu++; } led04 =0; } int main() { uartMX28.baud(57142); // débit standard pour les MX-28 et -106 serialPc.baud(115200); serialPc.attach(&receptionPc); // defini la fonction interruption panelLed1.setBrightness(1); // par défaut à 50% //serialPc.printf("Entrer une commande\n"); led01 = 1; // Clear buffer memset(&bufferRec[0], 0, sizeof(bufferRec)); // Config Accelerometre char dataLu[2]; dataLu[0]=0x20; // Registre CTRL1 dataLu[1]=0x67; // Accelero ON et data rate = 100Hz i2cLsm303D.write(addrLsm303D, dataLu, 2); dataLu[0]=0x26; // Registre CTRL7 dataLu[1]=0x82; // Accelero ON et data rate = 100Hz i2cLsm303D.write(addrLsm303D, dataLu, 2); // Gain moteurs setMotorGainSpeed(); while(1) { led01 = 0; wait(0.1); led01 = 1; wait(0.1); valeurLux = mesureDeLux(); //mesure cyclique de luminosité valeurAccX = mesureAcc(0x28); valeurAccY = mesureAcc(0x2A); valeurAccZ = mesureAcc(0x2C); } }