Магнитометр
- Войдите на сайт для отправки комментариев
Пт, 15/10/2021 - 13:00
Простейший домашний магнитометр с двумя устройствами типа компас. Написан с использованием свободно распространяемого в Интернет кода и библиотек.
Весь проект со схемами в ZIP файле можно скачать по ссылке. Просто не увидел, что здесь можно вставлять архивные файлы.
Забыл вставить исходный код
001
/*
002
Домашний магнетометр
003
Модуль ESP32 WROOM. В менеджере плат - DOIT ESP32 DEVKIT V1. Версия для ESP32 - Espresiif system v 1.0.6
004
Arduino IDE 1.8.13
005
*/
006
#define SCREEN_WIDTH 128 // OLED display width, in pixels
007
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
008
#define sizeTrend 30//количество точек в тренде
009
#define OLED_MOSI 23
010
#define OLED_CLK 18
011
#define OLED_DC 16
012
#define OLED_CS 5 //Для других SPI устойств CS должен быть другим
013
#define OLED_RESET 17
014
#define BUZZER_PIN 2
015
#define BUZZER_CHANNEL 0
016
017
#include <Tone32.h>
018
#include <SPI.h>
019
#include <Wire.h>
020
#include <Adafruit_GFX.h>
021
#include <Adafruit_SSD1306.h>
022
#include <Adafruit_Sensor.h>
023
//#include <DFRobot_QMC5883.h>
024
#include <Adafruit_LIS3MDL.h>
025
#include "GyverTimer.h"
026
027
int
Freq_signal = 100;
028
GTimer myTimer(MS, Freq_signal);
// создать миллисекундный таймер
029
//GTimer myTimer(US); // US - микросекундный
030
#include "GyverButton.h"
031
// Варианты инициализации кнопок:
032
// GButton btn;// без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
033
// GButton btn(пин);// с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
034
// GButton btn(пин, тип подключ.);// с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN)
035
// GButton btn(пин, тип подключ., тип кнопки);// с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
036
// GButton btn(BTN_NO_BTN_PIN, тип подключ., тип кнопки);// без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
037
038
//DFRobot_QMC5883 compass1;
039
//DFRobot_QMC5883 compass2;
040
//Декларируем две I2C шины
041
042
/*int *in1 = new int[sizeTrend+1]; //массив для первого тренда
043
int *in2 = new int[sizeTrend+1]; //массив для второго тренда
044
int *in3 = new int[sizeTrend+1]; //массив для второго тренда*/
045
int
in1[sizeTrend];
//массив для первого тренда
046
int
in2[sizeTrend];
//массив для второго тренда
047
int
in3[sizeTrend];
//массив для второго тренда
048
const
int
LED = 15;
//синий светодиод
049
//int r=0;
050
int
x, y, z, t;
int
_x, _y, _z, _t;
051
int
X1, Y1, Z1;
int
X2, Y2, Z2;
052
int
Min, Max;
int
MIN, MAX;
int
MIN2, MAX2;
053
054
int
cnt_LeftRight = 1;
//Счетчик перемещения по горизонтальному меню
055
int
cnt_UpDown = 1;
//Счетчик перемещения по вертикальному меню
056
int
cnt_UpDownSensor = 1;
//Счетчик перемещения по вертикальному меню для сенсоров
057
bool
flag_UpDownSensor =
true
;
058
059
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
060
OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
061
GButton btn_Left(27);
062
GButton btn_Right(12);
063
GButton btn_Up(13);
064
GButton btn_Down(14);
065
GButton btn_Enter(26);
066
Adafruit_LIS3MDL compass1;
067
Adafruit_LIS3MDL compass2;
068
069
bool
menu_OnOff =
false
;
bool
menu_Senor =
true
;
070
char
*Coordinats =
"ZXY"
;
int
cnt_Coordinats = 1;
071
int
TrigerMINz = 0;
int
TrigerMAXz = 0;
072
int
MINz = 400;
int
MAXz = -400;
073
int
Volume = 0;
int
freq = 600;
int
channel = 0;
074
int
resolution = 8;
075
int
Buzzer = 0;
int
Algoritm = 1;
int
Chanel = 1;
076
int
Raznica = 0;
int
Porog = 0;
int
Param1 = 0;
float
Param2 = 0.0;
077
078
//конвертирование данных из массива для варианта приема байтовых значений
079
int
convert(
int
y,
int
mn,
int
mx,
byte
yTrend,
byte
heightTrend,
int
*buf ) {
080
int
ny = y;
081
ny = map(ny, mn, mx, heightTrend - 1 + yTrend, yTrend);
082
//ny=map(ny,mn,mx,yTrend,heightTrend-1+yTrend);
083
return
ny;
084
}
085
086
//отрисовка тренда (ширина, высота, x координата, y координата, аналоговый вход, массив для хранения измерений)
087
void
drawTrend(
int
widthTrend,
int
heightTrend,
int
xTrend,
int
yTrend,
int
cn,
int
*buf) {
088
buf[sizeTrend - 1] = cn;
//добавляем новое значение
089
int
oldX = 0;
090
int
oldY = 0 + yTrend;
091
int
mn = MINz;
//для поиска минимума
092
int
mx = MAXz;
//для поиска максимума
093
double
k = 0.0;
094
//сдвигаем график
095
for
(
int
x = 0; x < (sizeTrend - 1); x++) {
096
buf[x] = buf[x + 1];
//переписываем в текущюю ячейку массива данные из следующей
097
}
098
099
//поиск мин и макс
100
for
(
int
i = 0; i < sizeTrend; i++) {
//пробегаем по массиву
101
if
(buf[i] > mx) {
//если значение в ячейке больше макс
102
mx = buf[i];
//то макс = содержимому ячейки
103
}
104
if
(buf[i] < mn) {
//если значение в ячейке меньше мин
105
mn = buf[i];
//то мин = содержимому ячейки
106
}
107
}
108
if
(mn == mx) {
//если мин=макс
109
mx = mn + 1;
//устанавливаем макс+=1
110
mn = mn - 1;
//мин-=1
111
}
112
113
//формирование буфера вывода
114
for
(
int
x = 0; x < sizeTrend - 1; x++) {
//Х координата
115
int
y = convert(buf[x], mn, mx, yTrend, heightTrend, buf);
//Y координата
116
int
nxt_x = map(x, 0, sizeTrend - 1, 0, widthTrend);
117
//отрисовка тренда
118
display.drawLine(xTrend + oldX, oldY, xTrend + nxt_x, y, WHITE);
119
oldX = nxt_x;
120
oldY = y;
121
}
122
123
//отрисовка рамки
124
display.drawRect(xTrend, yTrend, widthTrend, heightTrend, WHITE);
125
126
//вывод минимума и максимума на экран
127
display.setCursor(xTrend + widthTrend + 3, yTrend);
128
display.println(mx); Max = mx;
129
display.setCursor(xTrend + widthTrend + 3, yTrend + heightTrend - 8);
130
display.println(mn); Min = mn;
131
display.setCursor(xTrend + widthTrend + 3, yTrend + (heightTrend / 2) - 4);
132
display.println(buf[sizeTrend - 1]);
//текущее
133
oldX = 0;
//чтобы новая линия сначала тренда отрисовывалась
134
oldY = convert(buf[0], mn, mx, yTrend, heightTrend, buf);
135
136
}
137
138
//Опрашиваем кнопки по прерыванию*************************************************************************
139
void
isr_Left() {
140
btn_Left.tick();
141
}
142
void
isr_Right() {
143
btn_Right.tick();
144
}
145
void
isr__Up() {
146
btn_Up.tick();
147
}
148
void
isr__Down() {
149
btn_Down.tick();
150
}
151
void
isr__Enter() {
152
btn_Enter.tick();
153
}
154
//********************************************************************************************************
155
156
void
setup
() {
157
Serial
.begin(115200);
158
//memset(in1, 0x0, sizeTrend);
159
//memset(in2, 0x0, sizeTrend);
160
//memset(in3, 0x0, sizeTrend);
161
pinMode(LED, OUTPUT);
//синий светодиод тревоги
162
digitalWrite(LED, LOW);
163
pinMode(19, OUTPUT);
//красный светодиод тревоги
164
digitalWrite(19, LOW);
165
166
//Настройка кнопок**************************************************************************************
167
// настройка антидребезга (по умолчанию 80 мс)
168
// настройка таймаута на удержание (по умолчанию 500 мс)
169
btn_Left.setDebounce(50); btn_Left.setTimeout(300);
170
btn_Right.setDebounce(50); btn_Right.setTimeout(300);
171
btn_Up.setDebounce(50); btn_Up.setTimeout(300);
172
btn_Down.setDebounce(50); btn_Down.setTimeout(300);
173
btn_Enter.setDebounce(50); btn_Enter.setTimeout(300);
174
//Кнопки настроены***************************************************************************************
175
176
//Init display ******************************************************************************************
177
if
(!display.begin(SSD1306_SWITCHCAPVCC)) {
178
Serial
.println(F(
"SSD1306 allocation failed"
));
179
}
180
display.display();
181
delay(1000);
182
display.clearDisplay();
183
display.setCursor(0, 0);
184
display.setTextSize(1);
185
display.setTextColor(SSD1306_WHITE);
// Draw white text
186
display.cp437(
true
);
// Use full 256 char 'Code Page 437' font
187
display.println(
"Init..."
);
188
display.println(
"Display SSD1306"
);
189
//End Init display ****************************************************************************************
190
191
// Initialize magnetic sensors LIS3MDL********************************************************************
192
if
(compass1.begin_I2C(0x1E)) {
// hardware I2C mode, can pass in address & alt Wire 0x1E
193
display.println(
"Sensor1 Ok"
);
194
}
195
if
(compass2.begin_I2C(0x1C)) {
// hardware I2C mode, can pass in address & alt Wire0x1C
196
display.println(
"Sensor2 Ok"
);
197
}
198
// End initialize LIS3MDL*********************************************************************************
199
200
// Initialize magnetic sensors HMC5883, QMC5883, VCM5883L**************************************************
201
/*
while
(!compass1.begin()) {
202
//Serial.println("Could not find a valid magnetic sensor, check wiring!");
203
display.println(
"No magnetic sensor1"
);
204
delay(500);
205
}
206
207
if
(compass1.isHMC()) {
208
//Serial.println("Sensor1 HMC5883");
209
display.println(
"Sensor1 HMC5883"
);
210
//compass1.setRange(HMC5883L_RANGE_1_3GA);
211
//compass1.setMeasurementMode(HMC5883L_CONTINOUS);
212
//compass1.setDataRate(HMC5883L_DATARATE_15HZ);
213
//compass1.setSamples(HMC5883L_SAMPLES_8);
214
}
else
if
(compass1.isQMC()) {
215
//Serial.println("Sensor1 QMC5883");
216
display.println(
"Sensor1 QMC5883"
);
217
compass1.setRange(QMC5883_RANGE_2GA);
218
//compass1.setMeasurementMode(QMC5883_CONTINOUS);
219
//compass1.setDataRate(QMC5883_DATARATE_50HZ);
220
//compass1.setSamples(QMC5883_SAMPLES_8);
221
}
else
if
(compass1.isVCM()) {
222
//Serial.println("Sensor1 VCM5883L");
223
display.println(
"Sensor1 VCM5883L"
);
224
//compass1.setMeasurementMode(VCM5883L_CONTINOUS);
225
//compass1.setDataRate(VCM5883L_DATARATE_200HZ);
226
}
else
display.println(
"No sensors1"
);
227
228
while
(!compass2.begin()){
229
//Serial.println("Could not find a valid magnetic sensor, check wiring!");
230
display.println(
"No magnetic sensor1"
);
231
delay(500);
232
}
233
if
(compass2.isHMC()){
234
//Serial.println("Sensor2 HMC5883");
235
display.println(
"Sensor2 HMC5883"
);
236
//compass2.setRange(HMC5883L_RANGE_1_3GA);
237
//compass2.setMeasurementMode(HMC5883L_CONTINOUS);
238
//compass2.setDataRate(HMC5883L_DATARATE_15HZ);
239
//compass2.setSamples(HMC5883L_SAMPLES_8);
240
}
else
if
(compass2.isQMC()){
241
//Serial.println("Sensor2 QMC5883");
242
display.println(
"Sensor2 QMC5883"
);
243
compass2.setRange(QMC5883_RANGE_2GA);
244
//compass2.setMeasurementMode(QMC5883_CONTINOUS);
245
//compass2.setDataRate(QMC5883_DATARATE_50HZ);
246
//compass2.setSamples(QMC5883_SAMPLES_8);
247
}
else
if
(compass2.isVCM()){
248
//Serial.println("Sensor VCM5883L");
249
display.println(
"Sensor2 VCM5883L"
);
250
//compass2.setMeasurementMode(VCM5883L_CONTINOUS);
251
//compass2.setDataRate(VCM5883L_DATARATE_200HZ);
252
}
else
display.println(
"No sensors2"
);*/
253
// End initialize HMC5883, QMC5883, VCM5883L *************************************************
254
255
display.display();
256
delay(4000);
257
display.clearDisplay();
258
display.setCursor(0, 0);
259
display.setTextSize(1);
260
display.setTextColor(SSD1306_WHITE);
// Draw white text
261
display.cp437(
true
);
// Use full 256 char 'Code Page 437' font
262
263
//Вывести Номер сенсора-датчика
264
for
(
int
cntr = 1; cntr < 9; cntr++) {
265
display.clearDisplay();
//Очистить буфер дисплея и картинку
266
display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor);
267
display.display();
268
delay(100);
269
}
270
display.setTextSize(1);
271
display.clearDisplay();
272
display.display();
273
274
//Инициализация зумера тревоги
275
ledcSetup(channel, freq, resolution);
276
ledcAttachPin(2, channel);
277
}
278
279
void
loop
() {
280
btn_Left.tick();
// опрашиваем в скетче, иначе не будут работать проверки по времени!
281
btn_Right.tick();
282
btn_Up.tick();
283
btn_Down.tick();
284
btn_Enter.tick();
285
//Раскоментировать для тестирования кнопок*****************************************************
286
/*if (btn_Left.isSingle()) Serial.println("Single Left"); // проверка на один клик
287
if (btn_Left.hasClicks()) // проверка на наличие нажатий
288
Serial.println(btn_Left.getClicks()); // получить (и вывести) число нажатий
289
if (btn_Right.isSingle()) Serial.println("Single Right"); // проверка на один клик
290
if (btn_Right.hasClicks()) // проверка на наличие нажатий
291
Serial.println(btn_Right.getClicks()); // получить (и вывести) число нажатий*/
292
//***********************************************************************************************
293
294
if
(myTimer.isReady()) {
295
display.clearDisplay();
//Очистить буфер дисплея и картинку
296
297
//МЕНЮ On/Off***************************************************************************************
298
if
(btn_Enter.hasClicks()) {
299
menu_OnOff = !menu_OnOff;
300
menu_Senor = !menu_OnOff;
301
}
302
//МЕНЮ On/Off end***********************************************************************************
303
304
//Установка порядка и размеров графиков по координатом на экране************************************
305
306
//Клавиша ВЛЕВО*************************************************************************************
307
if
(btn_Left.hasClicks() && menu_OnOff) {
308
--cnt_LeftRight;
309
int
clicks = btn_Left.getClicks();
//число кликов
310
if
(clicks != 1) cnt_LeftRight = clicks;
311
}
312
//Отработано Клавиша ВЛЕВО**************************************************************************
313
314
//Клавиша ВПРАВО************************************************************************************
315
if
(btn_Right.hasClicks() && menu_OnOff) {
316
++cnt_LeftRight;
317
//--cnt_UpDownSensor;
318
int
clicks = btn_Right.getClicks();
//число кликов
319
if
(clicks != 1) cnt_LeftRight = clicks;
320
}
321
//Отработано Клавиша ВПРАВО*************************************************************************
322
323
//Клавиша ВВЕРХ, cnt_UpDown = количеству пунктов вертикального меню*********************************
324
if
(btn_Up.hasClicks() && menu_OnOff) {
325
--cnt_UpDown;
326
int
clicks = btn_Up.getClicks();
//число кликов
327
if
(clicks != 1) cnt_UpDown = clicks;
328
}
329
//end ВВЕРХ******************************************************************************************
330
331
//Клавиша ВНИЗ***************************************************************************************
332
if
(btn_Down.hasClicks() && menu_OnOff) {
333
++cnt_UpDown;
334
int
clicks = btn_Down.getClicks();
//число кликов
335
if
(clicks != 1) cnt_UpDown = clicks;
336
}
337
//end Клавиша ВНИЗ************************************************************************************
338
339
//Обрабатываем ВВЕРХ-ВНИЗ*****************************************************************************
340
341
//Показать номер сенсора******************************************************************************
342
if
(!menu_OnOff) {
343
if
(btn_Up.hasClicks() && !menu_OnOff) {
344
--cnt_UpDownSensor;
345
flag_UpDownSensor = !flag_UpDownSensor;
346
if
(cnt_UpDownSensor < 1) cnt_UpDownSensor = 2;
347
for
(
int
cntr = 1; cntr < 9; cntr++) {
348
display.clearDisplay();
//Очистить буфер дисплея и картинку
349
display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor);
350
display.display();
351
delay(50);
352
}
353
display.setTextSize(1);
354
display.clearDisplay();
355
display.display();
356
}
357
358
if
(btn_Down.hasClicks() && !menu_OnOff) {
359
++cnt_UpDownSensor;
360
flag_UpDownSensor = !flag_UpDownSensor;
361
if
(cnt_UpDownSensor > 2) cnt_UpDownSensor = 1;
362
for
(
int
cntr = 1; cntr < 9; cntr++) {
363
display.clearDisplay();
//Очистить буфер дисплея и картинку
364
display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor);
365
display.display();
366
delay(50);
367
}
368
display.setTextSize(1);
369
display.clearDisplay();
370
display.display();
371
}
372
}
373
//Показали номер сенсора******************************************************************************
374
375
//Меню************************************************************************************************
376
if
(menu_OnOff) {
377
if
(cnt_UpDown < 1) cnt_UpDown = 6;
378
if
(cnt_UpDown > 6) cnt_UpDown = 1;
379
switch
(cnt_UpDown) {
380
case
1:
381
if
(btn_Right.hasClicks()) cnt_Coordinats += 1;
382
if
(cnt_Coordinats > 3) cnt_Coordinats = 1;
383
if
(btn_Left.hasClicks()) cnt_Coordinats -= 1;
384
if
(cnt_Coordinats < 1) cnt_Coordinats = 3;
385
if
(cnt_Coordinats == 1) {
386
Coordinats =
""
;
387
Coordinats =
"ZXY"
;
388
}
389
if
(cnt_Coordinats == 2) {
390
Coordinats =
""
;
391
Coordinats =
"YZX"
;
392
}
393
if
(cnt_Coordinats == 3) {
394
Coordinats =
""
;
395
Coordinats =
"XYZ"
;
396
}
397
//display.clearDisplay();
398
display.setCursor(5, 0); display.printf(
"> %-12s %s"
,
"Coordinats"
, Coordinats);
399
display.setCursor(5, 10); display.printf(
"2 %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
400
display.setCursor(5, 20); display.printf(
"3 %-12s %d"
,
"Triger MINz"
, TrigerMINz);
401
display.setCursor(5, 30); display.printf(
"4 %-12s %d"
,
"Buzzer"
, Buzzer);
402
display.setCursor(5, 40); display.printf(
"5 %-12s %d"
,
"Algoritm"
, Algoritm);
403
display.setCursor(5, 50); display.printf(
"6 %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
404
display.display();
405
break
;
406
case
2:
407
if
(btn_Right.hasClicks()) {
408
int
clicks = btn_Right.getClicks();
//число кликов
409
if
(clicks == 1) ++TrigerMAXz;
410
if
(clicks == 2) TrigerMAXz += 10;
411
if
(clicks == 3) TrigerMAXz += 100;
412
if
(clicks == 4) TrigerMAXz += 1000;
413
}
414
if
(btn_Left.hasClicks()) {
415
int
clicks = btn_Left.getClicks();
//число кликов
416
if
(clicks == 1) --TrigerMAXz;
417
if
(clicks == 2) TrigerMAXz -= 10;
418
if
(clicks == 3) TrigerMAXz -= 100;
419
if
(clicks == 4) TrigerMAXz -= 1000;
420
}
421
display.setCursor(5, 0); display.printf(
"1 %-12s %s"
,
"Coordinats"
, Coordinats);
422
display.setCursor(5, 10); display.printf(
"> %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
423
display.setCursor(5, 20); display.printf(
"3 %-12s %d"
,
"Triger MINz"
, TrigerMINz);
424
display.setCursor(5, 30); display.printf(
"4 %-12s %d"
,
"Buzzer"
, Buzzer);
425
display.setCursor(5, 40); display.printf(
"5 %-12s %d"
,
"Algoritm"
, Algoritm);
426
display.setCursor(5, 50); display.printf(
"6 %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
427
display.display();
428
break
;
429
case
3:
430
if
(btn_Right.hasClicks()) {
431
int
clicks = btn_Right.getClicks();
//число кликов
432
if
(clicks == 1) ++TrigerMINz;
433
if
(clicks == 2) TrigerMINz += 10;
434
if
(clicks == 3) TrigerMINz += 100;
435
if
(clicks == 4) TrigerMINz += 1000;
436
}
437
if
(btn_Left.hasClicks()) {
438
int
clicks = btn_Left.getClicks();
//число кликов
439
if
(clicks == 1) --TrigerMINz;
440
if
(clicks == 2) TrigerMINz -= 10;
441
if
(clicks == 3) TrigerMINz -= 100;
442
if
(clicks == 4) TrigerMINz -= 1000;
443
}
444
display.setCursor(5, 0); display.printf(
"1 %-12s %s"
,
"Coordinats"
, Coordinats);
445
display.setCursor(5, 10); display.printf(
"2 %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
446
display.setCursor(5, 20); display.printf(
"> %-12s %d"
,
"Triger MINz"
, TrigerMINz);
447
display.setCursor(5, 30); display.printf(
"4 %-12s %d"
,
"Buzzer"
, Buzzer);
448
display.setCursor(5, 40); display.printf(
"5 %-12s %d"
,
"Algoritm"
, Algoritm);
449
display.setCursor(5, 50); display.printf(
"6 %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
450
display.display();
451
break
;
452
case
4:
453
if
(btn_Right.hasClicks()) {
454
int
clicks = btn_Right.getClicks();
//число кликов
455
if
(++Buzzer > 1) Buzzer = 0;
456
}
457
if
(btn_Left.hasClicks()) {
458
int
clicks = btn_Left.getClicks();
//число кликов
459
if
(--Buzzer < 0) Buzzer = 1;
460
}
461
display.setCursor(5, 0); display.printf(
"1 %-12s %s"
,
"Coordinats"
, Coordinats);
462
display.setCursor(5, 10); display.printf(
"2 %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
463
display.setCursor(5, 20); display.printf(
"3 %-12s %d"
,
"Triger MINz"
, TrigerMINz);
464
display.setCursor(5, 30); display.printf(
"> %-12s %d"
,
"Buzzer"
, Buzzer);
465
display.setCursor(5, 40); display.printf(
"5 %-12s %d"
,
"Algoritm"
, Algoritm);
466
display.setCursor(5, 50); display.printf(
"6 %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
467
display.display();
468
break
;
469
case
5:
470
if
(btn_Right.hasClicks()) {
471
int
clicks = btn_Right.getClicks();
//число кликов
472
if
(++Algoritm > 2) Algoritm = 1;
473
}
474
if
(btn_Left.hasClicks()) {
475
if
(--Algoritm < 1) Algoritm = 2;
476
}
477
display.setCursor(5, 0); display.printf(
"1 %-12s %s"
,
"Coordinats"
, Coordinats);
478
display.setCursor(5, 10); display.printf(
"2 %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
479
display.setCursor(5, 20); display.printf(
"3 %-12s %d"
,
"Triger MINz"
, TrigerMINz);
480
display.setCursor(5, 30); display.printf(
"4 %-12s %d"
,
"Buzzer"
, Buzzer);
481
display.setCursor(5, 40); display.printf(
"> %-12s %d"
,
"Algoritm"
, Algoritm);
482
display.setCursor(5, 50); display.printf(
"6 %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
483
display.display();
484
break
;
485
case
6:
486
if
(btn_Right.hasClicks()) {
487
int
clicks = btn_Right.getClicks();
//число кликов
488
if
(++cnt_UpDownSensor > 2) cnt_UpDownSensor = 1;
489
}
490
if
(btn_Left.hasClicks()) {
491
int
clicks = btn_Left.getClicks();
//число кликов
492
if
(--cnt_UpDownSensor < 1) cnt_UpDownSensor = 2;
493
}
494
display.setCursor(5, 0); display.printf(
"1 %-12s %s"
,
"Coordinats"
, Coordinats);
495
display.setCursor(5, 10); display.printf(
"2 %-12s %d"
,
"Triger MAXz"
, TrigerMAXz);
496
display.setCursor(5, 20); display.printf(
"3 %-12s %d"
,
"Triger MINz"
, TrigerMINz);
497
display.setCursor(5, 30); display.printf(
"4 %-12s %d"
,
"Buzzer"
, Buzzer);
498
display.setCursor(5, 40); display.printf(
"5 %-12s %d"
,
"Algoritm"
, Algoritm);
499
display.setCursor(5, 50); display.printf(
"> %-12s %d"
,
"Sensor"
, cnt_UpDownSensor);
500
display.display();
501
break
;
502
}
503
}
504
//end ВВЕРХ-ВНИЗ Меню*********************************************************************************
505
506
//Обрабатываем ВЛЕВО-ВПРАВО***************************************************************************
507
if
(!menu_OnOff) {
508
if
(btn_Right.hasClicks()) cnt_Coordinats += 1;
509
if
(cnt_Coordinats > 3) cnt_Coordinats = 1;
510
if
(btn_Left.hasClicks()) cnt_Coordinats -= 1;
511
if
(cnt_Coordinats < 1) cnt_Coordinats = 3;
512
if
(cnt_UpDownSensor == 1) {
//Работаем с 1 сенсором
513
_x = X1; _y = Y1; _z = Z1;
514
}
515
if
(cnt_UpDownSensor == 2) {
//Работаем с 2 сенсором
516
_x = X2; _y = Y2; _z = Z2;
517
}
518
switch
(cnt_Coordinats) {
519
case
1:
520
Coordinats =
""
; Coordinats =
"ZXY"
;
521
display.setCursor(0, 25); display.println(
"z"
);
522
display.setCursor(25, 30); display.println(
"x"
);
523
display.setCursor(90, 30); display.println(
"y"
);
524
//int Raznica = 0; int Porog = 0; int Param1 = 0; float Param2 = 0.0;
525
if
(Algoritm == 2) {
526
display.setCursor(10, 25);
527
display.printf(
"[%d] [%d] [%.1f]"
, Raznica,Porog,Param2);
528
}
529
drawTrend(95, 25, 0, 0, _z, in1);
//вывод 1 тренда по данным из массива in1-Z
530
//Запись в переменные в зависимости от выбранного канала датчика cnt_UpDownSensor по Z**********
531
if
(cnt_UpDownSensor == 1) {
532
MIN = Min; MAX = Max;
533
}
534
if
(cnt_UpDownSensor == 2) {
535
MIN2 = Min; MAX2 = Max;
536
}
537
//***********************************************************************************************
538
drawTrend(30, 25, 0, 39, _x, in2);
//вывод второго по данным из in2-X
539
drawTrend(34, 25, 60, 39, _y, in3);
//вывод третьего по данным из in3-Y
540
display.display();
541
break
;
542
case
2:
543
Coordinats =
""
; Coordinats =
"YZX"
;
544
//display.clearDisplay();
545
display.setCursor(0, 25); display.println(
"y"
);
546
display.setCursor(25, 30); display.println(
"z"
);
547
display.setCursor(90, 30); display.println(
"x"
);
548
if
(Algoritm == 2) {
549
display.setCursor(10, 25);
550
display.printf(
"[%d] [%d] [%.1f]"
, Raznica,Porog,Param2);
551
}
552
drawTrend(95, 25, 0, 0, _y, in3);
//вывод 1 тренда по данным из массива in3-Y
553
drawTrend(30, 25, 0, 39, _z, in1);
//вывод второго по данным из in1-Z
554
//Запись в переменные в зависимости от выбранного канала датчика cnt_UpDownSensor по Z************
555
//MIN2 = Min; MAX2 = Max; X2 = x; Y2 = y; Z2 = z;
556
if
(cnt_UpDownSensor == 1) {
557
MIN = Min; MAX = Max;
558
}
559
if
(cnt_UpDownSensor == 2) {
560
MIN2 = Min; MAX2 = Max;
561
}
562
//*************************************************************************************************
563
drawTrend(34, 25, 60, 39, _x, in2);
//вывод третьего по данным из in2-X
564
display.display();
565
break
;
566
case
3:
567
Coordinats =
""
; Coordinats =
"XYZ"
;
568
//display.clearDisplay();
569
display.setCursor(0, 25); display.println(
"x"
);
570
display.setCursor(25, 30); display.println(
"y"
);
571
display.setCursor(90, 30); display.println(
"z"
);
572
if
(Algoritm == 2) {
573
display.setCursor(10, 25);
574
display.printf(
"[%d] [%d] [%.1f]"
, Raznica,Porog,Param2);
575
}
576
drawTrend(95, 25, 0, 0, _x, in2);
//вывод 1 тренда по данным из массива in2-X
577
drawTrend(30, 25, 0, 39, _y, in3);
//вывод второго по данным из in3-Y
578
drawTrend(34, 25, 60, 39, _z, in1);
//вывод третьего по данным из in1-Z
579
if
(cnt_UpDownSensor == 1) {
580
MIN = Min; MAX = Max;
581
}
582
if
(cnt_UpDownSensor == 2) {
583
MIN2 = Min; MAX2 = Max;
584
}
585
display.display();
586
break
;
587
588
}
589
}
590
display.clearDisplay();
//Очистить буфер дисплея и картинку
591
//display.display();
592
//Отработали ВЛЕВО-ВПРАВО*****************************************************************************
593
594
//выводим в плоттер по последовательному порту в зависимости от выбранного датчика*******
595
//После отладки закоментировать блок
596
if
(cnt_UpDownSensor == 1) {
597
Serial
.print(
" X1:"
);
598
Serial
.print(X1);
599
Serial
.print(
" Y1:"
);
600
Serial
.print(Y1);
601
Serial
.print(
" Z1:"
);
602
Serial
.println(Z1);
603
}
604
if
(cnt_UpDownSensor == 2) {
605
Serial
.print(
" X2:"
);
606
Serial
.print(X2);
607
Serial
.print(
" Y2:"
);
608
Serial
.print(Y2);
609
Serial
.print(
" Z2:"
);
610
Serial
.println(Z2);
611
}
612
613
//плоттер end****************************************************************************************
614
myTimer.start();
//Перезапуск таймера
615
}
616
617
/*
if
(cnt_UpDownSensor == 1) {
//Первый I2C датчик QMC5883
618
Vector mag = compass1.readRaw();
// Читаем значения датчика. При другой библиотеке и датчике заменить
619
//x = mag.XAxis;
620
//y = mag.YAxis;
621
//z = mag.ZAxis;
622
X1 = mag.XAxis;
623
Y1 = mag.YAxis;
624
Z1 = mag.ZAxis;
625
}
626
if
(cnt_UpDownSensor == 2) {
//Второй I2C датчик QMC5883
627
Vector mag = compass1.readRaw();
// Читаем значения датчика. При другой библиотеке и датчике заменить
628
X2 = mag.XAxis;
629
Y2 = mag.YAxis;
630
Z2 = mag.ZAxis;
631
}*/
632
sensors_event_t event1;
633
sensors_event_t event2;
634
//if (cnt_UpDownSensor == 1) { //Первый I2C датчик
635
/*compass1.read(); //в Гаусах
636
X1 = compass1.x;
637
Y1 = compass1.y;
638
Z1 = compass1.z;*/
639
compass1.getEvent(&event1);
//в Тесла
640
X1 = event1.magnetic.x;
641
Y1 = event1.magnetic.y;
642
Z1 = event1.magnetic.z;
643
//}
644
//if (cnt_UpDownSensor == 2) { //Второй I2C датчик
645
/*compass2.read(); //в Гаусах
646
X2 = compass2.x;
647
Y2 = compass2.y;
648
Z2 = compass2.z;*/
649
compass2.getEvent(&event2);
//в Тесла
650
X2 = event2.magnetic.x;
651
Y2 = event2.magnetic.y;
652
Z2 = event2.magnetic.z;
653
//}
654
/*Тест для датчика Амперка
655
Serial.print(compass1.readMagneticGaussX());
656
Serial.print("\t\t");
657
// Выводим напряженность магнитного поля в Гауссах по оси Y
658
Serial.print(compass1.readMagneticGaussY());
659
Serial.print("\t\t");
660
// Выводим напряженность магнитного поля в Гауссах по оси Z
661
Serial.println(compass1.readMagneticGaussZ());
662
Serial.println("=================================================");
663
*/
664
665
//*****************************************************************************************************
666
//*****************************************************************************************************
667
//*****************************************************************************************************
668
/*
669
БЛОК МОЙ КОД
670
ЦИКЛЫ ДЕЛАТЬ НЕЛЬЗЯ (крайне не рекомендуется)!!!. СОБЪЕТСЯ ЧАСТОТА ОПРОСА СИГНАЛА и скорость вывода на экран.
671
Чем больше интервал частоты опроса (реже опрашиваем), тем больше мы срезаем ПОМЕХ.
672
(
int
) Freq_signal = 100 милисекунд. Можете изменить частоту опроса датчиков
673
Здесь пишем алгоритмы обработки сигнала...
674
Когда и при каких условиях срабатывают тригеры...
675
Когда и как срабатывает световая и звуковая сигнализация...
676
(
int
) TrigerMINz - устанавливается в Меню вручную. Граница срабатывания по оси Z
677
(
int
) TrigerMAXz - устанавливается в Меню вручную. Граница срабатывания по оси Z
678
Данные с выбранного в Меню датчика реализовано только по оси Z
679
Значение cnt_UpDownSensor == 1 - Первый I2C датчик
680
Значение cnt_UpDownSensor == 2 - Второй I2C датчик
681
В зависимости от cnt_UpDownSensor в x, y, z будут отражены данные от 1го или 2го датчика
682
(
int
) x - значение 1(2) датчика по X
683
(
int
) y - значение 1(2) датчика по Y
684
(
int
) z - значение 1(2) датчика по Z
685
(
int
) X1, Y1, Z1 - переменные для экспериментов по первому датчику
686
(
int
) X2, Y2, Z2 - переменные для экспериментов по второму датчику
687
(
int
) MIN, MAX - переменные для экспериментов по первому датчику установленные программно
688
(
int
) MIN2, MAX2 - переменные для экспериментов по второму датчику установленные программно
689
(
int
) Algoritm - переключатель алгоритма обработки значений датчика
690
(
int
) LED - Адрес светодиода 15 (D15)
691
(
int
) BUZZER_PIN - Адрес зумера 2 (D2)
692
693
(
int
) Raznica = 0; (
int
) Porog = 0; (
int
) Param1 = 0; (
float
) Param2 = 0.0;
694
Алгоритм работы с двумя датчиками
695
696
Dat1 - показания первого датчика после усреднения.
697
Dat2 - показания второго датчика после усреднения.
698
Porog - порог срабатывания (настраивается кнопками на плате).
699
Raznica - разница между показаниями двух датчиков.
700
701
Прибор срабатывает (подает звуковой сигнал) если Raznica по модулю (без учета знака +-) >= Porog.
702
if
(abs(Dat1 - Dat2) >= Porog) { даем сигнал на динамик }
703
704
Усреднение данных - Экспоненциальное бегущее среднее
705
706
float
k = 0.1;
// коэффициент фильтрации, 0.0-1.0
707
// бегущее среднее
708
float
expRunningAverage(
float
newVal) {
709
static
float
filVal = 0;
710
filVal += (newVal - filVal) * k;
711
return
filVal;
712
}
713
"Сила"
фильтра настраивается коэффициентом (0.0 – 1.0). Чем он меньше, тем плавнее фильтр
714
715
В ДРУГОЙ КОД НЕ ЛЕЗЕМ!!! Внутри БЛОКА все что угодно. Делаем копию БЛОКА!
716
*/
717
//Отладка. Выводим в монитор последовательного порта. Мешает выводу в плоттер. После отладки закоментировать***
718
//Serial.printf("X1 = %6d, Y1 = %6d, Z1 = %6d\n",X1, Y1, Z1);
719
//Serial.printf("X2 = %6d, Y2 = %6d, Z2 = %6d\n",X2, Y2, Z2);
720
//Serial.printf("MIN = %6d, MAX = %6d\n", MIN, MAX);
721
//Serial.printf("MIN2 = %6d, MAX2 = %6d\n", MIN2, MAX2);
722
//Монитор end***************************************************************************************************
723
724
//Алгоритм 1. Обрабатывает данные минимального и максимального значения датчика по оси Z
725
//включает/выключает синий светодиод (минимум), краный светодиод (максимум) и зуммер
726
if
(Algoritm == 1) {
727
if
(Z1 < TrigerMINz) {
728
digitalWrite(LED, HIGH);
729
if
(Buzzer == 1) {
730
//tone(BUZZER_PIN, NOTE_C4, 5, BUZZER_CHANNEL);
731
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
732
//tone(BUZZER_PIN, NOTE_D4, 500, BUZZER_CHANNEL);
733
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
734
//tone(BUZZER_PIN, NOTE_E4, 500, BUZZER_CHANNEL);
735
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
736
//tone(BUZZER_PIN, NOTE_F4, 500, BUZZER_CHANNEL);
737
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
738
//tone(BUZZER_PIN, NOTE_G4, 500, BUZZER_CHANNEL);
739
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
740
//tone(BUZZER_PIN, NOTE_A4, 500, BUZZER_CHANNEL);
741
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
742
tone(BUZZER_PIN, NOTE_B4, 10, BUZZER_CHANNEL);
743
noTone(BUZZER_PIN, BUZZER_CHANNEL);
744
}
745
else
noTone(BUZZER_PIN, BUZZER_CHANNEL);
746
}
747
else
digitalWrite(LED, LOW);
748
749
if
(Z1 > TrigerMAXz) {
750
digitalWrite(19, HIGH);
751
if
(Buzzer == 1) {
752
tone(BUZZER_PIN, NOTE_C4, 10, BUZZER_CHANNEL);
753
noTone(BUZZER_PIN, BUZZER_CHANNEL);
754
//tone(BUZZER_PIN, NOTE_D4, 500, BUZZER_CHANNEL);
755
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
756
//tone(BUZZER_PIN, NOTE_E4, 500, BUZZER_CHANNEL);
757
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
758
//tone(BUZZER_PIN, NOTE_F4, 500, BUZZER_CHANNEL);
759
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
760
//tone(BUZZER_PIN, NOTE_G4, 500, BUZZER_CHANNEL);
761
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
762
//tone(BUZZER_PIN, NOTE_A4, 500, BUZZER_CHANNEL);
763
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
764
//tone(BUZZER_PIN, NOTE_B4, 5, BUZZER_CHANNEL);
765
//noTone(BUZZER_PIN, BUZZER_CHANNEL);
766
}
767
else
noTone(BUZZER_PIN, BUZZER_CHANNEL);
768
}
769
else
digitalWrite(19, LOW);
770
}
771
772
//Алгоритм 2. Здесь исходный код Заказчика. Основаный на примере Алгоритм 1.
773
//включает/выключает ... if (abs(Dat1 - Dat2) >= Porog) { даем сигнал на динамик }
774
if
(Algoritm == 2) {
775
Raznica = 1; Porog = 2; Param1 = 3; Param2 = 4.0;
776
if
(Porog > TrigerMAXz) {
777
digitalWrite(19, HIGH);
778
}
779
else
digitalWrite(19, LOW);
780
if
(Porog > TrigerMAXz) {
781
digitalWrite(LED, HIGH);
782
}
783
else
digitalWrite(19, LOW);
784
}
785
786
/*
787
Конец блока МОЙ КОД********************************************************************************
788
В ДРУГОЙ КОД ВНЕ БЛОКА НЕ ЛЕЗЕМ!!!
789
*/
790
//*****************************************************************************************************
791
//*****************************************************************************************************
792
//*****************************************************************************************************
793
}
//Конец цикла Loop
Ну, хоть маленькое описание-то надо!
Чего измеряем, в каких попугаях, в каком диапазоне, с какой точностью? Ну, чего ж ничего-то нет?
01
//if (cnt_UpDownSensor == 1) { //Первый I2C датчик
02
635
03
/*compass1.read(); //в Гаусах
04
05
compass1.getEvent(&event1); //в Тесла
06
07
//if (cnt_UpDownSensor == 2) { //Второй I2C датчик
08
645
09
/*compass2.read(); //в Гаусах
10
11
compass2.getEvent(&event2); //в Тесла
12
13
/*Тест для датчика Амперка
14
655
15
Serial.print(compass1.readMagneticGaussX());
16
656
17
Serial.print("\t\t");
18
657
19
// Выводим напряженность магнитного поля в Гауссах по оси Y
20
658
21
Serial.print(compass1.readMagneticGaussY());
22
659
23
Serial.print("\t\t");
24
660
25
// Выводим напряженность магнитного поля в Гауссах по оси Z
26
661
27
Serial.println(compass1.readMagneticGaussZ());
28
662
29
Serial.println("=================================================");
30
663
31
*/
Ну, я же говорю, нужна какая-никакая документация. Даже если юзер и будет рыться по Вашим кодам, чтобы что-то там узнать из комментариев, там у Вас много нет. Например, какова погрешность? Какова чувствительность? Предельные диапазоны измеряемой величины? Как правильно пользоваться? Вот посмотрите, например, вот в этом проекте. Есть два документа в формате PDF: инструкция и схема.
Ну, я же говорю, нужна какая-никакая документация. Даже если юзер и будет рыться по Вашим кодам, чтобы что-то там узнать из комментариев, там у Вас много нет. Например, какова погрешность? Какова чувствительность? Предельные диапазоны измеряемой величины? Как правильно пользоваться? Вот посмотрите, например, вот в этом проекте. Есть два документа в формате PDF: инструкция и схема.
Ну не знает большинство людей, что такое ДОМАШНИЙ МАГНИТОМЕТР. Я не знаю что такое и не домашний.
Скачал ваш архив, думал там будет написано для чего может быть использован. Какие возможны сценарии и с какой точностью.
Но не нашел.
Дополнено позже. Может быть я не прав и для тех, кто в теме, информации достаточно.
Ну не знает большинство людей, что такое ДОМАШНИЙ МАГНИТОМЕТР. Я не знаю что такое и не домашний.
Скачал ваш архив, думал там будет написано для чего может быть использован. Какие возможны сценарии и с какой точностью.
Но не нашел.
Дополнено позже. Может быть я не прав и для тех, кто в теме, информации достаточно.
IMU-сенсор 10-DOF v2: инструкция, схемы и примеры использования [Амперка / Вики] (amperka.ru)
Насколько я понимаю правильно, сам плохо ориентируюсь в магнетизме земли. Специальный датчик, он же датчик магнитного компаса (могу не правильно излагать термины) измеряет напряженность магнитного поля, определить направление Севера, наклон датчика например относительно горизонта... Программа, это просто оболочка-врапер дающая возможность считать какое то значение датчика по осям Х, Y, Z. Удобно визуализировать в виде бегущих графиков на дисплее значения измерений. Отображает значения в виде цифр. Есть возможность переключать и отображать на дисплее оси координат. Переключать экраны для графиков датчиков. Есть меню и возможность устанавливать пороги срабатывания по MAX и MIN значений. Для того что бы не лезть в код. Есть программный блок, где можно писать свои обработчики полученных данных от датчиков. В программе он специально выделен комментариями. Где использовать? Ну например на пляже в песке забытые монеты и тому подобное на глубине не более 10 см :) Профессиональные комлексы с другими принципами, ищут подводные лодки на глубина в 100 метры. Характеристики ищут в специальных документах на датчики. Даташит.
Есть такая штука уже модулем... Работает без ардуины. Напрямую с Nextion, например: https://youtube.com/shorts/0nEAC3PHouc