Program Resource

開発者向け各種コード、アルゴリズム、リソース情報ライブラリ もしくはねふぁの覚え書き

DRV2605はバイブモーターを制御するモジュールである。モジュールはちょっと高いが、バイブの強弱、100種類以上の振動パターン、モーターの各種制御機能が備わっている。

https://www.switch-science.com/catalog/2178/

筆者がこのモジュールに接続して使用しているモーターはAmazonの安価なタイプ。

uxcell マイクロモーター 振動モーター 電動機 ブラシレス DC 1.5V-3V 10mm x 2.7mm 携帯電話用 5個セット
uxcell マイクロモーター 振動モーター 電動機 ブラシレス DC 1.5V-3V 10mm x 2.7mm 携帯電話用 5個セット

I2C通信で制御し、AdafruitやSparkfun等が出しているライブラリを利用して制御する事が出来る。チップに100種類以上の振動パターン内蔵されており、パターンを指定して鳴らしたり、別の入力と連動させたりと言った使い方が出来る。

ところが、最初は調子良く動いていたが、急に動かなくなった。パターンを指定しても全く動かないか、ちょっと動いたりする程度。モーターかモジュールを壊してしまったかと思い、マイコンを変えたりモーターを交換してみたりしたが回復せず。

ライブラリやデータシートを色々調べてみた所、DRV2605は単にモーターを回すだけでなく、かなり高度な制御を行っている事が分かった。

http://www.tij.co.jp/jp/lit/ds/symlink/drv2605l.pdf

かなり複雑なので深い所までは把握できていないが、モーターの過負荷による温度超過や過電流による停止機能、モーターの種別や電流の制御方法を設定・保存、自動調整、電圧を監視する機能等がついている。

ステータスレジスタ0x00を読み取ると、温度超過や過電流により停止した場合ビット0や1にフラグが立つらしい。DRV2605Lの場合正常時0xE0の値が返る。ステータスレジスタの読み取りによりこのフラグはクリアされるらしい。

レジスタ0x16~0x1Aには各種設定が入っており、この値は電源断後も保持される。このため、この値を狂わせた場合単に再起動しても元には戻らない。

ステータスレジスタの読み取りや0x16~0x1Aのレジスタにデータシート記載のデフォルト値を設定した所、正常に動作する様になった。なにかのはずみでエラー状態になっていたか、設定値が狂ったのかもしれない。

下記はSparkfunのライブラリを使い、起動時シリアルに現在の状態とレジスタ値を出力後、出荷時の設定に値を上書きし、再度設定値を出力、その後プリセットの振動パターンを順番に出力するスケッチ。

//data sheet
//http://www.tij.co.jp/jp/lit/ds/symlink/drv2605l.pdf?ts=1591282871686

#include <Sparkfun_DRV2605L.h> //SparkFun Haptic Motor Driver Library 
#include <Wire.h> //I2C library 

SFE_HMD_DRV2605L HMD; //Create haptic motor driver object

//0x16 - 0x1a nonvolatile device settings see ref. page 20, page 30 9.5.7

//0x1A setting
#define FD_ERM		0x00
#define FD_LRA		0x80

#define FD_FACT_1X		0x00
#define FD_FACT_2X		0x10	//default
#define FD_FACT_3X		0x20
#define FD_FACT_4X		0x30
#define FD_FACT_6X		0x40
#define FD_FACT_8X		0x50
#define FD_FACT_16X		0x60
#define FD_FACT_DIS		0x70

#define FD_GAIN_LOW		0x00
#define FD_GAIN_MID		0x04	//default
#define FD_GAIN_HIGH	0x08
#define FD_GAIN_MAX		0x0C

#define FD_ERM_0		0x00	//0.255x
#define FD_ERM_1		0x01	//0.7875x
#define FD_ERM_2		0x02	//1.365x		default
#define FD_ERM_3		0x03	//3.0x

bool statusok = false;
char chbuff[128];

bool checkstatus() {
	//The Status Register (0x00): The Device ID is bits 7-5. For DRV2605L it should be 7 or 111.
	//bits 4 and 2 are reserved. Bit 3 is the diagnostic result. You want to see 0.
	//bit 1 is the over temp flag, you want this to be 0
	//bit 0 is  over current flag, you want this to be zero.
	// Ideally the register will read 0xE0.

	uint8_t status = HMD.readDRV2605L(STATUS_REG);
	Serial.print("Status Register 0x");
	Serial.print(status, HEX);
	if (status == 0xE0) {
		Serial.println(" OK");
		statusok = true;
	}
	else {
		Serial.println(" NG");
		statusok = false;
	}
	sprintf(chbuff, " Device id:%d\n", (status >> 5) & 0x07);
	Serial.print(chbuff);
	sprintf(chbuff, " Diag result:%d\n", (status >> 3) & 0x01);
	Serial.print(chbuff);
	sprintf(chbuff, " Overtemp:%d\n", (status >> 1) & 0x01);
	Serial.print(chbuff);
	sprintf(chbuff, " Overccurent:%d\n", (status >> 0) & 0x01);
	Serial.print(chbuff);

	return statusok;
}

void resettodefault() {
	//bit 7 device reset
	Serial.println("Device reset");
	HMD.writeDRV2605L(MODE_REG, 0x80);

	//set register to default (from data sheet)
	HMD.writeDRV2605L(0x16, 0x3e);
	HMD.writeDRV2605L(0x17, 0x8c);
	HMD.writeDRV2605L(0x18, 0x0c);
	HMD.writeDRV2605L(0x19, 0x6c);
	HMD.writeDRV2605L(0x1A, 0x36);
}

void showsetting() {
	sprintf(chbuff, "Reg 0x16 : %02X (Rated voltage DEF 0x3E)\n", HMD.readDRV2605L(0x16));
	Serial.print(chbuff);
	sprintf(chbuff, "Reg 0x17 : %02X (od clamp DEF 0x8C)\n", HMD.readDRV2605L(0x17));
	Serial.print(chbuff);
	sprintf(chbuff, "Reg 0x18 : %02X (Auto cal comp result DEF 0x0C)\n", HMD.readDRV2605L(0x18));
	Serial.print(chbuff);
	sprintf(chbuff, "Reg 0x19 : %02X (Auto cal BEMF result DEF 0x6C)\n", HMD.readDRV2605L(0x19));
	Serial.print(chbuff);
	byte reg = HMD.readDRV2605L(0x1A);
	sprintf(chbuff, "Reg 0x1A : %02X (Feedback Control DEF 0x36)\n", reg);
	Serial.print(chbuff);
	sprintf(chbuff, " ERM/LRA:%d DEF 0\n", (reg >> 7) & 0x01);
	Serial.print(chbuff);
	sprintf(chbuff, " Brake Factor:%d DEF 3\n", (reg >> 4) & 0x07);
	Serial.print(chbuff);
	sprintf(chbuff, " Loop Gain:%d DEF 1\n", (reg >> 2) & 0x03);
	Serial.print(chbuff);
	sprintf(chbuff, " BEMF Gain:%d DEF 2\n", (reg >> 0) & 0x03);
	Serial.print(chbuff);

	reg = HMD.readDRV2605L(0x1D);
	sprintf(chbuff, "Reg 0x1D : %02X (Control3 Register)\n", reg);
	Serial.print(chbuff);
	sprintf(chbuff, " Noise gate threshold:%d DEF 2\n", (reg >> 7) & 0x03);
	Serial.print(chbuff);
	sprintf(chbuff, " Open loop:%d DEF 1\n", (reg >> 5) & 0x01);
	Serial.print(chbuff);
	sprintf(chbuff, " Supply compensation:%d DEF 0\n", (reg >> 4) & 0x01);
	Serial.print(chbuff);
	sprintf(chbuff, " Data format:%d DEF 0\n", (reg >> 3) & 0x01);
	Serial.print(chbuff);
}

void setup()
{
	Wire.begin();

	delay(1000);
	Serial.println("\n-------------");

	checkstatus();
	showsetting();

	if (!statusok) {
		Serial.println("Invalid status!");
		delay(5000);
	}

	Serial.println("-------------");
	resettodefault();
	checkstatus();
	showsetting();

	HMD.Mode(0); // Internal trigger input mode -- Must use the GO() function to trigger playback.
	HMD.Library(1); //1-5 & 7 for ERM motors, 6 for LRA motors */
}

void goWait() {
	//wait until pattern is done
	while (HMD.readDRV2605L(0x0C) & 0x01) {
		yield(); // needed for RTOS based ESP8266/ESP32, etc.
	}
}

int wave;
unsigned long lastvib = 0;
void loop()
{
	if (millis() - lastvib >= 1500 && statusok) {
		runeffect(wave + 1);
		wave = (wave + 1) % 122;
		lastvib = millis();
	}
}

void runeffect(int effect) {
	if (effect == 1)     Serial.println(F("1 - Strong Click - 100%"));
	else if (effect == 2)     Serial.println(F("2 - Strong Click - 60%"));
	else if (effect == 3)     Serial.println(F("3 - Strong Click - 30%"));
	else if (effect == 4)     Serial.println(F("4 - Sharp Click - 100%"));
	else if (effect == 5)     Serial.println(F("5 - Sharp Click - 60%"));
	else if (effect == 6)     Serial.println(F("6 - Sharp Click - 30%"));
	else if (effect == 7)     Serial.println(F("7 - Soft Bump - 100%"));
	else if (effect == 8)     Serial.println(F("8 - Soft Bump - 60%"));
	else if (effect == 9)     Serial.println(F("9 - Soft Bump - 30%"));
	else if (effect == 10)     Serial.println(F("10 - Double Click - 100%"));
	else if (effect == 11)     Serial.println(F("11 - Double Click - 60%"));
	else if (effect == 12)     Serial.println(F("12 - Triple Click - 100%"));
	else if (effect == 13)     Serial.println(F("13 - Soft Fuzz - 60%"));
	else if (effect == 14)     Serial.println(F("14 - Strong Buzz - 100%"));
	else if (effect == 15)     Serial.println(F("15 - 750 ms Alert 100%"));
	else if (effect == 16)     Serial.println(F("16 - 1000 ms Alert 100%"));
	else if (effect == 17)     Serial.println(F("17 - Strong Click 1 - 100%"));
	else if (effect == 18)     Serial.println(F("18 - Strong Click 2 - 80%"));
	else if (effect == 19)     Serial.println(F("19 - Strong Click 3 - 60%"));
	else if (effect == 20)     Serial.println(F("20 - Strong Click 4 - 30%"));
	else if (effect == 21)     Serial.println(F("21 - Medium Click 1 - 100%"));
	else if (effect == 22)     Serial.println(F("22 - Medium Click 2 - 80%"));
	else if (effect == 23)     Serial.println(F("23 - Medium Click 3 - 60%"));
	else if (effect == 24)     Serial.println(F("24 - Sharp Tick 1 - 100%"));
	else if (effect == 25)     Serial.println(F("25 - Sharp Tick 2 - 80%"));
	else if (effect == 26)     Serial.println(F("26 - Sharp Tick 3 - 60%"));
	else if (effect == 27)     Serial.println(F("27 - Short Double Click Strong 1 - 100%"));
	else if (effect == 28)     Serial.println(F("28 - Short Double Click Strong 2 - 80%"));
	else if (effect == 29)     Serial.println(F("29 - Short Double Click Strong 3 - 60%"));
	else if (effect == 30)     Serial.println(F("30 - Short Double Click Strong 4 - 30%"));
	else if (effect == 31)     Serial.println(F("31 - Short Double Click Medium 1 - 100%"));
	else if (effect == 32)     Serial.println(F("32 - Short Double Click Medium 2 - 80%"));
	else if (effect == 33)     Serial.println(F("33 - Short Double Click Medium 3 - 60%"));
	else if (effect == 34)     Serial.println(F("34 - Short Double Sharp Tick 1 - 100%"));
	else if (effect == 35)     Serial.println(F("35 - Short Double Sharp Tick 2 - 80%"));
	else if (effect == 36)     Serial.println(F("36 - Short Double Sharp Tick 3 - 60%"));
	else if (effect == 37)     Serial.println(F("37 - Long Double Sharp Click Strong 1 - 100%"));
	else if (effect == 38)     Serial.println(F("38 - Long Double Sharp Click Strong 2 - 80%"));
	else if (effect == 39)     Serial.println(F("39 - Long Double Sharp Click Strong 3 - 60%"));
	else if (effect == 40)     Serial.println(F("40 - Long Double Sharp Click Strong 4 - 30%"));
	else if (effect == 41)     Serial.println(F("41 - Long Double Sharp Click Medium 1 - 100%"));
	else if (effect == 42)     Serial.println(F("42 - Long Double Sharp Click Medium 2 - 80%"));
	else if (effect == 43)     Serial.println(F("43 - Long Double Sharp Click Medium 3 - 60%"));
	else if (effect == 44)     Serial.println(F("44 - Long Double Sharp Tick 1 - 100%"));
	else if (effect == 45)     Serial.println(F("45 - Long Double Sharp Tick 2 - 80%"));
	else if (effect == 46)     Serial.println(F("46 - Long Double Sharp Tick 3 - 60%"));
	else if (effect == 47)     Serial.println(F("47 - Buzz 1 - 100%"));
	else if (effect == 48)     Serial.println(F("48 - Buzz 2 - 80%"));
	else if (effect == 49)     Serial.println(F("49 - Buzz 3 - 60%"));
	else if (effect == 50)     Serial.println(F("50 - Buzz 4 - 40%"));
	else if (effect == 51)     Serial.println(F("51 - Buzz 5 - 20%"));
	else if (effect == 52)     Serial.println(F("52 - Pulsing Strong 1 - 100%"));
	else if (effect == 53)     Serial.println(F("53 - Pulsing Strong 2 - 60%"));
	else if (effect == 54)     Serial.println(F("54 - Pulsing Medium 1 - 100%"));
	else if (effect == 55)     Serial.println(F("55 - Pulsing Medium 2 - 60%"));
	else if (effect == 56)     Serial.println(F("56 - Pulsing Sharp 1 - 100%"));
	else if (effect == 57)     Serial.println(F("57 - Pulsing Sharp 2 - 60%"));
	else if (effect == 58)     Serial.println(F("58 - Transition Click 1 - 100%"));
	else if (effect == 59)     Serial.println(F("59 - Transition Click 2 - 80%"));
	else if (effect == 60)     Serial.println(F("60 - Transition Click 3 - 60%"));
	else if (effect == 61)     Serial.println(F("61 - Transition Click 4 - 40%"));
	else if (effect == 62)     Serial.println(F("62 - Transition Click 5 - 20%"));
	else if (effect == 63)     Serial.println(F("63 - Transition Click 6 - 10%"));
	else if (effect == 64)     Serial.println(F("64 - Transition Hum 1 - 100%"));
	else if (effect == 65)     Serial.println(F("65 - Transition Hum 2 - 80%"));
	else if (effect == 66)     Serial.println(F("66 - Transition Hum 3 - 60%"));
	else if (effect == 67)     Serial.println(F("67 - Transition Hum 4 - 40%"));
	else if (effect == 68)     Serial.println(F("68 - Transition Hum 5 - 20%"));
	else if (effect == 69)     Serial.println(F("69 - Transition Hum 6 - 10%"));
	else if (effect == 70)     Serial.println(F("70 - Transition Ramp Down Long Smooth 1 - 100 to 0%"));
	else if (effect == 71)     Serial.println(F("71 - Transition Ramp Down Long Smooth 2 - 100 to 0%"));
	else if (effect == 72)     Serial.println(F("72 - Transition Ramp Down Medium Smooth 1 - 100 to 0%"));
	else if (effect == 73)     Serial.println(F("73 - Transition Ramp Down Medium Smooth 2 - 100 to 0%"));
	else if (effect == 74)     Serial.println(F("74 - Transition Ramp Down Short Smooth 1 - 100 to 0%"));
	else if (effect == 75)     Serial.println(F("75 - Transition Ramp Down Short Smooth 2 - 100 to 0%"));
	else if (effect == 76)     Serial.println(F("76 - Transition Ramp Down Long Sharp 1 - 100 to 0%"));
	else if (effect == 77)     Serial.println(F("77 - Transition Ramp Down Long Sharp 2 - 100 to 0%"));
	else if (effect == 78)     Serial.println(F("78 - Transition Ramp Down Medium Sharp 1 - 100 to 0%"));
	else if (effect == 79)     Serial.println(F("79 - Transition Ramp Down Medium Sharp 2 - 100 to 0%"));
	else if (effect == 80)     Serial.println(F("80 - Transition Ramp Down Short Sharp 1 - 100 to 0%"));
	else if (effect == 81)     Serial.println(F("81 - Transition Ramp Down Short Sharp 2 - 100 to 0%"));
	else if (effect == 82)     Serial.println(F("82 - Transition Ramp Up Long Smooth 1 - 0 to 100%"));
	else if (effect == 83)     Serial.println(F("83 - Transition Ramp Up Long Smooth 2 - 0 to 100%"));
	else if (effect == 84)     Serial.println(F("84 - Transition Ramp Up Medium Smooth 1 - 0 to 100%"));
	else if (effect == 85)     Serial.println(F("85 - Transition Ramp Up Medium Smooth 2 - 0 to 100%"));
	else if (effect == 86)     Serial.println(F("86 - Transition Ramp Up Short Smooth 1 - 0 to 100%"));
	else if (effect == 87)     Serial.println(F("87 - Transition Ramp Up Short Smooth 2 - 0 to 100%"));
	else if (effect == 88)     Serial.println(F("88 - Transition Ramp Up Long Sharp 1 - 0 to 100%"));
	else if (effect == 89)     Serial.println(F("89 - Transition Ramp Up Long Sharp 2 - 0 to 100%"));
	else if (effect == 90)     Serial.println(F("90 - Transition Ramp Up Medium Sharp 1 - 0 to 100%"));
	else if (effect == 91)     Serial.println(F("91 - Transition Ramp Up Medium Sharp 2 - 0 to 100%"));
	else if (effect == 92)     Serial.println(F("92 - Transition Ramp Up Short Sharp 1 - 0 to 100%"));
	else if (effect == 93)     Serial.println(F("93 - Transition Ramp Up Short Sharp 2 - 0 to 100%"));
	else if (effect == 94)     Serial.println(F("94 - Transition Ramp Down Long Smooth 1 - 50 to 0%"));
	else if (effect == 95)     Serial.println(F("95 - Transition Ramp Down Long Smooth 2 - 50 to 0%"));
	else if (effect == 96)     Serial.println(F("96 - Transition Ramp Down Medium Smooth 1 - 50 to 0%"));
	else if (effect == 97)     Serial.println(F("97 - Transition Ramp Down Medium Smooth 2 - 50 to 0%"));
	else if (effect == 98)     Serial.println(F("98 - Transition Ramp Down Short Smooth 1 - 50 to 0%"));
	else if (effect == 99)     Serial.println(F("99 - Transition Ramp Down Short Smooth 2 - 50 to 0%"));
	else if (effect == 100)     Serial.println(F("100 - Transition Ramp Down Long Sharp 1 - 50 to 0%"));
	else if (effect == 101)     Serial.println(F("101 - Transition Ramp Down Long Sharp 2 - 50 to 0%"));
	else if (effect == 102)     Serial.println(F("102 - Transition Ramp Down Medium Sharp 1 - 50 to 0%"));
	else if (effect == 103)     Serial.println(F("103 - Transition Ramp Down Medium Sharp 2 - 50 to 0%"));
	else if (effect == 104)     Serial.println(F("104 - Transition Ramp Down Short Sharp 1 - 50 to 0%"));
	else if (effect == 105)     Serial.println(F("105 - Transition Ramp Down Short Sharp 2 - 50 to 0%"));
	else if (effect == 106)     Serial.println(F("106 - Transition Ramp Up Long Smooth 1 - 0 to 50%"));
	else if (effect == 107)     Serial.println(F("107 - Transition Ramp Up Long Smooth 2 - 0 to 50%"));
	else if (effect == 108)     Serial.println(F("108 - Transition Ramp Up Medium Smooth 1 - 0 to 50%"));
	else if (effect == 109)     Serial.println(F("109 - Transition Ramp Up Medium Smooth 2 - 0 to 50%"));
	else if (effect == 110)     Serial.println(F("110 - Transition Ramp Up Short Smooth 1 - 0 to 50%"));
	else if (effect == 111)     Serial.println(F("111 - Transition Ramp Up Short Smooth 2 - 0 to 50%"));
	else if (effect == 112)     Serial.println(F("112 - Transition Ramp Up Long Sharp 1 - 0 to 50%"));
	else if (effect == 113)     Serial.println(F("113 - Transition Ramp Up Long Sharp 2 - 0 to 50%"));
	else if (effect == 114)     Serial.println(F("114 - Transition Ramp Up Medium Sharp 1 - 0 to 50%"));
	else if (effect == 115)     Serial.println(F("115 - Transition Ramp Up Medium Sharp 2 - 0 to 50%"));
	else if (effect == 116)     Serial.println(F("116 - Transition Ramp Up Short Sharp 1 - 0 to 50%"));
	else if (effect == 117)     Serial.println(F("117 - Transition Ramp Up Short Sharp 2 - 0 to 50%"));
	else if (effect == 118)     Serial.println(F("118 - Long buzz for programmatic stopping - 100%"));
	else if (effect == 119)     Serial.println(F("119 - Smooth Hum 1 (No kick or brake pulse) - 50%"));
	else if (effect == 120)     Serial.println(F("120 - Smooth Hum 2 (No kick or brake pulse) - 40%"));
	else if (effect == 121)     Serial.println(F("121 - Smooth Hum 3 (No kick or brake pulse) - 30%"));
	else if (effect == 122)     Serial.println(F("122 - Smooth Hum 4 (No kick or brake pulse) - 20%"));
	else if (effect == 123)     Serial.println(F("123 - Smooth Hum 5 (No kick or brake pulse) - 10%"));

	HMD.Waveform(0, wave + 1);
	HMD.Waveform(1, 0);
	HMD.go();
	goWait();
}

Print Friendly, PDF & Email

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


*

CAPTCHA