フォト
2017年5月
  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      
無料ブログはココログ

« IchigoJamでのBASICプログラミング その1 | トップページ | Aliexpressで購入した商品が不良品のため「紛争」を起こすことに.. »

2015年2月15日 (日)

IchigoJamとArduinoとの連携(1)

IchigoJamATtiny13A(赤外線リモコン受信機能搭載)をつなげて、
「ゲームなんか作ると面白そう!」と思い、今回はその準備と実験結果のメモです。

IchigoJamにはシリアル通信機能があるのでそれでつなげれば一番簡単なのですが、
コンソールと共用のため画面にもデータが表示されてしまい画面が乱れます。

そこで、IchigoJamのI/O端子を利用してデータ通信を行うことにしました。
IchigoJam BASICからは、IN命令、OUT命令でビット単位での入出力が出来ます。
(ICのラベルにピン割り付けが表示されています)

IchigoJamの入出力ピン
    出力ピン:OUT1〜 OUT6(EX3がOUT5, EX4がOUT6)の6ピン
     入力ピン:IN1 〜 IN4の4ピン


まずは、この入出力ピンを使ってarduinoからバイトデータを取得する機能を
実装してみます。
赤外線リモコンのデータ受信を想定し、IchigoJamからはポーリング形式で
データを取得します。データが無い場合でも即時復帰します。
取得するデータは1バイトとし、入力ピン2つを使って一度に2ビット受信し、
4回受信して1バイトを作成します。

通信機能概要
・IchigoJamから、arduinoにデータ取得要求を行う。
・IchigoJamで同期用クロックを生成し、arduinoから2ビットずつ受信する。
・4回受信を行い8ビットデータを受信し、通信を終了する。
・通信中はIchigoJamから、一方的に中断を行う場合もあるので、
   arduinoの同期待ちにはタイムアウト機能が必要となる。
・arduinoでは、赤外線受信において待ち状態になるので、
  IchigoJamからのデータ取得要求は割り込み処理により実装する。

なんか、意外と面倒な処理臭いのでDFD(データフロー・ダイアグラム)を書いてみました。
(クリックすると拡大表示します)

02


ちょっと分かりやすくなった気がします。
IchigoJamのポーリングと、赤外線リモコンのボタン押しのタイミングが
同期していない点が要注意ですね。

ボタンの状態はキューは使わず、最新の状態のみを保持することにします。
ただし、ボタンが押されていない場合、IchigoJamが古い同じデータを取得すると
まずそうなので、配布状態を管理することにします。

次にIchigojamとarduinoの接続です。

01

こんな感じで、データ用は4線接続です。
データ送信を2ピンにしたのは、Ichigojamの演算処理が遅いためです。
1ビットを2ビットにするだけで、演算回数が減り2倍の速度になりました。
(4ビットにするとさらに早くなりますが、接続ピン数節約とします)

ここで問題となるのが、Ichigojamが3.3V駆動であることですが、
3.3Vで動く手持ちのArduino Uno互換機を使いました。
最終的にATtiny13A(3.3V)を想定しているのでこれで良しとします。

Dscn3608

実装ソース
Ichigojam側
5 OUT6,0:OUT6,1
20 D=0
30 OUT5,0:OUT5,1:D=((IN()&3)<<6)
40 OUT5,0:OUT5,1:D=D+((IN()&3)<<4)
50 OUT5,0:OUT5,1:D=D+((IN()&3)<<2)
60 OUT5,0:OUT5,1:D=D+((IN()&3))
70 PRINT D
80 GOTO 5

単純に受信したデータを表示するだけです。
5行のOUT命令でarduinoにデータ受信の割り込みをかけています。
30〜60はOUT命令でLOW→HIGHのクロックを生成して2ビットデータをIN命令で
取得しています。

arduino側

//
// IchigoJamにデータを送信
//

#define ICHIGO_CLK   7
#define ICHIGO_OUT6  0
#define ICHIGO_IN1  8
#define ICHIGO_IN2  9

uint8_t buttoncode = 0; 
uint8_t flgsent = 0;

void setup() {
  reset();
  pinMode(ICHIGO_CLK,INPUT);
  pinMode(13,OUTPUT);
  pinMode(ICHIGO_IN1,OUTPUT);
  pinMode(ICHIGO_IN2,OUTPUT);
  attachInterrupt(ICHIGO_OUT6,reqest, RISING);
  Serial.begin(115200);
  randomSeed(analogRead(0));
}

void reset() {
  flgsent = 0;
  buttoncode = 0;
}

// 同期クロック待ち(タイムアウト付き)
// 戻り値:0 同期
//        1 リセット抜け
void clk() {
  uint16_t cnt = 0;
  uint8_t flgtout = 0;
  // CLK _| ̄ (L->H)を検出待ち 
  while(digitalRead(ICHIGO_CLK) == LOW && flgtout== 0) {
    delay(1);
    cnt++;
    if (cnt > 50) flgtout=1; 
  } 
  cnt=0;
  while(digitalRead(ICHIGO_CLK) == HIGH && flgtout== 0) {
    delay(1);
    cnt++;
    if (cnt > 50) flgtout=1;
  }
  return;
}

// データ取得要求割り込み
void reqest() {
  if (flgsent) {
    send_data(0);            // 送信済みの場合
  } else {
    send_data(buttoncode);   // 未送信の場合  
    flgsent = 1;
  }
}

void setButtonData(uint8_t b) {
  buttoncode = b;
  flgsent = 0;
}

// データ送信
uint8_t send_data(uint8_t d) {
  for (uint8_t i=0; i <4; i++) {
    // CLK _| ̄ (L->H)を検出待ち
    clk();
    //上位2ビット取得
    digitalWrite(ICHIGO_IN2,bitRead(d,7));
    digitalWrite(ICHIGO_IN1,bitRead(d,6));
    d<<=2;
  }
  return 0;
}

void loop() {
 uint8_t r;
 r = (uint8_t)random(256);
 setButtonData(r);
 Serial.print(buttoncode);
 Serial.print(" [");
 Serial.print(flgsent); 
 Serial.println("]");
 delay(100);
}

arduino側では、IchgoJamのOUT命令で割り込みを発生させて、
データ送信を行っています。clk()関数で2ビット送信の同期をとっていいます。

物理ボタン(赤外線リモコンのボタン)は実装していないので、
今回は乱数を発生して、ボタンの代わりとしてます。

一応、これで問題なく動いています。次は赤外線受信部を実装してみます。

単純な処理ですが、今回の通信の作成で割り込み処理や、同期の取り方等の
勉強になりました。

« IchigoJamでのBASICプログラミング その1 | トップページ | Aliexpressで購入した商品が不良品のため「紛争」を起こすことに.. »

arduino」カテゴリの記事

IchigoJam」カテゴリの記事

コメント

コメントを書く

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

トラックバック

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

この記事へのトラックバック一覧です: IchigoJamとArduinoとの連携(1):

« IchigoJamでのBASICプログラミング その1 | トップページ | Aliexpressで購入した商品が不良品のため「紛争」を起こすことに.. »