// 16ch Temp&Hum // by WANG Yanqi // Created 4 Jan 2024 #include 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; }