Liep vandaag in de kringloopwinkel tegen een '
ATAL MB450NV' aan.
Iemand een idee wat voor CO
2-sensor erin zit? Nog niet uitgebreid vergeleken met een andere meter, maar zo op het eerste gezicht zat hij +50-60 ppm boven m'n Aranet4.
IC's op de printplaat:
- IL2596 DC-DC converter die van de 12V adapter 5V maakt (waarom dan niet gelijk met 5V voeden?)
- FineChips FD1000A controller voor het display
- Analog Devices ADUC848BSZ32-5 MCU
- LM258 amplifier
- AD8629 amplifier
- ADR03A voltage reference
Er zit ook een miniUSB connector op, na inpluggen aan PC presenteerde hij zich als een FTDI USB-Serial converter. Was even zoeken naar de juiste baudrate, ik zag wel dat hij elke 3s data uitspuugde, maar was niet leesbaar. Uiteindelijk bleek 19200 de juiste baudrate te zijn:
code:
1
| c0671t+247h54e0000o000062 |
Ik had eerst zoiets van: "Waar kijk ik naar, is dit hexadecimale tsjak ofzo???" totdat het kwartje viel en het gewoon leesbare data is: 671 ppm, 24,7°C en 54% luchtvochtigheid en iets van een checksum
Claude AI had binnen een paar minuten de CRC gekraakt nadat ik wat tientallen samples had aangeleverd. En vervolgens een werkend Python-script voor mij gemaakt om de meter uit te lezen
Mogelijk ga ik er nog even een ESP in frotten en dan met ESPHome doorsturen naar Home Assistant
De FTDI USB-Serial lijkt onder het scherm te zitten, maar hij spuugt de data gelukkig ook uit via de TXD-pin op de witte connector bovenaan, waar ik veel makkelijker op kan inhaken met een ESP.
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
| #!/usr/bin/env python3
"""
CO2 Sensor Reader met Checksum verificatie
Leest data van CO2 sensor via seriële poort (19200 baud)
Format: c[CO2]t[temp]h[humidity]e0000o[CHECKSUM]
Checksum: som van alle bytes in data deel - 1
Usage: python sensor.py [COM_PORT]
Bijvoorbeeld: python sensor.py COM5
"""
import serial
import time
import re
import sys
from typing import Tuple, Optional
def parse_sensor_data(data_string: str) -> Optional[Tuple[int, float, int, str, bool]]:
"""
Parseert de sensor data string
Returns:
Tuple van (co2_ppm, temperature, humidity, raw_data, crc_valid) of None bij fout
"""
# Remove whitespace en newlines
data_string = data_string.strip()
# Regex pattern voor het dataformaat: c[CO2]t[temp]h[humidity]e0000o[CRC]
# Ondersteunt zowel kleine 'c' als hoofdletter 'C' voor hoge CO2 waarden
pattern = r'[cC](\d+)t([+-]?\d+)h(\d+)e0000o([0-9A-Fa-f]+)'
match = re.match(pattern, data_string)
if not match:
print(f"Invalid data format: {data_string}")
return None
co2_raw = match.group(1)
temp_raw = match.group(2)
humidity_raw = match.group(3)
crc_hex = match.group(4)
try:
co2_ppm = int(co2_raw)
temperature = float(temp_raw) / 10.0 # Blijkbaar in tienden van graden
humidity = int(humidity_raw)
# CRC verificatie
crc_valid = verify_crc(data_string, crc_hex)
return (co2_ppm, temperature, humidity, data_string, crc_valid)
except ValueError as e:
print(f"Error parsing values: {e}")
return None
def calculate_checksum(data: str) -> int:
"""
Berekent de checksum voor de gegeven data string
Gebaseerd op analyse van sample data: som van alle bytes - 1
"""
# Haal de data zonder de checksum eruit (alles voor 'o')
if 'o' in data:
data_part = data.split('o')[0]
else:
data_part = data
# Bereken som van alle bytes en trek 1 af
sum_bytes = sum(ord(c) for c in data_part)
checksum = (sum_bytes - 1) & 0xFF
return checksum
def verify_crc(data_string: str, provided_crc_hex: str) -> bool:
"""
Verificeert of de checksum correct is
Gebruikt: som van alle bytes - 1
"""
try:
provided_crc = int(provided_crc_hex, 16)
calculated_crc = calculate_checksum(data_string)
# Exacte match voor checksum
return provided_crc == calculated_crc
except ValueError:
return False
def read_co2_sensor(port: str = '/dev/ttyUSB0', baudrate: int = 19200, timeout: int = 2):
"""
Leest data van de CO2 sensor
Args:
port: Seriële poort (bijv. '/dev/ttyUSB0' op Linux, 'COM3' op Windows)
baudrate: Baudrate (19200 voor jouw sensor)
timeout: Timeout in seconden
"""
try:
# Open seriële verbinding
ser = serial.Serial(port, baudrate, timeout=timeout)
print(f"Verbonden met {port} op {baudrate} baud")
print("Druk Ctrl+C om te stoppen\n")
while True:
try:
# Lees een regel
line = ser.readline().decode('ascii', errors='ignore').strip()
if line:
# Parse de data
result = parse_sensor_data(line)
if result:
co2, temp, humidity, raw, crc_valid = result
crc_status = "✓" if crc_valid else "✗"
print(f"CO2: {co2:4d} ppm | "
f"Temp: {temp:5.1f}°C | "
f"RH: {humidity:2d}% | "
f"CRC: {crc_status} | "
f"Raw: {raw}")
else:
print(f"Parse error: {line}")
time.sleep(0.1) # Kleine delay
except KeyboardInterrupt:
print("\nStoppen...")
break
except serial.SerialException as e:
print(f"Seriële poort error: {e}")
except Exception as e:
print(f"Onverwachte fout: {e}")
finally:
if 'ser' in locals():
ser.close()
print("Seriële verbinding gesloten")
if __name__ == "__main__":
print("CO2 Sensor Reader")
print("=" * 50)
# Parse command line arguments
if len(sys.argv) > 1:
port = sys.argv[1]
else:
port = 'COM5' # Default poort
print(f"Geen poort opgegeven, gebruik default: {port}")
print(f"Usage: python {sys.argv[0]} [COM_PORT]")
print(f"Bijvoorbeeld: python {sys.argv[0]} COM3")
print()
print(f"Connecting to {port}...")
read_co2_sensor(port) |
Ik vind de bouwkwaliteit overigens vrij matig voor wat het ding nieuw moet kosten (+/- €139 ex. BTW). Lijkt eentje te zijn die veel op scholen werd/wordt gebruikt.
[
Voor 9% gewijzigd door
ThinkPad op 18-08-2025 09:31
]