COSA
An Object-Oriented Platform for Arduino Programming
DHT.cpp
Go to the documentation of this file.
1 
21 #include "DHT.hh"
22 #include "Cosa/RTT.hh"
23 #include "Cosa/Watchdog.hh"
24 
25 /*
26  * The interrupt handler, enabled after the request pulse, and on
27  * falling (low to high) transition. This allows lower interrupt
28  * frequency than on change mode (which would be required for pin
29  * change interrupts. First pulse is the device response and a
30  * one(1) bit is encoded as a long pulse (54 + 80 = 134 us), a
31  * zero(0) bit as a short pulse (54 + 24 = 78 us). Sequence ends
32  * with a low pulse (54 us) which allows falling/rising detection.
33  */
34 void
35 DHT::on_interrupt(uint16_t arg)
36 {
37  UNUSED(arg);
38 
39  // Calculate the pulse width and check against thresholds
40  uint16_t stop = RTT::micros();
41  uint16_t us = (stop - m_start);
42  bool valid = false;
43 
44  // Check the initial response pulse
45  if (m_state == RESPONSE) {
46  if (us < BIT_THRESHOLD) goto exception;
47  m_state = SAMPLING;
48  m_start = stop;
49  m_bits = 0;
50  m_ix = 0;
51  return;
52  }
53 
54  // Sanity check the pulse length
55  if (us < LOW_THRESHOLD || us > HIGH_THRESHOLD) goto exception;
56  m_start = stop;
57 
58  // Sample was valid, collect bit and check for more
59  m_value = (m_value << 1) + (us > BIT_THRESHOLD);
60  m_bits += 1;
61  if (m_bits != CHARBITS) return;
62 
63  // Next byte ready
65  m_bits = 0;
66  valid = (m_ix == DATA_MAX);
67  if (valid) goto completed;
68  return;
69 
70  // Invalid sample reject sequence
71  exception:
72  m_ix = 0;
73 
74  // Sequence completed
75  completed:
77  disable();
78  if (valid) adjust_data();
79  on_sample_completed(valid);
80 }
81 
82 bool
84 {
85  // Issue a request; pull down for more than 18 ms
87  IOPin::clear();
88  Watchdog::delay(32);
89 
90  // Request pulse completed; pull up for 40 us and collect
91  // data as a sequence of on rising mode interrupts
92  m_state = RESPONSE;
93  m_start = RTT::micros();
94  IOPin::set();
96  DELAY(40);
97  enable();
98  return (true);
99 }
100 
101 bool
103 {
104  // Wait for the sample request to complete
105  uint32_t start = RTT::millis();
106  while (m_state != COMPLETED && (RTT::since(start) < MIN_PERIOD))
107  yield();
108  if (m_state != COMPLETED) return (false);
109 
110  // Data reading was completed; validate data and check sum
111  m_state = INIT;
112  return (is_valid());
113 }
114 
115 bool
117 {
118  if (m_ix != DATA_MAX) return (false);
119  uint8_t sum = 0;
120  for (uint8_t i = 0; i < DATA_LAST; i++)
121  sum += m_data.as_byte[i];
122  return (sum == m_data.chksum);
123 }
124 
125 void
127 {
128  m_humidity = m_data.humidity * 10;
130 }
131 
132 void
134 {
137  if (m_temperature >= 0) return;
138  m_temperature = -(m_temperature & 0x7fff);
139 }
140 
141 IOStream&
142 operator<<(IOStream& outs, DHT& dht)
143 {
144  outs << PSTR("RH = ") << dht.m_humidity / 10
145  << '.' << dht.m_humidity % 10
146  << PSTR("%, T = ") << dht.m_temperature / 10
147  << '.' << dht.m_temperature % 10
148  << PSTR(" C");
149  return (outs);
150 }
uint8_t chksum
Definition: DHT.hh:184
uint8_t m_ix
Definition: DHT.hh:201
bool sample_await()
Definition: DHT.cpp:102
Waiting for response.
Definition: DHT.hh:156
bool is_valid()
Definition: DHT.cpp:116
data_t m_data
Definition: DHT.hh:204
uint8_t m_bits
Definition: DHT.hh:198
void set() const
Definition: OutputPin.hh:85
friend IOStream & operator<<(IOStream &outs, DHT &dht)
Definition: DHT.cpp:142
static const uint8_t DATA_MAX
Definition: DHT.hh:170
Mode mode() const
Definition: IOPin.hh:71
#define PSTR(s)
Definition: Types.h:202
Initial state.
Definition: DHT.hh:153
static const uint16_t BIT_THRESHOLD
Definition: DHT.hh:166
virtual void disable()
Collecting samples.
Definition: DHT.hh:157
bool sample_request()
Definition: DHT.cpp:83
static uint32_t micros()
Definition: RTT.cpp:103
#define DELAY(us)
Definition: Types.h:280
static uint32_t since(uint32_t start)
Definition: RTT.hh:107
int16_t humidity
Definition: DHT.hh:182
virtual void adjust_data()
Definition: DHT.cpp:126
#define CHARBITS
Definition: Types.h:57
virtual void adjust_data()=0
static const uint16_t HIGH_THRESHOLD
Definition: DHT.hh:167
static uint32_t millis()
Definition: RTT.cpp:121
volatile uint8_t m_state
Definition: DHT.hh:189
void(* yield)()
Data transfer completed.
Definition: DHT.hh:158
virtual void adjust_data()
Definition: DHT.cpp:133
#define swap(a, b)
Definition: Canvas.cpp:164
#define UNUSED(x)
Definition: ATmega328P.hh:31
static const uint8_t DATA_LAST
Definition: DHT.hh:173
virtual void on_interrupt(uint16_t arg=0)
Definition: DHT.cpp:35
uint16_t m_start
Definition: DHT.hh:192
uint8_t as_byte[DATA_MAX]
Definition: DHT.hh:180
Definition: DHT.hh:34
int16_t m_humidity
Definition: DHT.hh:207
void clear() const
Definition: OutputPin.hh:124
uint8_t m_value
Definition: DHT.hh:195
virtual void on_sample_completed(bool valid)
Definition: DHT.hh:131
static const uint16_t MIN_PERIOD
Definition: DHT.hh:162
static void delay(uint32_t ms)
Definition: Watchdog.cpp:73
int16_t temperature
Definition: DHT.hh:183
int16_t m_temperature
Definition: DHT.hh:210