Re: The history of "M&Y"

Team "M&Y" and "花鳥風月"
the soliloquy of the father
毎日更新!

EV3ねた その14 いよいよArduinoとの接続

2020-05-08 | EV3ねた

前の記事はこちら EV3ねた その13 ROBOT-C でI2C通信 出来てた!

 

さて、いろいろと試行錯誤を繰り返して EV3とArduino を接続する方法を考えました。

まず、ハード的な接続は、こんな感じです。

     EV3        Arduino
青 SDA    <---> A4 (100kΩの抵抗をプルアップ接続)
緑 SCL     <---> A5 (100kΩの抵抗をプルアップ接続)
黄 VBUS  <---> +5V
赤 GRND <---> GND

それから、ArduinoのD5ポートに緑色のLEDを配線しました。(通信の動作確認用)

 

 

そして、まずEV3側のプログラム(ROBOT-C)


void checkI2C(tSensors port)
{
 while(nI2CStatus[S1]!=0)
   {}
  return;
}

void LED_ON()
{
  char Wbuf[3] = {2,0x62,0x01};
  char Rbuf[1];

  sendI2CMsg(S1,Wbuf,0);
  checkI2C(S1);
  readI2CReply(S1,Rbuf,1);
}

void LED_OFF()
{
  char Wbuf[3] = {2,0x62,0x02};
  char Rbuf[1];

  sendI2CMsg(S1,Wbuf,0);
  checkI2C(S1);
  readI2CReply(S1,Rbuf,1);
}

int SENSOR_A()
{
  char Wbuf[3] = {2,0x62,0x10};
  char Rbuf[1];

  sendI2CMsg(S1,Wbuf,1);
  checkI2C(S1);
  readI2CReply(S1,Rbuf,1);
 return Rbuf[0];
}

int SENSOR_B()
{
  char Wbuf[3] = {2,0x62,0x20};
  char Rbuf[2];
  sendI2CMsg(S1,Wbuf,2);
  checkI2C(S1);
  readI2CReply(S1,Rbuf,2);
  return (Rbuf[0]<<8)+Rbuf[1];
}

task main()
{
 int i;

 while(true)
  {
    LED_ON();
    wait1Msec(100);

    i=SENSOR_A();
    displayBigTextLine(8,"A: %d",i);
    i=SENSOR_B();
    displayBigTextLine(10,"B: %d",i);

    LED_OFF();
    wait1Msec(900);
  }
}

 

それから、Arduino 側のプログラム

#include  
#define LED_RED 13
#define LED_GREEN 5
#define I2C_ADDRESS 0x31

byte COM;
int v1=0;
int v2=10000;

void receiveEvent(int DataNum)
  {      
  digitalWrite(LED_RED, HIGH);
  COM = Wire.read();
  if(COM==1)
    {
    digitalWrite(LED_GREEN,HIGH);
    }
  else if(COM==2)
    {
    digitalWrite(LED_GREEN,LOW);
    }
  else if(COM==0x10)
    {
    v1++;
    if(v1>100)
      v1=0;  
    }
  else if(COM==0x20)
    {
    v2--;
    if(v2<0)
      v2=100;
    }  
  digitalWrite(LED_RED, LOW);
  }

void requestEvent() 
  {
  byte d[2];
  
  digitalWrite(LED_RED, HIGH);
  if ((COM == 1) || (COM == 2)) 
    {
    d[0]=0;
    Wire.write(d,1);
    }
  else if (COM == 0x10) 
    {
    d[0]=v1;
    Wire.write(d,1);
    }
  else if (COM == 0x20) 
    {
    d[0]=v2 >> 8;
    d[1]=v2 & 0xff;
    Wire.write(d,2);
    }
  digitalWrite(LED_RED, LOW);
  }

void setup()
  {  
  pinMode(LED_RED, OUTPUT);
  digitalWrite(LED_RED, LOW);
  pinMode(LED_GREEN, OUTPUT);
  digitalWrite(LED_GREEN, LOW);

  Wire.begin(I2C_ADDRESS);
  Wire.onReceive(receiveEvent);    
  Wire.onRequest(requestEvent);                 
  }

void loop() 
  {
  }

 

なるべく単純にプログラムになるように心がけました。

 

やることは

(1) EV3の指示でArduinoのD5ポートのLEDを点灯する。
(2) EV3の指示でArduinoのD5ポートのLEDを消灯する。
(3) EV3の指示でArduinoの 変数v1 の値をEV3に送る。(1byte)
(4) EV3の指示でArduinoの 変数v2 の値をEV3に送る。(2byte)

こんな感じです。

(3)と(4)でArduinoに接続したセンサーの値を v1 や v2 に格納すれば、読み取ったセンサーの値をEV3に送れますね。

 

プログラムは、ROBOT-C や arduino の基本的にな使い方に沿っていないところがあるかもしれませんが・・・(なにせ、急遽勉強してつくったもので)

 

これで沢山のセンサーをEV3に接続できますね。

(ただ、EV3とArduinoの接続に I2Cポート(A4とA5)を使用してしまうので、アナログポートが2つつぶれてしまうのと、TPA-81のような、I2C接続のセンサーが使えない・・・これは、どうすればいいかなぁ

 

以下、自分の備忘録として解説

まず、EV3側で sendI2CMsg を実行します。第1パラメータはポート番号、第2パラメータはI2C機器に送るデータの配列、第3パラメータは受信するデータ数(=Byte数)です。で、第2パラメータの配列には、送るデータ数、I2Cアドレス、送るデータ・・・を格納します。

Arduino側は、EV3からの sendI2CMsg の通信を受け取って、Wire.onReceive で設定した関数(今回は receiveEvent )を呼び出します。 receiveEvent の中の Wire.read でEV3からのデータうぃ受け取ります。

次に、EV3側で readI2CReply を実行します。第1パラメータはポート番号、第2パラメータはI2C機器から受け取ったデータを格納する配列、第3パラメータは受信するデータ数です。

Arduino側は、EV3からの readI2CReply の通信を受け取って、Wire.onRequest で設定した関数(今回は requestEvent)を呼び出します。 requestEventの中の Wire.write でEv3にデータを送ります。

そうすると、EV3側では、 readI2CReply の第2パラメータの配列に Arduinoからのデータが格納されます。

 

続きの記事はこちら EV3ねた その15 TPA-81を接続してみる

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする