cansat_B 2019 / Mbed 2 deprecated camera-pic-xbee

Dependencies:   mbed JPEGCamera

Files at this revision

API Documentation at this revision

Comitter:
saeichi
Date:
Mon Nov 25 08:19:58 2019 +0000
Commit message:
camera-pic-xbee;

Changed in this revision

JPEGCamera.cpp Show annotated file Show diff for this revision Revisions of this file
JPEGCamera.h Show annotated file Show diff for this revision Revisions of this file
JPEGCamera.lib Show annotated file Show diff for this revision Revisions of this file
base64.cpp Show annotated file Show diff for this revision Revisions of this file
base64.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/JPEGCamera.cpp	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,144 @@
+/* Arduino JPEGCamera Library
+ * Copyright 2010 SparkFun Electronic
+ * Written by Ryan Owens
+ * Modified by arms22
+ * Ported to mbed by yamaguch
+ */
+
+#include "JPEGCamera.h"
+
+#define min(x, y) ((x) < (y)) ? (x) : (y)
+
+const int RESPONSE_TIMEOUT = 500;
+const int DATA_TIMEOUT = 1000;
+
+JPEGCamera::JPEGCamera(PinName tx, PinName rx) : Serial(tx, rx) {
+    printf("AA\r\n");
+    baud(38400);
+    state = READY;
+}
+
+bool JPEGCamera::setPictureSize(JPEGCamera::PictureSize size, bool doReset) {
+    char buf[9] = {0x56, 0x00, 0x31, 0x05, 0x04, 0x01, 0x00, 0x19, (char) size};
+    int ret = sendReceive(buf, sizeof buf, 5);
+
+    if (ret == 5 && buf[0] == 0x76) {
+        if (doReset)
+            reset();
+        return true;
+    } else
+        return false;
+}
+
+bool JPEGCamera::isReady() {
+    return state == READY;
+}
+
+bool JPEGCamera::isProcessing() {
+    return state == PROCESSING;
+}
+
+bool JPEGCamera::takePicture(char *filename) {
+    if (state == READY) {
+        fp = fopen(filename, "wb");
+        if (fp != 0) {
+            if (takePicture()) {
+                imageSize = getImageSize();
+                address = 0;
+                state = PROCESSING;
+            } else {
+                fclose(fp);
+                printf("takePicture(%s) failed", filename);
+                state = ERROR;
+            }
+        } else {
+            printf("fopen() failed");
+            state = ERROR;
+        }
+    }
+    return state != ERROR;
+}
+
+bool JPEGCamera::processPicture() {
+    if (state == PROCESSING) {
+        if (address < imageSize) {
+            char data[1024];
+            int size = readData(data, min(sizeof(data), imageSize - address), address);
+            int ret = fwrite(data, size, 1, fp);
+            if (ret > 0)
+                address += size;
+            if (ret == 0 || address >= imageSize) {
+                stopPictures();
+                fclose(fp);
+                wait(0.1); // ????
+                state = ret > 0 ? READY : ERROR;
+            }
+        }
+    }
+
+    return state == PROCESSING || state == READY;
+}
+
+bool JPEGCamera::reset() {
+    char buf[4] = {0x56, 0x00, 0x26, 0x00};
+    int ret = sendReceive(buf, sizeof buf, 4);
+    if (ret == 4 && buf[0] == 0x76) {
+        wait(4.0);
+        state = READY;
+    } else {
+        state = ERROR;
+    }
+    return state == READY;
+}
+
+bool JPEGCamera::takePicture() {
+    char buf[5] = {0x56, 0x00, 0x36, 0x01, 0x00};
+    int ret = sendReceive(buf, sizeof buf, 5);
+
+    return ret == 5 && buf[0] == 0x76;
+}
+
+bool JPEGCamera::stopPictures() {
+    char buf[5] = {0x56, 0x00, 0x36, 0x01, 0x03};
+    int ret = sendReceive(buf, sizeof buf, 5);
+
+    return ret == 4 && buf[0] == 0x76;
+}
+
+int JPEGCamera::getImageSize() {
+    char buf[9] = {0x56, 0x00, 0x34, 0x01, 0x00};
+    int ret = sendReceive(buf, sizeof buf, 9);
+
+    //The size is in the last 2 characters of the response.
+    return (ret == 9 && buf[0] == 0x76) ? (buf[7] << 8 | buf[8]) : 0;
+}
+
+int JPEGCamera::readData(char *dataBuf, int size, int address) {
+    char buf[16] = {0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A, 0x00, 0x00,
+                    address >> 8, address & 255, 0x00, 0x00, size >> 8, size & 255, 0x00, 0x0A
+                   };
+    int ret = sendReceive(buf, sizeof buf, 5);
+
+    return (ret == 5 && buf[0] == 0x76) ? receive(dataBuf, size, DATA_TIMEOUT) : 0;
+}
+
+int JPEGCamera::sendReceive(char *buf, int sendSize, int receiveSize) {
+    while (readable()) getc();
+
+    for (int i = 0; i < sendSize; i++) putc(buf[i]);
+
+    return receive(buf, receiveSize, RESPONSE_TIMEOUT);
+}
+
+int JPEGCamera::receive(char *buf, int size, int timeout) {
+    timer.start();
+    timer.reset();
+
+    int i = 0;
+    while (i < size && timer.read_ms() < timeout) {
+        if (readable())
+            buf[i++] = getc();
+    }
+
+    return i;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/JPEGCamera.h	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,122 @@
+
+/* Arduino JPEGCamera Library
+ * Copyright 2010 SparkFun Electronics
+ * Written by Ryan Owens
+ * Modified by arms22
+ * Ported to mbed by yamaguch
+ */
+
+#ifndef JPEG_CAMERA_H
+#define JPEG_CAMERA_H
+
+#include "mbed.h"
+
+/**
+ * Interface for LinkSprite JPEG Camera module LS-Y201
+ */
+class JPEGCamera : public Serial {
+public:
+    /***/
+    enum PictureSize {
+        SIZE160x120 = 0x22,
+        SIZE320x240 = 0x11,
+        SIZE640x480 = 0x00,
+    };
+
+    /**
+     * Create JPEG Camera
+     *
+     * @param tx tx pin
+     * @param rx rx pin
+     */
+    JPEGCamera(PinName tx, PinName rx);
+
+    /**
+     * Set picture size
+     *
+     * @param size picture size (available sizes are SIZE160x120, SIZE320x240, SIZE640x480)
+     * @param doReset flag to perform reset operation after changing size
+     *
+     * @returns true if succeeded, false otherwise
+     */
+    bool setPictureSize(JPEGCamera::PictureSize size, bool doReset = true);
+
+    /**
+     * Return whether camera is ready or not
+     *
+     * @returns true if ready, false otherwise
+     */
+    bool isReady();
+
+    /**
+     * Return whether camera is processing the taken picture or not
+     *
+     * @returns true if the camera is in processing, false otherwise
+     */
+    bool isProcessing();
+
+    /**
+     * Take a picture
+     *
+     * @param filename filename to store the picture data
+     * @returns true if succeeded, false otherwise
+     */
+    bool takePicture(char *filename);
+    /**
+     * Process picture (writing the file)
+     *
+     * @returns true if no error in processing, false otherwise
+     */
+    bool processPicture();
+
+    /**
+     * Perform reset oepration (it takes 4 seconds)
+     *
+     * @returns true if succeeded, false otherwise
+     */
+    bool reset();
+
+    /**
+     * Send a picture command to the camera module
+     *
+     *  @returns true if succeeded, false otherwise
+     */
+    bool takePicture(void);
+
+    /**
+     * Send a stop pictures command to the camera module
+     *
+     *  @returns true if succeeded, false otherwise
+     */
+    bool stopPictures(void);
+
+    /**
+     * Get the picture image size
+     *
+     * @returns the actual image size in bytes
+     */
+    int getImageSize();
+
+    /**
+     * Read the picture data to the buffer
+     *
+     * @param dataBuf data buffer address to store the received data
+     * @param size data size to read
+     * @param address the address of the picture data to read
+     *
+     * @returns the size of the data read
+     */
+    int readData(char *dataBuf, int size, int address);
+
+//private:
+    Timer timer;
+    FILE *fp;
+    int imageSize;
+    int address;
+    enum State {UNKNOWN, READY, PROCESSING, ERROR = -1} state;
+    
+    int sendReceive(char *buf, int sendSize, int receiveSize);
+    int receive(char *buf, int size, int timeout);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/JPEGCamera.lib	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/cansat_B-2019/code/JPEGCamera/#64b220982d94
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base64.cpp	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,180 @@
+#include "base64.h"
+
+const char *base64::szB64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+base64::base64() : lpszOutputString(NULL)
+{
+}
+
+base64::~base64()
+{
+    if(lpszOutputString)
+        delete[] lpszOutputString;
+}
+
+const char *base64::Encode(const char *szStr, int iLens)
+{
+    int i,j;
+
+    if(lpszOutputString)
+        delete[] lpszOutputString;
+
+    if(iLens == -1)
+        iLen = strlen(szStr);
+    else
+        iLen = iLens;
+
+    lpszOutputString =
+        new char[(int)((double)(iLen)*1.5)+10];
+    for(i = 0,j = 0; i < (iLen - (iLen % 3)); i+=3)
+    {
+        lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
+        lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4) |
+                                    ((szStr[i+1] & 0xf0) >> 4)];
+        lpszOutputString[j+2] = szB64[((szStr[i+1] & 0x0f) <<2 ) |
+                                    ((szStr[i+2] & 0xc0) >> 6)];
+        lpszOutputString[j+3] = szB64[(szStr[i+2] & 0x3f)];
+        j += 4;
+    }
+    i = iLen-(iLen % 3);    // 残りのサイズを計算
+    switch(iLen % 3)
+    {
+    case 2: // 1文字分パディングが必要
+    {
+        lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
+        lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4) |
+                                    ((szStr[i+1] & 0xf0) >> 4)];
+        lpszOutputString[j+2] = szB64[((szStr[i+1] & 0x0f) <<2 )];
+        lpszOutputString[j+3] = szB64[64];  // Pad
+        lpszOutputString[j+4] = '\0';
+    }
+    break;
+    case 1: // 2文字分パディングが必要
+    {
+        lpszOutputString[j] = szB64[(szStr[i] & 0xfc) >> 2];
+        lpszOutputString[j+1] = szB64[((szStr[i] &0x03) << 4)];
+        lpszOutputString[j+2] = szB64[64];  // Pad
+        lpszOutputString[j+3] = szB64[64];  // Pad
+        lpszOutputString[j+4] = '\0';
+    }
+    break;
+    }
+    lpszOutputString[j+4] = '\0';
+
+    return lpszOutputString;
+}
+
+void base64::Encode(istream& istr, ostream& ostr, int iRet)
+{
+    int i;
+    char c[3];
+
+    i = 0;
+    while(!istr.eof())
+    {
+        c[0] = c[1] = c[2] = '\0';
+        istr.read(c,3);
+
+        ostr << szB64[(c[0] & 0xfc) >> 2];
+        i++;    if(i >= iRet && iRet != -1){ ostr << endl; i = 0; }
+        ostr << szB64[((c[0] &0x03) << 4) | ((c[1] & 0xf0) >> 4)];
+        i++;    if(i >= iRet && iRet != -1){ ostr << endl; i = 0; }
+        if(istr.gcount() == 1)
+            ostr << szB64[64];
+        else
+            ostr << szB64[((c[1] & 0x0f) <<2 ) | ((c[2] & 0xc0) >> 6)];
+        i++;    if(i >= iRet && iRet != -1){ ostr << endl; i = 0; }
+        if(istr.gcount() == 3)
+            ostr << szB64[(c[2] & 0x3f)];
+        else
+            ostr << szB64[64];
+        i++;    if(i >= iRet && iRet != -1){ ostr << endl; i = 0; }
+    }
+    ostr.flush();
+}
+
+
+int base64::FindIndexInB64(char c)
+{
+    int index = 0;
+    while(szB64[index] != '\0' && szB64[index] != c)
+        index++;
+
+    if(szB64[index] == '\0')
+        return -1;  // 見つからず
+
+    return index;   // 見つかった。
+}
+
+const char *base64::Decode(const char *szStr)
+{
+    //lpszOutputString
+    int i, j, l,iWriteCount,len;
+    char c;
+    char buf[4];
+
+    len = iLen = strlen(szStr);
+    if(lpszOutputString)
+        delete[] lpszOutputString;
+
+    iLen = (int)(((double)(iLen)/4.0)*3.0) + 4;
+
+    lpszOutputString = new char[iLen];
+
+    for(i = 0, j = 0; i < len; i+=4)
+    {
+        iWriteCount = 3;
+        for(l = 0; l < 4 && i+l<len; l++)
+        {
+            c = szStr[i+l];
+            if(c == szB64[64])  // Pad
+                iWriteCount--;
+            else {
+                buf[l] = FindIndexInB64(c);
+                //if(buf[l] == -1) error!;
+            }
+        }
+        lpszOutputString[j] = ((buf[0] << 2) & 0xfc) | ((buf[1] >> 4) & 0x03);
+        if(iWriteCount >= 2)
+            lpszOutputString[j+1] = ((buf[1] << 4) & 0xf0) | ((buf[2] >> 2) & 0x0f);
+        if(iWriteCount == 3)
+            lpszOutputString[j+2] = ((buf[2] << 6) & 0xc0) | (buf[3] & 0x3f);
+        j+=iWriteCount;
+    }
+    iLen = j;
+    lpszOutputString[j] = '\0';
+
+    return lpszOutputString;
+}
+
+void base64::Decode(istream& istr, ostream& ostr)
+{
+    int i,iWriteCount;
+    char c;
+    char buf[4];
+    char out[3];
+
+    while(1)
+    {
+        iWriteCount = 3;
+        for(i = 0; i < 4; i++)
+        {
+            istr >> c;
+            if(istr.eof())
+            {
+                ostr.flush();
+                return;
+            }
+            if(c == szB64[64])  // Pad
+                iWriteCount--;
+            else {
+                buf[i] = FindIndexInB64(c);
+                //if(buf[i] == -1) error!;
+            }
+        }
+        out[0] = ((buf[0] << 2) & 0xfc) | ((buf[1] >> 4) & 0x03);
+        out[1] = ((buf[1] << 4) & 0xf0) | ((buf[2] >> 2) & 0x0f);
+        out[2] = ((buf[2] << 6) & 0xc0) | (buf[3] & 0x3f);
+        ostr.write(out, iWriteCount);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base64.h	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,45 @@
+#if !defined BASE64_H_INC_
+#define BASE64_H_INC_
+
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+// Base64 Encodeing
+class base64
+{
+    int iLen;
+    char *lpszOutputString; // 結果出力先
+    static const char *szB64; // Base64変換テーブル
+
+    static int FindIndexInB64(char c);//szB64の Base64変換テーブルのなかの、どれか、探し出す。ない場合、-1
+public:
+    base64();
+    ~base64();
+    const char *Encode(const char *szStr, int iLens = -1);  // エンコード(文字列用)。ただし、データの長さを指定すれば、バイナリデータが可能
+    const char *Decode(const char *szStr);  // デコード(文字列用)
+    int GetLenght() const { return iLen; }  // 出力された長さ
+    const char *Get() const { return lpszOutputString; }    // 文字列用の結果を取得
+
+    static void Encode(istream& istr, ostream& ostr, int iRet = 76);    // istrはバイナリストリーム推奨
+        // エンコード(ストリーム用) iRetは、何文字目で改行するか。-1なら、改行しない。
+    static void Decode(istream& istr, ostream& ostr);   // ostrはバイナリストリーム推奨
+        // デコード(ストリーム用)
+
+    static void Encode(const char *lpszImputFileName, const char *lpszOutputFileName, int iRet = 76)
+    {
+        ifstream f(lpszImputFileName,ios::in | ios::binary);
+        ofstream of(lpszOutputFileName);
+        Encode(f,of);
+    }
+    static void Decode(const char *lpszImputFileName, const char *lpszOutputFileName)
+    {
+        ifstream f(lpszImputFileName);
+        ofstream of(lpszOutputFileName,ios::out | ios::trunc | ios::binary);
+        Decode(f,of);
+    }
+};
+
+#endif // #if !defined BASE64_H_INC_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,55 @@
+#include "mbed.h"
+#include "JPEGCamera.h"
+#include <stdio.h>
+#include <base64.h>
+
+LocalFileSystem local("local");
+
+Serial pc(USBTX,USBRX);
+JPEGCamera camera(p9,p10);//TX,RX
+Serial xbee(p13,p14);
+
+int main(){
+    
+    Timer timer;
+    timer.start();
+    camera.setPictureSize(JPEGCamera::SIZE320x240);
+
+    FILE *fp;
+    base64 *bs;
+    int c;
+    
+    for (int i = 0; i < 1; i++) {
+        if (camera.isReady()) {
+            char filename[32];
+            sprintf(filename, "/local/pict%03d.jpg",i);
+            printf("Picture: %s ",filename);
+            if (camera.takePicture(filename)) {
+                while (camera.isProcessing()) {
+                    camera.processPicture();
+                }
+            } else {
+                printf("take picture failed\r\n");
+            }
+        } else {
+            printf("camera is not ready\r\n");
+        }
+    }
+    printf("time = %f\n", timer.read());
+    
+        
+    xbee.printf("xbee connected!\r\n");
+    bs = new base64();
+    bs->Encode("/local/PICT000.jpg","/local/d.txt");
+        
+        
+    if((fp=fopen("/local/d.txt","r"))!=NULL)
+    {
+        while ((c=fgetc(fp))!=EOF){
+            xbee.printf("%c",c);
+        }
+        fclose(fp);
+    }
+    return 0;
+}
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Nov 25 08:19:58 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file