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

아두이노 나노로 만드는 휴대용 가이거 계수기

부품 및 소모품

아두이노 나노 R3 1개
기성 가이거 계수기 키트 (조립 완료품) 1개
0.96인치 컬러 OLED 디스플레이 96x64 1개
마이크로 USB 충전 보드 (18650 배터리용) 1개
3.7V 4000mAh 보호 회로 내장 18650 리튬이온 배터리 1개
트랜지스터 BC547 1개
부저 12mm 1개
저항 1k옴 1개

필요한 도구 및 장비

앱 및 온라인 서비스

프로젝트 소개

이 프로젝트는 뱅굿에서 기성 가이거 계수기 키트를 구매하면서 시작되었습니다.

이 키트를 3D 프린팅한 하우징에 넣어 완전히 작동하는 휴대용 가이거 계수기 세트를 만드는 것이 아이디어였습니다. 최종 결과물은 아래와 같습니다.

1단계: 시스템 설계

휴대용 가이거 계수기 설계도는 아래 다이어그램과 같습니다.

0.96인치 컬러 OLED 디스플레이를 장착해 측정된 CPM(분당 계수, 이온화 사건 검출률)과 계산된 선량 당량(µSv/hr)을 표시합니다. µSv/hr 변환은 사용된 가이거-뮐러(GM) 관 타입에 대한 문헌 값인 151 계수를 사용했습니다(위키피디아: Counts per minute 참조).

표시되는 CPM은 초당 계수(CPS)를 측정해 최근 10초간 측정값을 배열에 저장하고, 이 10초간 총 계수에 6을 곱해 산출합니다. 직전 1초 계수로는 OLED에 막대 그래프로 순간적 측정치를 표시해 고선량이나 급격한 변화 시 유용합니다.

전원은 18650 리튬이온 배터리(마이크로 USB로 충전). 아두이노 나노 USB 포트도 소프트웨어 업데이트용으로 접근 가능. 기성 키트의 부저 소리가 작아 외부 부저 추가.

모든 전자 부품은 3D 프린팅 하우징 내부에 장착. OLED 디스플레이는 가이거 계수기 위쪽 별도 박스에 장착. 완전 조립품 사진 참조.

2단계: 가이거 계수기 조립

사용 재료:

전자 회로 설계

가이거 계수기 키트 회로도와 전체 회로도, 브레드보드 테스트 설정 사진 참조. 5V는 충전 보드에 장착된 18650 배터리에서 공급, OLED용 3.3V도 이 보드에서 가져옴.

3단계: 소프트웨어 설계

소프트웨어 전체 흐름 순서도와 OLED 표시 화면 구성 참조. 전체 아두이노 스케치는 아래와 같습니다(약 150줄, 풍부한 주석 포함).

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
// OLED 연결 핀
#define sclk 13 // SCL (파랑)
#define mosi 11 // SDA (하양)
#define cs 10   // CS (회색)
#define rst 9   // RES (초록)
#define dc 8    // DC (노랑)
#define LOGtime 1000 // 로깅 간격 1초(ms)
#define Minute 60000 // CPM 계산용 1분 주기
#define show endWrite
#define clear() fillScreen(0)
// 색상 정의
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
int Counts = 0; // LOGtime 내 GM 관 이벤트 수
unsigned long previousMillis = 0; // 이전 시간 저장
int AVGCPM = 0; // 고정 이동 윈도우 기간 평균 계수
int TenSecCPM = 0;
int units = 0, tens = 0, hundreds = 0, thousands = 0;
float Sievert = 0;
int COUNTS[10]; // 연속 10초간 1초당 측정된 임펄스 저장 배열
int t = 0;

void setup() {
  Serial.begin(115200);
  display.begin();
  display.fillScreen(BLACK);
  float Battery = analogRead(A3); // 배터리 전압 읽기 (주황 선)
  float BattPerc = 100 * (Battery/770);
  // 시리얼 디버그 출력 생략
  display.setCursor(4,4);
  display.setTextSize(2);
  display.setTextColor(MAGENTA);
  display.println("Battery");
  display.setCursor(4,24);
  display.print(int(BattPerc)); display.print("."); display.print(int((10*BattPerc)-(10*int(BattPerc)))); display.print(" %");
  delay(3000);
  display.fillScreen(BLACK);
  for(int x = 0; x < 10 ; x++) COUNTS[x] = 0; // 배열 초기화
  attachInterrupt(0, IMPULSE, FALLING); // D2/INT0 외부 인터럽트 설정 (녹색 선)
  display.drawRect(0,0,96,64,WHITE);
  display.setCursor(4,4);
  display.setTextColor(RED);
  display.setTextSize(2);
  display.print("CPM");
  display.setCursor(50,4);
  display.setTextSize(1);
  display.print("10 sec");
  display.setCursor(50,12);
  display.print("window");
  display.setCursor(4,38);
  display.setTextSize(1);
  display.setTextColor(GREEN);
  display.print("uSv/hr");
  display.drawRect(0,48, 96, 16, YELLOW);
}

void loop() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOGtime) {
    previousMillis = currentMillis;
    COUNTS[t] = Counts;
    for (int y = 0; y < 10 ; y++) TenSecCPM += COUNTS[y]; // 최근 10초 합산
    AVGCPM = 6 * TenSecCPM; // CPM 환산
    TenSecCPM = 0;
    t++; if (t > 9) t = 0;
    // 디버그 출력 생략
    display.fillRect(4,20,90,17,BLACK); // CPM 값 영역 지우기
    display.setCursor(4,20);
    display.setTextColor(RED);
    display.setTextSize(2);
    display.println(AVGCPM);
    display.fillRect(45,38,50,10,BLACK); // µSv/hr 영역 지우기
    display.setCursor(45,38);
    display.setTextColor(GREEN);
    display.setTextSize(1);
    Sievert = (AVGCPM / 151.0); // µSv/hr 계산
    units = int(Sievert);
    tens = int((10*Sievert) - (10*units));
    hundreds = int((100*Sievert) - (100*units) - (10*tens));
    thousands = int((1000*Sievert) - (1000*units) - (100*tens) - (10*hundreds));
    display.print(units); display.print("."); display.print(tens); display.print(hundreds); display.println(thousands);
    display.fillRect(1,49,94,14,BLACK); // CPM 표시 바 영역 지우기
    display.fillRect(1,49,Counts,14,RED); // 직전 1초 계수(CPS) 막대 그래프
    Counts = 0;
  }
}

// GM 관 임펄스 인터럽트 루틴 (INT 신호가 LOW 펄스로 들어옴)
void IMPULSE() { Counts++; }

가장 중요한 부분은 GM 관에서 임펄스가 감지되어 가이거 계수기의 INT 출력이 순간적으로 LOW가 될 때 호출되는 인터럽트 함수입니다. INT 신호는 아두이노 나노의 D2 핀(외부 인터럽트 INT0)에 연결됩니다.

attachInterrupt(0, IMPULSE, FALLING);

INT 신호가 들어오면 IMPULSE() 루틴이 실행돼 Counts++ 합니다.

1000ms 경과 후: Counts를 0으로 리셋, COUNTS[] 배열에 최근 1초 계수 저장, 배열 전체 합산×6으로 CPM 계산해 표시. CPM/151로 µSv/hr 산출 표시. 컬러 OLED에 직전 1초 계수(Counts) 기반 빨간 막대 그래프로 CPS 표시.

코드

Geiger_Counter.ino (아두이노) - 위 전체 스케치 참조

3D 프린팅 파일

회로도

전자 부품 연결 설정도 참조

제조공정

  1. 아두이노로 만드는 레트로 누미트론 클락: 심플하고 신뢰성 높으며 에너지 효율적
  2. 아두이노 나노와 MPU-6050으로 실시간 자이로스코프 게임 만들기
  3. 아두이노 디지털 주사위: LCD 기반 랜덤 넘버 제너레이터 만들기
  4. DIY 아두이노 USB 게임 컨트롤러 - 나만의 고성능 게임패드 만들기
  5. 스마트 저금통 만들기: 아두이노 나노로 동전 인식기 제어하기
  6. 아두이노 나노로 테트리스 게임 만들기: DIY 16×8 LED 매트릭스
  7. 아두이노 블루투스로 LED 제어하기 - HC-05 & MIT App Inventor 입문 가이드
  8. 아두이노 나노와 조이스틱으로 2개 스테퍼 모터 제어하기 – 비주이노(Visuino) 튜토리얼
  9. 아두이노, 고압 부스트, 20x4 LCD로 맞춤형 가이거-뮐러 계수기 만들기
  10. 픽셀 체이서: 아두이노 나노로 만든 인터랙티브 원탭 LED 게임