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

Arduino 연동 고급 팁핑 버킷 강우량계

부품 및 소모품

Arduino Nano R3 × 1개
Tiny RTC I2C DS1307 × 1개
SD 카드 모듈 (LC Studios) × 1개
7-12 VDC 파워 서플라이 (또는 월 월트) × 1개
Adafruit 표준 LCD 16x2 (흰색/파랑) × 1개
Texas Instruments 74HC595N 시프트 레지스터 (직렬-병렬) × 1개
1kΩ 저항 × 2개
330Ω 저항 × 2개
100nF 커패시터 × 1개
10kΩ 단회전 포텐셔미터 × 1개
PCB 순간 접점 푸시버튼 스위치 × 1개
리드 스위치, SPST-NO × 1개
자석 (7mm OD x 7mm 길이) × 1개
5x10cm 단면 프로토타입 보드 × 1개

필요한 도구 및 장비

프로젝트 소개

이것은 전문 기상학자들이 사용하는 강우량을 기반으로 한 팁핑 버킷 강우량계입니다. 장치는 빗물을 깔때기로 모아 시소 모양의 팁핑 버킷으로 유도합니다. 양끝에 각각 약 2ml 빗물을 담는 버킷이 있어, 한쪽이 차면 버킷이 기울며 빗물이 반대쪽 버킷으로 모이기 시작합니다. 버킷이 기울 때마다 리드 스위치가 일시적으로 켜지며 Arduino 하드웨어 인터럽트에 신호를 보냅니다. Arduino는 각 버킷 '팁'을 추적하고, 버킷 부피와 집수조 표면적(16.605 sq.in.)을 기반으로 '팁'을 강우량(인치)으로 변환합니다.

실내 디스플레이 유닛에는 '현재 시간', '이전 시간', '현재 일', '이전 일' 합계를 선택하는 메뉴가 있습니다.

각 버킷 팁마다 날짜 스탬프가 찍힌 이벤트가 SD 카드 파일에 기록됩니다. 이 파일은 나중에 Excel로 가져와 분석과 차트 작성에 활용할 수 있습니다.

실제 '버킷 팁'을 보여주는 영상은 없지만, 이 영상에서 실제 강우 이벤트 기록을 확인할 수 있습니다.

1단계

나열된 모든 구성 요소를 출력합니다. 실외 사용 시 자외선과 온도 노출에 강한 PETG를 30% 인필로 사용했습니다. 상단 필터는 수평 쉘(위/아래)을 모두 끄고 다공성 디테일을 생성하도록 출력하세요.

Arduino 연동 고급 팁핑 버킷 강우량계

2단계

전면 패널 회로 보드 조립 전, LCD를 PY-5*10CM 보드에 납땜하지 않고 올려 핀 1이 보드의 C-1 구멍 위치에 오게 합니다. LCD 보드 마운트 구멍 4개 위치에서 퍼프 보드에 드릴로 구멍을 뚫습니다. 이제 LCD를 제거해 나중에 조립합니다.

3단계

전면 패널 회로 보드 조립. 74HC595N 시프트 레지스터 IC, 스위치, 저항을 사진과 같이 배치. 필요한 모든 배선(배선도 참조)을 LCD 디스플레이 연결 지점과 6인치 길이(나중 두 번째 보드 연결용)로 라우팅.

Arduino 연동 고급 팁핑 버킷 강우량계

4단계

LCD를 전면 패널 보드에 장착. IC 위로 LCD를 들어올릴 수 있도록 출력된 스페이서 사용. 3mm x 15mm 캡 스크류와 너트로 고정. (모든 패스너는 Fastenal 또는 McMaster Carr에서 구매 가능)

Arduino 연동 고급 팁핑 버킷 강우량계

5단계

메인 회로 보드 조립. Arduino를 핀 D12가 보드 구멍 R27 위치에 오게 장착. 커패시터와 저항 추가, SD와 RTC 모듈 장착 전 모든 배선을 위치에 라우팅. 배선 회로도 참조.

Arduino 연동 고급 팁핑 버킷 강우량계

6단계

SD 리더를 구멍 A-3~B-10에 조립. TinyRTC를 구멍 C-24~I-24에 조립. 모든 연결 납땜.

Arduino 연동 고급 팁핑 버킷 강우량계

7단계

실내 유닛 컨트롤 인클로저에 실외 유닛으로 갈 두 선과 외부 파워 서플라이/월 월트 선용 구멍을 적절한 위치에 뚫으세요. 선을 인클로저 안으로 통과시켜 적절한 위치에 납땜. 메인 보드를 케이스에 슬라이드해 3mm x 6mm 롱 스크류 2개로 고정. 푸시버튼을 전면 커버 구멍으로 통과시키고 전면 회로 보드를 3mm x 6mm 롱 스크류로 전면 패널에 부착. 참고: 출력된 부품 대신 작은 황동 선삭 부품을 스위치 버튼으로 사용했는데 '감촉'이 더 좋아서입니다.

Arduino 연동 고급 팁핑 버킷 강우량계

8단계

M3-0.5 x 10mm 플랫헤드 스크류로 전면 커버 부착.

9단계

USB를 PC에 연결하고 RTC 프로그램 업로드해 시간 설정. 시계 설정 후 메인 프로그램 업로드. SD 카드 삽입. 실외 유닛 리드 스위치 연결 단자를 쇼트시켜 테스트. 강우 합계가 각 쇼트(접점 닫힘) 이벤트마다 증가해야 함. 컴퓨터에서 메모장/워드패드 같은 텍스트 에디터로 SD 카드 읽어 날짜 스탬프 확인. "Text.txt" 파일이 있어야 하며 각 '팁' 이벤트마다 날짜 스탬프가 기록됨.

10단계

리드 스위치를 서브 베이스에 부착. 타이로 고정. 자석을 버킷에 조립, 버킷을 약 2인치 길이의 1/8인치 직경 황동 튜브로 피벗 마운트. 조립 전 1/8인치 드릴로 버킷 구멍 정리. 버킷이 마찰 없이 쉽게 기울어야 함. 필요시 작은 원형 줄로 버킷 구멍 다듬기. 버킷 바깥쪽에 작은 1/8인치 와셔로 간격 약간 좁히기. 실외 유닛 마운트 방식 결정. 저는 1인치 알루미늄 앵글 사용. 베이스와 앵글/브래킷을 1/4-20 육각 볼트로 안쪽에서 바깥으로 고정. 서브 베이스를 실외 유닛 하부에 M3-0.5 x 10mm 스크류로 부착.

Arduino 연동 고급 팁핑 버킷 강우량계

11단계

깔때기를 상단 인클로저에 삽입. 약 24개 2인치 길이 18게이지 아연도금 와이어 준비. 펜치로 와이어 잡고 토치/라이터로 가열해 플라스틱 상단에 조심스럽게 눌러 박기. 이 와이어들이 새가 유닛 위에 앉는 걸 방지. 빗물 양을 측정해야지 새똥을 측정하면 안 됩니다. 상단을 메인 인클로저에 (4)M3-0.5 x 6mm 스크류로 부착. 필터를 깔때기 상단에 장착. 이 필터가 낙엽 차단 및 막힘 방지. 주기적으로 확인하고 청소하세요.

Arduino 연동 고급 팁핑 버킷 강우량계

12단계

실외 유닛 마운트하고 선을 실내 유닛으로 연결. 실외 유닛 상단이 양방향으로 수평인지 확인.

13단계

전원 켜고 실외 유닛에 물 부어 동작 확인.

14단계 (선택사항)

정확도 검증을 위해 물 한 컵을 매우 천천히 부어 0.87인치 강우량 측정되는지 확인. (한 컵 = 14.44 입방인치. 집수조 면적 16.605 sq.in. [강우량 = 14.44 cu.in. / 16.605 = 0.87인치]. 메인 프로그램에서 보정 계수 조정 가능.)

축하합니다!! 강우량 추적의 기쁨을 누리세요.

코드

RTC 시간 설정용 Arduino 코드

이 코드를 먼저 업로드해 RTC 시간 설정. 업로드 전 실제 날짜/시간으로 코드 수정.

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); }
byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); }
void setDateDs1307() {
  second = 00; minute = 11; hour = 12;
  dayOfWeek = 5; dayOfMonth = 24; month = 7; year = 20;
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(decToBcd(0));
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}
void getDateDs1307() {
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(decToBcd(0)); Wire.endTransmission();
  Wire.requestFrom(DS1307_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());
  Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC);
  Serial.print(":"); Serial.print(second, DEC); Serial.print(" ");
  Serial.print(month, DEC); Serial.print("/"); Serial.print(dayOfMonth, DEC);
  Serial.print("/"); Serial.print(year,DEC); Serial.println();
}
void setup() { Wire.begin(); Serial.begin(19200); setDateDs1307(); }
void loop() { delay(2000); getDateDs1307(); }

강우량계 메인 프로그램 Arduino 코드

강우량계 메인 프로그램. 컴파일 전 모든 관련 라이브러리 설치 필수. LiquidCrystal 라이브러리 업데이트 지침은 [여기](https://roboindia.com/tutorials/arduino-3-pin-serial-lcd/) 참조.

/* Tipping Bucket Rain Gauge - Written by Bob Torrence */
#include <SPI.h> #include <SD.h> #include <Wire.h> #include "RTClib.h"
#include <LiquidCrystal_SR.h> // 특수 버전 LiquidCrystal 라이브러리
LiquidCrystal_SR lcd(6, 5, 9); // Pin 6=Data/SER, 5=Clock/SCL, 9=SCK
RTC_DS3231 rtc;
int backlight = 7;
const byte interruptPin_bucket = 3;
const byte interruptPin_menu = 2;
volatile int Bucket_Tip_Occurence = 0;
volatile int Menu_Select = 0;
float Bucket_tip_hour_total = 0;
float Bucket_tip_current_hour_total = 0;
float Bucket_tip_previous_hour_total = 0;
float Bucket_tip_current_day_total = 0;
float Bucket_tip_previous_day_total = 0;
int current_minute, loop_minute, current_hour, loop_hour, current_day, loop_day, tip_counter;
float conversion_factor = .00854; // 팁당 강우량(인치) - 버킷 부피와 집수조 면적(16.605 sq.in.)으로 계산
volatile unsigned long backlightOfftime;
volatile unsigned long backlightOnDuration = 30000;
String print_time(DateTime timestamp) {
  char message[120];
  sprintf(message, "%02d:%02d:%02d %02d/%02d", timestamp.hour(), timestamp.minute(), timestamp.second(), timestamp.month(), timestamp.day());
  return message;
}
File myFile;
void setup() {
  lcd.begin(16,2); lcd.home();
  rtc.begin();
  pinMode(10, OUTPUT); pinMode(backlight, OUTPUT);
  digitalWrite(backlight, HIGH);
  backlightOfftime = millis() + backlightOnDuration;
  if (!SD.begin(4)) { lcd.print("insert SD Card"); return; }
  pinMode(interruptPin_bucket, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin_bucket), count, FALLING);
  pinMode(interruptPin_menu, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin_menu), menu, RISING);
  myFile = SD.open("test.txt", FILE_WRITE);
  if (myFile) { myFile.println("Rain Gauge Ready - unit powered up"); myFile.close(); }
  DateTime now = rtc.now();
  current_minute = loop_minute = now.minute();
  current_hour = loop_hour = now.hour();
  lcd.setCursor(0,0); lcd.print(print_time(now));
  lcd.setCursor(1,1); lcd.print("Rain Gauge");
}
void loop() {
  DateTime now = rtc.now();
  current_minute = loop_minute = now.minute();
  current_hour = loop_hour = now.hour();
  current_day = loop_day = now.day();
  while (loop_day - current_day == 0) {
    while (loop_hour - current_hour == 0) {
      if (millis() > backlightOfftime) digitalWrite(backlight, LOW);
      if (Bucket_Tip_Occurence == 1) {
        Bucket_Tip_Occurence = 0; tip_counter++;
        now = rtc.now();
        myFile = SD.open("test.txt", FILE_WRITE);
        myFile.print("Event "); myFile.print(now.year(), DEC); myFile.print('/');
        myFile.print(now.month(), DEC); myFile.print('/'); myFile.print(now.day(), DEC);
        myFile.print(" "); myFile.print(now.hour(), DEC); myFile.print(':');
        myFile.print(now.minute(), DEC); myFile.print(':'); myFile.print(now.second(), DEC);
        myFile.print(" "); myFile.print(conversion_factor, 5); myFile.println();
        myFile.close(); delay(200);
      } else {
        now = rtc.now(); loop_hour = now.hour();
      }
      switch (Menu_Select) {
        case 1: lcd.clear(); lcd.setCursor(0,0); lcd.print("Current Hour");
                lcd.setCursor(0,1); lcd.print(tip_counter * conversion_factor); delay(500); break;
        case 2: lcd.clear(); lcd.setCursor(0,0); lcd.print("Previous Hour");
                lcd.setCursor(0,1); lcd.print(Bucket_tip_previous_hour_total); delay(500); break;
        case 3: lcd.clear(); lcd.setCursor(0,0); lcd.print("Current Day");
                lcd.setCursor(0,1); lcd.print(Bucket_tip_current_day_total + tip_counter * conversion_factor); delay(500); break;
        case 4: lcd.clear(); lcd.setCursor(0,0); lcd.print("Previous Day");
                lcd.setCursor(0,1); lcd.print(Bucket_tip_previous_day_total); delay(500); break;
      }
    }
    now = rtc.now();
    current_hour = now.hour(); loop_day = now.day(); loop_hour = now.hour();
    Bucket_tip_previous_hour_total = tip_counter * conversion_factor;
    Bucket_tip_current_day_total += Bucket_tip_previous_hour_total;
    tip_counter = 0;
  }
  Bucket_tip_previous_day_total = Bucket_tip_current_day_total;
  Bucket_tip_current_day_total = 0; Bucket_tip_current_hour_total = 0; tip_counter = 0;
}
void count() {
  static unsigned long last_interrupt_time_bucket = 0;
  unsigned long interrupt_time_bucket = millis();
  if (interrupt_time_bucket - last_interrupt_time_bucket > 300) Bucket_Tip_Occurence = 1;
  last_interrupt_time_bucket = interrupt_time_bucket;
}
void menu() {
  static unsigned long last_interrupt_time_menu = 0;
  unsigned long interrupt_time_menu = millis();
  if (interrupt_time_menu - last_interrupt_time_menu > 300) {
    if (digitalRead(backlight) == LOW) digitalWrite(backlight, HIGH);
    else { Menu_Select++; if (Menu_Select > 4) Menu_Select = 1; }
    backlightOfftime = millis() + backlightOnDuration;
  }
  last_interrupt_time_menu = interrupt_time_menu;
}

커스텀 파트 및 인클로저

회로도

프로젝트 배선 회로도 (.fzz 파일)

제조공정

  1. 산업 및 안전용 정밀 압력 게이지
  2. 스마트 블라인드: 아두이노와 태양광으로 자동 조명 제어
  3. 이탈리안 워드 클럭(Word Clock) 제작: 아두이노 나노 + 네오픽셀 + LCD + RTC
  4. 디지털 하이트 게이지: 정밀 측정 및 품질 관리 솔루션
  5. 마이크로미터 나사 게이지: 정의, 역사 및 실용적 사용법
  6. 압력 게이지 작동 원리: 유형, 기능, 장점 총정리
  7. 스트레인 게이지(Strain Gauge) 원리·종류·응용·장단점 완벽 해설
  8. 피라니 게이지 완벽 가이드: 작동 원리, 용도, 장단점
  9. 다이어프램 압력 게이지: 정밀도와 신뢰성의 원리
  10. 부르돈 압력 게이지 마스터하기: 설계, 작동, 응용