Arduinoベースの圧力センサー&データロガーで正確な空気圧監視
部品と材料
| Arduino UNO | ×1 |
| Delkin Commercial MLC SDカード | ×1 |
| 圧力センサー SKU237545 | ×1 |
| データロガー RTC(リアルタイムクロック) | ×1 |
| I2C LCDディスプレイ | ×1 |
| 防水クリアカバー プラスチック電子プロジェクトボックス (158×90×60mm) | ×1 |
| HALJIA M3ナイロン黒六角ネジ 300個セット | ×1 |
| ELEGOO 120本多色デュポンワイヤー | ×1 |
アプリとオンラインサービス
- Arduino IDE
このプロジェクトについて
このプロジェクトは、貯蔵タンク内の空気圧を記録して機械式コンプレッサーの効率を確認したいという要望から生まれました。George Kontaxis氏の支援を受けています(参考動画)。
ディスプレイには日付、圧力(barとPSI)が表示されます。3つの圧力値を同時に読み取るArduino圧力計として機能します。
コード
SKU237545圧力センサー:LCD、リアルタイムクロック、データロギング対応
// 2018年8月12日作成 Philip Blayney & Jack Davidson
// George Kontaxis氏のコードを使用(SKU237545圧力センサー用)
// https://www.youtube.com/watch?v=AB7zgnfkEi4
#include "LiquidCrystal_PCF8574.h"
#include "RTClib.h" // リアルタイムクロック
#include // SDカード
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 255
LiquidCrystal_PCF8574 lcdI2C;
RTC_DS1307 RTC;
int n = 1;
int val;
// シンプルなデータロガー(Arduinoアナログピン用)
#define LOG_INTERVAL 1000 // エントリ間のミリ秒(短くすると高速/多量データ取得可能)
#define SYNC_INTERVAL 10000 // flush()呼び出し間隔(データをカードに永続書き込み)
// 600000 = 10分
uint32_t syncTime = 0;
const int chipSelect = 10; // データロギングシールド用:デジタルピン10をSDカードCS線に使用
File logfile;
void error(char *str) {
Serial.print(F("error: "));
Serial.println(str);
}
void setup(void) {
Serial.begin(9600);
Serial.println(F("SKU237545センサーからの圧力読み取り"));
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
lcdI2C.print(F("SKU237545 SENSOR"));
lcdI2C.setCursor(0,1);
lcdI2C.print(F(" bar and psi "));
delay(2000);
// SDカード初期化
Serial.print(F("Initializing SD card..."));
pinMode(10, OUTPUT);
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println(F("card initialized."));
// 新規ファイル作成
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (!SD.exists(filename)) {
logfile = SD.open(filename, FILE_WRITE);
break;
}
}
if (!logfile) {
error("couldnt create file");
}
lcdI2C.clear();
lcdI2C.setCursor(0,0);
lcdI2C.print(F("File No "));
lcdI2C.print(filename);
Serial.print(F("Logging to: "));
Serial.println(filename);
// RTC接続
if (!RTC.begin()) {
logfile.println("RTC failed");
Serial.println(F("RTC failed"));
}
logfile.println("Date / Time ,pressure ,bar ,reading ,psi,reading ");
delay(5000);
lcdI2C.clear();
}
void loop(void) {
int sensorVal = analogRead(A1);
float voltage = (sensorVal * 5.0) / 1024.0;
float pressure_pascal = (3.0 * ((float)voltage - 0.475)) * 1000000.0; // ここでキャリブレーション
float pressure_bar = pressure_pascal / 10e5;
float pressure_psi = pressure_bar * 14.5038;
Serial.print("Pressure = ");
Serial.print(pressure_bar);
Serial.print(" bars ");
Serial.print("psi ");
Serial.print(pressure_psi);
Serial.println();
DateTime now = RTC.now();
delay((LOG_INTERVAL - 1) - (millis() % LOG_INTERVAL));
int H = now.hour();
int M = now.minute();
int S = now.second();
// SDカードへのログ書き込み
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
if (H < 10) logfile.print(0);
logfile.print(now.hour(), DEC);
logfile.print(":");
if (M < 10) logfile.print(0);
logfile.print(now.minute(), DEC);
logfile.print(":");
if (S < 10) logfile.print(0);
logfile.print(now.second(), DEC);
// シリアルモニターにも出力
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
if (H < 10) Serial.print(0);
Serial.print(now.hour(), DEC);
Serial.print(":");
if (M < 10) Serial.print(0);
Serial.print(now.minute(), DEC);
Serial.print(F(":"));
if (S < 10) Serial.print(0);
Serial.print(now.second(), DEC);
Serial.println();
// LCD表示
lcdI2C.setCursor(0,0);
lcdI2C.print(pressure_bar);
lcdI2C.print("bar ");
lcdI2C.print(pressure_psi);
lcdI2C.print("psi ");
lcdI2C.setCursor(0,1);
lcdI2C.print(now.day(), DEC);
lcdI2C.print("/");
lcdI2C.print(now.month(), DEC);
lcdI2C.print(" ");
if (H < 10) lcdI2C.print(0);
lcdI2C.print(now.hour(), DEC);
lcdI2C.print(":");
if (M < 10) lcdI2C.print(0);
lcdI2C.print(now.minute(), DEC);
lcdI2C.print(":");
if (S < 10) lcdI2C.print(0);
lcdI2C.print(now.second(), DEC);
// CSV形式でデータ記録
logfile.print(", ");
logfile.print(" Pressure = ");
logfile.print(",");
logfile.print(pressure_bar);
logfile.print(",");
logfile.print(" bar ");
logfile.print(",");
logfile.print(pressure_psi);
logfile.print(",");
logfile.print("psi");
logfile.println();
// 定期的にflushしてデータを確実に書き込み
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
logfile.flush();
delay(10);
}
リアルタイムクロックの設定
// tronixstuff氏のコード
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// 10進数をBCD(2進化10進数)に変換
byte decToBcd(byte val) {
return ((val/10*16) + (val%10));
}
// BCDを10進数に変換
byte bcdToDec(byte val) {
return ((val/16*10) + (val%16));
}
void setup() {
Wire.begin();
Serial.begin(9600);
// 初期時刻をここで設定:
// DS3231 秒、分、時、曜日、日、月、年
setDS3231time(0, 43, 14, 3, 14, 8, 18); // 必要な時刻を設定
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // 秒レジスタから開始
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek)); // 1=日曜日, 7=土曜日
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year)); // 0-99
Wire.endTransmission();
}
void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void displayTime() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
if (minute < 10) Serial.print("0");
Serial.print(minute, DEC);
Serial.print(":");
if (second < 10) Serial.print("0");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day of week: ");
switch(dayOfWeek) {
case 1: Serial.println("Sunday"); break;
case 2: Serial.println("Monday"); break;
case 3: Serial.println("Tuesday"); break;
case 4: Serial.println("Wednesday"); break;
case 5: Serial.println("Thursday"); break;
case 6: Serial.println("Friday"); break;
case 7: Serial.println("Saturday"); break;
}
}
void loop() {
displayTime();
delay(1000);
}
必要なライブラリ
- LiquidCrystal_PCF8574.h: GitHubからZIPをダウンロードし、スケッチ>ライブラリをインクルード>.ZIP形式のライブラリを追加でインストール
- RTClib.h: GitHubからZIPをダウンロード、解凍後、残りのZIPファイルをライブラリに追加
回路図
配線接続:
- A5 → SCL
- A4 → SDA
- 5V → VCC
- GND → GND
圧力センサー接続:
- 黄色ワイヤー → A1
- 黒ワイヤー → GND
- 赤ワイヤー → 5V
PCに接続して正常動作を確認してください。
製造プロセス
- Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
- DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
- Arduino UNOで作るLCDアニメーション&ゲーム入門
- スマート自動靴紐シューズ:発電機能内蔵で実用性抜群
- BME280 温湿度・気圧データを Nextion タッチスクリーンに表示
- Arduino超音波センサーとProcessingで作るリアルタイム距離測定ソナー
- Pixel Chaser: Arduino Nanoで作るワンタップLEDゲーム
- Arduino Nanoとロータリーエンコーダーで作る高精度測定ホイール
- Bolt IoTとArduino UNOでLED輝度をシームレス制御
- Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
- 空気圧安全コンポーネント:主要用途とコンプライアンスガイダンス