上传文件至 /
This commit is contained in:
parent
7368123e7b
commit
8b0e34d188
139
8ch_temp_hum_v0.2.ino
Normal file
139
8ch_temp_hum_v0.2.ino
Normal 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
BIN
Cover.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
111
Monitor.py
Normal file
111
Monitor.py
Normal 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
8
launch.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user