Магнитометр
- Войдите на сайт для отправки комментариев
Пт, 15/10/2021 - 13:00


Простейший домашний магнитометр с двумя устройствами типа компас. Написан с использованием свободно распространяемого в Интернет кода и библиотек.
Весь проект со схемами в ZIP файле можно скачать по ссылке. Просто не увидел, что здесь можно вставлять архивные файлы.
Забыл вставить исходный код
/* Домашний магнетометр Модуль ESP32 WROOM. В менеджере плат - DOIT ESP32 DEVKIT V1. Версия для ESP32 - Espresiif system v 1.0.6 Arduino IDE 1.8.13 */ #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define sizeTrend 30//количество точек в тренде #define OLED_MOSI 23 #define OLED_CLK 18 #define OLED_DC 16 #define OLED_CS 5 //Для других SPI устойств CS должен быть другим #define OLED_RESET 17 #define BUZZER_PIN 2 #define BUZZER_CHANNEL 0 #include <Tone32.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> //#include <DFRobot_QMC5883.h> #include <Adafruit_LIS3MDL.h> #include "GyverTimer.h" int Freq_signal = 100; GTimer myTimer(MS, Freq_signal); // создать миллисекундный таймер //GTimer myTimer(US); // US - микросекундный #include "GyverButton.h" // Варианты инициализации кнопок: // GButton btn;// без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. HIGH_PULL и NORM_OPEN) // GButton btn(пин);// с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN) // GButton btn(пин, тип подключ.);// с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN) // GButton btn(пин, тип подключ., тип кнопки);// с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE) // GButton btn(BTN_NO_BTN_PIN, тип подключ., тип кнопки);// без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE) //DFRobot_QMC5883 compass1; //DFRobot_QMC5883 compass2; //Декларируем две I2C шины /*int *in1 = new int[sizeTrend+1]; //массив для первого тренда int *in2 = new int[sizeTrend+1]; //массив для второго тренда int *in3 = new int[sizeTrend+1]; //массив для второго тренда*/ int in1[sizeTrend]; //массив для первого тренда int in2[sizeTrend]; //массив для второго тренда int in3[sizeTrend]; //массив для второго тренда const int LED = 15; //синий светодиод //int r=0; int x, y, z, t; int _x, _y, _z, _t; int X1, Y1, Z1; int X2, Y2, Z2; int Min, Max; int MIN, MAX; int MIN2, MAX2; int cnt_LeftRight = 1; //Счетчик перемещения по горизонтальному меню int cnt_UpDown = 1; //Счетчик перемещения по вертикальному меню int cnt_UpDownSensor = 1; //Счетчик перемещения по вертикальному меню для сенсоров bool flag_UpDownSensor = true; Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); GButton btn_Left(27); GButton btn_Right(12); GButton btn_Up(13); GButton btn_Down(14); GButton btn_Enter(26); Adafruit_LIS3MDL compass1; Adafruit_LIS3MDL compass2; bool menu_OnOff = false; bool menu_Senor = true; char *Coordinats = "ZXY"; int cnt_Coordinats = 1; int TrigerMINz = 0; int TrigerMAXz = 0; int MINz = 400; int MAXz = -400; int Volume = 0; int freq = 600; int channel = 0; int resolution = 8; int Buzzer = 0; int Algoritm = 1; int Chanel = 1; int Raznica = 0; int Porog = 0; int Param1 = 0; float Param2 = 0.0; //конвертирование данных из массива для варианта приема байтовых значений int convert(int y, int mn, int mx, byte yTrend, byte heightTrend, int *buf ) { int ny = y; ny = map(ny, mn, mx, heightTrend - 1 + yTrend, yTrend); //ny=map(ny,mn,mx,yTrend,heightTrend-1+yTrend); return ny; } //отрисовка тренда (ширина, высота, x координата, y координата, аналоговый вход, массив для хранения измерений) void drawTrend(int widthTrend, int heightTrend, int xTrend, int yTrend, int cn, int *buf) { buf[sizeTrend - 1] = cn; //добавляем новое значение int oldX = 0; int oldY = 0 + yTrend; int mn = MINz; //для поиска минимума int mx = MAXz; //для поиска максимума double k = 0.0; //сдвигаем график for (int x = 0; x < (sizeTrend - 1); x++) { buf[x] = buf[x + 1]; //переписываем в текущюю ячейку массива данные из следующей } //поиск мин и макс for (int i = 0; i < sizeTrend; i++) { //пробегаем по массиву if (buf[i] > mx) { //если значение в ячейке больше макс mx = buf[i]; //то макс = содержимому ячейки } if (buf[i] < mn) { //если значение в ячейке меньше мин mn = buf[i]; //то мин = содержимому ячейки } } if (mn == mx) { //если мин=макс mx = mn + 1; //устанавливаем макс+=1 mn = mn - 1; //мин-=1 } //формирование буфера вывода for (int x = 0; x < sizeTrend - 1; x++) { //Х координата int y = convert(buf[x], mn, mx, yTrend, heightTrend, buf); //Y координата int nxt_x = map(x, 0, sizeTrend - 1, 0, widthTrend); //отрисовка тренда display.drawLine(xTrend + oldX, oldY, xTrend + nxt_x, y, WHITE); oldX = nxt_x; oldY = y; } //отрисовка рамки display.drawRect(xTrend, yTrend, widthTrend, heightTrend, WHITE); //вывод минимума и максимума на экран display.setCursor(xTrend + widthTrend + 3, yTrend); display.println(mx); Max = mx; display.setCursor(xTrend + widthTrend + 3, yTrend + heightTrend - 8); display.println(mn); Min = mn; display.setCursor(xTrend + widthTrend + 3, yTrend + (heightTrend / 2) - 4); display.println(buf[sizeTrend - 1]); //текущее oldX = 0; //чтобы новая линия сначала тренда отрисовывалась oldY = convert(buf[0], mn, mx, yTrend, heightTrend, buf); } //Опрашиваем кнопки по прерыванию************************************************************************* void isr_Left() { btn_Left.tick(); } void isr_Right() { btn_Right.tick(); } void isr__Up() { btn_Up.tick(); } void isr__Down() { btn_Down.tick(); } void isr__Enter() { btn_Enter.tick(); } //******************************************************************************************************** void setup() { Serial.begin(115200); //memset(in1, 0x0, sizeTrend); //memset(in2, 0x0, sizeTrend); //memset(in3, 0x0, sizeTrend); pinMode(LED, OUTPUT); //синий светодиод тревоги digitalWrite(LED, LOW); pinMode(19, OUTPUT); //красный светодиод тревоги digitalWrite(19, LOW); //Настройка кнопок************************************************************************************** // настройка антидребезга (по умолчанию 80 мс) // настройка таймаута на удержание (по умолчанию 500 мс) btn_Left.setDebounce(50); btn_Left.setTimeout(300); btn_Right.setDebounce(50); btn_Right.setTimeout(300); btn_Up.setDebounce(50); btn_Up.setTimeout(300); btn_Down.setDebounce(50); btn_Down.setTimeout(300); btn_Enter.setDebounce(50); btn_Enter.setTimeout(300); //Кнопки настроены*************************************************************************************** //Init display ****************************************************************************************** if (!display.begin(SSD1306_SWITCHCAPVCC)) { Serial.println(F("SSD1306 allocation failed")); } display.display(); delay(1000); display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); // Draw white text display.cp437(true); // Use full 256 char 'Code Page 437' font display.println("Init..."); display.println("Display SSD1306"); //End Init display **************************************************************************************** // Initialize magnetic sensors LIS3MDL******************************************************************** if (compass1.begin_I2C(0x1E)) { // hardware I2C mode, can pass in address & alt Wire 0x1E display.println("Sensor1 Ok"); } if (compass2.begin_I2C(0x1C)) { // hardware I2C mode, can pass in address & alt Wire0x1C display.println("Sensor2 Ok"); } // End initialize LIS3MDL********************************************************************************* // Initialize magnetic sensors HMC5883, QMC5883, VCM5883L************************************************** /*while (!compass1.begin()) { //Serial.println("Could not find a valid magnetic sensor, check wiring!"); display.println("No magnetic sensor1"); delay(500); } if (compass1.isHMC()) { //Serial.println("Sensor1 HMC5883"); display.println("Sensor1 HMC5883"); //compass1.setRange(HMC5883L_RANGE_1_3GA); //compass1.setMeasurementMode(HMC5883L_CONTINOUS); //compass1.setDataRate(HMC5883L_DATARATE_15HZ); //compass1.setSamples(HMC5883L_SAMPLES_8); } else if (compass1.isQMC()) { //Serial.println("Sensor1 QMC5883"); display.println("Sensor1 QMC5883"); compass1.setRange(QMC5883_RANGE_2GA); //compass1.setMeasurementMode(QMC5883_CONTINOUS); //compass1.setDataRate(QMC5883_DATARATE_50HZ); //compass1.setSamples(QMC5883_SAMPLES_8); } else if (compass1.isVCM()) { //Serial.println("Sensor1 VCM5883L"); display.println("Sensor1 VCM5883L"); //compass1.setMeasurementMode(VCM5883L_CONTINOUS); //compass1.setDataRate(VCM5883L_DATARATE_200HZ); } else display.println("No sensors1"); while (!compass2.begin()){ //Serial.println("Could not find a valid magnetic sensor, check wiring!"); display.println("No magnetic sensor1"); delay(500); } if (compass2.isHMC()){ //Serial.println("Sensor2 HMC5883"); display.println("Sensor2 HMC5883"); //compass2.setRange(HMC5883L_RANGE_1_3GA); //compass2.setMeasurementMode(HMC5883L_CONTINOUS); //compass2.setDataRate(HMC5883L_DATARATE_15HZ); //compass2.setSamples(HMC5883L_SAMPLES_8); }else if (compass2.isQMC()){ //Serial.println("Sensor2 QMC5883"); display.println("Sensor2 QMC5883"); compass2.setRange(QMC5883_RANGE_2GA); //compass2.setMeasurementMode(QMC5883_CONTINOUS); //compass2.setDataRate(QMC5883_DATARATE_50HZ); //compass2.setSamples(QMC5883_SAMPLES_8); }else if (compass2.isVCM()){ //Serial.println("Sensor VCM5883L"); display.println("Sensor2 VCM5883L"); //compass2.setMeasurementMode(VCM5883L_CONTINOUS); //compass2.setDataRate(VCM5883L_DATARATE_200HZ); } else display.println("No sensors2");*/ // End initialize HMC5883, QMC5883, VCM5883L ************************************************* display.display(); delay(4000); display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); // Draw white text display.cp437(true); // Use full 256 char 'Code Page 437' font //Вывести Номер сенсора-датчика for (int cntr = 1; cntr < 9; cntr++) { display.clearDisplay(); //Очистить буфер дисплея и картинку display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor); display.display(); delay(100); } display.setTextSize(1); display.clearDisplay(); display.display(); //Инициализация зумера тревоги ledcSetup(channel, freq, resolution); ledcAttachPin(2, channel); } void loop() { btn_Left.tick(); // опрашиваем в скетче, иначе не будут работать проверки по времени! btn_Right.tick(); btn_Up.tick(); btn_Down.tick(); btn_Enter.tick(); //Раскоментировать для тестирования кнопок***************************************************** /*if (btn_Left.isSingle()) Serial.println("Single Left"); // проверка на один клик if (btn_Left.hasClicks()) // проверка на наличие нажатий Serial.println(btn_Left.getClicks()); // получить (и вывести) число нажатий if (btn_Right.isSingle()) Serial.println("Single Right"); // проверка на один клик if (btn_Right.hasClicks()) // проверка на наличие нажатий Serial.println(btn_Right.getClicks()); // получить (и вывести) число нажатий*/ //*********************************************************************************************** if (myTimer.isReady()) { display.clearDisplay(); //Очистить буфер дисплея и картинку //МЕНЮ On/Off*************************************************************************************** if (btn_Enter.hasClicks()) { menu_OnOff = !menu_OnOff; menu_Senor = !menu_OnOff; } //МЕНЮ On/Off end*********************************************************************************** //Установка порядка и размеров графиков по координатом на экране************************************ //Клавиша ВЛЕВО************************************************************************************* if (btn_Left.hasClicks() && menu_OnOff) { --cnt_LeftRight; int clicks = btn_Left.getClicks(); //число кликов if (clicks != 1) cnt_LeftRight = clicks; } //Отработано Клавиша ВЛЕВО************************************************************************** //Клавиша ВПРАВО************************************************************************************ if (btn_Right.hasClicks() && menu_OnOff) { ++cnt_LeftRight; //--cnt_UpDownSensor; int clicks = btn_Right.getClicks(); //число кликов if (clicks != 1) cnt_LeftRight = clicks; } //Отработано Клавиша ВПРАВО************************************************************************* //Клавиша ВВЕРХ, cnt_UpDown = количеству пунктов вертикального меню********************************* if (btn_Up.hasClicks() && menu_OnOff) { --cnt_UpDown; int clicks = btn_Up.getClicks(); //число кликов if (clicks != 1) cnt_UpDown = clicks; } //end ВВЕРХ****************************************************************************************** //Клавиша ВНИЗ*************************************************************************************** if (btn_Down.hasClicks() && menu_OnOff) { ++cnt_UpDown; int clicks = btn_Down.getClicks(); //число кликов if (clicks != 1) cnt_UpDown = clicks; } //end Клавиша ВНИЗ************************************************************************************ //Обрабатываем ВВЕРХ-ВНИЗ***************************************************************************** //Показать номер сенсора****************************************************************************** if (!menu_OnOff) { if (btn_Up.hasClicks() && !menu_OnOff) { --cnt_UpDownSensor; flag_UpDownSensor = !flag_UpDownSensor; if (cnt_UpDownSensor < 1) cnt_UpDownSensor = 2; for (int cntr = 1; cntr < 9; cntr++) { display.clearDisplay(); //Очистить буфер дисплея и картинку display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor); display.display(); delay(50); } display.setTextSize(1); display.clearDisplay(); display.display(); } if (btn_Down.hasClicks() && !menu_OnOff) { ++cnt_UpDownSensor; flag_UpDownSensor = !flag_UpDownSensor; if (cnt_UpDownSensor > 2) cnt_UpDownSensor = 1; for (int cntr = 1; cntr < 9; cntr++) { display.clearDisplay(); //Очистить буфер дисплея и картинку display.setCursor(0, 0); display.setTextSize(cntr); display.print(cnt_UpDownSensor); display.display(); delay(50); } display.setTextSize(1); display.clearDisplay(); display.display(); } } //Показали номер сенсора****************************************************************************** //Меню************************************************************************************************ if (menu_OnOff) { if (cnt_UpDown < 1) cnt_UpDown = 6; if (cnt_UpDown > 6) cnt_UpDown = 1; switch (cnt_UpDown) { case 1: if (btn_Right.hasClicks()) cnt_Coordinats += 1; if (cnt_Coordinats > 3) cnt_Coordinats = 1; if (btn_Left.hasClicks()) cnt_Coordinats -= 1; if (cnt_Coordinats < 1) cnt_Coordinats = 3; if (cnt_Coordinats == 1) { Coordinats = ""; Coordinats = "ZXY"; } if (cnt_Coordinats == 2) { Coordinats = ""; Coordinats = "YZX"; } if (cnt_Coordinats == 3) { Coordinats = ""; Coordinats = "XYZ"; } //display.clearDisplay(); display.setCursor(5, 0); display.printf("> %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("2 %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("3 %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("4 %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("5 %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("6 %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; case 2: if (btn_Right.hasClicks()) { int clicks = btn_Right.getClicks(); //число кликов if (clicks == 1) ++TrigerMAXz; if (clicks == 2) TrigerMAXz += 10; if (clicks == 3) TrigerMAXz += 100; if (clicks == 4) TrigerMAXz += 1000; } if (btn_Left.hasClicks()) { int clicks = btn_Left.getClicks(); //число кликов if (clicks == 1) --TrigerMAXz; if (clicks == 2) TrigerMAXz -= 10; if (clicks == 3) TrigerMAXz -= 100; if (clicks == 4) TrigerMAXz -= 1000; } display.setCursor(5, 0); display.printf("1 %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("> %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("3 %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("4 %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("5 %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("6 %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; case 3: if (btn_Right.hasClicks()) { int clicks = btn_Right.getClicks(); //число кликов if (clicks == 1) ++TrigerMINz; if (clicks == 2) TrigerMINz += 10; if (clicks == 3) TrigerMINz += 100; if (clicks == 4) TrigerMINz += 1000; } if (btn_Left.hasClicks()) { int clicks = btn_Left.getClicks(); //число кликов if (clicks == 1) --TrigerMINz; if (clicks == 2) TrigerMINz -= 10; if (clicks == 3) TrigerMINz -= 100; if (clicks == 4) TrigerMINz -= 1000; } display.setCursor(5, 0); display.printf("1 %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("2 %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("> %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("4 %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("5 %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("6 %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; case 4: if (btn_Right.hasClicks()) { int clicks = btn_Right.getClicks(); //число кликов if (++Buzzer > 1) Buzzer = 0; } if (btn_Left.hasClicks()) { int clicks = btn_Left.getClicks(); //число кликов if (--Buzzer < 0) Buzzer = 1; } display.setCursor(5, 0); display.printf("1 %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("2 %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("3 %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("> %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("5 %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("6 %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; case 5: if (btn_Right.hasClicks()) { int clicks = btn_Right.getClicks(); //число кликов if (++Algoritm > 2) Algoritm = 1; } if (btn_Left.hasClicks()) { if (--Algoritm < 1) Algoritm = 2; } display.setCursor(5, 0); display.printf("1 %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("2 %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("3 %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("4 %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("> %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("6 %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; case 6: if (btn_Right.hasClicks()) { int clicks = btn_Right.getClicks(); //число кликов if (++cnt_UpDownSensor > 2) cnt_UpDownSensor = 1; } if (btn_Left.hasClicks()) { int clicks = btn_Left.getClicks(); //число кликов if (--cnt_UpDownSensor < 1) cnt_UpDownSensor = 2; } display.setCursor(5, 0); display.printf("1 %-12s %s", "Coordinats", Coordinats); display.setCursor(5, 10); display.printf("2 %-12s %d", "Triger MAXz", TrigerMAXz); display.setCursor(5, 20); display.printf("3 %-12s %d", "Triger MINz", TrigerMINz); display.setCursor(5, 30); display.printf("4 %-12s %d", "Buzzer", Buzzer); display.setCursor(5, 40); display.printf("5 %-12s %d", "Algoritm", Algoritm); display.setCursor(5, 50); display.printf("> %-12s %d", "Sensor", cnt_UpDownSensor); display.display(); break; } } //end ВВЕРХ-ВНИЗ Меню********************************************************************************* //Обрабатываем ВЛЕВО-ВПРАВО*************************************************************************** if (!menu_OnOff) { if (btn_Right.hasClicks()) cnt_Coordinats += 1; if (cnt_Coordinats > 3) cnt_Coordinats = 1; if (btn_Left.hasClicks()) cnt_Coordinats -= 1; if (cnt_Coordinats < 1) cnt_Coordinats = 3; if (cnt_UpDownSensor == 1) { //Работаем с 1 сенсором _x = X1; _y = Y1; _z = Z1; } if (cnt_UpDownSensor == 2) { //Работаем с 2 сенсором _x = X2; _y = Y2; _z = Z2; } switch (cnt_Coordinats) { case 1: Coordinats = ""; Coordinats = "ZXY"; display.setCursor(0, 25); display.println("z"); display.setCursor(25, 30); display.println("x"); display.setCursor(90, 30); display.println("y"); //int Raznica = 0; int Porog = 0; int Param1 = 0; float Param2 = 0.0; if (Algoritm == 2) { display.setCursor(10, 25); display.printf("[%d] [%d] [%.1f]", Raznica,Porog,Param2); } drawTrend(95, 25, 0, 0, _z, in1); //вывод 1 тренда по данным из массива in1-Z //Запись в переменные в зависимости от выбранного канала датчика cnt_UpDownSensor по Z********** if (cnt_UpDownSensor == 1) { MIN = Min; MAX = Max; } if (cnt_UpDownSensor == 2) { MIN2 = Min; MAX2 = Max; } //*********************************************************************************************** drawTrend(30, 25, 0, 39, _x, in2); //вывод второго по данным из in2-X drawTrend(34, 25, 60, 39, _y, in3); //вывод третьего по данным из in3-Y display.display(); break; case 2: Coordinats = ""; Coordinats = "YZX"; //display.clearDisplay(); display.setCursor(0, 25); display.println("y"); display.setCursor(25, 30); display.println("z"); display.setCursor(90, 30); display.println("x"); if (Algoritm == 2) { display.setCursor(10, 25); display.printf("[%d] [%d] [%.1f]", Raznica,Porog,Param2); } drawTrend(95, 25, 0, 0, _y, in3); //вывод 1 тренда по данным из массива in3-Y drawTrend(30, 25, 0, 39, _z, in1); //вывод второго по данным из in1-Z //Запись в переменные в зависимости от выбранного канала датчика cnt_UpDownSensor по Z************ //MIN2 = Min; MAX2 = Max; X2 = x; Y2 = y; Z2 = z; if (cnt_UpDownSensor == 1) { MIN = Min; MAX = Max; } if (cnt_UpDownSensor == 2) { MIN2 = Min; MAX2 = Max; } //************************************************************************************************* drawTrend(34, 25, 60, 39, _x, in2); //вывод третьего по данным из in2-X display.display(); break; case 3: Coordinats = ""; Coordinats = "XYZ"; //display.clearDisplay(); display.setCursor(0, 25); display.println("x"); display.setCursor(25, 30); display.println("y"); display.setCursor(90, 30); display.println("z"); if (Algoritm == 2) { display.setCursor(10, 25); display.printf("[%d] [%d] [%.1f]", Raznica,Porog,Param2); } drawTrend(95, 25, 0, 0, _x, in2); //вывод 1 тренда по данным из массива in2-X drawTrend(30, 25, 0, 39, _y, in3); //вывод второго по данным из in3-Y drawTrend(34, 25, 60, 39, _z, in1); //вывод третьего по данным из in1-Z if (cnt_UpDownSensor == 1) { MIN = Min; MAX = Max; } if (cnt_UpDownSensor == 2) { MIN2 = Min; MAX2 = Max; } display.display(); break; } } display.clearDisplay(); //Очистить буфер дисплея и картинку //display.display(); //Отработали ВЛЕВО-ВПРАВО***************************************************************************** //выводим в плоттер по последовательному порту в зависимости от выбранного датчика******* //После отладки закоментировать блок if (cnt_UpDownSensor == 1) { Serial.print(" X1:"); Serial.print(X1); Serial.print(" Y1:"); Serial.print(Y1); Serial.print(" Z1:"); Serial.println(Z1); } if (cnt_UpDownSensor == 2) { Serial.print(" X2:"); Serial.print(X2); Serial.print(" Y2:"); Serial.print(Y2); Serial.print(" Z2:"); Serial.println(Z2); } //плоттер end**************************************************************************************** myTimer.start(); //Перезапуск таймера } /*if (cnt_UpDownSensor == 1) { //Первый I2C датчик QMC5883 Vector mag = compass1.readRaw();// Читаем значения датчика. При другой библиотеке и датчике заменить //x = mag.XAxis; //y = mag.YAxis; //z = mag.ZAxis; X1 = mag.XAxis; Y1 = mag.YAxis; Z1 = mag.ZAxis; } if (cnt_UpDownSensor == 2) { //Второй I2C датчик QMC5883 Vector mag = compass1.readRaw();// Читаем значения датчика. При другой библиотеке и датчике заменить X2 = mag.XAxis; Y2 = mag.YAxis; Z2 = mag.ZAxis; }*/ sensors_event_t event1; sensors_event_t event2; //if (cnt_UpDownSensor == 1) { //Первый I2C датчик /*compass1.read(); //в Гаусах X1 = compass1.x; Y1 = compass1.y; Z1 = compass1.z;*/ compass1.getEvent(&event1); //в Тесла X1 = event1.magnetic.x; Y1 = event1.magnetic.y; Z1 = event1.magnetic.z; //} //if (cnt_UpDownSensor == 2) { //Второй I2C датчик /*compass2.read(); //в Гаусах X2 = compass2.x; Y2 = compass2.y; Z2 = compass2.z;*/ compass2.getEvent(&event2); //в Тесла X2 = event2.magnetic.x; Y2 = event2.magnetic.y; Z2 = event2.magnetic.z; //} /*Тест для датчика Амперка Serial.print(compass1.readMagneticGaussX()); Serial.print("\t\t"); // Выводим напряженность магнитного поля в Гауссах по оси Y Serial.print(compass1.readMagneticGaussY()); Serial.print("\t\t"); // Выводим напряженность магнитного поля в Гауссах по оси Z Serial.println(compass1.readMagneticGaussZ()); Serial.println("================================================="); */ //***************************************************************************************************** //***************************************************************************************************** //***************************************************************************************************** /* БЛОК МОЙ КОД ЦИКЛЫ ДЕЛАТЬ НЕЛЬЗЯ (крайне не рекомендуется)!!!. СОБЪЕТСЯ ЧАСТОТА ОПРОСА СИГНАЛА и скорость вывода на экран. Чем больше интервал частоты опроса (реже опрашиваем), тем больше мы срезаем ПОМЕХ. (int) Freq_signal = 100 милисекунд. Можете изменить частоту опроса датчиков Здесь пишем алгоритмы обработки сигнала... Когда и при каких условиях срабатывают тригеры... Когда и как срабатывает световая и звуковая сигнализация... (int) TrigerMINz - устанавливается в Меню вручную. Граница срабатывания по оси Z (int) TrigerMAXz - устанавливается в Меню вручную. Граница срабатывания по оси Z Данные с выбранного в Меню датчика реализовано только по оси Z Значение cnt_UpDownSensor == 1 - Первый I2C датчик Значение cnt_UpDownSensor == 2 - Второй I2C датчик В зависимости от cnt_UpDownSensor в x, y, z будут отражены данные от 1го или 2го датчика (int) x - значение 1(2) датчика по X (int) y - значение 1(2) датчика по Y (int) z - значение 1(2) датчика по Z (int) X1, Y1, Z1 - переменные для экспериментов по первому датчику (int) X2, Y2, Z2 - переменные для экспериментов по второму датчику (int) MIN, MAX - переменные для экспериментов по первому датчику установленные программно (int) MIN2, MAX2 - переменные для экспериментов по второму датчику установленные программно (int) Algoritm - переключатель алгоритма обработки значений датчика (int) LED - Адрес светодиода 15 (D15) (int) BUZZER_PIN - Адрес зумера 2 (D2) (int) Raznica = 0; (int) Porog = 0; (int) Param1 = 0; (float) Param2 = 0.0; Алгоритм работы с двумя датчиками Dat1 - показания первого датчика после усреднения. Dat2 - показания второго датчика после усреднения. Porog - порог срабатывания (настраивается кнопками на плате). Raznica - разница между показаниями двух датчиков. Прибор срабатывает (подает звуковой сигнал) если Raznica по модулю (без учета знака +-) >= Porog. if (abs(Dat1 - Dat2) >= Porog) { даем сигнал на динамик } Усреднение данных - Экспоненциальное бегущее среднее float k = 0.1; // коэффициент фильтрации, 0.0-1.0 // бегущее среднее float expRunningAverage(float newVal) { static float filVal = 0; filVal += (newVal - filVal) * k; return filVal; } "Сила" фильтра настраивается коэффициентом (0.0 – 1.0). Чем он меньше, тем плавнее фильтр В ДРУГОЙ КОД НЕ ЛЕЗЕМ!!! Внутри БЛОКА все что угодно. Делаем копию БЛОКА! */ //Отладка. Выводим в монитор последовательного порта. Мешает выводу в плоттер. После отладки закоментировать*** //Serial.printf("X1 = %6d, Y1 = %6d, Z1 = %6d\n",X1, Y1, Z1); //Serial.printf("X2 = %6d, Y2 = %6d, Z2 = %6d\n",X2, Y2, Z2); //Serial.printf("MIN = %6d, MAX = %6d\n", MIN, MAX); //Serial.printf("MIN2 = %6d, MAX2 = %6d\n", MIN2, MAX2); //Монитор end*************************************************************************************************** //Алгоритм 1. Обрабатывает данные минимального и максимального значения датчика по оси Z //включает/выключает синий светодиод (минимум), краный светодиод (максимум) и зуммер if (Algoritm == 1) { if (Z1 < TrigerMINz) { digitalWrite(LED, HIGH); if (Buzzer == 1) { //tone(BUZZER_PIN, NOTE_C4, 5, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_D4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_E4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_F4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_G4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_A4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); tone(BUZZER_PIN, NOTE_B4, 10, BUZZER_CHANNEL); noTone(BUZZER_PIN, BUZZER_CHANNEL); } else noTone(BUZZER_PIN, BUZZER_CHANNEL); } else digitalWrite(LED, LOW); if (Z1 > TrigerMAXz) { digitalWrite(19, HIGH); if (Buzzer == 1) { tone(BUZZER_PIN, NOTE_C4, 10, BUZZER_CHANNEL); noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_D4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_E4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_F4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_G4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_A4, 500, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); //tone(BUZZER_PIN, NOTE_B4, 5, BUZZER_CHANNEL); //noTone(BUZZER_PIN, BUZZER_CHANNEL); } else noTone(BUZZER_PIN, BUZZER_CHANNEL); } else digitalWrite(19, LOW); } //Алгоритм 2. Здесь исходный код Заказчика. Основаный на примере Алгоритм 1. //включает/выключает ... if (abs(Dat1 - Dat2) >= Porog) { даем сигнал на динамик } if (Algoritm == 2) { Raznica = 1; Porog = 2; Param1 = 3; Param2 = 4.0; if (Porog > TrigerMAXz) { digitalWrite(19, HIGH); } else digitalWrite(19, LOW); if (Porog > TrigerMAXz) { digitalWrite(LED, HIGH); } else digitalWrite(19, LOW); } /* Конец блока МОЙ КОД******************************************************************************** В ДРУГОЙ КОД ВНЕ БЛОКА НЕ ЛЕЗЕМ!!! */ //***************************************************************************************************** //***************************************************************************************************** //***************************************************************************************************** }//Конец цикла LoopНу, хоть маленькое описание-то надо!
Чего измеряем, в каких попугаях, в каком диапазоне, с какой точностью? Ну, чего ж ничего-то нет?
//if (cnt_UpDownSensor == 1) { //Первый I2C датчик 635 /*compass1.read(); //в Гаусах compass1.getEvent(&event1); //в Тесла //if (cnt_UpDownSensor == 2) { //Второй I2C датчик 645 /*compass2.read(); //в Гаусах compass2.getEvent(&event2); //в Тесла /*Тест для датчика Амперка 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 */Ну, я же говорю, нужна какая-никакая документация. Даже если юзер и будет рыться по Вашим кодам, чтобы что-то там узнать из комментариев, там у Вас много нет. Например, какова погрешность? Какова чувствительность? Предельные диапазоны измеряемой величины? Как правильно пользоваться? Вот посмотрите, например, вот в этом проекте. Есть два документа в формате PDF: инструкция и схема.
Ну, я же говорю, нужна какая-никакая документация. Даже если юзер и будет рыться по Вашим кодам, чтобы что-то там узнать из комментариев, там у Вас много нет. Например, какова погрешность? Какова чувствительность? Предельные диапазоны измеряемой величины? Как правильно пользоваться? Вот посмотрите, например, вот в этом проекте. Есть два документа в формате PDF: инструкция и схема.
Ну не знает большинство людей, что такое ДОМАШНИЙ МАГНИТОМЕТР. Я не знаю что такое и не домашний.
Скачал ваш архив, думал там будет написано для чего может быть использован. Какие возможны сценарии и с какой точностью.
Но не нашел.
Дополнено позже. Может быть я не прав и для тех, кто в теме, информации достаточно.
Ну не знает большинство людей, что такое ДОМАШНИЙ МАГНИТОМЕТР. Я не знаю что такое и не домашний.
Скачал ваш архив, думал там будет написано для чего может быть использован. Какие возможны сценарии и с какой точностью.
Но не нашел.
Дополнено позже. Может быть я не прав и для тех, кто в теме, информации достаточно.
IMU-сенсор 10-DOF v2: инструкция, схемы и примеры использования [Амперка / Вики] (amperka.ru)
Насколько я понимаю правильно, сам плохо ориентируюсь в магнетизме земли. Специальный датчик, он же датчик магнитного компаса (могу не правильно излагать термины) измеряет напряженность магнитного поля, определить направление Севера, наклон датчика например относительно горизонта... Программа, это просто оболочка-врапер дающая возможность считать какое то значение датчика по осям Х, Y, Z. Удобно визуализировать в виде бегущих графиков на дисплее значения измерений. Отображает значения в виде цифр. Есть возможность переключать и отображать на дисплее оси координат. Переключать экраны для графиков датчиков. Есть меню и возможность устанавливать пороги срабатывания по MAX и MIN значений. Для того что бы не лезть в код. Есть программный блок, где можно писать свои обработчики полученных данных от датчиков. В программе он специально выделен комментариями. Где использовать? Ну например на пляже в песке забытые монеты и тому подобное на глубине не более 10 см :) Профессиональные комлексы с другими принципами, ищут подводные лодки на глубина в 100 метры. Характеристики ищут в специальных документах на датчики. Даташит.
Есть такая штука уже модулем... Работает без ардуины. Напрямую с Nextion, например: https://youtube.com/shorts/0nEAC3PHouc