산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

UltraV: 안전한 햇빛 노출을 위한 휴대용 UV 지수 측정기

구성품 및 부품

부품 수량
Arduino Nano R3 1
Texas Instruments ML-8511 UV 센서 1
128x64 OLED 디스플레이 (SSD1306) 1
MT3608 DC-DC 스텝업 컨버터 1
CR2 (3V) 배터리 1
CR2 배터리 홀더 1

프로젝트 소개

피부과 문제로 햇빛 노출이 어려워, 해변에서 보낼 시간을 자외선 측정기 제작에 투자했습니다. 그게 바로 UltraV입니다.

아두이노 나노 리비전 3, UV 센서, 3V 배터리 전압을 승압하는 DC/DC 컨버터, 소형 OLED 디스플레이로 구성됩니다. 주 목표는 휴대성으로, 언제 어디서든 UV 지수를 바로 확인할 수 있게 하는 것입니다.

1단계: 부품 및 구성품

2단계: 센서 (ML8511)

ML8511(Lapis Semiconductors)은 실내외 자외선 강도 측정에 적합한 UV 센서입니다. 내부 증폭기가 있어 광전류를 UV 강도에 따라 전압으로 변환하므로 ADC 등 외부 회로와 인터페이스가 쉽습니다. 파워다운 모드에서 대기 전류가 0.1µA에 불과해 배터리 수명이 깁니다.

특징:

불행히도 센서를 보호할 UV 투과 소재를 구하지 못했습니다. 테스트한 모든 투명 커버(플라스틱, 유리 등)가 UV 측정을 감쇠시켰습니다. 최선은 융합 석영 유리지만 합리적 가격에 구할 수 없어 센서를 박스 밖 개방 공간에 노출시켰습니다.

3단계: 작동 방법

측정하려면 기기를 켜고 태양 방향으로 몇 초간 향하게 한 뒤 디스플레이를 봅니다. 왼쪽 인덱스는 순간 측정값(200ms마다 갱신), 오른쪽은 세션 중 최대값으로 이것이 실제 참고값입니다. 좌측 하단에는 WHO 기준 등급(LOW, MODERATE, HIGH, VERY HIGH, EXTREME)이 표시됩니다.

4단계: 배터리 전압 및 측정

크기와 용량(800mAh) 때문에 CR2 배터리를 선택했습니다. 여름 내내 사용했는데 배터리가 아직 2.8V로 만족스럽습니다. 동작 시 약 100mA 소모하지만 측정은 몇 초면 끝납니다. 배터리 공칭 전압 3V를 MT3608로 9V로 승압해 Vin 핀에 연결했습니다.

배터리 전압 표시를 위해 아날로그 입력 A2를 사용했습니다. 아두이노 아날로그 입력은 0-5V DC 측정 가능하지만 보정이 필요합니다. 멀티미터로 아두이노 5V 핀(레귤레이터 출력) 실측값을 스케치에 반영하세요(예: 5.023V 읽혔다면 voltage = ((long)sum / (long)NUM_SAMPLES * 5023) / 1024.0;). 스케치에서 10개 샘플 평균을 냅니다.

5단계: 회로도 및 연결

(회로도 이미지 참조)

6단계: 소프트웨어

디스플레이는 U8g2lib를 사용해 폰트 선택과 위치 제어가 자유롭습니다.

ML8511 전압 읽기는 아두이노 3.3V 레퍼런스 핀(1% 정확도)을 ADC 기준으로 사용합니다. 3.3V 핀을 A1에 연결해 ADC 읽기를 한 뒤, 센서 읽기와 비교해 실제 전압을 역산출합니다(VIN이 3.4V 이상이면 상관없음).

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

전체 코드는 여기서 다운로드 가능합니다.

7단계: 인클로저 케이스

시판 플라스틱 박스에 디스플레이 창을 직접 뚫어보니 영 안 예뻐서 CAD로 직접 설계했습니다. 최대한 작게 만들기 위해 CR2 배터리를 배터리 홀더와 함께 후면 외부에 장착했습니다.

STL 파일: UltraV.stl.zip

8단계: 향후 개선 사항

9단계: 이미지 갤러리

(완성된 기기 사진들)

10단계: 크레딧

코드

UltraV (C/C++)

/* Fabio Marzocca @ 2018
   ADC는 VCC에 완전히 의존. USB 전원 시 4.75V~5.25V로 불확실해 부정확.
   정확한 온보드 3.3V 레퍼런스(1% 정확도) 사용해 보정.
   v2.0.0 - 2018.07 - 16x2 LCD에서 OLED로 변경
   v2.0.1 - 2018.09 - 배터리 읽기 함수 변경 */

#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);   // 순간 UV
    u8g2.setCursor(70, 40); u8g2.print(maxUV);         // 최대 UV
    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);
  return runningValue / numberOfReadings;
}

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 = (battery - VccMin) / 140;
  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, 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. 감자 배터리 만들기: DIY 전기화학 전지 단계별 가이드
  3. 미터 설계의 이해: 클래식 검류계에서 최신 디지털 디스플레이까지
  4. 멀티미터: 아날로그에서 디지털까지 - 종합 가이드
  5. 배터리 구조 기초: 셀, 내부 저항, 연결 방식
  6. 휴대용 스폿 용접기: 정의, 작동 원리, 주요 장점
  7. 고정형 vs 휴대용 CMM(3차원 측정기) 선택 가이드: 필수 고려사항
  8. 자동차 배터리 완벽 가이드: 종류, 구조, 작동 원리, 관리법
  9. 알터네이터 테스트 완벽 가이드: 전압계·멀티미터·드라이버·배터리 분리법
  10. 알터네이터 고장의 7가지 명확한 신호