MaixduinoでBME280（気温、湿度、気圧）センサーを使う

# はじめに

前回の [Maixduinoにサーマルカメラをつなぐ](https://qiita.com/drafts/4ab026adbee856ba38b1) でI2Cの入力が比較的簡単にできたので、今度はBME280（気温、湿度、気圧）センサーを使ってみます。

# 準備

- [Maixduino](https://www.seeedstudio.com/Sipeed-Maixduino-Kit-for-RISC-V-AI-IoT-p-4047.html) まずはこれ
![Maixduino](https://media-cdn.seeedstudio.site/media/catalog/product/cache/ab187aaa5f626ad16c8031644cd2de5b/m/a/maixduino-kit_1.jpg)
- [Grove Base Shield V2.0 for Arduino](https://www.seeedstudio.com/Base-Shield-V2.html) MaixduinoにGPIO、I2Cなどのコネクターを追加します。Maixduinoに接続する時は、スイッチを3.3V側に設定する必要があります。
![Grove Base Shield V2.0 for Arduino](https://media-cdn.seeedstudio.site/media/catalog/product/cache/ab187aaa5f626ad16c8031644cd2de5b/h/t/httpsstatics3.seeedstudio.comseeedimg2016-09ojyc6a5jtrgslqwc5j7gw9ti.jpg)
- [Grove BME280 Temperature Humidity Barometer Sensor, support I2C and SPI](https://www.seeedstudio.com/Grove-BME280-Environmental-Sensor-Temperature-Humidity-Barometer.html) 気温、湿度、気圧センサー
![Grove BME280 Temperature Humidity Barometer Sensor, support I2C and SPI](https://media-cdn.seeedstudio.site/media/catalog/product/cache/0c1bcd6b388d999a96199efd2a3e354c/h/t/httpsstatics3.seeedstudio.comseeedimg2016-06r425ianm2rr93qmjqfuewgx7.jpg)


# コード

参考にさせて頂いた [BME280 を M5stack で使って再びハマったこと、BOSCH 純正ドライバの使用について](https://www.mgo-tec.com/blog-entry-bosch-driver-bme280-m5stack-esp32.html/3) をほぼそののまま利用させて頂いています。

```c++:main.cpp
#include <Arduino.h>
#include <Wire.h>
#include "bme280.h"
 
struct bme280_dev dev;
struct bme280_data comp_data;
 
//******************************
void user_delay_ms( uint32_t period ){
  delay( period );
}

//******************************
int8_t user_i2c_read( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ){
  int8_t rslt_read = 0; /* Return 0 for Success, non-zero for failure */
 
  Wire.beginTransmission( dev_id );
  Wire.write( reg_addr );
  Wire.endTransmission();
  uint8_t req_from_ret = Wire.requestFrom( dev_id, (uint8_t)len, true );
 
  if( req_from_ret == 0 ){
//    Wire.reset();
//    Serial.println("@@@@@@@@@@@@@@@@ Wire Reset! @@@@@@@@@@@@@@");
    rslt_read = 1;
  }else{
    for( int i = 0; i < len; i++ ){
      reg_data[i] = Wire.read();
    }
    rslt_read = 0;
  }
 
  return rslt_read;
}

//******************************
int8_t user_i2c_write( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ){
  int8_t rslt_write = 0; /* Return 0 for Success, non-zero for failure */
 
  Wire.beginTransmission( dev_id );
  Wire.write( reg_addr );
  for( int i = 0; i < len; i++ ){
    Wire.write( reg_data[i] );
  }
  rslt_write = Wire.endTransmission();
 
  return rslt_write;
}

//******************************
void print_sensor_data(struct bme280_data *comp_data){
  //BME280_FLOAT_ENABLE
 
  float temperature = (float)comp_data->temperature;
  float pressure = (float)comp_data->pressure/100.0;
  float humidity = (float)comp_data->humidity;
  if( temperature > 100 || temperature < -9 ) temperature = -100;
  if( pressure > 2000 || pressure < 700 ) pressure = 0;
  if( humidity > 100 || humidity < 0 ) humidity = -1;
  char temp_c[10], hum_c[10], pres_c[10];
 
  String pres_str = "";
  String temp_str = "";
  String hum_str = "";
 
  if( pressure == 0 ){
    pres_str = "??";
  }else{
    sprintf( pres_c, "%6.1f", pressure );
    pres_str = String(pres_c);
  }
 
  if( temperature == -100 ){
    temp_str = "??";
  }else{
    sprintf( temp_c, "%4.1f", temperature );
    temp_str = String(temp_c);
  }
 
  if( humidity == -1 ){
    hum_str = "??";
  }else{
    sprintf( hum_c, "%5.1f", humidity );
    hum_str = String(hum_c);
  }
 
  Serial.println("-----------------------");
  Serial.print( "pressure = ");
  Serial.print( pres_str );
  Serial.println( " hPa" );
  Serial.print( "temperature = ");
  Serial.print( temp_str );
  Serial.println( " ℃" );
  Serial.print( "humidity = ");
  Serial.print( hum_str );
  Serial.println( " %" );
}

//*********BME280 init*********
void BoschBME280init(){
  Wire.begin((uint8_t) SDA, (uint8_t) SCL, 400000);
  dev.dev_id = BME280_I2C_ADDR_PRIM; //=0x76
  dev.intf = BME280_I2C_INTF; //I2C interface
  dev.read = user_i2c_read;
  dev.write = user_i2c_write;
  dev.delay_ms = user_delay_ms;
 
  int8_t rslt = bme280_init( &dev );
  Serial.printf( "bme280_init rslt=%d\r\n", rslt );
 
  dev.settings.osr_h = BME280_OVERSAMPLING_1X;
  dev.settings.osr_p = BME280_OVERSAMPLING_16X;
  dev.settings.osr_t = BME280_OVERSAMPLING_2X;
  dev.settings.filter = BME280_FILTER_COEFF_16;
  dev.settings.standby_time = BME280_STANDBY_TIME_62_5_MS; //62.5ms
 
  uint8_t settings_sel;
  settings_sel = BME280_OSR_PRESS_SEL;
  settings_sel |= BME280_OSR_TEMP_SEL;
  settings_sel |= BME280_OSR_HUM_SEL;
  settings_sel |= BME280_STANDBY_SEL;
  settings_sel |= BME280_FILTER_SEL;
  rslt = bme280_set_sensor_settings( settings_sel, &dev );
  Serial.printf( "sensor settings rslt=%d\r\n",rslt );
  rslt = bme280_set_sensor_mode(BME280_NORMAL_MODE, &dev );
  Serial.printf( "sensor mode rslt=%d\r\n", rslt );
}

//********BME280 get sensor value**********************
void BoschBME280dataGet(){
  dev.delay_ms( 1000 ); //1sec
  int8_t rslt = bme280_get_sensor_data( BME280_ALL, &comp_data, &dev );
  Serial.printf( "bme280_get_sensor_data rslt=%d\r\n", rslt );
  print_sensor_data( &comp_data );
}

//*********setup*********
void setup() {
  pll_init();
  uarths_init();
  Serial.begin(115200);
  BoschBME280init();
}

//*********main loop*********
void loop() {
  BoschBME280dataGet();
}
```


# 最後に

MaixduinoにGrove Base Shieldを組み合わせて、簡単にBME280（気温、湿度、気圧）センサーを使うことができました。