8ch_temp_hum/8ch_temp_hum_v0.2.ino
2025-07-18 10:51:54 +08:00

139 lines
3.6 KiB
C++

// 16ch Temp&Hum
// by WANG Yanqi
// Created 4 Jan 2024
#include <Wire.h>
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long interval = 1000;
const uint8_t addr_hub[] = {0x70, 0x72};
const uint8_t addr_sen = 0x44;
const int size_hub = sizeof(addr_hub)/sizeof(addr_hub[0]);
uint8_t data[6];
uint8_t data_crc[2];
float temp;
float hum;
float fun_temp(float raw);
float fun_hum(float raw);
uint8_t crc8(const uint8_t* data, size_t length);
void setup() {
Wire.begin();
Serial.begin(9600);
delay(5000);
// Go through all the hubs
for (int i = 0; i < size_hub; i++) {
// Go through 8 ch. in a hub
for (uint8_t ch = 0b00000001; ch != 0; ch = ch << 1) {
// Open the ch.
Wire.beginTransmission(addr_hub[i]);
Wire.write(ch);
Wire.endTransmission();
// Soft reset sens
Wire.beginTransmission(addr_sen);
Wire.write(0x30);
Wire.write(0xA2);
Wire.endTransmission();
delay(100);
}
// Close all the ch.
Wire.beginTransmission(addr_hub[i]);
Wire.write(0);
Wire.endTransmission();
}
}
void loop() {
// Get the current number of milliseconds since the program started
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Go through all the hubs
for (int i = 0; i < size_hub; i++) {
// Go through 8 ch. in a hub
for (uint8_t ch = 0b00000001; ch != 0; ch = ch << 1) {
// Open the ch.
Wire.beginTransmission(addr_hub[i]);
Wire.write(ch);
Wire.endTransmission();
read_sen(addr_sen, data);
// Check temp
data_crc[0] = data[0];
data_crc[1] = data[1];
if (crc8(data_crc, sizeof(data_crc)) == data[2]) {
temp = fun_temp((data[0] << 8) | data[1]);
// Serial.print(temp);
} else {
temp = NAN;
// temp = (data[0] << 8) | data[1];
// Serial.print(temp, BIN);
}
// Serial.print(",");
// Check hum
data_crc[0] = data[3];
data_crc[1] = data[4];
if (crc8(data_crc, sizeof(data_crc)) == data[5]) {
hum = fun_hum((data[3] << 8) | data[4]);
// Serial.print(hum);
} else {
hum = NAN;
// hum = (data[3] << 8) | data[4];
// Serial.print(hum, BIN);
}
// Print data
Serial.print(temp);
Serial.print(",");
Serial.print(hum);
if (i != size_hub-1 || ch != 0b10000000) {
Serial.print(";");
}
}
// Close all the ch.
Wire.beginTransmission(addr_hub[i]);
Wire.write(0);
Wire.endTransmission();
}
Serial.print("\n");
previousMillis = currentMillis;
}
}
void read_sen(uint8_t addr, uint8_t* data) {
// Clock stretching, high repeatability
Wire.beginTransmission(addr);
Wire.write(0x2C);
Wire.write(0x06);
Wire.endTransmission();
Wire.requestFrom(addr, 6);
for (int i = 0; i < 6; i++) {
data[i] = Wire.read();
}
}
uint8_t crc8(const uint8_t* data, size_t length) {
uint8_t crc = 0xFF; // Start with 0xFF for initialization
for (size_t i = 0; i < length; ++i) {
crc ^= data[i]; // XOR byte into least sig. byte of crc
for (uint8_t j = 8; j; --j) { // Loop over each bit
if (crc & 0x80) { // If the uppermost bit is 1...
crc = (crc << 1) ^ 0x31; // ... shift left and XOR with the polynomial
} else {
crc <<= 1; // Otherwise, just shift left
}
}
}
// No final XOR
return crc;
}
float fun_temp(float raw) {
float temp = -45.0 + 175.0 * raw / 65535;
return temp;
}
float fun_hum(float raw) {
float hum = 100.0 * raw / 65535;
return hum;
}