티스토리 뷰

개요

 

1) 기본적인 센서 측정 동작을 둘러보고, 개념을 이해한다.

2) interrupt 제대로 작동하는지, 놓치는 경우는 없는지 확인한다.

 

참고사항

 

- 이전 포스팅들과 중복되는 부분이 있겠지만 참고할 부분들을 적어본다.

 

참고1. 센서와 라즈베리파이 연결

 

PPD42NS 센서

라즈베리파이 3B

1 (GND)

아래그림 6 GND

3 (5V)

아래그램 2 또는 4 5V

2 (Output PM25)

아래그림 3 GPIO 2

4 (Output PM10)

아래그림 7 GPIO 4

 

참고2. Base code (GitHub)

 

- 링크: https://github.com/mauricecyril/pidustsensor/blob/master/pidustsensor.py

 

참고3. pigpio 실행시키기

 

$sudo pigpiod

 

- 기본적인 GPIO 컨트롤을 위해서 pigpio demon 우선 실행해주어야 한다.

- 이후 Python program localhost pigpio daemon 통신하며 GPIO 제어한다.

- 링크: https://www.raspberrypi.org/forums/viewtopic.php?t=103752

 

참고4. rmate 원격 프로그래밍을 하려 할때에 소스코드가 vscode 뜨지 않는다면?

 

1) netstat 찍어보기

sudo netstat -plant | grep 52698

 

2) 프로세스 12418 포트를 잡고 있다.

netstat 명령의 의미를 알아보는 것은 생략하고 아무튼 52698 포트를 12418 프로세스가 잡고 있는게 보인다.

 

3) 이것만 삭제해버리면 정상동작한다. 그리고 라즈베리파이에 재접속하면 된다.

sudo kill -9 12418

 


 

본격 코드 리뷰

 

하나씩 정리된 코드는 아래 링크의 깃헙에 올리겠음

- GitHub 링크: https://github.com/nicewook/dustsensor_public/blob/master/ds_test1.py

 

프로그램의 시작

 


 

1) 파일명은 ds_test1.py 이다.

- ds dust sensor 의미한다.

 

2) pigpio.pi('localhost')

- pigpio deamon 연결하고

- 명령을 보내거나 노티를 받기위한 리소스를 리턴받아 놓는다.

 

3) sensor class 인스턴스를 생성한다.

- 하나는 PM1.0 측정을 위한 GPIO 4

- 하나는 PM2.5 측정을 위한 GPIO 2핀을 파라미터도 전달하여 생성한다.

바로 아래에 클래스 생성시의 동작을 설명하겠음


 

파이썬에서 class 인스턴스를 생성하면 __init__ 함수가 실행된다.

- 생성자라고 생각하면 된다.

 

1) self.pi self.gpio

-  pigpio 리소스를 계속 사용하도록 self.pi 저장해둔다

- gpio 번호도 self.gpio 저장해둔다.

 

2) LPO Time 측정을 위한 변수들

- tick 32bit microsecond 값이며, 대략 72 분마다 overflow 되어 다시 0 된다.

- level 센서의 출력값이 1인지 0인지를 말해준다.

self._start_tick = None

self._last_tick = None

- 측정 시작하는 순간의 tick

- 이전 인터럽트시의 tick

self._low_ticks = 0

self._high_ticks = 0

- Low pulse tick 들의 누적

- High pulse tick 들의 누적

self._last_level = 0

- 이전 인터럽트 시의 high / low

 

3) 측정 측정시 참고 값들을 저장할 변수들

self.wrong_level_count = 0

이전 level 이번 인터럽트시의 level 같은

오류가 있는지를 체크하여 count

self.total_interrupt_count = 0

interrupt 번이나 발생하는지 count

self.on_measure = False

한번의 측정은 30 정도인데

측정 시간 이외에는 인터럽트를 무시하도록

하기위한 flag

 

4) set_mode() callback()

- 센서로부터의 값을 읽어들이므로 해당 핀을 pigpio.INPUT 으로 모드설정

- 해당 핀이 Low to High, High to Low 바뀌는 경우 모두에 대해 (= pigpio.EITHER_EDGE)

이벤트 발생시 처리할 callback function self._cbf 함수를 설정해둠

 

초기화가 되고 나면, 측정을 시작한다.

1) 측정 시작 - 30 대기 - 측정 종료

- measureStart()

- sleep()

- measureStop()

 

2) 측정값 읽기

- read()

 

3) 측정값 출력으로 되어 있다.

 

참고1. 1114000.62 센서값의 오류가 발생시 나오는 값이다.

참고2. 30초만에 동시에 출력값을 측정하는 것과, 각각 30초씩 측정하는 값을 비교하는 코드가 있지만, 여기 설명에선 생략한다.

 

측정 시작과 측정 종료

 

- base code 링크: https://github.com/mauricecyril/pidustsensor/blob/master/pidustsensor.py

베이스 코드는 가지 문제가 있다고 보았다.

 

1) 측정을 시작해도 첫번째 인터럽트가 발생해야 진짜 측정이 시작됨

 

2) 만약 마지막 인터럽트 측정 종료시까지 인터럽트가 없으면 반영이 안됨

 

부분을 개선하기 위해 measureStart(), measureStop() 함수를 추가하였음

 

1) 시작하자 마자 self._start_tick, self._last_tick 업데이트 하였고

self._last_level 업데이트 하였음

 

2) 종료시에에도 마찬가지 작업을 해주어서

self._low_ticks, self._high_ticks 마지막 상태의 tick 소요시간을 더해 주었다.

 

 

측정값 읽어오기

 

내용은 것이 없다.

 

1) 전체 소요시간인 interval 계산한 다음

 

2) LPO Time 퍼센티지로 계산하였다. (ratio)

 

3) 이를 바탕으로 공식에 따라 concentration 값을 계산하였는데

- 이는 LPO Time 통해 먼지개수/0.01 ft3 통계적으로 유추한 값이다.  

- , LPO Time ratio 만큼이면 0.01 ft3 공간에 개의 먼지가 있을 것인가 계산

 

4) 그리고 전체 인터럽트 개수와, 잘못된 인터럽트 발생개수 까지 포함하여 리턴

 

 

실행 결과 참고

 

1) 잘못된 인터럽트는 전혀 없으며 (Pigpio 짱짱맨)

2) PM1.0 측정 개수는 PM2.5 개수까지 포함된 것이니 빼주는게 맞겠지만 차이는 없어 보인다.

 


  

삽질의 기록

 

- 부분은 읽어도

1) Base code 에서는 예를 들어 ds_test1.py 파일에 class sensor 가 있다 하면

2) main 에서 import app 을 해주고, s10 = ds_test1.sensor(pi, 4) 로 인스턴스를 생성하는 코드였음.

 

3) 이런 저런 테스트를 하다보니 복사해서 작업을 하는데 미처 이부분을 고치지 않았던게 삽질의 원인이었음

- , ds_test1.sensor(pi, 4) 라고 해야 하는데

- ds.py import 하여 ds.sensor(pi, 4) 라고

 

 


반응형
반응형
잡학툰 뱃지
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함