LoginSignup
3
0

SPRESENSE HDRカメラに無理やり電動レンズをつけてみた話

Posted at

電動レンズを入手

SPRESENSE HDRカメラのよいところは、レンズが着脱可能なところ。せっかくならズームレンズとか制御できるともっと面白いかなと思い、実験用に次のレンズを入手しました。

電動レンズ、アルミ合金カメラレンズ、カメラオートアイリスレンズCCTVカメラ
image.png

アイリス制御なのであまり面白みはないですが、実験用なので安いのにしてみました。で、肝心のモータ制御ですが、探せども探せどもモータに関するドキュメントがまったく見つからない。Arduino界隈では電動レンズ制御はあまり流行らないのでしょうか。

やっと見つけたドキュメントが下記。どうもステッピングモーターを使っているっぽいです。アイリスのオープン、クローズに3秒もかかるのにちょっとびっくりです。

image.png

HDRカメラに電動レンズを装着

HDRカメラのレンズはネジ止めされているので簡単に外すことができます。M14レンズホルダとなっていましたが、ネジ穴はM12と同じ位置にあるので次のアダプタを3Dプリンタで印刷して使うことができます。

ただネジ穴が途中で細くなっていたので、上からネジが止められません。そこで無理やりドリルを使ってネジ穴を広げました。ステンレス製なのでちょっと苦労しました。

すったもんだで装着した状態の写真です。かっこいいですね。

DSC02551.JPG

SPRESENSEと電動レンズHDRカメラを接続する

電動レンズはきっとステッピングモータだろうということで、定番のDRV8835を使って次のように SPRESENSEと接続をしました。

image.png

実際の接続の様子は次の通りです。

DSC02552.jpg

制御プログラムは普通のステッピングモータと同じようなコードを組んでみたのですがどうも挙動がおかしい。加える電圧パターンでアイリスが開いたり閉じたり。電圧を印加する時間でアイリスの開口率も変わるみたいで、なにが何やら、、、いろいろと試行錯誤を繰り返し、なんとなく動いたかなというのが下記のコード。

#include <Camera.h>
#include <MP.h>
#include "Adafruit_ILI9341.h"

#define TFT_DC  9
#define TFT_CS  10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define SAVE_IMAGE
#ifdef SAVE_IMAGE
#include <SDHCI.h>
#include <BmpImage.h>
SDClass SD;
BmpImage bmp;
#endif

const int pinIN1 = 0;  // Black  C+ (A) 制動+
const int pinIN2 = 1;  // Yellow C- (B) 制動ー
const int pinIN3 = 2;  // White  D+ (C) 駆動+
const int pinIN4 = 3;  // Red    D- (D) 駆動ー

int phase = 0;
//   Phase ABCD Coils
//   0     1000  A      0x01
//   1     1100  AB     0x03
//   2     0100   B     0x02
//   3     0110   BC    0x06
//   4     0010    C    0x04
//   5     0011    CD   0x0c
//   6     0001     D   0x08
//   7     1001  A  D   0x09
const uint8_t phase_map[] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};

void Init() {
  pinMode(pinIN1, OUTPUT); 
  pinMode(pinIN2, OUTPUT); 
  pinMode(pinIN3, OUTPUT); 
  pinMode(pinIN4, OUTPUT); 
}

void SetPhase(int8_t p) {
  phase = p;
  if (phase < 0) phase = 7;
  if (phase > 7) phase = 0;
  digitalWrite(pinIN1, ((phase_map[phase] & 0x01) == 0x01 ? HIGH : LOW));
  digitalWrite(pinIN2, ((phase_map[phase] & 0x02) == 0x02 ? HIGH : LOW));
  digitalWrite(pinIN3, ((phase_map[phase] & 0x04) == 0x04 ? HIGH : LOW));
  digitalWrite(pinIN4, ((phase_map[phase] & 0x08) == 0x08 ? HIGH : LOW));
}

void Reset() {
  digitalWrite(pinIN1, LOW);
  digitalWrite(pinIN2, LOW);
  digitalWrite(pinIN3, LOW);
  digitalWrite(pinIN4, LOW);
}

void setup() {
  tft.begin();
  theCamera.begin();
  tft.setRotation(3);

  Init();

  theCamera.setAutoExposure(false);
  theCamera.setAbsoluteExposure(100); // 10msec
  theCamera.setAutoWhiteBalance(true);
  theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_FLUORESCENT);

  theCamera.setStillPictureImageFormat(
    CAM_IMGSIZE_QVGA_H ,CAM_IMGSIZE_QVGA_V
   ,CAM_IMAGE_PIX_FMT_RGB565);

  Reset();
  delay(100);
}


void loop() {
  static int inc = 25;
  static int delay_time = 0;
  static const int max_delay = 3000;

  static int count = 0;
  printf("%d\n", count++);

  delay_time += inc;
  if (delay_time >= max_delay) delay_time = max_delay-1;
  printf("delay_time = %d\n", delay_time);

  SetPhase(5);  // なぜこれでアイリスが開くか謎すぎる
  delay(delay_time); // 短い時間のほうがアイリスが開く?

  CamImage img;
  img = theCamera.takePicture();
  if (img.isAvailable()) {
    tft.drawRGBBitmap(0, 0, (uint16_t *)img.getImgBuff(), CAM_IMGSIZE_QVGA_H, CAM_IMGSIZE_QVGA_V);

#ifdef SAVE_IMAGE
    // need 896kB for Maincore memory to save the below bmp file
    char filename[16] = {0};
    bool reverse = false;
    bmp.begin(BmpImage::BMP_IMAGE_RGB565, CAM_IMGSIZE_QVGA_H, CAM_IMGSIZE_QVGA_V, (uint8_t*)img.getImgBuff(), reverse);
    bmp.alignImageLine();
    sprintf(filename, "img%03d.bmp", delay_time);
    File myFile = SD.open(filename, FILE_WRITE);
    myFile.write(bmp.getBmpBuff(), bmp.getBmpSize());
    myFile.close();
    bmp.end();
#endif // SAVE_IMAGE
  }  

  SetPhase(2); // なぜこれでアイリスが開いたままになるか謎すぎる
  delay(max_delay); // 短い時間だとうまくいかない なぜ??
}

撮影結果

撮影結果を次に示します。ただ、電圧印加時間が500ミリ秒を超えると画が変わりませんでした。印加ア時間を長くすることでアイリスをもっと閉じれると思ったのですが、この制御パターンだとある一定の開口で止まってしまうようです。

印加時間 50ミリ秒
img050.jpg

印加時間 100ミリ秒
img100.jpg

印加時間 150ミリ秒
img150.jpg

印加時間 200ミリ秒
img200.jpg

印加時間 250ミリ秒
img250.jpg

印加時間 300ミリ秒
img300.jpg

印加時間 350ミリ秒
img350.jpg

印加時間 400ミリ秒
img400.jpg

印加時間 450ミリ秒
img450.jpg

印加時間 500ミリ秒
img500.jpg

なんとなくそれっぽい結果が得られましたが、このコードなんで動くのかさっぱりわかりません。何が正解かも不明… いろいろ調査した結果、どうもこのアイリス制御は次のコンポーネントを使っているのではないかと思われました。(光学系のキーコンポーネントは、やはり日本製なんですね)

新亜光学工業株式会社 オートアイリス N78DCS
image.png

制御方式を見ると、「制動コイルによる速度制御方式」とありますが、どのように制御するのかどこにもドキュメントがなく、ここで手詰まり。どなたか、制御方法ご存知の方がいたら教えてください!!

作ってみた感想

電動レンズが使えることがわかったのは朗報です。しかし、素性のよくわからないモータ製品は、やはり簡単には制御はできませんね。このレンズをバラせればもう少し分かりそうですがステレンス製でがっちり組み上げられているので難しそうです。もう少し調べて制御できるようにして、次はもっと高機能なズームやフォーカスのついた電動レンズにチャレンジしてみたいと思います。

3
0
2

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