2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

定点観測カメラを電池駆動で作る

Last updated at Posted at 2020-04-04

#はじめに
屋外用の定点観測カメラということで電源は電池!と云うことからスタートした。モバイルバッテリーも考えたができるだけ小型化したかったので、電池駆動にこだわった。そしてなるべく汎用的に低予算でシンプルに・・・。

初号機で完成したモノが下。


※弐号機はもう少しコンパクトにする予定です。

関係ありませんが、下↓が零号機です。右上にコードが集まってクリップに挟まっているのがカメラです。下がESP32。上が書き込み装置。

大抵↑ここで満足してしまうのですが、ここでは上の初号機のユニバーサル基板化まで行きます!

#ここ大事
がっかりさせないために最初から言っておきます。残念ながら画像サイズは160x120です。下の画像です。
image.png

ブラウザで見ると1.5倍ぐらになっていると思う↑これよりもっと小さいです。この画像を保存して画像ソフトでみると分かると思います。カメラの性能的はVGAまでいけるのですが、ESP32だと頑張ってもう一つ上の320x240。このサイズで我慢できる人のみ挑戦してみてください。
ちなみにこの画像は、横向きですが我が家の桜の木です。

#部品

部品 値段 購入元
ESP-WROOM-32 1,100円 スイッチサイエンス
OV7670(FiFo無) 300円 Amazon
ユニバーサル基板 170円 秋月
ピンヘッダー 350円 秋月
ピンソケット 80円 秋月
ワイヤー 550円 秋月
タクトスイッチ 20円 秋月
抵抗(10Kx2, 4.7Kx2, 1K, 100K) 100円 秋月
トランジスタ 200円 秋月
コンデンサー 0.1μF 10円 秋月
電池 220円 ダイソー
電池ボックス 40円 秋月
全部で3,140円ですが、ピンヘッダーとかワイヤーとかお手持ちのもので良いので実際には2,000円ぐらいでイケると思います。

※写真ではスライドスイッチが付いていますが、使用していません。このスイッチがあまり良くなくてかなり悩んでしまいました。定格で0.5AまでイケるとあるのですがESP32だと超えてしまうのかうまく起動できない状態になってしまい、結局使っていません。かわりにタクトスイッチでリセットスイッチを入れました。

ESP-WROOM-32

電池駆動したいので開発ボードではなく、[ピッチ変換のみしたボード](https://www.switch-science.com/catalog/3170/)。1,100円とお高め。単体でESP32が700円でボードが300円なので自分でハンダすれば100円浮くけど、ここにはケチらずハンダ済みのを使った。ピンヘッダは付けないといけないけど。次回からは[aitendo](http://www.aitendo.com/product/15536)の方が最低限の部品もついているのでこっちにするかも。

##OV7670(FiFo無)

とてもお安くて Amazon で300円で購入した。Primeじゃなかったので2週間待ったが、弐号機を作る予定のでさらに必要になってくる。
お安いのは当然で、このOV7670には、FiFo(たぶん簡単に言うとバッファ用メモリ)が無くて、接続側が面倒見る必要がある。手間がかかる分だけお安い。実際に来たモノは上写真と同じモノ。注文したモノには上部にジャンパなどがあったけど無い。中華モノなのと値段で許容範囲。

#回路図

ESP32 ⇔ OV7670

ESP32とOV7670の接続はかなりあるのでうんざりしますが根気強く頑張りましょう。
回路図にOV7670→ESP32のGPIOを記述してあります。
SIOCとSIODは4.7Kでプルアップしてください。10Kでも大丈夫でした。

###OV7670のPower Down Mode
datasheetによると
image.png

撮影時は 60mW でスタンバイ時は20μA以下ということで、Deepsleep中はカメラをスタンバイにしないと!やり方は以下のように PWDNピンをHIGHにするとPower Downモードになるらしい。

image.png

HIGHにするのはちょっと厄介でNPNトランジスタでNOT回路作りました。回路図の右下辺り。
GPIO13をHIGHにするとPWDNがLOWになり、GPIO13をLOWにするとPWDNがHIGHになるように。実際にはESP32の起動時にGPIO13をHIGHにしてDeepsleep時には勝手にLOWになる。
ところが、実際に計測したところ 500μAまでしか下がらない!!分かる方がいたら教えて下さい!!

###自己電圧
自己電圧を取得したいので回路図中央辺りのR10Kx2。IO23をHIGHにしてR10K+R10Kで分圧してGPIO39(SENSOR_VN)ピンでAnalogRead()してます。0.1Vぐらい高いような気がしますが。

digitalWrite(GPIO_NUM_23, HIGH);
float analog = analogRead(GPIO_NUM_39);
float V = analog / 4096 * 3.9 * 2;

#電源
回路図には 3V3 とありますが、実際にはダイソーの充電式単3ニッケル水素電池×2本です。
なのでフル充電しても3Vにも届きません・・・。公式にはESP32は3.0~3.6Vとなっていますが少し前までは2.7V~でした。安定して動作させるには3.0V必要なんですねきっと。ただ頑張れば2.5V辺りでも動作すると聞いたので、NiMH×2本の2.5V~2.8Vの電圧で動かしてみよう!ってことになっています。本来、NiMH の1本は1.1V~1.2Vが一番美味しいところなんですが、ほとんど無駄にしてます。

Bitmap to JPEG

Slackの画像アップロードですが、Bitmap(RGB565)ファイルを上げると単なるファイルとして認識されるようで、画像フォーマットとしてはサポートしていないようです。
キャプチャ.PNG

PNG かJPEG にエンコードできるライブラリがないか探していたのですが適当なものが見つからず。spressif の標準に convert_line_format() なるもの発見。しかし色が変。
capture (1).jpg
んー、けど全くダメではなくて、色が変なので何とか自力で直してみた。下記、コメントアウト部分を変更しました。オリジナルとは関数名を変えて使っています。

to_jpg.cpp
static IRAM_ATTR void convert_line_format_(uint8_t * src, pixformat_t format, uint8_t * dst, size_t width, size_t in_channels, size_t line)
{
    int i=0, o=0, l=0;
    if(format == PIXFORMAT_GRAYSCALE) {
        memcpy(dst, src + line * width, width);
    } else if(format == PIXFORMAT_RGB888) {
        l = width * 3;
        src += l * line;
        for(i=0; i<l; i+=3) {
            dst[o++] = src[i+2];
            dst[o++] = src[i+1];
            dst[o++] = src[i];
        }
    } else if(format == PIXFORMAT_RGB565) {
        l = width * 2;
        src += l * line;
        for(i=0; i<l; i+=2) {
            /*
            dst[o++] = src[i] & 0xF8;
            dst[o++] = (src[i] & 0x07) << 5 | (src[i+1] & 0xE0) >> 3;
            dst[o++] = (src[i+1] & 0x1F) << 3;
            */
            dst[o++] = src[i+1] & 0xF8;
            dst[o++] = (src[i+1] & 0x07) << 5 | (src[i] & 0xE0) >> 3;
            dst[o++] = (src[i] & 0x1F) << 3;
        }
    } else if(format == PIXFORMAT_YUV422) {

##Slack
Slackへの投稿とアップロードは以下を参考にさせて頂きました。
https://qiita.com/ikegam1/items/f9a9351bb7d325b02ed3

Slackへのアップロードですが、切断前にインターバルを入れないと上手くアップされないようで、2秒入れてあります。

  client.readStringUntil('\n');
  delay(2000); // need!! slack.com interval
  client.stop();

##ESP32 I2S Camera
ベースとなるコードは、こちらを使わせて頂きました。
https://github.com/bitluni/ESP32CameraI2S

#ソースコード
作成した全コードは下記に置いておきます。
https://github.com/nori-dev-akg/esp32-ov7670-slack

#目標
やりたいことは、先程もありましたが桜の植木の開花記録をしたいと思っています。
1日3回の撮影で3ヶ月を目標にしました。
撮影だけでも 3回(1日)×90日(3ヶ月)=270回 は出来ないといけません。

実際には slack に送信して記録しています。
テストでは、10分間隔で769回の撮影はできました。あとは長期運転かなと。ダメなら単4×3本も考えないとかなぁ・・・。

13.png

No.769の次がNo.2になっています。ここでDeepSleepからの復帰ができず、リブートが掛かっています。リブートが掛かるとNoが1に戻ってしまいます。この後またNo.73まで行くのですが、以降はDeepSleepからの復帰でBrownOutが発生し、結局2.56Vで終わりました。
(No.768がありませんが送信エラーだったのでしょう。たまにあります。)

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

を入れてどれくらい伸びるか期待しています。

2020/04/04 追記

ようやく芽吹いてきました。うちのコは遅咲きのようです。
202004040.png

2020/05/27 追記

残念ながら2ヶ月も持ちませんでした。1ヶ月と10日ぐらいです。スタートがフル充電ではなかったのでもう一度計測し直しますが、さほど変わらないでしょう。

#最後に
結果は後日分かり次第追記したいと思います。
現在、弐号機の製作に取り掛かっています。コンパクト化が中心ですが、これも後日アップしたいと思います。

#SpecialThanks!!
https://github.com/kobatan/OV7670-ESP32
https://www.webzoit.net/hp/it/internet/homepage/env/iot/esp8266/esp32_ov7670_without_fifo_on_linux/
https://github.com/bitluni/ESP32CameraI2S
https://qiita.com/lumbermill/items/2517c5f130384cced335

2
3
1

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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?