1+ /*
2+ Thermo sensor Sencor T25 reader via RXB^receiver
3+ Initial version for use with functions, preparation for develop T25 library
4+ Output to serial console
5+ Miklik, 20.6.2016
6+ v0.2.0 - copy from 0.1.9 and remove coments and debug data
7+ v0.2.1 - add new funcion - enable, disable and remove some variables
8+ v0.2.2 - rename data array to buffer, and use data array for data per chanel
9+ v0.2.3 - save data directly to data array
10+ v0.2.4 - rename get functions to decode and create new getfunctions and some isFFF functions
11+ v0.2.5 - correct some daty types
12+ v0.2.6 - set prefix _ for global private objects
13+ v0.3.0 - do it like class
14+ v0.3.1 - change all to static
15+ v0.3.2 - rename class to SensorT25
16+ v0.4.0 - save it like library
17+ */
18+
19+ #include < SensorT25.h>
20+
21+ unsigned long SensorT25::_buffer[BUFF_ROW] = {0L ,0L ,0L }; // raw data buffer
22+ boolean SensorT25::_valid[SENSCOUNT] = {false ,false ,false }; // valid dta forsensor
23+ byte SensorT25::_sid[SENSCOUNT]; // sensor ID
24+ float SensorT25::_temperature[SENSCOUNT]; // temperature
25+ unsigned long SensorT25::_time[SENSCOUNT]; // last set time
26+ boolean SensorT25::_start = LOW; // start data reading flag
27+ boolean SensorT25::_space = LOW; // space is starting
28+ boolean SensorT25::_bit0 = LOW;
29+ boolean SensorT25::_bit1 = LOW;
30+ byte SensorT25::_bits = 0 ; // bits counter in data word
31+ byte SensorT25::_repeat = 0 ; // counter for repeated reading
32+ unsigned long SensorT25::_lastTime = 0 ; // variable for last time point
33+ byte SensorT25::_irq_pin; // number of used IRQ PIN
34+ // methods
35+ void SensorT25::enable (byte irq_pin) // enable data reading - INT0,INT1 name, number 2 or 3 for UNO
36+ {
37+ _irq_pin = irq_pin;
38+ pinMode (irq_pin, INPUT_PULLUP); // input for RF receiver
39+ attachInterrupt (digitalPinToInterrupt (irq_pin), _irqHandler, CHANGE); // IRQ handler for RF receiver
40+ }
41+
42+ void SensorT25::disable (byte irq_pin) // disable daata reading
43+ {
44+ detachInterrupt (digitalPinToInterrupt (irq_pin)); // stop IRQ
45+ }
46+
47+ // are data valid for channel
48+ boolean SensorT25::isValid (byte channel)
49+ {
50+ return (isValidChannel (channel) ? _valid[channel] : false );
51+ }
52+
53+ // set data as invalid for channel
54+ void SensorT25::setInValid (byte channel)
55+ {
56+ if (isValidChannel (channel))
57+ {
58+ _valid[channel] = false ;
59+ }
60+ }
61+
62+ // get sensor ID for channel
63+ byte SensorT25::getSID (byte channel)
64+ {
65+ return (isValidChannel (channel) ? _sid[channel] : 0 );
66+ }
67+
68+ // get temperature for channel
69+ float SensorT25::getTemperature (byte channel)
70+ {
71+ return (isValidChannel (channel) ? _temperature[channel] : 0 );
72+ }
73+
74+ // get temperature value age in s
75+ long SensorT25::getValueAge (byte channel)
76+ {
77+ return (isValidChannel (channel) ? (millis () - _time[channel])/1000 : 0 );
78+ }
79+
80+ // channel number validation
81+ boolean SensorT25::isValidChannel (byte channel)
82+ {
83+ return ( channel >= 0 && channel < SENSCOUNT);
84+ }
85+
86+ // return specified bits from sensor word
87+ unsigned int SensorT25::_decodeBits (unsigned long buffer, unsigned long mask, byte shift )
88+ {
89+ return ((buffer & mask) >> shift);
90+ }
91+
92+ // decode sensor ID from data word
93+ byte SensorT25::_decodeSID (unsigned long buffer)
94+ {
95+ return _decodeBits (buffer, SID_MASK, SID_SHIFT);
96+ }
97+
98+ // decode sensor channel from data word , 0 to 2
99+ byte SensorT25::_decodeChanel (unsigned long buffer)
100+ {
101+ return _decodeBits (buffer, CHA_MASK, CHA_SHIFT);
102+ }
103+
104+ // decode temperature from data word
105+ float SensorT25::_decodeTemp (unsigned long buffer)
106+ {
107+ int t = _decodeBits (buffer, TEM_MASK, TEM_SHIFT);
108+ if (t > 2047 ) {t = t - 4095 ;}
109+ return float (t)/10 ;
110+ }
111+
112+ // IRQ handler for decode bits
113+ void SensorT25::_irqHandler ()
114+ {
115+ unsigned long currentTime = micros (); // shot time
116+ int duration = currentTime - _lastTime; // calculate duration
117+ _lastTime = currentTime; // memory curent time
118+ boolean state = digitalRead (_irq_pin); // read input status
119+ if (!state) // goes from HIGH to LOW
120+ {
121+ _space = _isImpuls (duration - IMPULSE, ITRESHOLD); // if impuls time is valid
122+ }
123+ else if (_space) // goes from LOW to HIGH
124+ {
125+ if (!_start) // start flag is false
126+ {
127+ _start = _isImpuls (duration - PAUSE, STRESHOLD); // start temperature data it was pause signal
128+ }
129+ else // start flag is true
130+ {
131+ _bit0 = _isImpuls (duration - BIT0, STRESHOLD); // is it bit 0
132+ _bit1 = _isImpuls (duration - BIT1, STRESHOLD); // is it bit 1
133+ if (_bit0 ^ _bit1) // XOR / only one is true
134+ {
135+ _bit1 && bitSet (_buffer[_repeat],DATA_LONG - _bits - 1 ); // write bit 1
136+ _bit0 && bitClear (_buffer[_repeat],DATA_LONG - _bits - 1 ); // write bit 0
137+ _bits++; // increment bit counter
138+ }
139+ else // both or nothing bit
140+ {
141+ _resetTWord (); // reset reading
142+ }
143+ if (_bits >= DATA_LONG) // last bit was reading
144+ {
145+ if (_repeat > 0 ) // is it temp sentence hienr then 0
146+ {
147+ if (_buffer[_repeat] != _buffer[_repeat-1 ]) // current temp word is differnt than previous
148+ {
149+ _resetTWord (); // reset reading
150+ }
151+ }
152+ _repeat++; // increment temp word reading
153+ _newTWord (); // reset counters and flags
154+ }
155+ }
156+ }
157+
158+ // write valid data to data array
159+ if (_repeat >= BUFF_ROW) // buffer is full
160+ {
161+ byte ch = (_decodeChanel (_buffer[0 ])); // set channel
162+ _valid[ch] = true ; // set data valid
163+ _sid[ch] = (_decodeSID (_buffer[0 ])); // sensor ID // save sensor ID
164+ _temperature[ch] = (_decodeTemp (_buffer[0 ])); // save temperature
165+ _time[ch] = millis (); // save data timestamp
166+ _resetTWord (); // reset reading
167+ }
168+ }
169+
170+ void SensorT25::_resetTWord () // reset reading
171+ {
172+ _newTWord (); // reset counter and flags
173+ _repeat = 0 ; // reset temp word counter
174+ }
175+
176+ void SensorT25::_newTWord () // reset temp word counter
177+ {
178+ _bits = 0 ; // bits counter
179+ _space = LOW; // space is measured
180+ _start = LOW; // starting data reading
181+ }
182+
183+ boolean SensorT25::_isImpuls (int duration, byte TRESHOLD) // is it valid impulse
184+ {
185+ return (abs (duration) <= TRESHOLD);
186+ }
0 commit comments