Чтение данных с датчика MIS-3600-006DI

Согласен, почти как настоящая :slight_smile:
Как минимум вполне годится как заготовка для допиливания.

Тут другой вопрос - библиотеки под этот датчик нет не потому, что ее сложно написать, а потому что она нафик никому не нужна. Датчик по описанию мне показался кривым глючным барахлом.

ЗЫ Интересно, куда @127486 пропал?

Да я вообще не об этом.

Ты код то посмотри. Я не просил его настраивать таймер на этапе компиляции. Он сам это придумал.

Т.е. они начинают генерировать идеи. Это пугает.

Ну так не надо размещать сообщения на форуме, и никто не будет тратить на Вас свое время.
Если Вы размещаете просьбу о помощи на форуме, то сам этот факт предполагает от Вас выражения благодарности тем, кто хотя бы прочитает, а не указаний, что кому следует делать.

Вот в этом и есть различие между нейронными сетями и “программой”.

он не писал её, надо просто найти откуда он её выдрал, писал её человек

кстати, ты проверял на нано? у меня не компилируется, но так как я совсем никакой не знаток в С разобраться выше моих сил, но вот такая настройка таймера, это ужос-ужасов (// Toggle OC2A on compare match, CTC mode), я же писал где-то выше, что только с пятого моего пинка когда заставил сделать так как заставил он выдал правильный код настройки таймера

Под miniCore скомпилировалось, на удивление дрожания фазы нет, но по частоте несколько не то:

PS поправил флаги комптляции на -std=gnu++17 и под нано тоже, но это же полукостыль, надо бы как-то в библиотеке заставить компилятор это делать?

CTC:

FAST PWM:

Ну, как я смог понять - алгоритм есть в любом случае.
Если он универсальный - не значит что его нет совсем.
@ЕвгенийП даже его определил:

Возможно, я опять чего-то не понял

Да пробовал. Я под PlatformIO компилирую. Там наоборот - для AVR сразу по дефолту стоит gnu++17, а для ESP32 пришлось руками указать т.к. там по умолчанию gnu++11.
Он же мне ещё 4 примера накатал, не стал просто размещать, чтобы форум не засорять.

Спойлер
/**
    Пример использования библиотеки MIS3600 с MCLK

    Подключение датчика:
    - VDD -> 3.3V или 5V
    - GND -> GND
    - SDA -> A4 (Arduino Uno) или 21 (ESP32) или custom
    - SCL -> A5 (Arduino Uno) или 22 (ESP32) или custom
    - CS -> VDD (адрес 0x77) или GND (адрес 0x76)
    - MCLK -> 11 (Arduino Uno) или 25 (ESP32) или custom

    Не забудьте подключить pull-up резисторы 10кОм на линии SDA и SCL!
*/

#include <Wire.h>
#include <MIS3600.h>

// ============ НАСТРОЙКИ ДЛЯ РАЗНЫХ ПЛАТФОРМ ============

#if defined(ARDUINO_ARCH_ESP32)
// ESP32 - можно использовать любые пины
const int MCLK_PIN = 25;  // Пин для MCLK
const int SDA_PIN = 21;   // Пин SDA
const int SCL_PIN = 22;   // Пин SCL

// Создание объекта датчика для ESP32
MIS3600 sensor (MIS3600_15PSI, MIS3600_I2C_ADDR_CS_HIGH,
                MCLK_PIN, SDA_PIN, SCL_PIN);
#else
// AVR (Arduino Uno/Mega) - пины фиксированы аппаратно
// MCLK: Pin 11 (Arduino Uno), Pin 10 (Arduino Mega)
// SDA/SCL: стандартные пины I2C

// Создание объекта датчика для AVR
MIS3600 sensor (MIS3600_15PSI, MIS3600_I2C_ADDR_CS_HIGH);
#endif

// Переменные для вывода данных
unsigned long lastReadTime = 0;
const unsigned long readInterval = 1000; // Интервал чтения (мс)

void setup()
{
	// Инициализация Serial
	Serial.begin (115200);

	while (!Serial)
	{
		; // Ожидание подключения Serial
	}

	Serial.println (F ("================================="));
	Serial.println (F ("  MIS3600 Sensor with MCLK Test "));
	Serial.println (F ("================================="));
	Serial.println();

	// Инициализация датчика с включенным MCLK
	Serial.print (F ("Инициализация датчика... "));

	if (!sensor.begin (&Wire, true))   // true = включить MCLK
	{
		Serial.println (F ("ОШИБКА!"));
		Serial.println (F ("Проверьте подключение датчика:"));
		Serial.println (F ("- Правильность I2C адреса"));
		Serial.println (F ("- Подключение SDA/SCL"));
		Serial.println (F ("- Подключение MCLK"));
		Serial.println (F ("- Наличие pull-up резисторов"));
		Serial.println (F ("- Питание датчика"));

		while (1)
			delay (1000);
	}

	Serial.println (F ("OK!"));
	Serial.println();

	// Вывод информации о MCLK
	sensor.printMCLKInfo();
	Serial.println();

	// Проверка погрешности MCLK
	float error = sensor.getMCLKError();

	if (abs (error) > 1.0)
	{
		Serial.println (F ("⚠ ВНИМАНИЕ: Погрешность MCLK превышает 1%!"));
		Serial.println (F ("Это может повлиять на точность измерений."));
		Serial.println();
	}

	// Вывод калибровочных коэффициентов
	sensor.printCalibrationData();
	Serial.println();

	// Опционально: выполнить обнуление
	Serial.print (F ("Выполнение процедуры обнуления... "));

	if (sensor.performZeroing())
		Serial.println (F ("OK!"));

	else
		Serial.println (F ("ОШИБКА!"));

	Serial.println();

	// Заголовки таблицы
	Serial.println (F ("Время(мс)\tТемпература(°C)\tДавление(PSI)\tОтносит.Давление(PSI)"));
	Serial.println (F ("------------------------------------------------------------------------"));
}

void loop()
{
	unsigned long currentTime = millis();

	// Чтение с заданным интервалом
	if (currentTime - lastReadTime >= readInterval)
	{
		lastReadTime = currentTime;

		// Выполнение измерения
		if (sensor.measure())
		{
			// Получение данных
			float temperature = sensor.getTemperature();
			float pressure = sensor.getPressure();
			float relativePressure = sensor.getRelativePressure();

			// Вывод данных
			Serial.print (currentTime);
			Serial.print (F ("\t\t"));
			Serial.print (temperature, 2);
			Serial.print (F ("\t\t"));
			Serial.print (pressure, 4);
			Serial.print (F ("\t\t"));
			Serial.println (relativePressure, 4);
		}
		else
			Serial.println (F ("Ошибка чтения данных!"));
	}
}

Спойлер
/**
    Пример работы с двумя датчиками MIS-3600 одновременно
    с генерацией MCLK

    ESP32: Каждый датчик может иметь свой MCLK
    AVR: Только один датчик может использовать аппаратный MCLK
*/

#include <Wire.h>
#include <MIS3600.h>

#if defined(ARDUINO_ARCH_ESP32)
	// ESP32 - два датчика с разными MCLK
	MIS3600 sensor1 (MIS3600_15PSI, 0x77, 25, 21, 22); // MCLK на GPIO25
	MIS3600 sensor2 (MIS3600_15PSI, 0x76, 26, 21, 22); // MCLK на GPIO26
	#define DUAL_MCLK
#else
	// AVR - только один датчик с MCLK, второй без него
	MIS3600 sensor1 (MIS3600_15PSI, 0x77, 11); // С MCLK
	MIS3600 sensor2 (MIS3600_15PSI, 0x76, -1); // Без MCLK (если датчик имеет внутренний генератор)
#endif

void setup()
{
	Serial.begin (115200);

	while (!Serial);

	Serial.println (F ("=== Dual MIS3600 Sensor Test ==="));
	Serial.println();

	// Инициализация первого датчика
	Serial.print (F ("Sensor 1 (0x77)... "));

	if (!sensor1.begin (&Wire, true))
	{
		Serial.println (F ("FAILED!"));

		while (1);
	}

	Serial.println (F ("OK"));

	// Инициализация второго датчика
	Serial.print (F ("Sensor 2 (0x76)... "));
	#if defined(DUAL_MCLK)

	if (!sensor2.begin (&Wire, true))   // С MCLK
	{
	#else

	if (!sensor2.begin (&Wire, false))   // Без MCLK для AVR
	{
	#endif
		Serial.println (F ("FAILED!"));

		while (1);
	}

	Serial.println (F ("OK"));
	Serial.println();

	// Информация о MCLK для датчика 1
	Serial.println (F ("--- Sensor 1 MCLK Info ---"));
	sensor1.printMCLKInfo();
	Serial.println();

	// Информация о MCLK для датчика 2
	#if defined(DUAL_MCLK)
	Serial.println (F ("--- Sensor 2 MCLK Info ---"));
	sensor2.printMCLKInfo();
	Serial.println();
	#else
	Serial.println (F ("Sensor 2: MCLK disabled"));
	Serial.println();
	#endif

	// Обнуление обоих датчиков
	sensor1.performZeroing();
	sensor2.performZeroing();

	Serial.println (F ("Time\tS1_Temp\tS1_Press\tS2_Temp\tS2_Press"));
	Serial.println (F ("--------------------------------------------------------"));
}

void loop()
{
	if (sensor1.measure() && sensor2.measure())
	{
		Serial.print (millis());
		Serial.print (F ("\t"));
		Serial.print (sensor1.getTemperature(), 1);
		Serial.print (F ("\t"));
		Serial.print (sensor1.getPressure(), 3);
		Serial.print (F ("\t\t"));
		Serial.print (sensor2.getTemperature(), 1);
		Serial.print (F ("\t"));
		Serial.println (sensor2.getPressure(), 3);
	}

	delay (1000);
}

Спойлер
/**
    Пример работы в режиме низкого энергопотребления
    MCLK включается только во время измерения
*/

#include <Wire.h>
#include <MIS3600.h>

#if defined(ARDUINO_ARCH_ESP32)
	MIS3600 sensor (MIS3600_15PSI, MIS3600_I2C_ADDR_CS_HIGH, 25, 21, 22);
#else
	MIS3600 sensor (MIS3600_15PSI);
#endif

void setup()
{
	Serial.begin (115200);

	while (!Serial);

	Serial.println (F ("=== Low Power Mode Example ==="));
	Serial.println (F ("MCLK включается только во время измерений"));
	Serial.println();

	// Инициализация БЕЗ автоматического запуска MCLK
	if (!sensor.begin (&Wire, false))   // false = не запускать MCLK
	{
		Serial.println (F ("Ошибка инициализации!"));

		while (1);
	}

	Serial.println (F ("Датчик инициализирован"));
	Serial.println (F ("MCLK выключен для экономии энергии"));
	Serial.println();
}

void loop()
{
	Serial.println (F ("--- Начало измерения ---"));

	// Включаем MCLK перед измерением
	Serial.print (F ("Запуск MCLK... "));

	if (sensor.startMCLK())
		Serial.println (F ("OK"));

	else
	{
		Serial.println (F ("ОШИБКА!"));
		delay (5000);
		return;
	}

	// Даем время на стабилизацию (минимум 10мс)
	delay (50);

	// Выполняем измерение
	Serial.print (F ("Измерение... "));

	if (sensor.measure())
	{
		Serial.println (F ("OK"));

		float temp = sensor.getTemperature();
		float press = sensor.getPressure();

		Serial.print (F ("Температура: "));
		Serial.print (temp, 2);
		Serial.println (F (" °C"));

		Serial.print (F ("Давление: "));
		Serial.print (press, 4);
		Serial.println (F (" PSI"));
	}
	else
		Serial.println (F ("ОШИБКА!"));

	// Выключаем MCLK для экономии энергии
	Serial.print (F ("Остановка MCLK... "));
	sensor.stopMCLK();
	Serial.println (F ("OK"));

	Serial.println (F ("--- Конец измерения ---"));
	Serial.println();

	// Пауза между измерениями (в это время MCLK выключен)
	delay (5000);
}

Спойлер
/**
    Диагностика MCLK
    Показывает детальную информацию о генерации тактовой частоты
*/

#include <Wire.h>
#include <MIS3600.h>

#if defined(ARDUINO_ARCH_ESP32)
	MIS3600 sensor (MIS3600_15PSI, MIS3600_I2C_ADDR_CS_HIGH, 25, 21, 22);
#else
	MIS3600 sensor (MIS3600_15PSI);
#endif

void setup()
{
	Serial.begin (115200);

	while (!Serial);

	Serial.println (F ("========================================"));
	Serial.println (F ("     MIS3600 MCLK Diagnostics Tool     "));
	Serial.println (F ("========================================"));
	Serial.println();

	// Компиляционная информация
	Serial.println (F ("=== Compile-Time Information ==="));

	#if defined(ARDUINO_ARCH_ESP32)
	Serial.println (F ("Platform: ESP32"));
	Serial.println (F ("MCLK Method: LEDC PWM"));
	#elif defined(__AVR__)
	Serial.println (F ("Platform: AVR"));
	Serial.println (F ("MCLK Method: Hardware Timer2"));

	Serial.print (F ("F_CPU: "));
	Serial.print (F_CPU);
	Serial.println (F (" Hz"));

	Serial.print (F ("Calculated Prescaler: "));
	Serial.println (MIS3600_TimerCalc::getPrescalerValue (
	                    MIS3600_TimerCalc::calculateAVRPrescaler()));

	Serial.print (F ("Calculated OCR2A: "));
	Serial.println (MIS3600_TimerCalc::calculateAVROCR());

	Serial.print (F ("Expected Frequency: "));
	Serial.print (MIS3600_TimerCalc::calculateActualFreq());
	Serial.println (F (" Hz"));

	Serial.print (F ("Expected Error: "));
	Serial.print (MIS3600_TimerCalc::calculateError(), 6);
	Serial.println (F (" %"));
	#endif

	Serial.println();

	// Инициализация датчика БЕЗ MCLK
	Serial.println (F ("=== Sensor Initialization ==="));
	Serial.print (F ("Initializing sensor... "));

	if (!sensor.begin (&Wire, false))
	{
		Serial.println (F ("FAILED!"));
		Serial.println (F ("Cannot communicate with sensor"));

		while (1) delay (1000);
	}

	Serial.println (F ("OK"));
	Serial.println();

	// Тест MCLK
	Serial.println (F ("=== MCLK Test ==="));

	Serial.print (F ("Starting MCLK... "));

	if (sensor.startMCLK())
		Serial.println (F ("OK"));

	else
	{
		Serial.println (F ("FAILED!"));

		while (1) delay (1000);
	}

	delay (100); // Стабилизация

	// Вывод информации о MCLK
	sensor.printMCLKInfo();
	Serial.println();

	// Проверка точности
	Serial.println (F ("=== Frequency Accuracy Check ==="));
	float error = sensor.getMCLKError();

	Serial.print (F ("Frequency error: "));
	Serial.print (error, 6);
	Serial.println (F (" %"));

	if (abs (error) < 0.1)
		Serial.println (F ("✓ Отлично! Погрешность < 0.1%"));

	else
		if (abs (error) < 0.5)
			Serial.println (F ("✓ Хорошо! Погрешность < 0.5%"));

		else
			if (abs (error) < 1.0)
				Serial.println (F ("⚠ Приемлемо. Погрешность < 1%"));

			else
				Serial.println (F ("✗ Высокая погрешность! Может повлиять на точность."));

	Serial.println();

	// Тест измерений с MCLK
	Serial.println (F ("=== Measurement Test (with MCLK) ==="));

	delay (50); // Стабилизация перед измерением

	for (int i = 0; i < 5; i++)
	{
		Serial.print (F ("Test "));
		Serial.print (i + 1);
		Serial.print (F (": "));

		if (sensor.measure())
		{
			Serial.print (F ("Temp="));
			Serial.print (sensor.getTemperature(), 2);
			Serial.print (F ("°C, Press="));
			Serial.print (sensor.getPressure(), 4);
			Serial.println (F (" PSI"));
		}
		else
			Serial.println (F ("FAILED"));

		delay (500);
	}

	Serial.println();

	// Тест остановки MCLK
	Serial.println (F ("=== MCLK Stop Test ==="));
	Serial.print (F ("Stopping MCLK... "));
	sensor.stopMCLK();
	Serial.println (F ("OK"));

	Serial.print (F ("MCLK Status: "));
	Serial.println (sensor.isMCLKRunning() ? F ("Running") : F ("Stopped"));

	Serial.println();
	Serial.println (F ("=== Diagnostics Complete ==="));
}

void loop()
{
	// Интерактивное меню
	if (Serial.available())
	{
		char cmd = Serial.read();

		switch (cmd)
		{
			case '1':
				Serial.println (F ("\nStarting MCLK..."));

				if (sensor.startMCLK())
					Serial.println (F ("MCLK started"));

				else
					Serial.println (F ("Failed to start MCLK"));

				break;

			case '2':
				Serial.println (F ("\nStopping MCLK..."));
				sensor.stopMCLK();
				Serial.println (F ("MCLK stopped"));
				break;

			case '3':
				Serial.println();
				sensor.printMCLKInfo();
				break;

			case '4':
				Serial.println (F ("\nPerforming measurement..."));

				if (sensor.measure())
				{
					Serial.print (F ("Temperature: "));
					Serial.print (sensor.getTemperature(), 2);
					Serial.println (F (" °C"));

					Serial.print (F ("Pressure: "));
					Serial.print (sensor.getPressure(), 4);
					Serial.println (F (" PSI"));
				}
				else
					Serial.println (F ("Measurement failed"));

				break;

			case 'h':
			case 'H':
			case '?':
				printHelp();
				break;
		}
	}
}

void printHelp()
{
	Serial.println();
	Serial.println (F ("=== Commands ==="));
	Serial.println (F ("1 - Start MCLK"));
	Serial.println (F ("2 - Stop MCLK"));
	Serial.println (F ("3 - Print MCLK info"));
	Serial.println (F ("4 - Perform measurement"));
	Serial.println (F ("h - Show this help"));
	Serial.println (F ("==============="));
	Serial.println();
}

При движении поршня вверх открываем клапан подачи топлива.
Вблизи НМТ закрываем его.
Вблизи ВМТ подаем напряжение на свечу.
И так для всех цилиндров.

Вы правда думаете, что это можно считать алгоритмом “Как из Астрахани проехать в Барнаул”?

Чтобы было понятнее: поведение НС зависит не от алгоритма работы нейронов, а от весовых коэффициентов, настроенных в результате обучения.

Спасибо за ответ. Не за ради спора, а только чтобы разобраться вынужден тогда уж спросить: а эти весовые коэффициенты настраиваются с помощью некоего алгоритма?
Ведь система может быть и сложной . Алгоритм может быть не один, а совокупность разных.

а ты заметил, что там 2024 год? )))
У кого-то эта библиотека на гитхабе висит, но закрытая, он умеет вытаскивать из нерасшаренных библиотек

Так получается он умеет лучше, чем я. Это тоже пугает.

Пора учиться писать правильные промты :worried:

Один только вопрос, какая точно частота MCLK должна быть 32к или 32768?

в ДШ все есть

30000 - 35000 Гц.

32768 → номинальное.

понятно, главное видимо стабильность частоты

думаю что никаких супер требований к стабильности там нет. Обычный АЦП

@Ljubitel
А Вы как Claude пользуете - через инет или у вас системе какой-то агент стоит? Например расширение в Платформио?

Чат в браузере. Он позволяет загружать на разбор не только текст, но и картинки и pdf.

От нас, я знаю, недоступен. Через ВПН работает? Или вы “там” живете?

дипсик остановился на этой частоте, режим CTC но сгенерировал сразу на 9 пин, так не затрагивается миллис()