7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

obniz, arduino, espでのI2C書き方比較

Last updated at Posted at 2018-09-05

同じことをしたくてもマイコンごとに言語や書き方が違って,せっかく学んでも使うマイコンが変わったらもう一度やり直しということがあります.

特にI2Cがマイコンごとの個性が出てるイメージがあったので,比較してみました.

比較したのは下3つです

初期化(master)

i2cのmasterとしての初期設定です.
クロックの設定や,ピンの設定を行います

obniz

obniz.i2c0.start({mode:"master", sda:2, scl:3, clock:400000}); 

arduino


Wire.begin(); 
Wire.setClock(400000); 
//対応ピンはボードごとに固定

esp32


int i2c_master_port = I2C_EXAMPLE_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_EXAMPLE_MASTER_FREQ_HZ;
i2c_param_config(i2c_master_port, &conf);
i2c_driver_install(i2c_master_port, conf.mode,
                   I2C_EXAMPLE_MASTER_RX_BUF_DISABLE,
                   I2C_EXAMPLE_MASTER_TX_BUF_DISABLE, 0);

espだけ設定項目が多いですね.
クロックの設定以外にもバッファとかプルアップの設定とかをしています
いろいろカスタマイズしたいときに融通がききそうです.

arduinoのi2cライブラリがWireとなっているのも混乱しやすい点かもしれません

書き込み(レスポンスなし書き込み)

次のようなコマンドを送る場合で比較します

  1. start
  2. SLASVE_ADDR + wr_bit
  3. write 2 byte (SEND_DATA1,SEND_DATA2)
  4. stop

obniz

obniz.i2c0.write(slave_addr, [SEND_DATA1, SEND_DATA2]);

arduino

Wire.beginTransmission(slave_addr);
Wire.write(SEND_DATA1);
Wire.write(SEND_DATA2);
Wire.endTransmission();

esp32

i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, SLASVE_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, SEND_DATA1, ACK_CHECK_EN);
i2c_master_write_byte(cmd, SEND_DATA2, ACK_CHECK_EN);
i2c_master_stop(cmd);
int ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

esp32はSLASVE_ADDRにwriteかreadかのフラグを自分で付加してbyte単位で書いていきます.
obnizとarduinoはそこは意識せずにSLASVE_ADDRを指定するだけですね

esp32だけ送信するコマンドを作る→送信するとなっているところも違いますね

読み込み(書き込みなしの読み込み)

受信は次のようなコマンドを送る場合で比較します

  1. start
  2. SLASVE_ADDR + read_bit
  3. receive 3 byte
  4. stop

あんまりこれに対応してるデバイスは無いかもしれません

obniz

var ret = await obniz.i2c0.readWait(SLASVE_ADDR, 3); //3byte読み込み
//ret = [data1,data2,data3]

arduino

Wire.requestFrom(SLASVE_ADDR, 3);  //3byte読み込み命令

byte val1 = Wire.read(); //データ受信
byte val2 = Wire.read(); //データ受信
byte val3 = Wire.read(); //データ受信

esp32

uint8_t data_rd[3];
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( SLASVE_ADDR << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read(cmd, data_rd, 2, ACK_VAL); //2byteはackありで受信
i2c_master_read_byte(cmd, &data_rd[2], NACK_VAL); //3byteで終了なので最後はnackで受信
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

やはりespだけ設定が細かいですね.
obnizとarduinoは受信したいバイト数だけ書けばあとは内部でやってくれてますが,
espは自分でackとnackを考えながらコマンドを作る必要があるようです

アドレス指定読み込み(レスポンスあり書き込み)

これが一番使うんじゃないでしょうか,

  1. start
  2. SLASVE_ADDR
  3. write 1 byte (WRITE_DATA)
  4. receive 3 byte
  5. stop

obniz

 obniz.i2c0.write(SLASVE_ADDR, [WRITE_DATA]);
 let val = await obniz.i2c0.readWait(SLASVE_ADDR, 3);

arduino

Wire.beginTransmission(SLASVE_ADDR);
Wire.write(WRITE_DATA);
Wire.endTransmission(false);

Wire.requestFrom(0x1E, 3, true);

byte val1 = Wire.read();
byte val2 = Wire.read();
byte val3 = Wire.read();

esp32

uint8_t data_rd[3];
i2c_cmd_handle_t cmd = i2c_cmd_link_create();

i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SLASVE_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, WRITE_DATA, true);

i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SLASVE_ADDR << 1) | I2C_MASTER_READ, true);


i2c_master_read(cmd, data_rd, cnt-1, ACK_VAL);
i2c_master_read_byte(cmd, &data_rd[2], NACK_VAL);
i2c_master_stop(cmd);

i2c_master_cmd_begin(i2c_num, cmd,  1000 / portTICK_RATE_MS);

i2c_cmd_link_delete(cmd);

どれもwriteとreadをつなぎ合わせた形になっています
接続部分がそれぞれ違ってますね

obnizはそのままつなげていて,arduinoはWire.endTransmission(false);と引数が入っています.
espはi2c_master_stop(cmd)をスキップしてつなげているようですね

まとめ

それぞれ違いがありますが,espがダントツで難しいですね
その分,使いこなせばいろいろ細かくできるのでしょうが,規格が決まってるのでカスタマイズ項目って少ないような...

obnizもarduinoもi2cの簡単さという点では似たり寄ったりのレベルですね
arduinoだとWireって言葉になれるのが大変・・・ぐらいでしょうか,

参考文献

obniz ドキュメント
arduino ドキュメント
esp ドキュメント

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?