工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

UltraV:安全な日光浴のための携帯型UVインデックスメーター

必要な部品と用品

部品 説明 数量
Arduino Nano R3 1
Texas Instruments ML-8511 UVセンサー 1
128x64 OLEDディスプレイ SSD1306 1
MT3608 DC-DCステップアップコンバーター 3Vを昇圧 1
CR2電池 (3V) 1
CR2電池ホルダー 1

プロジェクト概要

皮膚科の問題で日光を浴びられないため、ビーチで過ごす代わりに紫外線測定器「UltraV」を製作しました。

Arduino Nano rev.3、UVセンサー、DC/DCコンバーター(3V電池電圧を昇圧)、小型OLEDディスプレイで構成。主な目的は携帯性で、いつでもどこでもUVインデックスを即座に確認できるようにすることです。

ステップ1:パーツとコンポーネント

ステップ2:センサーについて

UltraV:安全な日光浴のための携帯型UVインデックスメーター

ML8511(ラピスセミコンダクタ製)は屋内外でUV強度を測定できるセンサーです。内蔵アンプにより光電流をUV強度に応じた電圧に変換するため、ADC等の外部回路とのインターフェースが容易です。パワーダウンモード時の待機電流は典型値0.1µAと極めて小さく、長時間の電池駆動が可能です。

特徴:

UltraV:安全な日光浴のための携帯型UVインデックスメーター

残念ながら、UVを透過する保護材(石英ガラス等)を安価に入手できませんでした。プラスチックやガラス等の透明カバーはすべてUV測定値を減衰させるため、センサーはケース外部に露出させることにしました。

ステップ3:操作方法

UltraV:安全な日光浴のための携帯型UVインデックスメーター

測定するには、デバイスの電源を入れ、太陽の方向に向けて数秒間保持します。ディスプレイ左側のインデックスは瞬時値(200msごとに更新)、右側の値はセッション中の最大値です。この最大値が重要な指標となります。

左下にはWHO基準によるUVインデックス区分(LOW、MODERATE、HIGH、VERY HIGH、EXTREME)も表示されます。

ステップ4:電池電圧と測定

CR2電池(800mAh)を選択。サイズと容量のバランスが良く、夏の間使用しても電圧は2.8Vを維持しており満足しています。動作時の消費電流は約100mAですが、測定は数秒で完了します。公称電圧3VをMT3608で9Vに昇圧し、Vinピンに接続しています。

電池電圧をディスプレイに表示するため、アナログ入力(A2)を使用しています。Arduinoのアナログ入力は0-5VのDC電圧を測定可能ですが、校正が必要です。校正手順:

  1. 最終的な電池(CR2)で回路に電源を供給(PCのUSB電源は使用しない)
  2. Arduinoの5Vピン(レギュレータ出力)の電圧をテスターで測定。これがADCの基準電圧になります
  3. 測定値をスケッチに反映(例:5.023Vなら以下のように設定)
voltage = ((long)sum / (long)NUM_SAMPLES * 5023) / 1024.0;

スケッチでは10サンプルの平均を取っています。

ステップ5:回路図と接続

UltraV:安全な日光浴のための携帯型UVインデックスメーター

ステップ6:ソフトウェア

ディスプレイにはU8g2libを使用。フォント選択や位置制御が柔軟で、この種のOLEDに最適です。

ML8511からの電圧読み取りには、Arduinoの3.3V基準ピン(精度1%以内)をADCの基準として使用。3.3Vピン(A1に接続)とセンサー出力(A0)の両方をADC変換し、比較することで、VIN電圧に依存しない正確な測定値を得ています(VINが3.4V以上なら)。

int uvLevel = averageAnalogRead(UVOUT);
int refLevel = averageAnalogRead(REF_3V3);
float outputVoltage = 3.3 / refLevel * uvLevel;

完全なコードはこちらからダウンロードできます。

ステップ7:ケース設計

UltraV:安全な日光浴のための携帯型UVインデックスメーター

市販のプラスチックケースにディスプレイ窓を手作業で開ける試行を繰り返した後、CADで専用ケースを設計しました。コンパクトにするため、CR2電池を背面に外付けしました(電池ホルダーをケースに接着)。

STLファイルはこちらからダウンロードできます。

ステップ8:今後の改善案

ステップ9:画像ギャラリー

UltraV:安全な日光浴のための携帯型UVインデックスメーター
UltraV:安全な日光浴のための携帯型UVインデックスメーター
UltraV:安全な日光浴のための携帯型UVインデックスメーター
UltraV:安全な日光浴のための携帯型UVインデックスメーター
UltraV:安全な日光浴のための携帯型UVインデックスメーター
UltraV:安全な日光浴のための携帯型UVインデックスメーター

ステップ10:クレジット

コード

UltraV (C/C++)

/* Fabio Marzocca @ 2018
   ADC変換は完全にVCCに依存する。USB給電時は5.25V〜4.75Vと変動するため、
   正確性に欠ける。オンボードの3.3V基準(精度1%以内)を使用し、
   3.3Vピン(A1)とセンサー出力のADC値を比較することで、
   VINに依存しない正確な測定を実現(3.4V以上なら)。
   v2.0.0 - 2018年7月 - 16x2 LCDからOLEDへ移行
   v2.0.1 - 2018年9月 - 電池読み取り関数を変更 */

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);

#define FIRST_ROW_Y 16
#define FIRST_ROW_X 16
#define BOX_H 38

const int UVOUT = A0;
const int REF_3V3 = A1;
const int VBATT = A2;

float maxUV = 0;

void setup() {
  pinMode(UVOUT, INPUT);
  pinMode(REF_3V3, INPUT);
  pinMode(VBATT, INPUT);
  u8g2.begin();
}

void loop() {
  u8g2.firstPage();
  do {
    int uvLevel = averageAnalogRead(UVOUT);
    int refLevel = averageAnalogRead(REF_3V3);
    float outputVoltage = 3.3 / refLevel * uvLevel;
    float uvIntensity = mapfloat(outputVoltage, 0.99, 2.6, 0.0, 15.0);
    readBattery();
    if (maxUV < uvIntensity) maxUV = uvIntensity;

    u8g2.drawFrame(0, FIRST_ROW_Y+1, 128, BOX_H);
    u8g2.setFont(u8g2_font_logisoso18_tf);
    u8g2.setCursor(10, 40);
    u8g2.print(uvIntensity);
    u8g2.setCursor(70, 40);
    u8g2.print(maxUV);
    u8g2.setFont(u8g2_font_u8glib_4_tf);
    u8g2.setCursor(10, 52);
    u8g2.print(F("INSTANT"));
    u8g2.setCursor(75, 52);
    u8g2.print(F("MAXIMUM"));
    showUVCategory();
    u8g2.setCursor(88, 64);
    u8g2.print(F("F.Marzocca"));
  } while (u8g2.nextPage());
  delay(200);
}

void showUVCategory() {
  char strCat[12];
  byte categ = (byte)(maxUV + 0.5);
  if (categ >= 0 && categ < 3) strcpy(strCat, "LOW");
  else if (categ >= 3 && categ < 6) strcpy(strCat, "MODERATE");
  else if (categ >= 6 && categ < 8) strcpy(strCat, "HIGH !");
  else if (categ >= 8 && categ < 10) strcpy(strCat, "VERY HIGH!");
  else if (categ >= 11) strcpy(strCat, "EXTREME!");
  u8g2.setCursor(0, 64);
  u8g2.print(strCat);
}

int averageAnalogRead(int pinToRead) {
  byte numberOfReadings = 16;
  unsigned int runningValue = 0;
  for (int x = 0; x < numberOfReadings; x++)
    runningValue += analogRead(pinToRead);
  runningValue /= numberOfReadings;
  return runningValue;
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void readBattery() {
  long battery = readBattVcc();
  long VccMin = 2300;
  byte batteryBar;
  int barStep = 140;
  batteryBar = (battery - VccMin) / barStep;
  u8g2.setFont(u8g2_font_open_iconic_embedded_2x_t);
  u8g2.drawGlyph(1, FIRST_ROW_Y, 73);
  u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
  for (byte i = 1; i <= batteryBar; i++) {
    u8g2.drawGlyph(128 - 9 * i, FIRST_ROW_Y - 4, 75);
  }
  u8g2.setFont(u8g2_font_freedoomr10_tu);
  u8g2.setCursor(25, FIRST_ROW_Y);
  u8g2.print(float(battery) / 1000, 3);
}

long readBattVcc() {
  int sum = 0;
  int sample_count = 0;
  long voltage = 0;
  #define NUM_SAMPLES 10
  while (sample_count < NUM_SAMPLES) {
    sum += analogRead(VBATT);
    sample_count++;
    delay(2);
  }
  voltage = ((long)sum / (long)NUM_SAMPLES * 5020) / 1024.0;
  return voltage;
}

製造プロセス

  1. ポータブルスポット溶接機の原理・操作・メリット:薄板金属接合の現場標準機
  2. 固定型と携帯型CMM測定機の選び方:知っておくべきポイント
  3. 自動車バッテリーの役割と仕組み:種類・構造・メンテナンス完全ガイド
  4. オルタネーター診断完全ガイド:電圧計・マルチメーター・ドライバー・バッテリー切離し4つのテスト方法
  5. オルタネーター故障の7つの明確なサイン|見逃せない警告症状
  6. 分圧回路ラボ:設計・測定・キルヒホフの電圧法則検証
  7. ジャガイモ電池の作り方:DIY電気化学電源のステップバイステップガイド
  8. メーター設計の理解:古典的ガルバノメーターから現代のデジタル表示まで
  9. マルチメーター:アナログからデジタルまで包括ガイド
  10. 電池構造の基礎:セル、内部抵抗、接続性
  11. 電池容量の理解:アンペアアワー定格と状態テスト