Smart coffee machine with facial recognition and remote control

Dependencies:   Camera_LS_Y201 EthernetInterface EthernetNetIf HTTPClient SRF05 TextLCD mbed-rtos mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Camera_LS_Y201.cpp Source File

Camera_LS_Y201.cpp

00001 /**
00002  * =============================================================================
00003  * LS-Y201 device driver class (Version 0.0.1)
00004  * Reference documents: LinkSprite JPEG Color Camera Serial UART Interface
00005  *                      January 2010
00006  * =============================================================================
00007  * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems)
00008  *
00009  * Permission is hereby granted, free of charge, to any person obtaining a copy
00010  * of this software and associated documentation files (the "Software"), to deal
00011  * in the Software without restriction, including without limitation the rights
00012  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00013  * copies of the Software, and to permit persons to whom the Software is
00014  * furnished to do so, subject to the following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included in
00017  * all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00020  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00022  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00024  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00025  * THE SOFTWARE.
00026  * =============================================================================
00027  */
00028 
00029 #include "Camera_LS_Y201.h"
00030 
00031 /**
00032  * Create.
00033  *
00034  * @param tx Transmitter.
00035  * @param rx Receiver.
00036  */
00037 Camera_LS_Y201::Camera_LS_Y201(PinName tx, PinName rx) : serial(tx, rx) {
00038     serial.baud(38400);
00039     setImageSize(Camera_LS_Y201::ImageSize320x280);
00040 }
00041 
00042 /**
00043  * Dispose.
00044  */
00045 Camera_LS_Y201::~Camera_LS_Y201() {
00046 }
00047 
00048 /**
00049  * Reset module.
00050  *
00051  * @return Error code.
00052  */
00053 Camera_LS_Y201::ErrorCode Camera_LS_Y201::reset() {
00054     uint8_t send[4] = {
00055         0x56,
00056         0x00,
00057         0x26,
00058         0x00
00059     };
00060     uint8_t recv[4];
00061 
00062     waitIdle();
00063     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00064         return SendError;
00065     }
00066     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00067         return RecvError;
00068     }
00069     if ((recv[0] == 0x76)
00070             && (recv[1] == 0x00)
00071             && (recv[2] == 0x26)
00072             && (recv[3] == 0x00)) {
00073         ErrorCode r = waitInitEnd();
00074         if (r != NoError) {
00075             return r;
00076         }
00077         wait(4);
00078         return NoError;
00079     } else {
00080         return UnexpectedReply;
00081     }
00082 }
00083 
00084 /**
00085  * Set image size.
00086  *
00087  * @param is Image size.
00088  * @return Error code.
00089  */
00090 Camera_LS_Y201::ErrorCode Camera_LS_Y201::setImageSize(ImageSize is) {
00091     uint8_t send[9] = {
00092         0x56,
00093         0x00,
00094         0x31,
00095         0x05,
00096         0x04,
00097         0x01,
00098         0x00,
00099         0x19,
00100         0x00    // 0x11:320x240, 0x00:640x480, 0x22:160x120
00101     };
00102     uint8_t recv[5];
00103     switch (is) {
00104         case ImageSize160x120:
00105             send[8] = 0x22;
00106             break;
00107         case ImageSize320x280:
00108             send[8] = 0x11;
00109             break;
00110         case ImageSize640x480:
00111             send[8] = 0x00;
00112             break;
00113         default:
00114             return InvalidArguments;
00115     }
00116     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00117         return SendError;
00118     }
00119     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00120         return RecvError;
00121     }
00122     if ((recv[0] == 0x76)
00123             && (recv[1] == 0x00)
00124             && (recv[2] == 0x31)
00125             && (recv[3] == 0x00)
00126             && (recv[4] == 0x00)) {
00127         wait(1);
00128         return reset();
00129     } else {
00130         return UnexpectedReply;
00131     }
00132 }
00133 
00134 /**
00135  * Take picture.
00136  *
00137  * @return Error code.
00138  */
00139 Camera_LS_Y201::ErrorCode Camera_LS_Y201::takePicture() {
00140     uint8_t send[5] = {
00141         0x56,
00142         0x00,
00143         0x36,
00144         0x01,
00145         0x00
00146     };
00147     uint8_t recv[5];
00148 
00149     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00150         return SendError;
00151     }
00152     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00153         return RecvError;
00154     }
00155 
00156     if ((recv[0] == 0x76)
00157             && (recv[1] == 0x00)
00158             && (recv[2] == 0x36)
00159             && (recv[3] == 0x00)
00160             && (recv[4] == 0x00)) {
00161         /*
00162          * I think the camera need a time for operating.
00163          * But there is no any comments on the documents.
00164          */
00165         wait_ms(100);
00166         return NoError;
00167     } else {
00168         return UnexpectedReply;
00169     }
00170 }
00171 
00172 /**
00173  * Read jpeg file size.
00174  *
00175  * @param fileSize File size.
00176  * @return Error code.
00177  */
00178 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileSize(int *fileSize) {
00179     uint8_t send[5] = {
00180         0x56,
00181         0x00,
00182         0x34,
00183         0x01,
00184         0x00
00185     };
00186     uint8_t recv[9];
00187 
00188     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00189         return SendError;
00190     }
00191     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00192         return RecvError;
00193     }
00194 
00195     if ((recv[0] == 0x76)
00196             && (recv[1] == 0x00)
00197             && (recv[2] == 0x34)
00198             && (recv[3] == 0x00)
00199             && (recv[4] == 0x04)
00200             && (recv[5] == 0x00)
00201             && (recv[6] == 0x00)) {
00202         *fileSize = ((recv[7] & 0x00ff) << 8)
00203                     | ((recv[8] & 0x00ff) << 0);
00204         return NoError;
00205     } else {
00206         return UnexpectedReply;
00207     }
00208 }
00209 
00210 /**
00211  * Read jpeg file content.
00212  *
00213  * @param func A pointer to a call back function.
00214  * @return Error code.
00215  */
00216 Camera_LS_Y201::ErrorCode Camera_LS_Y201::readJpegFileContent(
00217     void (*func)(int done, int total, uint8_t *buf, size_t siz, char *rep),
00218     void (*sendSocket)(char *chaine, int taille_chaine, char *reponse, int longueur_reponse_max),
00219     char *response
00220 ) {
00221     uint8_t send[16] = {
00222         0x56,
00223         0x00,
00224         0x32,
00225         0x0C,
00226         0x00,
00227         0x0A,
00228         0x00,
00229         0x00,
00230         0x00, // MH
00231         0x00, // ML
00232         0x00,
00233         0x00,
00234         0x00, // KH
00235         0x00, // KL
00236         0x00, // XX
00237         0x00  // XX
00238     };
00239     
00240     // Doit etre inférieur au MSS du réseau. MTU = MSS + TCP/IP header
00241     // généralement, MSS = 1460
00242     int TAILLE_BUF = 1024;
00243     
00244     uint8_t body[TAILLE_BUF]; // Valeur par défaut 32
00245     uint16_t m = 0; // Staring address.
00246     uint16_t k = sizeof(body); // Packet size.
00247     uint16_t x = 10;    // Interval time. XX XX * 0.01m[sec]
00248     bool end = false;
00249 
00250     /*
00251      * Get the data size.
00252      */
00253     int siz_done = 0;
00254     int siz_total = 0;
00255     ErrorCode r = readJpegFileSize(&siz_total);
00256     printf("\tBreizh size totale %d \r\n", siz_total);
00257     
00258     // Envoi de la taille au serveur
00259     char requete[10];
00260     sprintf(requete,"%d",siz_total);
00261     printf("\tRequete %s \r\n\r", requete);
00262     sendSocket(requete, sizeof(requete), response, 30); // Envoi de la taille de l'image. Réception de "TAILLE OK"
00263     printf("\tReponse %s : %s\r\n\r", requete, response);     
00264     
00265     if (r != NoError) {
00266         return r;
00267     }
00268 
00269     do {
00270         send[8] = (m >> 8) & 0xff;
00271         send[9] = (m >> 0) & 0xff;
00272         send[12] = (k >> 8) & 0xff;
00273         send[13] = (k >> 0) & 0xff;
00274         send[14] = (x >> 8) & 0xff;
00275         send[15] = (x >> 0) & 0xff;
00276         /*
00277          * Send a command.
00278          */
00279         if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00280             return SendError;
00281         }
00282         /*
00283          * Read the header of the response.
00284          */
00285         uint8_t header[5];
00286         if (!recvBytes(header, sizeof(header), 2 * 1000 * 1000)) {
00287             return RecvError;
00288         }
00289         /*
00290          * Check the response and fetch an image data.
00291          */
00292         if ((header[0] == 0x76)
00293                 && (header[1] == 0x00)
00294                 && (header[2] == 0x32)
00295                 && (header[3] == 0x00)
00296                 && (header[4] == 0x00)) {
00297             if (!recvBytes(body, sizeof(body), 2 * 1000 * 1000)) {
00298                 return RecvError;
00299             }
00300             siz_done += sizeof(body);
00301             if (func != NULL) {
00302                 if (siz_done > siz_total) {
00303                     siz_done = siz_total;
00304                 }
00305                 func(siz_done, siz_total, body, sizeof(body), response);
00306             }
00307             for (int i = 1; i < sizeof(body); i++) {
00308                 if ((body[i - 1] == 0xFF) && (body[i - 0] == 0xD9)) {
00309                     end = true;
00310                 }
00311             }
00312         } else {
00313             return UnexpectedReply;
00314         }
00315         /*
00316          * Read the footer of the response.
00317          */
00318         uint8_t footer[5];
00319         if (!recvBytes(footer, sizeof(footer), 2 * 1000 * 1000)) {
00320             return RecvError;
00321         }
00322 
00323         m += sizeof(body);
00324     } while (!end);
00325     
00326     if(siz_total % TAILLE_BUF > 0) {
00327         printf("\tBreizh siz_total non divisible par taille_buffer\r\n");
00328     }
00329     else {
00330         printf("\tBreizh siz_total divisible par taille_buffer\r\n");
00331     }
00332     
00333     return NoError;
00334 }
00335 
00336 /**
00337  * Stop taking pictures.
00338  *
00339  * @return Error code.
00340  */
00341 Camera_LS_Y201::ErrorCode Camera_LS_Y201::stopTakingPictures() {
00342     uint8_t send[5] = {
00343         0x56,
00344         0x00,
00345         0x36,
00346         0x01,
00347         0x03
00348     };
00349     uint8_t recv[5];
00350 
00351     if (!sendBytes(send, sizeof(send), 200 * 1000)) {
00352         return SendError;
00353     }
00354     if (!recvBytes(recv, sizeof(recv), 200 * 1000)) {
00355         return RecvError;
00356     }
00357 
00358     if ((recv[0] == 0x76)
00359             && (recv[1] == 0x00)
00360             && (recv[2] == 0x36)
00361             && (recv[3] == 0x00)
00362             && (recv[4] == 0x00)) {
00363         /*
00364          * I think the camera need a time for operating.
00365          * But there is no any comments on the documents.
00366          */
00367         wait_ms(100);
00368         return NoError;
00369     } else {
00370         return UnexpectedReply;
00371     }
00372 }
00373 
00374 /**
00375  * Wait init end codes.
00376  *
00377  * @return True if the data sended.
00378  */
00379 Camera_LS_Y201::ErrorCode Camera_LS_Y201::waitInitEnd() {
00380     static const char *PWR_ON_MSG = "Init end\x0d\x0a";
00381     for (int i = 0; i < strlen(PWR_ON_MSG); i++) {
00382         static const int MAXCNT = 128;
00383         int cnt = 0;
00384         uint8_t c = 0x00;
00385         do {
00386             if (!recvBytes(&c, sizeof(c), 500 * 1000)) {
00387                 return Timeout;
00388             }
00389 
00390             /*
00391              * What is the version of the camera.
00392              * You can check the version with this code.
00393              *
00394              * VC0703 1.00
00395              * 3o ctrl in
00396              * Init end
00397              */
00398 #if 0
00399             printf("%c", c);
00400 #endif
00401 
00402             cnt++;
00403             if (MAXCNT < cnt) {
00404                 return UnexpectedReply;
00405             }
00406         } while (c != PWR_ON_MSG[i]);
00407     }
00408     return NoError;
00409 }
00410 
00411 /**
00412  * Send bytes to camera module.
00413  *
00414  * @param buf Pointer to the data buffer.
00415  * @param len Length of the data buffer.
00416  *
00417  * @return True if the data sended.
00418  */
00419 bool Camera_LS_Y201::sendBytes(uint8_t *buf, size_t len, int timeout_us) {
00420     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00421         int cnt = 0;
00422         while (!serial.writeable()) {
00423             wait_us(1);
00424             cnt++;
00425             if (timeout_us < cnt) {
00426                 return false;
00427             }
00428         }
00429         serial.putc(buf[i]);
00430     }
00431     return true;
00432 }
00433 
00434 /**
00435  * Receive bytes from camera module.
00436  *
00437  * @param buf Pointer to the data buffer.
00438  * @param len Length of the data buffer.
00439  *
00440  * @return True if the data received.
00441  */
00442 bool Camera_LS_Y201::recvBytes(uint8_t *buf, size_t len, int timeout_us) {
00443     for (uint32_t i = 0; i < (uint32_t)len; i++) {
00444         int cnt = 0;
00445         while (!serial.readable()) {
00446             wait_us(1);
00447             cnt++;
00448             if (timeout_us < cnt) {
00449                 return false;
00450             }
00451         }
00452         buf[i] = serial.getc();
00453     }
00454     return true;
00455 }
00456 
00457 /**
00458  * Wait received.
00459  *
00460  * @return True if the data received.
00461  */
00462 bool Camera_LS_Y201::waitRecv() {
00463     while (!serial.readable()) {
00464     }
00465     return true;
00466 }
00467 
00468 /**
00469  * Wait idle state.
00470  */
00471 bool Camera_LS_Y201::waitIdle() {
00472     while (serial.readable()) {
00473         serial.getc();
00474     }
00475     return true;
00476 }