+14
-11
code/esp32/main.py
+14
-11
code/esp32/main.py
···
21
DHT22sensor = dht.DHT22(Pin(0))
22
# MLX90640 Infrared camera
23
MLX90640sensor = MLX90640(i2c)
24
-
MLX90640sensor.refresh_rate = RefreshRate.REFRESH_1_HZ
25
ir_frame = init_float_array(768)
26
# MH-RD Rain sensor
27
MHRDsensor = ADC(Pin(1))
···
29
MHRDsensor.atten(ADC.ATTN_11DB)
30
# TSL2591 luminosity
31
TSL2591 = tsl2591.TSL2591(i2c=i2c)
32
-
TSL2591.gain = tsl2591.GAIN_LOW
33
TSL2591.integration_time = tsl2591.INTEGRATIONTIME_100MS
34
35
def dew_point(tc, rh):
···
61
62
# Establish connection
63
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
64
-
s.bind(('', 80))
65
s.listen(5)
66
67
oldsec = -1
···
90
91
# MLX90640 Infrared camera
92
MLX90640sensor.get_frame(ir_frame)
93
ir_center = cutout_frame(ir_frame, 16, 12, 5, 5)
94
temp_sky = mean(ir_center)
95
# Heuristic to check in real conditions
···
102
103
# MHRD Rain sensor
104
rain_sens = MHRDsensor.read()
105
-
if (rain_sens > 3_200):
106
rain = 0
107
-
elif (rain_sens > 3_000):
108
-
rain = -(rain - 3_200)/(3_200-3_000)
109
else:
110
rain = 1
111
112
# TSL2591 luminosity
113
-
try:
114
-
tsl_lux = TSL2591.lux
115
-
except RuntimeError: # Luminosity saturation
116
-
tsl_lux = -1
117
tsl_ir = TSL2591.infrared
118
tsl_vis = TSL2591.visible
119
tsl_full = TSL2591.full_spectrum
···
136
# file.write(f"pressure={pressure:.2f} <br />\n") # WeatherWatcher keyword
137
file.write(f"luminosity={tsl_lux:.5f} <br />\n")
138
file.write('</body>\n')
139
-
file.write(f"<ir_image>\n{str(ir_frame)}\n</ir_image>\n")
140
file.write('</html>\n')
141
file.close()
142
···
21
DHT22sensor = dht.DHT22(Pin(0))
22
# MLX90640 Infrared camera
23
MLX90640sensor = MLX90640(i2c)
24
+
MLX90640sensor.refresh_rate = RefreshRate.REFRESH_2_HZ
25
ir_frame = init_float_array(768)
26
# MH-RD Rain sensor
27
MHRDsensor = ADC(Pin(1))
···
29
MHRDsensor.atten(ADC.ATTN_11DB)
30
# TSL2591 luminosity
31
TSL2591 = tsl2591.TSL2591(i2c=i2c)
32
+
TSL2591.gain = tsl2591.GAIN_HIGH
33
TSL2591.integration_time = tsl2591.INTEGRATIONTIME_100MS
34
35
def dew_point(tc, rh):
···
61
62
# Establish connection
63
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
64
+
try:
65
+
s.bind(('', 80))
66
+
except OSError:
67
+
continue
68
s.listen(5)
69
70
oldsec = -1
···
93
94
# MLX90640 Infrared camera
95
MLX90640sensor.get_frame(ir_frame)
96
+
MLX90640sensor.get_frame(ir_frame) # Read twice to solve checkerboard issue
97
ir_center = cutout_frame(ir_frame, 16, 12, 5, 5)
98
temp_sky = mean(ir_center)
99
# Heuristic to check in real conditions
···
106
107
# MHRD Rain sensor
108
rain_sens = MHRDsensor.read()
109
+
if (rain_sens > 3_000):
110
rain = 0
111
+
elif (rain_sens > 2_800):
112
+
rain = -(rain_sens - 3_000)/(3_000-2_800)
113
else:
114
rain = 1
115
116
# TSL2591 luminosity
117
+
tsl_lux = TSL2591.lux_auto_gain
118
tsl_ir = TSL2591.infrared
119
tsl_vis = TSL2591.visible
120
tsl_full = TSL2591.full_spectrum
···
137
# file.write(f"pressure={pressure:.2f} <br />\n") # WeatherWatcher keyword
138
file.write(f"luminosity={tsl_lux:.5f} <br />\n")
139
file.write('</body>\n')
140
+
file.write('<ir_image>\n')
141
+
file.write(f"ir_image={str(ir_frame)} <br />\n")
142
+
file.write('</ir_image>\n')
143
file.write('</html>\n')
144
file.close()
145
+6
-7
code/esp32/mlx90640.py
+6
-7
code/esp32/mlx90640.py
···
5
import struct
6
7
import machine
8
-
import typing
9
10
11
def init_float_array(size) -> array.array:
···
122
self._extract_parameters()
123
124
@property
125
-
def serial_number(self) -> typing.List[int]:
126
"""3-item tuple of hex values that are unique to each MLX90640"""
127
serial_words = [0, 0, 0]
128
self._i2c_read_words(self.mlx90640_deviceid1, serial_words)
···
145
value |= control_register[0] & 0xFC7F
146
self._i2c_write_word(0x800D, value)
147
148
-
def get_frame(self, framebuf: typing.List[int]) -> None:
149
"""Request both 'halves' of a frame from the sensor, merge them
150
and calculate the temperature in C for each of 32x24 pixels. Placed
151
into the 768-element array passed in!"""
···
214
215
return vdd
216
217
-
def _calculate_to(self, emissivity: float, tr: float, result: typing.List[float]) -> None:
218
sub_page = self.mlx90640_frame[833]
219
alpha_corr_r = [0] * 4
220
ir_data_cp = [0, 0]
···
761
if self._are_pixels_adjacent(broken_pixel, outlier_pixel):
762
raise RuntimeError('Adjacent broken and outlier pixels')
763
764
-
def _unique_list_pairs(self, input_list: typing.List[int]) -> typing.Tuple[int, int]:
765
for i, list_value1 in enumerate(input_list):
766
for list_value2 in input_list[i + 1:]:
767
yield list_value1, list_value2
···
795
def _i2c_read_words(
796
self,
797
addr: int,
798
-
buffer: typing.Union[int, typing.List[int]],
799
*,
800
-
end: typing.Optional[int] = None,
801
) -> None:
802
if end is None:
803
remaining_words = len(buffer)
···
5
import struct
6
7
import machine
8
9
10
def init_float_array(size) -> array.array:
···
121
self._extract_parameters()
122
123
@property
124
+
def serial_number(self):
125
"""3-item tuple of hex values that are unique to each MLX90640"""
126
serial_words = [0, 0, 0]
127
self._i2c_read_words(self.mlx90640_deviceid1, serial_words)
···
144
value |= control_register[0] & 0xFC7F
145
self._i2c_write_word(0x800D, value)
146
147
+
def get_frame(self, framebuf) -> None:
148
"""Request both 'halves' of a frame from the sensor, merge them
149
and calculate the temperature in C for each of 32x24 pixels. Placed
150
into the 768-element array passed in!"""
···
213
214
return vdd
215
216
+
def _calculate_to(self, emissivity: float, tr: float, result) -> None:
217
sub_page = self.mlx90640_frame[833]
218
alpha_corr_r = [0] * 4
219
ir_data_cp = [0, 0]
···
760
if self._are_pixels_adjacent(broken_pixel, outlier_pixel):
761
raise RuntimeError('Adjacent broken and outlier pixels')
762
763
+
def _unique_list_pairs(self, input_list):
764
for i, list_value1 in enumerate(input_list):
765
for list_value2 in input_list[i + 1:]:
766
yield list_value1, list_value2
···
794
def _i2c_read_words(
795
self,
796
addr: int,
797
+
buffer,
798
*,
799
+
end = None,
800
) -> None:
801
if end is None:
802
remaining_words = len(buffer)
+2
-1
code/esp32/test/test_mlx90640.py
+2
-1
code/esp32/test/test_mlx90640.py