안녕하세요.
ModbusTCP는 가상환경에서 동작하는 것을 이전 글에서 확인했습니다. 그러나 가상환경에서 GPIO 엣지 검출(Pulse)을 하려고 하는데 생각과 달리 잘 되지 않아서 차선책으로 찾은 방법을 남겨두려고 합니다.
그냥 폴링(Polling)으로 하기에는 정확도와 비효율적이라는 생각이 들어서 해결방법은 없을지 찾아보았습니다.
1. 기본 가상환경 생성 및 설정
Python 표준 라이브러리의 venv 모듈을 사용하여 가상 환경(virtual environment)을 생성합니다. 가상 환경은 Python 프로젝트마다 독립적인 패키지와 Python 인터프리터를 사용할 수 있게 해 줍니다.
아래와 같이 가상환경을 생성 후 RPi 라이브러리 설치
(이전 ModbusTCP 확인 때문에, 설치했다면 가상환경은 지나가도 됩니다. 다음 내용을 보시면 됩니다. )
$ python3 -m venv ~/virtualEnv
$ pip install RPi.GPIO
참고로, ModbusTCP 때문에 가상환경 설치한 글은 아래 링크를 참고하시면 됩니다.
2. add_event_detect() 에러 발생
가상환경에서 RPi.GPIO의 add_event_detect() 함수를 사용하면 이벤트를 받아서 처리할 수가 없었다고 에러가 나타납니다.
GPIO.add_event_detect(FLOW_SENSOR_PIN, GPIO.FALLING, callback=count_pulse) 와 같은 구현을 했을 경우 에러 발생가 발생합니다.
add_event_detect 를 사용한 유량측정 전체 코드는 아래 링크에서 참고하시면 됩니다.
3. 해결 방법
기본적으로 검색에는 잘 나오지 않아서 ChatGPT에게 도움을 요청했는데 방안은 sudo 권한으로 해보라, GPIOZero 라이브러리를 사용해 보라. 그런데 이 두 가지는 안되었고, wingpi도 나왔는데 버전이 맞지 않아 설치되지 않았습니다.
마지막 pigpio 라이브러리 사용하는 것이었습니다.
이것에 대해서 상세히 알지는 못하지만, 데몬을 먼저 실행을 해야 GPIO 제어가 가능합니다.
가상환경에서 pigpio 라이브러리를 설치하고 데몬을 실행시킵니다. pigpiod 데몬이 실행되지 않은 경우, pigpio.pi()를 호출하면 오류가 발생합니다.
$ pip install pigpio
$ sudo pigpiod
4. 유량센서 pigpio 이용한 코드 변경
import pigpio
import time
# 센서 설정
FLOW_SENSOR_PIN = 17 # 연결한 GPIO 핀 번호
PULSES_PER_LITER = 595 # 1L 당 약 595 펄스 발생
# 펄스 카운트를 위한 변수
pulse_count = 0
start_time = time.time()
# 펄스가 발생할 때마다 카운트를 증가하는 콜백 함수
def count_pulse(gpio, level, tick):
global pulse_count
pulse_count += 1
# pigpio 초기화
pi = pigpio.pi()
if not pi.connected:
print("pigpio 데몬이 실행되지 않았습니다. 데몬을 실행하세요: 'sudo pigpiod'")
exit(1)
# FLOW_SENSOR_PIN 핀을 입력으로 설정하고 pull-up 활성화
pi.set_mode(FLOW_SENSOR_PIN, pigpio.INPUT)
pi.set_pull_up_down(FLOW_SENSOR_PIN, pigpio.PUD_UP)
# 펄스 감지를 위한 콜백 등록
cb = pi.callback(FLOW_SENSOR_PIN, pigpio.FALLING_EDGE, count_pulse)
try:
while True:
# 측정 간격 설정 (10초)
time.sleep(10)
# 시간 계산
end_time = time.time()
elapsed_time = end_time - start_time
# 유량 계산 (L/min)
# 10초 동안의 유량이므로 6을 곱해 1분당 유량으로 변환
flow_rate = (pulse_count / PULSES_PER_LITER) * (60 / elapsed_time)
# 결과 출력
print(f"Flow Rate: {flow_rate:.2f} L/min")
# 카운트와 시간 초기화
pulse_count = 0
start_time = time.time()
except KeyboardInterrupt:
print("Measurement stopped")
finally:
# pigpio 자원 정리
cb.cancel() # 콜백 해제
pi.stop() # pigpio 종료
5. 동작확인
먼저, pigpiod 실행시키고, 소스 코드를 유량 펄스 카운트 소스를 실행시키면 문제없이 이전 글에 있는 유량센서와 동일하게 가상환경에서도 작동하는 것을 확인할 수 있습니다.
$ sudo pigpiod
$ python pulse_pigoio.py
감사합니다.