-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmlx.hpp
155 lines (137 loc) · 5.89 KB
/
mlx.hpp
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
/*--------------------------------------------------------------------------------
* MLX90640 instance
*--------------------------------------------------------------------------------*/
#include <Wire.h>
#include <Adafruit_MLX90640.h>
Adafruit_MLX90640 mlx;
/*--------------------------------------------------------------------------------
* The size of thermal image (max INTERPOLATE_SCALE = 8)
*--------------------------------------------------------------------------------*/
#define MLX90640_COLS 32
#define MLX90640_ROWS 24
#define INTERPOLATED_COLS (MLX90640_COLS * INTERPOLATE_SCALE)
#define INTERPOLATED_ROWS (MLX90640_ROWS * INTERPOLATE_SCALE)
/*--------------------------------------------------------------------------------
* Thermography image
*--------------------------------------------------------------------------------*/
#if ENA_MULTITASKING
float src[2][MLX90640_ROWS * MLX90640_COLS];
#else
float src[1][MLX90640_ROWS * MLX90640_COLS];
#endif
/*--------------------------------------------------------------------------------
* Initial values for range of temperature
*--------------------------------------------------------------------------------*/
#define MINTEMP 20 // Low temperature range
#define MAXTEMP 35 // High temperature range
/*--------------------------------------------------------------------------------
* MLX90640 control configuration
*--------------------------------------------------------------------------------*/
typedef struct MLXConfig {
// Member Variables
uint8_t interpolation; // 1, 2, 4, 6, 8
uint8_t box_size; // 1, 2, 4, 8
uint8_t refresh_rate; // sampline frequency (mlx90640_refreshrate_t)
uint8_t color_scheme; // 0: rainbow, 1: inferno
uint8_t marker_mode; // 0: off, 1: min/max, 2: picked up by user
bool range_auto; // automatic measurement of temperature min/max
int16_t range_min; // minimum temperature
int16_t range_max; // maximum temperature
float sampling_period; // sampling period [sec]
// Comparison Operators
bool operator >= (const MLXConfig &RHS) {
return (
(interpolation != RHS.interpolation) ||
(box_size != RHS.box_size ) ||
(refresh_rate != RHS.refresh_rate )
);
}
bool operator != (const MLXConfig &RHS) {
return (
(color_scheme != RHS.color_scheme ) ||
(marker_mode != RHS.marker_mode ) ||
(range_auto != RHS.range_auto ) ||
(range_min != RHS.range_min ) ||
(range_max != RHS.range_max )
);
}
// Copy some members
MLXConfig operator <<= (const MLXConfig &RHS) {
color_scheme = RHS.color_scheme;
marker_mode = RHS.marker_mode;
range_auto = RHS.range_auto;
range_min = RHS.range_min;
range_max = RHS.range_max;
return RHS;
};
// Setup refresh_rate according to INTERPOLATE_SCALE and BOX_SIZE
void init(void) {
sampling_period = 2.0f / pow(2.0f, (float)(refresh_rate - 1));
void filter_reset(void);
filter_reset();
void interpolate_setup(const int);
interpolate_setup(interpolation);
}
} MLXConfig_t;
constexpr MLXConfig_t mlx_ini = {
.interpolation = INTERPOLATE_SCALE, // 1, 2, 4, 6, 8
.box_size = BOX_SIZE, // 1, 2, 4, 8
.refresh_rate = REFRESH_RATE, // sampline frequency (32Hz, 16Hz, 8Hz, 4Hz, 2Hz)
.color_scheme = 0, // 0: rainbow, 1: inferno
.marker_mode = 0, // 0: off, 1: min/max, 2: picked up by user
.range_auto = false, // automatic measurement of temperature min/max
.range_min = MINTEMP, // minimum temperature (20 deg)
.range_max = MAXTEMP, // maximum temperature (35 deg)
};
MLXConfig_t mlx_cnf = mlx_ini;
/*--------------------------------------------------------------------------------
* MLX90640 capture control
*--------------------------------------------------------------------------------*/
typedef struct MLXCapture {
uint8_t capture_mode; // 0: camera, 1: video
bool recording; // false: stop, true: recording
char filename[30]; // "/MLX90640/mlx%04d.raw"
} MLXCapture_t;
MLXCapture_t mlx_cap = {
.capture_mode = 0, // 0: camera, 1: video
.recording = false, // false: stop, true: recording
};
/*--------------------------------------------------------------------------------
* Set MLX90640 refresh rate
*--------------------------------------------------------------------------------*/
bool mlx_refresh(void) {
// The initial value 64Hz is out of range
static uint8_t refreshRate = MLX90640_64_HZ;
// Refresh MLX90640 when refresh rate changes
if (refreshRate != mlx_cnf.refresh_rate) {
mlx.setRefreshRate((mlx90640_refreshrate_t)(refreshRate = mlx_cnf.refresh_rate));
mlx_cnf.init();
delay(100); // Wait a bit for the change to take effect
return true;
} else {
return false;
}
}
/*--------------------------------------------------------------------------------
* MLX90640 initializing
*--------------------------------------------------------------------------------*/
void mlx_setup(void) {
#ifdef MLX_I2C_SDA // defined in pin_assign.h
Wire.begin(MLX_I2C_SDA, MLX_I2C_SCL);
#else
Wire.begin();
#endif
// Initialize MLX90640 with I2C
if (!mlx.begin(MLX90640_I2CADDR_DEFAULT, &Wire)) {
DBG_EXEC(printf("MLX90640 not found!\n"));
} else {
DBG_EXEC(printf("MLX90640 found at I2C address 0x%X.\n", MLX90640_I2CADDR_DEFAULT));
DBG_EXEC(printf("Serial number: %04X%04X%04X\n", mlx.serialNumber[0], mlx.serialNumber[1], mlx.serialNumber[2]));
}
// I2C bus clock for MLX90640 (Officially, the ESP32S3 supports up to 800KHz)
Wire.setClock(1000000); // 400 KHz (Sm) or 1 MHz (Fm+)
// Set MLX90640 operating mode
mlx.setMode(MLX90640_CHESS); // or MLX90640_INTERLEAVED
mlx.setResolution(MLX90640_ADC_18BIT); // 16BIT, 17BIT, 18BIT (default) or 19BIT
mlx_refresh();
}