-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathWeatherSensorWH2.cpp
More file actions
179 lines (153 loc) · 3.92 KB
/
WeatherSensorWH2.cpp
File metadata and controls
179 lines (153 loc) · 3.92 KB
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
WeatherSensorWH2.cpp - Library for receiving wireless data from the WH2
wireless temperature and humidity sensor.
Created by Luc Small on 30 April 2012.
Released into the public domain.
This code contains a CRC-8 function adapted from the Arduino OneWire library:
http://www.pjrc.com/teensy/td_libs_OneWire.html
Thanks go to the authors of that project.
*/
/* Added to provide compatibility with Arduino 1.0 and 0022 */
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "WeatherSensorWH2.h"
WeatherSensorWH2::WeatherSensorWH2()
{
/* constructor */
_acquired = false;
}
void WeatherSensorWH2::accept(byte interval)
{
byte sample;
static byte state = 0;
static byte packet_no, bit_no, history;
// 1 is indicated by 500uS pulse
if (interval >= 17 && interval <= 25) {
sample = 1;
// 0 is indicated by ~1500us pulse
} else if (interval >= 55 && interval <= 70) {
sample = 0;
} else {
state = 0;
return;
}
// reset if in initial state
if(state == 0) {
// should history be 0, does it matter?
history = 0xFF;
state = 1;
} // fall thru to state one
// acquire preamble
if (state == 1) {
// shift history right and store new value
history <<= 1;
// store a 1 if required (right shift along will store a 0)
if (sample == 1) {
history |= 0x01;
}
// check if we have a valid start of frame
// xxxxx110
if ((history & B00000111) == B00000110) {
// need to clear packet, and counters
packet_no = 0;
// start at 1 becuase only need to acquire 7 bits for first packet byte.
bit_no = 1;
_packet[0] = _packet[1] = _packet[2] = _packet[3] = _packet[4] = 0;
// we've acquired the preamble
state = 2;
}
return;
}
// acquire packet
if (state == 2) {
_packet[packet_no] <<= 1;
if (sample == 1) {
_packet[packet_no] |= 0x01;
}
bit_no ++;
if(bit_no > 7) {
bit_no = 0;
packet_no ++;
}
if (packet_no > 4) {
// got packet - flag this event
_acquired = true;
// start the sampling process from scratch
state = 0;
}
}
}
bool WeatherSensorWH2::acquired()
{
bool temp = _acquired;
_acquired = false;
return temp;
}
byte WeatherSensorWH2::calculate_crc()
{
return _crc8(_packet, 4);
}
bool WeatherSensorWH2::valid()
{
return (calculate_crc() == _packet[4]);
}
byte* WeatherSensorWH2::get_packet()
{
return _packet;
}
int WeatherSensorWH2::get_sensor_id()
{
return (_packet[0] << 4) + (_packet[1] >> 4);
}
byte WeatherSensorWH2::get_humidity()
{
return _packet[3];
}
/* Temperature in deci-degrees. e.g. 251 = 25.1 */
int WeatherSensorWH2::get_temperature()
{
int temperature;
temperature = ((_packet[1] & B00000111) << 8) + _packet[2];
// make negative
if (_packet[1] & B00001000) {
temperature = -temperature;
}
return temperature;
}
String WeatherSensorWH2::get_temperature_formatted()
{
int temperature;
byte whole, partial;
String s;
temperature = ((_packet[1] & B00000111) << 8) + _packet[2];
whole = temperature / 10;
partial = temperature - (whole*10);
// 20130215: Changed to fix bug formatting negative temperatures
// Bug reported and fix contributed by Sebastian Muszynski (basti@linkt.de).
s = String();
if (_packet[1] & B00001000) {
s += String('-');
}
s += String(whole, DEC);
s += '.';
s += String(partial, DEC);
return s;
}
uint8_t WeatherSensorWH2::_crc8( uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
// Indicated changes are from reference CRC-8 function in OneWire library
while (len--) {
uint8_t inbyte = *addr++;
for (uint8_t i = 8; i; i--) {
uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01
crc <<= 1; // changed from right shift
if (mix) crc ^= 0x31;// changed from 0x8C;
inbyte <<= 1; // changed from right shift
}
}
return crc;
}