プレミアム胡桃ケース湿度・温度センサーキット:Arduino + NeoPixel + TFTディスプレイ
部品と材料
| Arduino UNO | ×1 |
| Adafruit NeoPixelリング:WS2812 5050 RGB LED | ×1 |
| DHT22温度センサー | ×1 |
| Adafruit 1.44インチ カラーTFT LCDディスプレイ(MicroSDカードブレークアウト付き) - ST7735R | ×1 |
| ブレッドボード(汎用) | ×1 |
| 単3電池ホルダー(4本用) | ×1 |
| ジャンパーワイヤー(汎用) | ×1 |
必要な工具と機械
- はんだごて(汎用)
- グルーガン(汎用)
このプロジェクトについて
プロジェクトの背景
胡桃材の留め継ぎ(ダブテイル)ケースを製作し、入手しやすいArduinoコンポーネントを使って、木工工房向けのスタイリッシュで実用的な湿度・温度モニターを作りました。このDIYプロジェクトは、胡桃材の留め継ぎ木工と、Arduino UnoおよびAdafruitの優れたパーツを使った初心者向けエレクトロニクスを融合しています。
私たちはテキサス中部に住んでいますが、春には湿度と温度の変動が激しく、特定の木工プロジェクトにとっては大変なことになります。このプロジェクトは、湿度の変化や上昇を検知してアラートを出し、木工プロジェクトを室内に移動させたり、高湿度時の加工を控えたりする判断材料になります。見た目も良く、ロゴも入れられています!
Arduinoとエレクトロニクスは初心者で、作りながら学びました。素晴らしいものを簡単に作れることを知り、今後もっとプロジェクトを作るのが楽しみです。
詳細な製作動画をご覧ください!
コード
Arduinoワークショップセンサーコード
#include
#include
#include
#include
#include
#include
#include // DHTXXライブラリはいくつかあります。機能レベルが様々です。
// ピン定義
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define DHT_PIN 2
#define PIXEL_PIN 6
#define PIXEL_NUM 24
#define SD_PIN 4
#define BMP_BUF 20
// グローバル変数
int currentColor = 9999; // チャートに対応する数値(下記参照)
CRGB leds[PIXEL_NUM];
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
DHT22 dht(DHT_PIN);
int loopDelay = 2000; // ms
// セットアップ
void setup() {
Serial.begin(9600);
Serial.println("Starting up.");
// DHT開始
dht.begin();
// LCD画面初期化
tft.initR(INITR_144GREENTAB);
// SDカード初期化
Serial.print("Initializing SD card.");
if (!SD.begin(SD_PIN)) {
Serial.println("Failed!");
return;
}
// 画面背景を黒に設定
tft.fillScreen(ST7735_BLACK);
// LED初期化
FastLED.addLeds(leds, PIXEL_NUM);
// ループ開始前の待機
delay(500);
}
// ループ
void loop() {
// センサーデータ取得
dht.readTemperature();
dht.readHumidity();
int f = dht.temperature_F; // 華氏温度
int h = dht.humidity; // 湿度(%)
// 温度アイコン描画
tft.fillCircle(102, 42, 6, ST7735_WHITE);
tft.fillCircle(102, 42, 4, ST7735_BLACK);
// LCD画面に温度表示
drawTemperature(f);
// 湿度に応じた色設定
setHumidityColors(h);
// シリアルモニターにデータ出力
Serial.print("Temperature: ");
Serial.println(f);
Serial.print("Humidity: ");
Serial.print(h);
Serial.println("%");
// 遅延
delay(1000);
}
// ビットマップ描画(LCD画面用)
void bmpDraw(char *filename, uint8_t x, uint8_t y) {
File bmpFile;
int bmpWidth, bmpHeight;
uint8_t bmpDepth;
uint32_t bmpImageoffset;
uint32_t rowSize;
uint8_t sdbuffer[3*BMP_BUF];
uint8_t buffidx = sizeof(sdbuffer);
boolean goodBmp = false;
boolean flip = true;
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if((x >= tft.width()) || (y >= tft.height())) return;
// SDカードからファイルを開く
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print("Bitmap file not found!");
return;
}
// BMPヘッダー解析
if(read16(bmpFile) == 0x4D42) {
read32(bmpFile);
(void)read32(bmpFile);
bmpImageoffset = read32(bmpFile);
read32(bmpFile);
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) {
bmpDepth = read16(bmpFile);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) {
goodBmp = true;
rowSize = (bmpWidth * 3 + 3) & ~3;
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h = tft.height() - y;
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row= sizeof(sdbuffer)) {
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0;
}
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.pushColor(tft.Color565(r,g,b));
}
}
}
}
}
bmpFile.close();
if(!goodBmp) Serial.println("BMP format not recognized.");
}
// ビットマップ/LCD画面用
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read();
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read();
return result;
}
// LCD画面に温度描画
void drawTemperature(int temp) {
int digits = numDigits(temp);
int x1_2 = 62, x2_2 = 32;
int x1_3 = 1, x2_3 = 1, x3_3 = 1;
int y = 38;
char digit1[12], digit2[12], digit3[12];
char digitStr1[24], digitStr2[24], digitStr3[24];
// 1桁目取得
itoa(temp % 10, digit1, 10);
strcpy(digitStr1, "");
strcat(digitStr1, digit1);
strcat(digitStr1, ".bmp");
// 2桁目取得
if(digits == 2){
itoa((temp / 10) % 10, digit2, 10);
strcpy(digitStr2, "");
strcat(digitStr2, digit2);
strcat(digitStr2, ".bmp");
}
// 3桁目取得
if(digits == 3){
itoa((temp / 100) % 10, digit3, 10);
strcpy(digitStr3, "");
strcat(digitStr3, digit3);
strcat(digitStr3, ".bmp");
}
if(digits > 2){
bmpDraw(digitStr1, x1_3, y);
bmpDraw(digitStr2, x2_3, y);
bmpDraw(digitStr3, x3_3, y);
} else {
bmpDraw(digitStr1, x1_2, y);
bmpDraw(digitStr2, x2_2, y);
}
}
// 画面配置決定用:温度の桁数取得
int numDigits(int number){
int valLen = 0;
if(number > 99) valLen = 3;
else valLen = 2;
return valLen;
}
// LED色設定
void setColors(int r, int g, int b){
for(int i = 0; i < PIXEL_NUM; i++){
leds[i].setRGB(r, g, b);
leds[i].fadeLightBy(125);
FastLED.show();
delay(100);
}
}
// 湿度レベルに基づく色決定
void setHumidityColors(int humidity){
// 湿度カラーチャート(独自設定)
// 赤: 0-17%
// オレンジ: 18-34%
// 黄色: 35-51%
// 緑: 52-68%
// 青: 69-85%
// 紫: 86-100%
int cRed[3] = {255,0,0};
int cOrange[3] = {255,90,0};
int cYellow[3] = {255,255,0};
int cGreen[3] = {0,255,0};
int cBlue[3] = {0,175,255};
int cPurple[3] = {255,0,255};
int range = map(humidity, 0, 100, 0, 6);
switch (range) {
case 0: // 赤
if(currentColor == 0) break;
else { setColors(cRed[0], cRed[1], cRed[2]); currentColor = 0; }
break;
case 1: // オレンジ
if(currentColor == 1) break;
else { setColors(cOrange[0], cOrange[1], cOrange[2]); currentColor = 1; }
break;
case 2: // 黄色
if(currentColor == 2) break;
else { setColors(cYellow[0], cYellow[1], cYellow[2]); currentColor = 2; }
break;
case 3: // 緑
if(currentColor == 3) break;
else { setColors(cGreen[0], cGreen[1], cGreen[2]); currentColor = 3; }
break;
case 4: // 青
if(currentColor == 4) break;
else { setColors(cBlue[0], cBlue[1], cBlue[2]); currentColor = 4; }
break;
case 5: // 紫
if(currentColor == 5) break;
else { setColors(cPurple[0], cPurple[1], cPurple[2]); currentColor = 5; }
break;
}
}
カスタムパーツとエンクロージャ
胡桃材ケースの設計データ(CADファイル)が提供されています。
回路図
Fritzingに実際のコンポーネントがほとんどなかったため、接続の流れを表現しています。配線図と実装写真を参照してください。
製造プロセス
- Raspberry PiとPythonでリモート温度センサーを構築 – ステップバイステップガイド
- EzTempでRaspberry Pi上の温度・湿度をシームレスに監視
- Raspberry PiとDS18B20でマルチセンサー温度・光監視システムを構築
- Raspberry Piと湿度センサーで作る自動エアロポニックスシステム
- Raspberry Pi、MCP9808、InfluxDB、Grafanaで作る家庭温度モニター
- 湿度センサーの検証とキャリブレーションで精密測定を実現
- Sensirion SVM30:空気清浄機およびHVAC向けオールインワンマルチガス・湿度・温度モジュール
- TE Connectivity HTU31:リニア応答の高精度湿度・温度センサ
- 湿度センサー:仕組みと主要アプリケーション
- DHT11センサー:仕組みと主要アプリケーション
- NASAゴダード研究所、リアルタイム流量・温度監視用ラボオンチップセンサを開発