0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpresenseAdvent Calendar 2024

Day 22

Spresense HDRカメラ用のズームフォーカスレンズのモーターを制御する

Last updated at Posted at 2024-12-21

Spresense HDRカメラをズームフォーカスカメラ化するために購入した正体不明のズームフォーカスレンズですが、ネットに転がっていた情報を頼りに動かしてみたいと思います。

モータードライバの選定

前回しらべた仕様では、モーターはステッピングモーターらしいことがわかっています。モータードライバには、TI社製のDRV8835を使おうと思います。DRV8835はロジック側の信号電圧が2Vで、少し定格割れですが、メインボードの1.8VのIO電圧でも動かせる利点があります。

image.png
https://akizukidenshi.com/catalog/g/g109848/

DRV8835はモードが「MODE」端子で指定できるようになっています。「MODE=0」で ”IN/IN”モード、「MODE=1」では、”PHASE/ENABLE”モードです。どちらがよいのか悩むところですが、今回使おうと思っている Arduino Stepper libraryのソースコードを見ると、どうも IN/IN モード前提となっているようなので、IN/INモードを使用します。

IN1 IN2 OUT1 OUT2 動作
0 0 HiZ HiZ 空転
0 1 L H 逆転
1 0 H L 正転
1 1 L L ブレーキ

このライブラリはモーターのスピードも設定できるようになっています。rpm(revolutions per minuites)で指定するようになっています。レンズのデータシートを見ると1パルス(ステップ)あたり 0.224度なのでモーターが1回転するステップ数は、1607パルスになります。推奨動作パルス数が 300-800 PPSなので、モーターを一回転するには、5.4~2.0秒になります。これを rpm に換算すると、「11~30 rpm」 になります。

SPRESENSEとレンズとの接続

SPRESENSEとの結線は次のようにしました。実験しやすいようにレンズのコネクタはとってピンヘッダを接続しています。MODEはGNDに落としていますが、DRV8835のデータシート見ると内部でプルダウンをしているようなので、接続しなくても問題なさそうです。

image.png

UART2を潰すのは少しもったいない気もしますが、SoftwareSerial で代用できるし、ここは配線を楽にすることを選びました。モーターのコントロールは可変抵抗で行います。メインボードのADCのレンジは0.7Vなので、1.8Vだと半分以下のコントロールしかできません。抵抗分圧すべきですが、動作確認用のためだけなので良しとしましょう。

動作確認用のコード

動作確認用に作ったスケッチが下記です。可変抵抗の値の読み込みに analogRead を使うの簡単ですが、レンジが1024とステップ数に不足するので、SDKのAPIで直接int16_tの値を直接読み込みます。

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <arch/cxd56xx/scu.h>
#include <arch/cxd56xx/adc.h>
#include <Stepper.h>
// D27 - Focus A+ (BLACK)
// D28 - Focus A- (BLUE) 
// D01 - Focus B+ (RED)
// D00 - Focus B- (WHITE)

// D23 - Zoom A+ (ORANGE)
// D24 - Zoom A- (GREEN)
// D25 - Zoom B+ (YELLOW)
// D26 - Zoom B- (PURPLE)

#define FOCUS_AP (27)
#define FOCUS_AN (28)
#define FOCUS_BP (1)
#define FOCUS_BN (0)

#define ZOOM_AP (23)
#define ZOOM_AN (24)
#define ZOOM_BP (25)
#define ZOOM_BN (26)

const int turnSteps = 1607;  // 0.224 deg/step
const int zoomMaxStep = 2342;
const int focusMaxStep = 2342;
const int rpm = 20;

Stepper FocusStepper(turnSteps, FOCUS_AP, FOCUS_AN, FOCUS_BP, FOCUS_BN);
Stepper ZoomStepper(turnSteps, ZOOM_AP, ZOOM_AN, ZOOM_BP, ZOOM_BN);

int fd_a2;
int fd_a3;

void setup() {
  Serial.begin(115200);

  // initialize LLPADC 2 and 3
  fd_a2 = open("/dev/lpadc2", O_RDONLY);
  fd_a3 = open("/dev/lpadc3", O_RDONLY);
  ioctl(fd_a2, SCUIOC_SETFIFOMODE, 1);
  ioctl(fd_a3, SCUIOC_SETFIFOMODE, 1);
  ioctl(fd_a2, ANIOC_CXD56_FIFOSIZE, 2);
  ioctl(fd_a3, ANIOC_CXD56_FIFOSIZE, 2);
  ioctl(fd_a2, ANIOC_CXD56_START, 0);
  ioctl(fd_a3, ANIOC_CXD56_START, 0);

  FocusStepper.setSpeed(rpm);
  ZoomStepper.setSpeed(rpm);

  Serial.println("move home position");
  FocusStepper.step(focusMaxStep);
  ZoomStepper.step(zoomMaxStep);
  Serial.println("home position");
  delay(1000);
}

void loop() {
  static int zoom_pos = zoomMaxStep;
  static int focus_pos = focusMaxStep;

  int16_t val_z;
  int16_t val_f;
  while(read(fd_a2, &val_z, sizeof(int16_t)) == 0);
  while(read(fd_a3, &val_f, sizeof(int16_t)) == 0);

  val_z = map(val_z, -0x7fff, 0x7fff, 0, zoomMaxStep);
  val_f = map(val_f, -0x7fff, 0x7fff, 0, zoomMaxStep);

  Serial.println("Zoom: " + String(val_z));
  Serial.println("Focus: " + String(val_f));

  int zoom_step = val_z - zoom_pos;
  int focus_step = val_f - focus_pos;
  zoom_pos = val_z;
  focus_pos = val_f;
  ZoomStepper.step(zoom_step);
  FocusStepper.step(focus_step);

  delay(100);
}

ズームフォーカスレンズの動作

動作の様子がこちら。モーターがすごく熱くなるのところが気になります。駆動するときだけモーター電源をつけるようにしたほうがよいかな。ちょっと悩むところです。

次はいよいよ画像をとってみたいと思います。

関連記事
Spresense HDRカメラのズームフォーカスレンズ用のフォルダを作る
Spresense HDRカメラ用のズームフォーカスレンズのモーターの仕様を確認する
Spresense ズームレンズ対応HDRカメラを動作させてみた

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?