気圧センサLPS331APと 温湿度センサSHT11、 I2C液晶を組み合わせて、液晶表示の温湿度・気圧計を作ってみます。 電源は気圧センサに合わせて3.3[V]にし、3.3[V]動作のArduinoを使います。
// include the library code: #include <I2CLiquidCrystal.h> #include <Wire.h> // --------------------- LPS331AP ------------------------- const byte LPS331AP_ADDR = B1011100; // SA0 = GND //const byte LPS331AP_ADDR = B1011101;// SA0 = VDD_IO const byte LPS331AP_WHOAMI = 0x0f; const byte LPS331AP_CTRL1 = 0x20; const byte LPS331AP_CTRL2 = 0x21; const byte LPS331AP_CTRL3 = 0x22; const byte LPS331AP_P_LL = 0x28; const byte LPS331AP_P_L = 0x29; const byte LPS331AP_P_H = 0x2A; const byte LPS331AP_T_L = 0x2B; const byte LPS331AP_T_H = 0x2C; // --------------------- SHT1X ------------------------- const int SHT_SCK = 2; const int SHT_DAT = 3; const byte SHT_MeasureTemperature = B00011; const byte SHT_MeasureHumidity = B00101; const byte SHT_ReadStatusRegistor = B00111; const byte SHT_WriteStatusRegistor = B00110; const byte SHT_SoftReset = B11110; struct SHT_result { unsigned short res; byte crc; byte err; }; inline void SHT_clk() { digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_SCK, LOW); } // ----------------------- I2CLCD ---------------------------- // initialize the library // uncomment next line if you are using a LCD from Straberry Linux I2CLiquidCrystal lcd(40, false); // | +--- set true if the power suply is 5V, false if it is 3.3V // +-------- contrast (0-63) // uncomment next line if you are using a LCD from Akizuki denshi // I2CLiquidCrystal lcd; // ---------------------- setup function -------------------- void setup() { digitalWrite(SHT_SCK, LOW); digitalWrite(SHT_DAT, HIGH); // pull-up pinMode(SHT_SCK, OUTPUT); pinMode(SHT_DAT, INPUT); Serial.begin(9600); while (!Serial) {} // set up the LCD's number of columns and rows: lcd.begin(16, 2); LPS331AP_write(LPS331AP_CTRL1, B10010000); // |||||||+ SPI Mode selection // ||||||+- DELTA_EN // |||||+-- BDU: block data update // ||||+--- DIFF_EN: interrupt circuit enable // |+++---- ODR2, ODR1, ODR0 (1Hz) // +------- PD: 0: power down, 1: active } // ---------------------- loop function -------------------- void loop() { // -------------- SHT11 ------------------ struct SHT_result ret; float h, t1; ret = SHT_read(SHT_MeasureHumidity); h = -4.0 + 0.0405*ret.res -2.8*0.000001*ret.res*ret.res; ret = SHT_read(SHT_MeasureTemperature); t1 = -40.00 + 0.01*ret.res; // ------------- LPS331AP ----------------- long P; short T; float p, t2; P = LPS331AP_read(LPS331AP_P_H); P = (P << 8) | LPS331AP_read(LPS331AP_P_L); p = P = (P << 8) | LPS331AP_read(LPS331AP_P_LL); p = p/4096.0; T = LPS331AP_read(LPS331AP_T_H); t2 = T = (T << 8) | LPS331AP_read(LPS331AP_T_L); t2 = 42.5 + t2/480.0; // Output to serial Serial.print(h); Serial.print(" % "); Serial.print(t1); Serial.print(" C "); Serial.print(p); // pressure in [mbar]/[hPa] Serial.print(" hPa "); Serial.print(t2); // temprerature in [`C] Serial.println(" C"); // Print to LCD lcd.setCursor(0, 0); lcd.print(h); lcd.print("% "); lcd.print(t1); lcd.print("C"); lcd.setCursor(0, 1); lcd.print(p); lcd.print("hPa "); lcd.print(t2); lcd.print("C"); delay(5000); } // --------------------- LPS331AP ------------------------- void LPS331AP_write(byte reg, byte val) { Wire.beginTransmission(LPS331AP_ADDR); Wire.write(reg); Wire.write(val); Wire.endTransmission(); } byte LPS331AP_read(byte reg) { byte ret = 0; // request the registor Wire.beginTransmission(LPS331AP_ADDR); Wire.write(reg); Wire.endTransmission(); // read Wire.requestFrom((unsigned int)LPS331AP_ADDR, 1); while (Wire.available()) { ret = Wire.read(); } return ret; } // --------------------- SHT1X ---------------------------- struct SHT_result SHT_read(byte cmd) { struct SHT_result ret; ret.err = 0; digitalWrite(SHT_DAT, HIGH); pinMode(SHT_DAT, OUTPUT); // send START digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_DAT, LOW); digitalWrite(SHT_SCK, LOW); digitalWrite(SHT_SCK, HIGH); digitalWrite(SHT_DAT, HIGH); digitalWrite(SHT_SCK, LOW); // send address = 000 digitalWrite(SHT_DAT, LOW); SHT_clk(); SHT_clk(); SHT_clk(); for (int i=0; i<5; i++) { if ((cmd & B10000) != 0) digitalWrite(SHT_DAT, HIGH); else digitalWrite(SHT_DAT, LOW); SHT_clk(); cmd <<= 1; } pinMode(SHT_DAT, INPUT); digitalWrite(SHT_DAT, HIGH); // wait for ACK unsigned long cur = millis(); while (digitalRead(SHT_DAT) == HIGH) { if ((millis()-cur)>1000) { ret.err = 1; return ret; } } // send clk SHT_clk(); // wait for data to come cur = millis(); while (digitalRead(SHT_DAT) == HIGH) { if ((millis()-cur)>1000) { ret.err = 1; return ret; } } ret.res = 0; for (int j=0; j<2; j++) { for (int i=0; i<8; i++) { ret.res <<= 1; if (digitalRead(SHT_DAT) == HIGH) ret.res |= 1; SHT_clk(); } // Send ACK pinMode(SHT_DAT, OUTPUT); digitalWrite(SHT_DAT, LOW); SHT_clk(); pinMode(SHT_DAT, INPUT); digitalWrite(SHT_DAT, HIGH); } ret.crc = 0; for (int i=0; i<8; i++) { ret.crc <<= 1; if (digitalRead(SHT_DAT) == HIGH) ret.crc |= 1; SHT_clk(); } // Skip ACK SHT_clk(); // CRC をチェックした方がいい return ret; }
上記のスケッチです