概要
SWITCH SCIENCE社で購入できるエンコーダカウンタを使ってみました。「Y2Kb」さんからの受託販売商品とのことです。もともと回転数を計測したくて、安価な方法を探していました。
100円程度のメカニカルロータリーエンコーダ信号をマイコンでカウントしても回転数の計測は出来そうでしたが、比較的回転速度が遅く、必ずしも正確な角度を測る必要がない電子ボリュームなどに利用されることが多い部品の様でしたので、今回のカウンタに魅力を感じました。
但し、ARDUINOでカウンタ値を取得する接続確認はしましたが、計測が正しいことの確認はしていません。精度については後日確かめることにします。
機器構成
下写真は、エンコーダーカウンタです。スィッチサイエンスで取り扱いしています。エンコーダーは、写真上 黄緑色ブロックターミナル左側から、5V:赤、GND:黒、A相:白、B相:緑 に接続します。ARDUINOは、写真下の通り、SCL,SDA,GND,5V を接続します。いずれもカウンタ基板表記に従います。
次の写真はロータリーエンコーダー写真です。AMAZONで接続出来そうなものを選びました。
プログラム
「Y2Kb」社サポートページのサンプルプログラムそのままです。カウンター値をI2C接続で取得し、シリアルモニタ出力します。
https://products.y2kb.com/encoder-counter/v1/
https://products.y2kb.com/doc/encoder-counter/v1/register_map_ja.pdf
以下、プログラムコードです。
#include <stdint.h>
#include <Wire.h>
#define I2C_SLAVE_DEV_ADDR 0x11
// Register address
#define ESTATUS_REG_ADDR 0x01
#define CRST_REG_ADDR 0x02
#define CVAL_REG_ADDR 0x03 // 0x03 - 0x06
#define RCVAL_REG_ADDR 0x07 // 0x07 - 0x0A
#define ECONF_REG_ADDR 0x0B
#define CCONF_REG_ADDR 0x0C
#define VMAJOR_REG_ADDR 0x0D
#define VMINOR_REG_ADDR 0x0E
#define VPATCH_REG_ADDR 0x0F
#define SYSRBT_REG_ADDR 0x10
#define I2CADDR_REG_ADDR 0x11
#define INIT_REG_ADDR 0x12
typedef union _32bit_u
{
uint8_t uint8_data[4];
uint32_t uint32_data;
int32_t int32_data;
} _32bit_u;
void setup() {
// Communication function init
Serial.begin(115200);
while (!Serial);
// I2C init
Wire.begin();
//Wire.setClock(400000); //最大通信速度:400 kbps
byte error;
// Set encoder config
// ECONF: Data type=int32, Count dir=Up, Multiply=x2_A, Phase=A,B
uint8_t econf = 0x07;
// Data type カウント値データ型 : int32(符号付32bit整数
// (-2147483648~2147483647、リセット初期値:0)
// Cnt direction カウント方向 : Up
// Multiply 逓倍設定 : x2_A(2逓倍, A相エッジカウント値変化)
// Phase 位相と出力方式設定:"A,B"(2相,電圧出力/オープンコレクタ出力)
Wire.beginTransmission(I2C_SLAVE_DEV_ADDR);
Wire.write(ECONF_REG_ADDR);
Wire.write(econf);
error = Wire.endTransmission();
if (error){
Serial.print("error=");Serial.println(error);
}
delay(4000); // Wait until the config is written and the device reboots
}
void loop() {
delay(100);
// Read encoder count
_32bit_u count;
Wire.beginTransmission(I2C_SLAVE_DEV_ADDR);
Wire.write(CVAL_REG_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(I2C_SLAVE_DEV_ADDR, 4);
for(int i = 0; i < 4; i++) {
count.uint8_data[i] = Wire.read();
}
Serial.print("count = ");Serial.println(count.int32_data);
}
まとめ
I2Cでカウンタ値を取得するだけです。使いやすいと思います。