LoginSignup
0
0

More than 1 year has passed since last update.

リモートカメラシステム (Arduino 部分)

Last updated at Posted at 2021-08-16

次のシステムを構成するサブシステムです。
Grove IoT スターターキット for SORACOM で作るリモートカメラシステム

制作開始日

2021年8月16日
システムを構築している様子を報告していきます。
必要な技術については見通しが立っているので、それを組み合わせていきます。

完成日

2021年8月23日
画像のアップロードを MQTT から HTTP POST に変えて完成しました。

IMG_20210816_092202.jpg

機能

HTTP GET でシャッター ON の信号を受け
画像を撮影
画像を HTTP で POST する。

要件

SD カードを使わない

フォルダー構造

$ tree remote_camera
remote_camera
├── camera_direct.ino
├── http_upload.ino
├── remote_camera.ino
└── setupLTE.ino
remote_camera.ino
// ---------------------------------------------------------------
/*
    remote_camera.ino

                Aug/22/2021 AM 08:30

        Adafruit VC0706 TTL Serial Camera
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>
#include <Adafruit_VC0706.h>
#include <stdio.h>
#include <Base64.h>
#include <ArduinoJson.h>
#include <WioLTEClient.h>

#define cameraconnection Serial

#define URL  "https://example.com/mqtt/http_to_mqtt/http_to_mqtt.py"
#define URL_STATUS  "https://example.com/mqtt/mqtt_work/status.json"

// #define INTERVAL        (9000)
#define INTERVAL        (3000)
#define DATA_SIZE (512)

WioLTE Wio;
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
String device = "00000000";


WioLTEClient WioClient(&Wio);


int icount = 0;

// ---------------------------------------------------------------
// [4]:
void setup()
{
    setupLTE();

    Wio.PowerSupplyGrove(true);

    Wio.LedSetRGB(0, 0, 1);
    delay(500);
    Wio.LedSetRGB(0, 1, 0);
    delay(500);

    snap_upload_proc();

    SerialUSB.println("*** remote_camera.ino *** Aug/22/2021 AM 08:30 ***");
}

// ---------------------------------------------------------------
// [6]:
void loop()
{
    delay(INTERVAL);

    if (get_status_prc())
        {
        snap_upload_proc();
        }
    else
        {
        SerialUSB.println("*** status *** no ON ***");
        }

    icount++;
}

// ---------------------------------------------------------------
// [6-4]:
boolean get_status_prc()
{
    boolean rvalue = true;

    DynamicJsonDocument doc(512);
    char data[512];
    int dataSize;
    dataSize=sizeof(data);

    rvalue = Wio.HttpGet(URL_STATUS, data, dataSize);
    if (!rvalue)
        {
        SerialUSB.println("### ERROR! HttpGet ###");
        }
    else
        {
        int llx = strlen(data);
        SerialUSB.println("llx = " + String(llx));
        data[llx] = '\0';
        String msg = String(data);

        SerialUSB.println(msg);

        deserializeJson(doc, msg);

        const char* button = doc["button"];
        if (strstr(button,"on"))
            {
            rvalue = true;
            SerialUSB.println("*** on ***");
            }
        else
            {
            rvalue = false;
            SerialUSB.println("*** off ***");
            SerialUSB.print("button = ");
            SerialUSB.println(button);
            }
        }

    SerialUSB.println("get_status_proc: rvalue = " + String(rvalue));

    return rvalue;
}

// ---------------------------------------------------------------
// [4-4]:
void snap_upload_proc()
{
    char str_json[8192];

    camera_direct_proc(str_json);
    http_upload_proc(str_json);
}

// ---------------------------------------------------------------
camera_direct.ino
// ---------------------------------------------------------------
/*
    camera_dicrect.ino

                Aug/23/2021 AM 08:00
*/
// ---------------------------------------------------------------
// [4]:
void camera_direct_proc(char str_json[])
{
    char data_encoded[5000 + DATA_SIZE];
    char data_jpg[5000 + DATA_SIZE];


    SerialUSB.println("*** camera_direct_proc *** start ***");

    Wio.LedSetRGB(1, 1, 0);

    int length_jpg = image_retrieve_proc(data_jpg);
//  SerialUSB.println("length_jpg =  " + String(length_jpg));

    int encodedLen = base64_enc_len(length_jpg);
//  SerialUSB.println("encodedLen =  " + String(encodedLen));

    base64_encode(data_encoded,data_jpg,encodedLen);

    Wio.LedSetRGB(1, 1, 1);

    to_json_proc(data_encoded,str_json);
}

// ---------------------------------------------------------------
// [4-4]:
int image_retrieve_proc(char data_jpg[])
{
    SerialUSB.println("*** image_retrieve_proc ***");

    take_picture_proc();

    // Get the size of the image (frame) taken  
    uint16_t jpglen = cam.frameLength();
    SerialUSB.println("*** jpglen = " + String(jpglen));
    int rvalue = jpglen;
    SerialUSB.print("Storing ");
    SerialUSB.print(jpglen, DEC);
    SerialUSB.print(" byte image.");

    int ipos = 0;
    while (jpglen > 0) {
        // read 64 bytes at a time;
        uint8_t *buffer;
        uint8_t bytesToRead = min((uint16_t)64, jpglen); // change 32 to 64 for a speedup but may not work with all setups!

        buffer = cam.readPicture(bytesToRead);

//      strncpy(&data_jpg[ipos],(const char *)buffer,bytesToRead);

        for (int it=0; it<bytesToRead; it++)
            {
            data_jpg[ipos+it] = buffer[it];
            }

        ipos += bytesToRead;
        jpglen -= bytesToRead;
    }

    data_jpg[ipos] = '\0';
    SerialUSB.println("*** ipos = " + String(ipos));

    delay(500);

    SerialUSB.println("*** image_retrieve_proc *** end ***");

    return rvalue;
}

// ---------------------------------------------------------------
// [4-4-2]:
void take_picture_proc()
{
    // Try to locate the camera
    if (cam.begin()) {
        SerialUSB.println("*** Camera Found. ***");
    } else {
        SerialUSB.println("No camera found?");
        return;
    }

//  get_camera_version_proc();

    // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
    // Remember that bigger pictures take longer to transmit!

//  cam.setImageSize(VC0706_640x480);   // biggest
//  cam.setImageSize(VC0706_320x240);   // medium
    cam.setImageSize(VC0706_160x120);   // small

    Wio.PowerSupplyGrove(false);

    delay(500);

    Wio.PowerSupplyGrove(true);

    // You can read the size back from the camera (optional, but maybe useful?)
    uint8_t imgsize = cam.getImageSize();
    SerialUSB.print("Image size: ");
    if (imgsize == VC0706_640x480) SerialUSB.println("640x480");
    if (imgsize == VC0706_320x240) SerialUSB.println("320x240");
    if (imgsize == VC0706_160x120) SerialUSB.println("160x120");

    delay(200);

    if (! cam.takePicture()) 
        SerialUSB.println("*** Failed to snap! ***");
    else 
        SerialUSB.println("*** Picture taken! ***");
        uint16_t jpglen = cam.frameLength();
        SerialUSB.print("cam.frameLength: ");
        SerialUSB.print(jpglen, DEC);
        SerialUSB.println(" byte image.");
}

// ---------------------------------------------------------------
// [4-4-2-4]:
void get_camera_version_proc()
{
    char *reply = cam.getVersion();
    if (reply == 0)
        {
        SerialUSB.println("*** Failed to get version ***");
        }
    else
        {
        SerialUSB.println("-----------------");
        SerialUSB.print(reply);
        SerialUSB.println("-----------------");
        }
}

// ---------------------------------------------------------------
void to_json_proc(char data_in[],char str_json_tt[])
{
    char str_json[8192];
    DynamicJsonDocument doc_camera(10512);

    doc_camera["base64"] = String(data_in);
    doc_camera["aa"] = "Hello";
    doc_camera["version"] = "Aug/21/2021 PM 13:10";
    doc_camera["device"] = device;
    doc_camera["sizeofdata"] = strlen(data_in);

    serializeJson(doc_camera, str_json);

    SerialUSB.print(str_json);
    delay(200);
    SerialUSB.println("");

    for (int it=0; it < 8192; it++)
        {
        str_json_tt[it] = str_json[it];
        }
}

// ---------------------------------------------------------------
http_upload.ino
// ---------------------------------------------------------------
/*
    http_upload.ino

                Aug/20/2021 AM 08:00
*/
// ---------------------------------------------------------------
// [6-4]:
void http_upload_proc(char url_target[], char str_json[])
{
    int status;

    SerialUSB.println("*** http_upload_proc *** start ***");

    if (!Wio.HttpPost(url_target, str_json, &status))
        {
        SerialUSB.println("### ERROR! HttpPost ###");
        }
    else
        {
        SerialUSB.print("Status: ");
        SerialUSB.println(status);
        }

    delay(200);

    SerialUSB.println("*** http_upload_proc *** end ***");
}

// ---------------------------------------------------------------

setupLTE.ino はこちら
UDP で温度と湿度を Harvest に送る

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0