I2C (ESP-IDF 環境 + C 言語)

プログラムの書き方.

I2C のプログラムの書き方は, ESP-IDF Programming GuideAPI ReferenceI2C Driver を参照して欲しい.

実践課題 4:LCD への表示

I2C で機器と LCD と通信する際は, i2c_master_write_byte などの引数を通信相手先の都合に合わせる必要がある.そのためには各機器のデータシートを確認せねばならない.

プロジェクトの準備

サンプルプロジェクトをコピーする.

$ cd ~/esp

$ cp -r esp-idf/examples/get-started/sample_project ./i2c

$ cd i2c

プログラムの作成

このサンプルプロジェクトのメインファイルは main ディレクトリ以下の main.c であるので, そのファイルを編集する.エディタとして,vi, emacs, gedit, code などが使える.

以下のプログラムには「穴」があるので,そこはデータシートを見ながら穴埋めすること.

#include "freertos/FreeRTOS.h"
#include "driver/i2c_master.h"
#include "esp_err.h"
#include "esp_log.h"

//デフォルト値の設定
int i2c_freq    = 10000;  //周波数
int i2c_scl_pin = 22;     //SCL
int i2c_sda_pin = 21;     //SDA
int i2c_addr_7  = 0x3e;   //LCD のアドレス

i2c_master_dev_handle_t dev_handle;

/*** LCD 用の関数 ***/
void lcd_cmd(uint8_t cmd){  //コマンド送信
   uint8_t buf[2];
   uint8_t bufsiz = 2;
   buf[0] = <穴>;
   buf[1] = cmd;
   i2c_master_transmit(dev_handle, buf, bufsiz, -1);
}

void lcd_data(uint8_t data){  //表示する文字の送信
   uint8_t buf[2];
   uint8_t bufsiz = 2;
   buf[0] = <穴>;
   buf[1] = data;
   i2c_master_transmit(dev_handle, buf, bufsiz, -1);
}

void lcd_print( const char* data, int n ){
   //引数で与えられた文字列の表示. lcd_data のラッパー
   for (int i = 0; i < n; i = i + 1) {
      lcd_data( data[i] );        //英数字を書くためのデータ = ascii
   }
}

void lcd_clear() {
   lcd_cmd(<穴>);         //Clear Display
}

void lcd_home1() {
   lcd_cmd(<穴>);  // 1 行目の 1 マス目へ
}

void lcd_home2() {
   lcd_cmd(<穴>);  // 2 行目の 1 マス目へ
}

void lcd_init() {
   //初期化はデータシートの「初期設定例」をコピー.
   lcd_cmd(<穴>); vTaskDelay(pdMS_TO_TICKS(<穴>));        //Function set
   lcd_cmd(<穴>); vTaskDelay(pdMS_TO_TICKS(<穴>));        //Function set
   ....(以下,必要な設定を追加する)....
}

/*** メイン関数 ***/
void app_main(void)
{
   // start I2C communication
   i2c_master_bus_config_t  bus_config = {
      .clk_source = I2C_CLK_SRC_DEFAULT,    //規定値
      .i2c_port   = I2C_NUM_0,              //規定値
      .scl_io_num = i2c_scl_pin,            //ピン番号 (SCL)
      .sda_io_num = i2c_sda_pin,            //ピン番号 (SDL)
      .glitch_ignore_cnt = 7,               //規定値
      .flags.enable_internal_pullup = true, //規定値
   };

   // i2C ハンドルの作成
   i2c_master_bus_handle_t bus_handle;
   i2c_new_master_bus(&bus_config, &bus_handle);

   // デバイスの設定
   i2c_device_config_t  dev_config = {
      .dev_addr_length = I2C_ADDR_BIT_LEN_7,
      .device_address  = i2c_addr_7,
      .scl_speed_hz    = i2c_freq,
   };

   // デバイスの追加
   i2c_master_bus_add_device(bus_handle, &dev_config, &dev_handle);

   // LCD 初期化
   lcd_init();
   lcd_clear();

   // Hello World の表示
   char* data1 = "Hello!! ";
   lcd_home1();
   lcd_print(data1, 8);

   char* data2 = "from ESP";
   lcd_home2();
   lcd_print(data2, 8);
}

ビルドとマイコンへの書き込み

idf.py build コマンドを実行する.

$ idf.py build

マイコンに書き込むのは idf.py flash コマンド, 標準出力を表示するのは idf.py monitor コマンドである. まとめて idf.py flash monitor としても良い.

$ idf.py flash monitor
monitor を終了するのは Ctrl-] である.