CRAC Team
/
Capt_couleur_smart
Prg du capteur de couleur avec liaison série et CAN Programme non testé
main.cpp
- Committer:
- loicmnt
- Date:
- 2022-01-14
- Revision:
- 5:b91bf2db2ea8
- Parent:
- 4:6212d7723c16
File content as of revision 5:b91bf2db2ea8:
#include "mbed.h" #include "glibr.h" #define SR 1 // 0 = CAN | 1 = serie #define DEBUG_COM 0 // 0 = pas de debug | 1 = print de toutes les tramme serie recue et envoyées #define DEBUG_SENS 0 // 0 = pas de debug | 1 = print de la couleur (fait pour tester le capteur en lui même) #if ((DEBUG_COM==1)||(DEBUG_SENS==1)) #define DEBUG_GENERAL 1 #else #define DEBUG_GENERAL 0 #endif #if (SR==0) #define OFFSET_DATA 2 // format CAN #else #define OFFSET_DATA 7 // format SR #endif // Adress #define data_adress_sensor 0x01 // pID specifique a chaque capteur (between 0x00 and 0xFD) #define data_adress_general 0xFF // pID génerale pour communiquer avec tout les capteurs #define adress_color_sensor 0x4B0 // CAN ID pareil pour tout les capteur (seulement pour le CAN) // Request commands #define send_RGB 0x00 #define send_RED 0x01 #define send_GREEN 0x02 #define send_BLUE 0x03 #define send_PROXIMITY 0x04 #define send_COLOR 0x05 // Setup commands #define setup_LED 0x08 #define setup_PROXIMITY_THRESHOLD 0x09 // Masks #define HIGH 0xFF00 #define LOW 0x00FF // Buffer #define CAN_MAX 256 #define SR_MAX 1024 Serial USB_link(USBTX, USBRX); // USB initialization RawSerial sr(PA_9,PA_10); // SR: PA_9 = TX ; PA_10 = RX glibr capt1(PB_7,PB_6); // I²C initialization : PB_7 = SDA ; PB_6 = SCL CAN can(PA_11, PA_12); PwmOut LED(D9); DigitalIn srTx(PA_9, PullUp); // Buffer CAN CANMessage canBuffer[CAN_MAX]; int canRempli = 0; int canVide = 0; int canPerdu = 0; //Buffer SR uint8_t srBuffer[SR_MAX]; int srRempli = 0; int srVide = 0; int srPerdu = 0; // traitement tramme SR int etatSR = 0; uint8_t checksumSR1 = 0,checksumSR2 = 0,calc_checksumSR1=0,calc_checksumSR2=0; uint8_t lenSR = 0, idSR,cmdSR, dataSR=0; // tramme retour char message[15], Len; int DataLen = 0; // capteur et traitement uint16_t r,g,b ; // RGB values in 2 bytes uint8_t a ; // proximity value in 1 byte char proximity_tresh = 250, color; char state; // PROTOTYPE DE FONCTIONS // /** Fonction initialisant les fréquence et le capteur APDS9960 * @return true si pas d'erreur, false sinon */ bool initialization(void); /** Fonction récéptionnant la tramme serie * et la stockant dans un buffer en attendant traitement */ void srRead(); /** Fonction decryptant la tramme serie recue dans le buffer */ void srTraitement(); /** Fonction receptionnant les messaages CAN dans un Buffer */ void canRead(); /** Fonction traitant le message et envoyant la reponse au format herkulex ou en simple message can * @param commande : la commande du message recu (voir table com) * @param data : la data du message recu si il y en a */ void envoi(char commande, char data); bool initialization(void) { #if DEBUG_GENERAL // baud init USB_link.baud(115200); #endif can.frequency(1000000); sr.baud(115200); // LED init LED.period_ms(10); LED.write(0.5); // Sensor init if( (capt1.ginit()) && (capt1.enableLightSensor(true)) && (capt1.enableProximitySensor(true)) ) { return true; } else { return false; } } int main() { #if DEBUG_GENERAL if (initialization()) USB_link.printf("Init finie\r\n"); else USB_link.printf("Erreur pendant l'init\r\n"); #else initialization(); #endif if(SR==0) { // liaison CAN selectionné #if DEBUG_COM int adColor = adress_color_sensor; int adSensor = data_adress_sensor; USB_link.printf("type de com : CAN\r\n"); USB_link.printf("ID can : %03X\r\ndata ID : %02X\r\n", adColor, adSensor); #endif can.attach(canRead); // le premier octet est toujours pareil message[0] = data_adress_sensor; } else if (SR==1) { // liaison Serie selectionnée #if DEBUG_COM USB_link.printf("type de com : Serie\r\n"); USB_link.printf("Id : %x\r\n",data_adress_sensor); #endif sr.attach(&srRead); // octets toujours pareil : message[0]=0xff; // Start of packet message[1]=0xff; message[3]= data_adress_sensor; // pID } while(1) { // acquisition capteurs // capt1.readRedLight(r); capt1.readGreenLight(g); capt1.readBlueLight(b); capt1.readProximity(a); // calcul couleur // if (a<proximity_tresh) { color = 0 ; // 0 Rien } else if ((r > g )&&(r > b )) { color = 1 ; // 1 rouge } else if ((g > r )&&(g > b )) { color = 2 ; // 2 vert } else if ((b > r )&&(b > g )) { color = 3 ; // 3 bleu } else { color = 4 ; // 4 noir ou blanc } #if DEBUG_SENS USB_link.printf("rouge : %x, vert : %x, bleu : %x ",r, g, b); USB_link.printf("color : %x \r\n", color); USB_link.printf("color : %hu \r\n", color); wait(0.5); #endif // liaison CAN // if (canRempli != canVide) { // si le buffer CAN n'est pas vide canVide++; if (canVide == CAN_MAX) canVide = 0; if ((canBuffer[canRempli-1].id==adress_color_sensor)&((canBuffer[canRempli-1].data[0]==data_adress_general)|(canBuffer[canRempli-1].data[0]==data_adress_sensor))) { if (canBuffer[canRempli-1].len==3){ envoi(canBuffer[canRempli-1].data[1],canBuffer[canRempli-1].data[2]); } else { envoi(canBuffer[canRempli-1].data[1],0); } } } // liaison serie // if (srRempli != srVide) { // si le buffer serie n'est pas vide srTraitement(); // traitement de la tramme sr } } } void srRead() { srBuffer[srRempli++] = sr.getc(); //stockage nouvel octet dans le buffer if (srRempli==SR_MAX) srRempli = 0; // on recommence au debut du tableau si le max est atteint if (srRempli == srVide) { // buffer plein on perd un caractère (le premier recu) srVide++; // le message commence donc un octet plus tard if (srVide == SR_MAX) srVide = 0; // on recommence au debut du tableau si le max est atteint srPerdu++; // mise en memoire : un message perdu } } void srTraitement() { uint8_t c = srBuffer[srVide++]; // c prends la valeur d'un octet de la tramme if (srVide == SR_MAX) srVide = 0; // on recommence au debut du tableau si le max est atteint #if DEBUG_COM USB_link.printf("etat : %d recu : %x\r\n",etatSR,c); #endif switch (etatSR) { case 0: // Verification premier octet header (FF) if (c==0xFF) { etatSR = 1; } break; case 1: // Verification dexième octet header (FF) calc_checksumSR1 = 0; if (c==0xFF) { etatSR = 2; } else { etatSR = 0; } break; case 2: // traitement octet Packet Size calc_checksumSR1 ^= c; lenSR=c; if (lenSR<7) etatSR =0; //impossible else etatSR = 3; break; case 3: // traitement octet ID calc_checksumSR1 ^= c; idSR = c; if (idSR!= data_adress_sensor) etatSR =0; //le capteur n'est pas concerné else etatSR = 4; break; case 4: // traitement octet CMD calc_checksumSR1 ^= c; cmdSR = c; etatSR = 5; break; case 5: // traitement octet checkSum1 checksumSR1 = c; etatSR = 6; break; case 6: // traitement octet checkSum2 checksumSR2 = c; if (lenSR>7) { etatSR =7;// si le message comporte des datas } else { dataSR = 0x00; etatSR=8; } break; case 7: // octet data (un seul octet dans notre cas) calc_checksumSR1 ^= c; dataSR=c; etatSR =8; break; } if (etatSR==8){// verification des checksum et envoi calc_checksumSR1 &=0xFE ; calc_checksumSR2 = (~calc_checksumSR1) & 0xFE; etatSR = 0; if ((checksumSR1 == calc_checksumSR1) && (checksumSR2 == calc_checksumSR2)) { // Verification validité de la tramme envoi(cmdSR,dataSR);// dataSR ne sera utilise que dans les cas de setup } } } void canRead() { can.read(canBuffer[canRempli++]); if (canRempli==CAN_MAX) { canRempli = 0; } if (canRempli == canVide) { // buffer plein on perd un message canVide++; if (canVide == CAN_MAX) canVide = 0; canPerdu++; } } void envoi(char commande, char data) { #if SR==0 // mode CAN message[1]=commande+0x40; // CMD (doc) #endif // Preparation des datas // switch (commande) { case send_RGB: message[OFFSET_DATA+0] = (char)((r & HIGH)>>8); // data message[OFFSET_DATA+1] = (char) (r & LOW); message[OFFSET_DATA+2] = (char)((g & HIGH)>>8); message[OFFSET_DATA+3] = (char) (g & LOW); message[OFFSET_DATA+4] = (char)((b & HIGH)>>8); message[OFFSET_DATA+5] = (char) (b & LOW); DataLen=6; break; case send_RED: message[OFFSET_DATA+0]= (char)((r & HIGH)>>8); message[OFFSET_DATA+1]= (char) (r & LOW); DataLen=2; break; case send_GREEN: message[OFFSET_DATA+0]= (char)((g & HIGH)>>8); message[OFFSET_DATA+1]= (char) (g & LOW); DataLen=2; break; case send_BLUE: message[OFFSET_DATA+0]= (char)((b & HIGH)>>8); message[OFFSET_DATA+1]= (char) (b & LOW); DataLen=2; break; case send_PROXIMITY: message[OFFSET_DATA+0] = (char) a ; DataLen=1; break; case send_COLOR: message[OFFSET_DATA+0] = color; DataLen=1; break; case setup_LED: LED.write(data/255.0); // a modifier : ON/OFF seulement DataLen=0; break; case setup_PROXIMITY_THRESHOLD : proximity_tresh = data; DataLen=0; break; } Len = DataLen+OFFSET_DATA;//calcul longueur msg #if SR==1 // format SR // message[2]= Len; message[4]=commande+0x40; // CMD (doc) int j; // calcul des checksums // message[5]=0; // checksum1 for(j=2; j<message[2]; j++) { if ((j!=5)&&(j!=6)) message[5] ^= message[j]; } message[5] &= 0xFE; // checksum1 message[6] = (~message[5]) & 0xFE;//checksum2 // envoi // //sr.enable_output(true); for (j=0; j<message[2]; j++) { while (!sr.writeable()); // attente liaison libre sr.putc(message[j]); // ecriture octet par octet wait_us(100); #if DEBUG_COM USB_link.printf("envoi : %x\r\n",message[j]); #endif } // sr.disable_output(true) #else // format CAN // can.write(CANMessage(adress_color_sensor,message,Len)); #endif }