上传文件至 /

This commit is contained in:
Frank14f 2025-07-18 10:51:54 +08:00
parent 7368123e7b
commit 8b0e34d188
5 changed files with 258 additions and 0 deletions

139
8ch_temp_hum_v0.2.ino Normal file
View File

@ -0,0 +1,139 @@
// 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;
}

BIN
Cover.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
FPC.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

111
Monitor.py Normal file
View File

@ -0,0 +1,111 @@
# pip install pyserial matplotlib pandas
import serial
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.widgets import Button
from datetime import datetime
max_points = 20 # Number of points to display on the graph
data = {
'Timestamp': [],
**{f'Temp{i+1}': [] for i in range(16)},
**{f'Hum{i+1}': [] for i in range(16)}
}
# Initialize plots
plt.ion()
fig, (ax_temp, ax_hum) = plt.subplots(2, 1, figsize=(15, 10))
# Set plot titles and labels
ax_temp.set_title('Temperature')
ax_temp.set_xlabel('Time')
ax_temp.set_ylabel('Temperature (°C)')
ax_hum.set_title('Humidity')
ax_hum.set_xlabel('Time')
ax_hum.set_ylabel('Humidity (%)')
# Global flag to control the data collection
collecting_data = False
exit_flag = False
# Button callback functions
def start_button_callback(event):
global collecting_data
collecting_data = True
def exit_button_callback(event):
global exit_flag
exit_flag = True
# Create the buttons
ax_start_button = plt.axes([0.7, 0.05, 0.1, 0.075])
ax_exit_button = plt.axes([0.81, 0.05, 0.1, 0.075])
start_button = Button(ax_start_button, 'Start')
start_button.on_clicked(start_button_callback)
exit_button = Button(ax_exit_button, 'Exit')
exit_button.on_clicked(exit_button_callback)
# Display the plot window
plt.show(block=False)
# Wait here until 'Start' button is pressed
while not collecting_data:
plt.pause(0.1) # Use a short pause to handle UI events
if exit_flag:
plt.close(fig)
raise SystemExit
# Main loop
try:
# Set up the serial connection (adjust the COM port as needed)
ser = serial.Serial('/dev/cu.usbmodem14101', 9600, timeout=1)
while not exit_flag:
line = ser.readline().decode('utf-8').strip()
if line:
try:
# Split the line into groups and then into temperature and humidity values
groups = line.split(';')
if len(groups) == 16:
timestamp = datetime.now().strftime('%H:%M:%S')
data['Timestamp'].append(timestamp)
temps = []
hums = []
for i, group in enumerate(groups):
temp, hum = map(float, group.split(','))
temps.append(temp)
hums.append(hum)
data[f'Temp{i+1}'].append(temp)
data[f'Hum{i+1}'].append(hum)
# Update temperature graph with latest 20 points
ax_temp.clear()
ax_temp.set_title('Temperature')
ax_temp.set_xlabel('Time')
ax_temp.set_ylabel('Temperature (°C)')
for i in range(16):
ax_temp.plot(data['Timestamp'][-max_points:], data[f'Temp{i+1}'][-max_points:], label=f'Temp{i+1}')
# Update humidity graph with latest 20 points
ax_hum.clear()
ax_hum.set_title('Humidity')
ax_hum.set_xlabel('Time')
ax_hum.set_ylabel('Humidity (%)')
for i in range(16):
ax_hum.plot(data['Timestamp'][-max_points:], data[f'Hum{i+1}'][-max_points:], label=f'Hum{i+1}')
plt.pause(0.5)
except ValueError as e:
print(f"Could not convert data to float: {line}, error: {e}")
except KeyboardInterrupt:
plt.ioff()
finally:
# Save the data to a CSV file
df = pd.DataFrame(data)
csv_filename = 'arduino_data.csv'
df.to_csv(csv_filename, index=False)
print(f"Data saved to '{csv_filename}'")
ser.close()

8
launch.json Normal file
View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}