Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: pixy2.cpp
- Revision:
- 0:dde1b9d6c9d6
- Child:
- 1:dd81f4065b6b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixy2.cpp Thu Feb 28 08:34:15 2019 +0000 @@ -0,0 +1,359 @@ +#include "pixy2.h" + +PIXY2::PIXY2(PinName tx, PinName rx, int debit) +{ + _Pixy2 = new Serial (tx, rx, debit); + _Pixy2->attach (callback(this,&PIXY2::pixy2_getByte)); + etat = idle; + rPointer = 0; + Pixy2_buffer = (Byte*) malloc (0x100); +} + +void PIXY2::pixy2_getByte () // Interruption de la pixy2 +{ + static Byte startPoint; + T_Word *buffer; + + Pixy2_buffer[wPointer] = _Pixy2->getc(); // On stocke l'octet reçu dans la première case dispo du tableau temporaire + wPointer++; + + switch (etat) { + case messageSent : // Si on a envoyé une requete => on attend un entête + if ( (wPointer - rPointer) >= 2) { // On attend d'avoir reçu 2 octets + startPoint = wPointer - 1; + buffer = (T_Word*) &Pixy2_buffer[startPoint]; //On pointe la structure sur les 2 derniers octets reçus + if ((buffer->mot == PIXY2_CSSYNC) || (buffer->mot == PIXY2_SYNC)) { + etat = receivingHeader; // On passe à l'état réception de l'entête + rPointer = startPoint; + if (buffer->mot == PIXY2_SYNC) frameContainChecksum = 0; // On mémorise qu'il n'y a pas de checksum à vérifier + else frameContainChecksum = 1; // On mémorise qu'il y a un checksum à vérifier + } + } + break; + + case receivingHeader : //Si on est en train de recevoir un entête (entre le SYNC et... La fin de l'entête) + if ((frameContainChecksum && ((wPointer - rPointer) == PIXY2_CSHEADERSIZE)) || (!frameContainChecksum && ((wPointer - rPointer) == PIXY2_NCSHEADERSIZE))) { + //Si on a reçu 6 octets pour une trame avec checksum ou 4 pour une trame sans checksum + etat = headerReceived; //On passe à entête reçu + dataSize = Pixy2_buffer[startPoint+3]; // Et on lit la taille de la payload + } + break; + + case headerReceived : // Si on vient de recevoir le premier octet de données + startPoint = wPointer; // On enregistre sa position + etat = receivingData; // Et on dit que l'on est en train de recevoir des données + break; + + case receivingData : // Si on est en train de recevoir des données. + if (wPointer == (dataSize + startPoint)) etat = dataReceived; //Quand on a reçu toutes les données promises on dit que c'est OK + break; + + default : // On ne traite volontairement ici pas tous les cas, en particulier idle et dataReceived. C'est à la fonction de le faire ! Le reste est lié à des réceptions de données. + break; + } +} + +int PIXY2::pixy2_sndGetVersion (void){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 0; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_VERS; + msg.frame.header.pixLength = 0; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndGetResolution (void){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 1; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_RESOL; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = 0; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetCameraBrightness (Byte brightness){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 1; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_BRIGHT; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = brightness; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetServo (Word s0, Word s1){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 4; + T_Word tmp; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_SERVOS; + msg.frame.header.pixLength = 1; + tmp.mot = s0; + msg.frame.data[0] = tmp.octet[0]; + msg.frame.data[1] = tmp.octet[1]; + tmp.mot = s1; + msg.frame.data[2] = tmp.octet[0]; + msg.frame.data[3] = tmp.octet[1]; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetLED (Byte red, Byte green, Byte blue){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 3; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_LED; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = red; + msg.frame.data[1] = green; + msg.frame.data[2] = blue; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetLamp (Byte upper, Byte lower){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 2; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_LED; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = upper; + msg.frame.data[1] = lower; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndGetFPS (void){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 0; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_FPS; + msg.frame.header.pixLength = 0; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndGetBlocks (Byte sigmap, Byte maxBloc){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 2; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_BLOC; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = sigmap; + msg.frame.data[1] = maxBloc; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndGetMainFeature (Byte type, Byte feature){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 2; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_LINE; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = type; + msg.frame.data[1] = feature; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetMode (Byte mode){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 1; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_MODE; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = mode; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetNexTurn (Word angle){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 2; + T_Word tmp; + tmp.mot = angle; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_TURN; + msg.frame.header.pixLength = 1; + tmp.mot = angle; + msg.frame.data[0] = tmp.octet[0]; + msg.frame.data[1] = tmp.octet[1]; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetDefaultTurn (Word angle){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 2; + T_Word tmp; + tmp.mot = angle; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_DEFTURN; + msg.frame.header.pixLength = 1; + tmp.mot = angle; + msg.frame.data[0] = tmp.octet[0]; + msg.frame.data[1] = tmp.octet[1]; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndSetVector (Byte vectorIndex){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 1; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_VECTOR; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = vectorIndex; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndReverseVector (void){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 0; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_SET_REVERSE; + msg.frame.header.pixLength = 0; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +int PIXY2::pixy2_sndGetRGB (Word x, Word y, Byte saturate){ + T_pixy2sendBuffer msg; + int i = 0, dataSize = 3; + msg.frame.header.pixSync = PIXY2_SYNC; + msg.frame.header.pixType = PIXY2_ASK_VIDEO; + msg.frame.header.pixLength = 1; + msg.frame.data[0] = x; + msg.frame.data[1] = y; + msg.frame.data[2] = saturate; + do { + while(!_Pixy2->writable()); + _Pixy2->putc(msg.data[i]); + i++; + } while (i<(PIXY2_NCSHEADERSIZE+dataSize)); + return 0; +} + +/* La fonction est bloquante à l'envoi (pas vraiment le choix), mais elle est non bloquante en réception. On essayera de faire une fonction non bloquante en envoi avec write, mais c'est pas la priorité. +Le principe c'est de stocker dans un buffer circulaire les données au fur et à mesure qu'elle sont reçues et de traiter uniquement en castant les infos. Pour cela, il faut recevoir et stocker. */ + +int PIXY2::pixy2_getVersion (T_Pixy2Version *version){ + + T_pixy2RcvHeader *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[rPointer]; + int cr = 0; + + switch (etat) { + case idle : + PIXY2::pixy2_sndGetVersion(); + etat = messageSent; + rPointer = wPointer; + cr = -2; //Busy + break; + + case dataReceived : + if (frameContainChecksum) { + if ( pixy2_validateChecksum (&Pixy2_buffer[rPointer]) ) { + if (msg->pixType == PIXY2_REP_VERS) { + version = (T_Pixy2Version*) &Pixy2_buffer[rPointer + PIXY2_CSHEADERSIZE]; + etat = idle; + } else cr = -7; // Type Error + } else cr = -3; // Checksum Error + } else { + if (msg->pixType == PIXY2_REP_VERS) { + version = (T_Pixy2Version*) &Pixy2_buffer[rPointer + PIXY2_NCSHEADERSIZE]; + etat = idle; + } else cr = -7; // Type Error + } + break; + + default : + cr = -1; // Busy + break; + } + return cr; +} + +int PIXY2::pixy2_getResolution (T_Pixy2Resolution *resolution){return 0;} +int PIXY2::pixy2_setCameraBrightness (Byte brightness){return 0;} +int PIXY2::pixy2_setServos (Word s0, Word s1){return 0;} +int PIXY2::pixy2_setLED (Byte red, Byte green, Byte blue){return 0;} +int PIXY2::pixy2_setLamp (Byte upper, Byte lower){return 0;} +int PIXY2::pixy2_getFPS (T_pixy2Framerate framerate){return 0;} +int PIXY2::pixy2_getBlocks (Byte sigmap, Byte maxBloc){return 0;} +int PIXY2::pixy2_getMainFeature (Byte type, Byte features){return 0;} +int PIXY2::pixy2_getAllFeature (Byte features){return 0;} +int PIXY2::pixy2_setMode (Byte mode){return 0;} +int PIXY2::pixy2_setNexTurn (Word angle){return 0;} +int PIXY2::pixy2_setDefaultTurn (Word angle){return 0;} +int PIXY2::pixy2_setVector (Byte vectorIndex){return 0;} +int PIXY2::pixy2_ReverseVector (void){return 0;} +int PIXY2::pixy2_getRGB (Word x, Word y, Byte saturate, T_pixy2Pixel *pixel){return 0;} + +int PIXY2::pixy2_validateChecksum (Byte* tab){ + Word sum; + + + return 1;} +