04.picoで温湿度(SHT30) C言語
04.picoで温湿度(SHT30) C言語
前回使用したセンサーENV2には温湿度センサーICのSHT30も入ってるので今回はその測定プログラムです。配線は前回のままです。
途中からセンサーを手で握っているので値が上がっています。
SHT30の仕様
・I2C通信・結露対策のためか、ヒーターのon/offが出来ます。
測定精度
2019/06 Ver6のデータシート(Ver3より精度が良くなっています)相対湿度(±%RH)
・2.0typ(10~90% Ta=0~80℃)・4.0typ(0~10,90~100% Ta=0~80℃)
・~4.0typ(0~10,90~100%で直線に変化 Ta=25℃)
・4.5max(10~90% Ta=25℃)
・~7.5max(0~10,90~100%で直線に変化 Ta=25℃)
温度(±℃)
・0.4max, 0.2typ(Ta=0~65℃)・~1.0max,~0.6typ(Ta=-40~0,65~125℃で直線に変化)
ENV2回路図
センサーユニットENV2の回路図より、https://docs.m5stack.com/en/unit/envII
・Vcc-SCLピン間、Vcc-SDAピン間にそれぞれ4.7kΩが入っていてプルアップしています。
・Vccから電圧レギュレータで3.3Vを作り、2つのICの電源電圧は3.3Vです。
・SHT30のアラート信号pinとリセット信号pinは、openで未使用です。
・I2CアドレスpinはGND接地で0x44固定です。(内部改造で0x45に変更可能)
データーシート
SHT30データシートVer6(英)https://sensirion.com/media/documents/213E6A3B/61641DC3/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf
SHT30データーシートVer3(日)
https://電子うさぎ.com/wp-content/uploads/2018/11/Sensirion_Humidity_SHT3x_DIS_Datasheet_V3_J.pdf
SHTシリーズ品には、SHT30(湿度精度±2%typ) / SHT31(±2%) / SHT35(±1.5%)があります。
プログラム資料
pico + C言語 + i2cでwebにあった下記記事を参考にしました。Raspberry Pi Picoでプログラミング10 i2c APIと気圧センサLPS25 (2021/4/13)
https://www.denshi.club/parts/2021/04/raspberry-pi-pico-10-i2c-lps25.html
機能
3.5-アラート信号 p9、3.6-リセット信号 p9、4.10-ヒーター p12 は使用しません。* 上記数字は、日本語データシートより
モードは4.5-周期モード p10 を選択しました。
・繰返精度=高、1回/2秒の頻度での設定コマンドは "0x2032" の2byte p11
・読出しコマンドは、"0xE000" の2byte p11
コマンドフロー
p11 表10より送受コマンドとデータは、1.書込み用としてI2Cアドレス1byte(0x44)の他に、測定設定コマンド2byte(0x2032)を送る。
2.呼出し用としてI2Cアドレス1byte(0x44)の他に、温度測定値MSB,LSB,チェックサム、湿度測定値MSB,LSB,チェックサムの計6byteを受取る。
* 1byte=8bit
換算式
測定データは、線形化、温度補償および電源電圧補償済の符号なし16bit整数(下式SRH,ST)で出力されますが、それを温湿度に換算する式 p13 は、・相対湿度RH(%RH) = 100*SRH/(2^16-1)
= 100*SRH/65535
= SRH/655.36
・温度T(℃) = -45+175*ST/(2^16-1)
= -45+175*ST/65535
= ST*35/13107-45
プログラム
test.c
// SHT30で温湿度測定 i2c通信 C言語
// Picoでi2c 気圧センサLPS25から修正
//https://www.denshi.club/parts/2021/04/raspberry-pi-pico-10-i2c-lps25.html
#include <stdio.h> // stdio_init_all使用
#include "hardware/i2c.h" // I2C使用
#include "pico/binary_info.h" //
#include "pico/stdlib.h" //
static int sht30_addr = 0x44; // I2Cアドレス 0x44 (改造で0x45)
#define I2C_PORT i2c0 // i2c0 or i2c1
#define SDA_PIN 4 // SDA GP4(BMP280と同じ)
#define SCL_PIN 5 // SCL GP5
/* 未使用
static void read_registers(uint8_t reg, uint8_t *buf, uint16_t len) {
i2c_write_blocking(I2C_PORT, sht30_addr, ®, 1, true);
i2c_read_blocking(I2C_PORT, sht30_addr, buf, len, false);
}*/
static void write_register(uint8_t reg, uint8_t data) { // 2byte送信
uint8_t buf[2]; // 2byte
buf[0] = reg; // 下位8bit
buf[1] = data; // 上位8bit
int A = i2c_write_blocking(I2C_PORT, sht30_addr, buf, 2, true); //2バイト書込む
//printf("%dbyte書込みました。\n",A);
}
int main() {
uint8_t buf3[3]; // 3byte受信データ定義
uint8_t buf6[6]; // 6byte受信データ定義
int32_t tmp, hum; // 温度と湿度変数定義
stdio_init_all(); // 標準stdioを初期化
sleep_ms(3000); // 3秒待つ
printf("\ni2c%d",i2c_hw_index(I2C_PORT));// I2C_PORT表示
printf(", SDA = GP%d, SCL = GP%d\n",SDA_PIN,SCL_PIN);//SDA SCLのGP表示
int f = i2c_init(I2C_PORT, 100 * 1000);//I2C初期化(port,ボーレート(Hz))
printf("ボーレート = %.1fkHz\n",(float)(f/1000)); // f(Hz)表示
gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);//GPIO機能選択(GPIO番号,GPIO関数)
gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);// SCLピンも同様
gpio_pull_up(SDA_PIN); //プルアップ 未送信時Hにするため 回路に入っているので不要かも
gpio_pull_up(SCL_PIN); // SCLピンも同様
write_register(0xF3, 0x2D); // 状態読込みコマンド(0xF320) p13 上の関数
i2c_read_blocking(I2C_PORT, sht30_addr, buf3, 3, false); // 3byte読取る
int A = buf3[0] << 8 | buf3[1]; // 整数化 buf3[2]はチェックサム
printf("状態レジスタ = %d (初期値32784)\n",A); // 表示
write_register(0x20, 0x32); // 測定モード設定コマンド p11 上の関数
// 繰返精度高(低-高) 連続頻度0.5回/秒(0.5-10)で0x2032
while (1) { // 永久ループ
write_register(0xE0, 0x00); // データ読出しコマンド(0xF000)
i2c_read_blocking(I2C_PORT, sht30_addr, buf6, 6, false);// 6byte読取る
tmp = buf6[0] << 8 | buf6[1]; // 2byte整数化 buf6[2]はチェックサム
hum = buf6[3] << 8 | buf6[4]; // 2byte整数化 buf6[5]はチェックサム
printf("%.1f℃", (float)(tmp * 35.0 / 13107.0 - 45.0)); // 温度表示 式p13
printf(" %.0f%%\n",(float)(hum / 655.36)); // 湿度表示 式p13
//printf(" 0:%3d/%3d/%3d/%3d/%3d/%3d:5\n",buf6[0],buf6[1],buf6[2],buf6[3],buf6[4],buf6[5]); //各buf表示
sleep_ms(5000); // 5秒待つ
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(project1 C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
#----------
add_executable(test test.c)
#----------
target_link_libraries(test pico_stdlib hardware_i2c)
pico_enable_stdio_usb(test 1)
pico_enable_stdio_uart(test 0)
pico_add_extra_outputs(test)