온습도 센서를 openCR에서 라즈베리로 보내주면 계속 에러가 났다

처음에는 온습도가 문제인지도 모르고 코드랑 주소만 바꿨다
IDLE을 쓰면 해결된다 했는데, There is no status packet! 에러가 늦게 뜰 뿐 여전히 에러가 남

비차단(Non-blocking) 방식의 핵심은 **"데이터가 올 때까지 CPU가 delay()하며 기다리지 않고, 다른 일을 하다가 데이터가 준비되면 낚아채는 것"**입니다.
사용자님의 환경(OpenCR + DHT11)에 맞춰서 DHT_NonBlocking 라이브러리를 사용하는 방식과 이를 상태 머신으로 관리하는 통합 코드를 짜드릴게요.
1. 사전 준비 (라이브러리 설치)
아두이노 IDE의 **라이브러리 관리자(Ctrl+Shift+I)**에서 DHT_NonBlocking (작성자: Ole Wolf)을 검색해서 설치하세요.

2. Turtlebot3Sensor.h (헤더 파일 수정)
기존 DHT 포인터를 새로운 라이브러리 클래스로 교체해야 합니다.
C++
// turtlebot3_sensor.h 내부
#include <dht_nonblocking.h> // 라이브러리 변경
class Turtlebot3Sensor {
private:
DHT_NonBlocking *p_dht; // 클래스명 변경
int dht_pin_;
public:
void initDHT(void);
bool readDHT(float &temp, float &humi); // 이제 한 번에 온습도를 읽는 방식으로 변경
};
3. Turtlebot3Sensor.cpp (함수 구현 수정)
readDHT 함수는 데이터가 준비되었을 때만 true를 반환하도록 설계합니다.
C++
// turtlebot3_sensor.cpp
void Turtlebot3Sensor::initDHT(void) {
dht_pin_ = 4;
p_dht = new DHT_NonBlocking(dht_pin_, DHT_TYPE_11); // DHT11 지정
}
// 비차단 방식으로 온습도를 읽는 함수
bool Turtlebot3Sensor::readDHT(float &temp, float &humi) {
// measure 함수는 내부적으로 타이머를 체크하여
// 데이터 읽기가 완료된 순간에만 true를 리턴합니다. (내부 delay 없음)
if (p_dht->measure(&temp, &humi)) {
return true;
}
return false;
}
4. turtlebot3.cpp (상태 머신 적용)
가장 중요한 부분입니다. update_analog_sensors에서 "데이터가 준비됐을 때만" 제어표(Control Table)를 갱신합니다.
C++
void update_analog_sensors(uint32_t interval_ms)
{
static uint32_t pre_time = 0;
// [Part 1] 빠른 센서 (가스, 불꽃 등 - 30ms 주기)
if(millis() - pre_time >= interval_ms){
pre_time = millis();
// (기존 가스, 불꽃 센서 로직 유지)
control_items.flame_digital_status = (analogRead(A2) <= 300) ? 1 : 0;
control_items.gas_digital_status = (digitalRead(12) == LOW) ? 1 : 0;
}
// [Part 2] 비차단 온습도 업데이트 (상태 머신)
float temp, humi;
// readDHT는 내부 타이머에 따라 약 2~4초마다 한 번씩만 true를 반환합니다.
// 그 외의 시간에는 0.001초도 멈추지 않고 바로 false를 뱉고 지나갑니다.
if (sensors.readDHT(temp, humi)) {
// 데이터가 준비된 찰나에만 값을 업데이트합니다.
control_items.dht_temp = (int32_t)(temp * 100.0f);
control_items.dht_humi = (int32_t)(humi * 100.0f);
// 디버깅용 로그 (필요할 때만 확인)
// DEBUG_PRINT("[DHT Success] T: "); DEBUG_PRINT(temp);
// DEBUG_PRINT(" H: "); DEBUG_PRINTLN(humi);
}
// 이 함수가 종료되면 즉시 dxl_slave.processPacket()이 실행될 수 있으므로
// 다이나믹셀 통신이 끊기지 않습니다.
}
💡 이 코드의 작동 원리 (왜 안 멈추나?)
- 기존 방식: readTemperature() 호출 → 데이터 올 때까지 CPU가 멍하니 기다림(Blocking) → 라즈베리파이가 부르는데 대답 못 함 → 에러 발생
- 비차단 방식: readDHT() 호출 → "아직 시간 안 됐네?" 또는 "읽는 중이야" 하고 바로 리턴 → 메인 루프 돌면서 dxl_slave.processPacket() 실행 → 라즈베리파이와 사이좋게 대화 → 통신 유지
이렇게 수정하면 온습도 센서 때문에 전체 시스템이 기절하는 현상을 완벽하게 막을 수 있습니다.
지금 바로 DHT_NonBlocking 라이브러리를 설치하고 코드를 적용해 보시겠어요? 설치 중에 막히는 부분이 있으면 바로 말씀해 주세요!
'아두이노' 카테고리의 다른 글
| 아두이노 - 도트 매트릭스 (0) | 2026.03.29 |
|---|---|
| 아두이노 millis (0) | 2026.03.29 |
| 아두이노 - 7세그먼트 (0) | 2026.03.26 |
| 아두이노 - 서보모터, 초음파 (0) | 2026.03.23 |
| 아두이노 - Timer (빛, 부저) (0) | 2026.03.23 |