フォト
2017年7月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
無料ブログはココログ

« DRV8830を使ったDCモーターの制御(2) | トップページ | Lenovo Miix 2 8でOneDriveフォルダをSDカード上に配置する »

2014年12月27日 (土)

DRV8830を使ったDCモーターの制御(3)

前回の続きです。赤外線リモコンでモーターを制御出来るようにしました。
さらに、単3電池1本で強引に駆動させてみました。

Dscn3394

リモコンによる操作機能
 電源ボタン 低速前進 or 停止
 +ボタン   速度をUP
 -ボタン     速度をDOWN
   速度は27段階(-13 〜 0 〜 13)で変化でき、
   0は停止、正の場合前進、負の場合は後進する。+、-ボタンで操作できる。



回路図

01

主な部品
・8ピン8ビットマイコン ATtiny13A
・赤外線受信モジュール PL-IRM2161-XD1
モータードライバモジュール DRV8830(秋月電子)
DC-DCコンバータ(in 1〜5V out 5V 500mA)
・M1 DCモーター (FA-130RA相当) ダイソー プチ電車に搭載
・C1,C2   0.1μF セラミックコンデンサ
・C3       1000pF セラミックコンデンサ
・R1,R2   2.2kΩ 1/4W 炭素被膜抵抗
・R3       0.2Ω 1W 炭素被膜抵抗

DC-DCコンバータはAliexpressで購入したものです。
1Vから5Vの電圧を生成出来ます。

スケッチ(プログラムソース)
前回のスケッチに赤外線リモコンの受信処理を追加しました。
スケッチのサイズはジャスト 1024バイトです。何とか実装出来ました。

#include <tinyI2C.h>
// I2Cアドレス
#define DRV_ADR   0xC8  // DRV8830のI2Cアドレス
#define CTR_ADR   0x00  // CONTROLレジスタのサブアドレス
#define FLT_ADR   0x01  // FAULTレジスタのアドレス

// ブリッジ制御
#define M_STANBY  B00   // スタンバイ   
#define M_REVERSE B01   // 逆転
#define M_NORMAL  B10   // 正転
#define M_BRAKE   B11   // ブレーキ

// 電圧定義
#define MAX_VSET 0x15   // 1.69V
#define MIN_VSET 0x09   // 0.72V

// for I/O Port
#define IR    0
#define IR_DDR    DDRB
#define IR_PORT   PORTB
#define IR_PININ  PINB

#define IRbitRead()    (IR_PININ&_BV(IR))
#define RC_RDH_TS      9000    // リーダコードOFF間隔  9ms判定用
#define RC_RDL_TS      3800    // リーダコードON間隔   4.5ms判定用
#define RC_BITLOW_TS   1000    // ビットデータON間隔   1.69ms判定用  
#define RC_TMOVER      8000    // タイムオバー

// リモコンコマンド
#define RC_CMD_SW    0xA2      // ON/OFF スイッチ
#define RC_CMD_UP    0x90      // 速度UP  
#define RC_CMD_DOWN  0xA8      // 速度DOWN

//
// 赤外線リモコンコード取得
// 4バイトのデータを返す
// CCCCDDdd
//    CCCC カスタムコード
//    DD   データコード
//    dd   データコードのビット反転(データチェック用)
// ただし、
//    リピートコードの場合  0
//    エラーの場合          0xFFFFFFFF
//  を返す.
//
uint32_t Read_IR() {
  uint8_t  repeat = 0;  // リピートコード検出フラグ
  uint32_t  dt    = 0;  // 赤外線リモコン読み取りデータ
  unsigned long t ;     // 信号長計測用

  // リード部の取得
  // 受信データはH/L反転で読まれる
  while(1) {
    while(IRbitRead());  // OFF検出受信待ち   
    t = micros();        // OFF検出時刻取得
    while(!IRbitRead()); // ON受信検出待ち 
    t = micros() -t;     // OFF->ONの時間間隔取得
    if (t > RC_RDH_TS) { // 9ms以上ならリーダコードとみなす
        t = micros();      // ON検出時刻取得
        while(IRbitRead());// OFF検出待ち
        t = micros() -t;   // ON->OFF時間間隔取得
        break;
    }
  }
  
  // データ部取得
  if (t < RC_RDL_TS) {
    // 0N->OFF がリピートコードの場合、データ取得はスキップ
    repeat = 1;          
  } else {
    // 0N->OFF がリダーコードの場合、データを取得
     for (uint8_t i = 0; i <32; i++) {  //32ビット分取得ループ
        // ビット開始待ち
        while(!IRbitRead());  // ON待ち
        t = micros();
        while(IRbitRead());  // OFF待ち
        t = micros() -t;
        if (t>RC_TMOVER)
          return 0xFFFFFFFF;  // エラー
        dt<<=1;
        dt |= (t>RC_BITLOW_TS) ? 1:0;     
    }
  }
  // ストップビットの待ち
  while(IRbitRead());  // OFF待ち  
  if (repeat)
    return 0;
  return dt;
}

// 制御コマンド送信
void write_vset(byte vs, byte ctr) {
  tinyI2C_Start();
  tinyI2C_Write(DRV_ADR);
  tinyI2C_ReadBit();
  tinyI2C_Write(CTR_ADR);
  tinyI2C_ReadBit();
  tinyI2C_Write( ctr + (vs<<2) );
  tinyI2C_ReadBit();
  tinyI2C_Stop();
}

//uint8_t dct = 0;  // 方向 0:前 1:後ろ
short spd = 0;       // 速度 (0:停止 ,走行:1-13)   
byte hbg = M_STANBY;
byte vout;

void setup() {
  IR_DDR &= ~_BV(IR);  // IRピンのみ入力設定する
  tinyI2C_Init();

  // スタンバイ
  write_vset(MIN_VSET, M_STANBY); 
}

void loop() {
   uint8_t rc =  (uint8_t)(Read_IR()>>8 & 0xFF);  // IR受信
   switch(rc) {
     case RC_CMD_SW:  // スイッチON/OFF
       if (spd == 0) {
         spd =1;
       } else {
         spd = 0;
       }
       break;        
     case RC_CMD_UP:
       if (spd < 13) spd ++; 
       break;
     case RC_CMD_DOWN:
       if (spd > -13) spd --;
       break;
   }
   if (spd == 0) {
      hbg = M_BRAKE;
      vout = MIN_VSET;
   } else if (spd > 0) {
      hbg = M_NORMAL;
      vout = MIN_VSET+spd-1;
   } else {
      hbg = M_REVERSE;
      vout = MIN_VSET-spd-1;
   }
   write_vset(vout,hbg);
}

あとは、基板実装してなんとかケース内に収めてみます。
「ATtiny13Aでダイソー プチ電車を赤外線リモコン操作してみた」に続きます。

« DRV8830を使ったDCモーターの制御(2) | トップページ | Lenovo Miix 2 8でOneDriveフォルダをSDカード上に配置する »

arduino」カテゴリの記事

ATtiny13A」カテゴリの記事

AVR」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/60874860

この記事へのトラックバック一覧です: DRV8830を使ったDCモーターの制御(3):

« DRV8830を使ったDCモーターの制御(2) | トップページ | Lenovo Miix 2 8でOneDriveフォルダをSDカード上に配置する »