Erriez Oregon THN128 433MHz temperature sensor library for Arduino 1.1.1
This is an Oregon THN128 433MHz temperature sensor transmit/receive library for Arduino.
Loading...
Searching...
No Matches
ErriezOregonTHN128.c
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2020-2026 Erriez
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
33#include <string.h>
34#include <stdio.h>
35#include "ErriezOregonTHN128.h"
36
42#define SET_ROL_ADDR(x) (((x) & 0x07) << 0)
44#define GET_ROL_ADDR(x) (((x) & 0x07) << 0)
45
47#define SET_CHANNEL(x) ((((x) - 1) & 0x03) << 6)
49#define GET_CHANNEL(x) ((((x) >> 6) & 0x03) + 1)
50
52#define SET_TEMP(x) ((((((uint32_t)(x) / 100) % 10)) << 16) | \
53 ((((uint32_t)(x) / 10) % 10) << 12) | \
54 (((x) % 10) << 8))
56#define GET_TEMP(x) (((((x) >> 16) & 0x0f) * 100) + \
57 ((((x) >> 12) & 0x0f) * 10) + \
58 (((x) >> 8) & 0x0f))
59
61#define SIGN_BIT (1UL << 21)
62
64#define LOW_BAT_BIT (1UL << 23)
65
67#define SET_CRC(x) ((uint32_t)(x) << 24)
69#define GET_CRC(x) ((x) >> 24)
70
81static uint8_t calcCrc(uint32_t rawData)
82{
83 uint16_t crc;
84
85 /* Add Bytes 0, 1 and 2 */
86 crc = ((rawData >> 16) & 0xff) + ((rawData >> 8) & 0xff) + ((rawData >> 0) & 0xff);
87 /* Add most significant Byte of the CRC to the final CRC */
88 crc = (crc >> 8) + (crc & 0xff);
89
90 /* Return 8-bit CRC */
91 return (uint8_t)crc;
92}
93
101bool OregonTHN128_CheckCRC(uint32_t rawData)
102{
103 return calcCrc(rawData) == GET_CRC(rawData);
104}
105
106/*------------------------------------------------------------------------------------------------*/
107/* Public functions */
108/*------------------------------------------------------------------------------------------------*/
118void OregonTHN128_TempToString(char *temperatureStr, uint8_t temperatureStrLen, int16_t temperature)
119{
120 bool tempNegative = false;
121 int tempAbs;
122
123 /* Convert temperature without using float to string */
124 tempAbs = temperature;
125 if (temperature < 0) {
126 tempNegative = true;
127 tempAbs *= -1;
128 }
129
130 snprintf(temperatureStr, temperatureStrLen, "%s%d.%d",
131 tempNegative ? "-" : "", (tempAbs / 10), tempAbs % 10);
132}
133
142{
143 uint32_t rawData;
144
145 /* Rolling address 0..7 */
146 rawData = SET_ROL_ADDR(data->rollingAddress);
147
148 /* Set channel 1..3 */
149 rawData |= SET_CHANNEL(data->channel);
150
151 /* Set temperature -999..999 */
152 if (data->temperature < 0) {
153 rawData |= SIGN_BIT;
154 rawData |= SET_TEMP(data->temperature * -1);
155 } else {
156 rawData |= SET_TEMP(data->temperature);
157 }
158
159 /* Low battery bit */
160 if (data->lowBattery) {
161 rawData |= LOW_BAT_BIT;
162 }
163
164 /* Calculate CRC */
165 rawData |= SET_CRC(calcCrc(rawData));
166
167 /* Return 32-bit raw data */
168 return rawData;
169}
170
180bool OregonTHN128_RawToData(uint32_t rawData, OregonTHN128Data_t *data)
181{
182 memset(data, 0, sizeof(OregonTHN128Data_t));
183
184 /* Set data structure */
185 data->rawData = rawData;
186 data->rollingAddress = GET_ROL_ADDR(rawData);
187 data->channel = GET_CHANNEL(rawData);
188 data->temperature = GET_TEMP(rawData);
189 if (rawData & SIGN_BIT) {
190 data->temperature *= -1;
191 }
192 data->lowBattery = (rawData & LOW_BAT_BIT) ? true : false;
193
194 /* Return CRC success or failure */
195 return calcCrc(rawData) == GET_CRC(rawData);
196}
uint32_t OregonTHN128_DataToRaw(OregonTHN128Data_t *data)
Convert data structure to 32-bit raw data.
bool OregonTHN128_RawToData(uint32_t rawData, OregonTHN128Data_t *data)
Cnonvert 32-bit raw data to OregonTHN128Data_t structure.
void OregonTHN128_TempToString(char *temperatureStr, uint8_t temperatureStrLen, int16_t temperature)
Convert temperature to string.
bool OregonTHN128_CheckCRC(uint32_t rawData)
Verify checksum.
#define SET_CRC(x)
#define GET_TEMP(x)
#define SET_ROL_ADDR(x)
#define SIGN_BIT
#define GET_CRC(x)
#define SET_TEMP(x)
#define LOW_BAT_BIT
#define SET_CHANNEL(x)
#define GET_CHANNEL(x)
#define GET_ROL_ADDR(x)