tAROの試行錯誤

技術的なことを色々試した過程を記録

Timer Camera Xで定点観測カメラを作る(その3)

前回からの続きです。

isogabamaware.hatenadiary.jp

前回は以下の3を作ったので、今回は4を作ります。 これができれば1ヶ月電池駆動カメラはひとまず完成です。

  1. Node-REDでhttpで画像を送受信し、表示する環境を作る
  2. TimerCameraXで撮影した画像をPC上で確認する
  3. TimerCameraXからhttpでNode-REDに画像を送信する
  4. TimerCameraXをディープスリープさせて定期的に撮影するようにする
  5. AWS部分を作り、node-redから画像を送信する
  6. TimerCameraXとAWSをつなぐ

4. TimerCameraXをディープスリープさせて定期的に撮影するようにする

電源周りは全然わからないので、公式の二つしかないサンプルのweb_camじゃない方のwakeupの方を見てみます。

github.com

おそらく、電源が入ればLEDが点滅して、その後5秒スリープして、また電源が入る、の繰り返しをしていると思われます。

最後の2行はUSBが繋がっている時だけ通過するようです。 早速スケッチを転送してみると、思った通り、5秒に1回LEDが明るくなる、暗くなるを繰り返します。 USBを差しても抜いても同じ動作をするのは想定通りです。

ディープスリープの方法がわかったので、次は前回のカメラをディープスリープ対応します。 以下のコードで無事動きました。ただ、ディープスリープができているかはわからないので、一晩動かし続けてみようと思います。

今回は短めでここまでにします。

追記: 朝起きたらもう止まっていました。PC側のNode-REDも止めてしまっていたので、残念ながら何時に止まったかわかりませんでした。 次はNode-REDを起動したままで時計でも撮影してみようと思います。

#include "esp_camera.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include <base64.hpp>
#include "camera_pins.h"
#include "battery.h"
#include "bmm8563.h"

const char* ssid = "";
const char* password = "";

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  config.frame_size = FRAMESIZE_UXGA;
  config.jpeg_quality = 10;
  config.fb_count = 2;
 
  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  //initial sensors are flipped vertically and colors are a bit saturated
  s->set_vflip(s, 1);//flip it back
  s->set_brightness(s, 1);//up the blightness just a bit
  s->set_saturation(s, -2);//lower the saturation

  //drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

  if (ssid=="")
    WiFi.begin();
  else
    WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // バッテリー初期化
  bat_init();
  // タイマー初期化
  bmm8563_init();
  // 60秒後に起動設定
  bmm8563_setTimerIRQ(60);
}

void loop() {
  camera_fb_t *fb = esp_camera_fb_get();
  if ( fb ) {
    Serial.printf("width: %d, height: %d, buf: 0x%x, len: %d\n", fb->width, fb->height, fb->buf, fb->len);
    unsigned int base64_length = encode_base64_length(fb->len);
    unsigned char *base64buff = new unsigned char[base64_length+1];
    base64buff[base64_length] = '\0';
    encode_base64(fb->buf, fb->len, base64buff);
    char *serverName = "http://192.168.0.25:1880/image";
    HTTPClient http;
    http.begin(serverName);
    http.addHeader("Content-Type", "text/plain");
    int httpResponseCode = http.POST(reinterpret_cast<char*>(base64buff));
    Serial.printf("%d", httpResponseCode);
    delete [] base64buff;
    esp_camera_fb_return(fb);
  }

  rtc_date_t date;
  bmm8563_getTime(&date);
  Serial.printf("Time: %d/%d/%d %02d:%02d:%-2d\r\n", date.year, date.month, date.day, date.hour, date.minute, date.second);
  Serial.printf("volt: %d mv\r\n", bat_get_voltage());
 
  // バッテリー出力を無効化
  bat_disable_output();

  //USBが繋がっていたら通電しているのでここを通る
  esp_deep_sleep(60000000);
  esp_deep_sleep_start();
}