Тогда ловить переход через ноль обычным пином по прерыванию, измерить величину через 5 мс(при 50Гц это как раз максимум).
Программа вот. Загрузил в stm32f411cc BlackPill.
Спойлер
//#include <Arduino.h>
#define ADC_PIN PA0
#define LED_PIN PC13
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
delay(2000);
// Заголовок таблицы
Serial.println("t1 (ms)\tu1 (ADC)\tt2 (ms)\tu2 (ADC)\ti");
Serial.println("-------------------------------------------------------------");
}
void loop() {
static uint32_t lastBlinkTime = 0;
// Мигание светодиодом 1 Гц
if (millis() - lastBlinkTime >= 1000) {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
lastBlinkTime = millis();
unsigned long t1 = millis();
int u1 = analogRead(A0);
// Задержка между измерениями
delay(5);
unsigned long t2 = millis();
int u2 = analogRead(A0);
// Перевод времени в секунды
float T1 = t1 / 1000.0;
float T2 = t2 / 1000.0;
// Расчёт знаменателя
float denominator = sin(100 * PI * T2) - sin(100 * PI * T1);
float i = 0.0;
if (abs(denominator) > 1e-6) { // Защита от деления на ноль
i = (u2 - u1) / denominator;
} else {
i = NAN; // Если деление невозможно — выводим NaN
}
// Вывод данных в виде таблицы
Serial.print(t1);
Serial.print("\t");
Serial.print(u1);
Serial.print("\t\t");
Serial.print(t2);
Serial.print("\t");
Serial.print(u2);
Serial.print("\t\t");
if (isnan(i)) {
Serial.println("NaN");
} else {
Serial.println(i, 4); // 4 знака после запятой
}
}
}
Сигнал 50 Гц, 1 вольт, смещение 1.7 вольта. Задержка 5 мс. Вывод только картинкой. Не знаю как из сериал монитора буквами скопировать. Не получается.
Вывод картинкой.
Не измеряет. Может я что то не так напрограммировал. Нормально получаем значения только с синхронизацией и сдвигом но 90 градусов и задержкой 10 мс. Но там синусы единица и можно обойтись (U2-U1)/2.
146%
Долго думал. Пришёл к выводу что это так не работает. Моменты времени t1 и t2 не могут быть произвольными. Они должны быть привязаны к нулевой фазе синусоиды и соответственно подставление в формулу случайных значений даст на выходе случайное значение. Что мы и имеем.
Отнюдь. Они должны быть относительно друг друга привязаны. Тебе ж сказали. Главное точно выдерживать время между t1 и t2. В чём я не доверяю Millis.
К тому же возможны всякие помехи, схема входа та же?
Вы, похоже, совсем не читаете, что я пишу.
Я же писал выше, что к переходу через постоянную составляющую должен быть привязан только один момент времени – самый первый отсчёт и только он. В этот момент время надо считать нулём (т.к. sin(0) == 0). В дальнейшем точки t1, t2 и т.д. могут быть любыми. Даже интервалы между ними не обязаны быть равными (лишь на не кратны полупериоду). При это считать надо всегда по двум последним точкам. И всё будет нормально.
Если частота там стабильна 50Гц, то это может работать часами, больше ничего и не надо. Если же частота будет уплывать, то периодически надо согласовывать (снова с нуля начинать).
Моё предложение сделать пример в протеусе (там частота стабильна) остаётся в силе.
Я сам Вас попрошу. Мне интересно.
Мне казалось что зная две точки и частоту можно построить единственную синусоиду.
Читиать то я читаю, вот только
Как сделать первое измерение при нулевой фазе? Программа начинает работать независимо от синусоиды. Фаза случайна. Без датчика пересечения нуля не обойтись. Но тут начинаются чудеса с косинусом фи. Мы измеряем ток, а датчики нулевой фазы обычно работают на напряжении.
Так ведь…
Я правильно понимаю что нужно регистрировать перекос фаз? К чему тогда синусоиды и прочие ругательства?
Перед самым первым “значимым” измерением дождаться, чтобы напряжение на пине было равно постоянной составляющей, которую мы, обычно, знаем их схемотехники (чаще всего – это половина питания).
А вот здесь, похоже, мы о разном говорим. Я говорю о том, что на пин приходит некое переменное напряжение и нужно измерить его амплитуду. Всё, больше я ничего не говорю. Если это не то, о чём Вы думали, то простите, значит я не о том всё время писал.
Чисто теоретические измышления. Использованная ТС библиотека точно измеряет без всяких этих фаз.
@Oserg58321 , значит так. Говори что это за устройство и мы скажем куда надо идти более конкретно.
Так он же уже всё сказал.
Всё дальнейшее – наши умствования.
Нет нет нет! Вы абсолютны правы с учётом всех допущений именно так. Проблему нулевой фазы можно решить по разному. Например просуммировать пару секунд входное напряжение, рассчитать среднее, дождаться этого значения на входе и объявить нулевое время. Дальше все времена отсчитывать от этой точки. Но к сожалению за последние несколько лет я ни разу не видел в сети 50 герц. Обычно меньше. Этого хватит что бы через сутки ошибка измерений стала существенной. Это тоже можно обойти делая калибровку например раз в час.
Ещё одна проблема - наводки. При измерениях часто используют сглаживание что бы избавиться от помех. Снятая одна точка в реальной системе будет иметь большую погрешность из за наводок. Соответственно и расчёт будет с ошибками.
Но в целом для идеальной системы метод рабочий.
Да ну эти лишние вычисления, зачем? Просто переход через ноль и замер через 5мс амплитуды. Всё остальное вычислить легко. И там пофиг 48 или 52Гц, на вершине график практически горизонтален и погрешность будет очень мала.
Есть две точки. Есть напряжение U1 и U2 есть время t1 и t2. Как мне получить амплитуду d ?
Амплитуду можно и по одной точке получить, зная частоту, U1 и t1.
Под рукой бумажки нет, в уме не соображу, в телефоне сложно(отмаз защитан?)
Зная момент точки измерения, вычислить текущий угол фазы. Далее находим значение при 90 градусах.
Сейчас попробую.
Но кстати 0 в любом случае будет 1ой точкой
На графике плохо видно U1=2.7, t1=8.7, U2=2.33, t2=18.9
Посчитал по этой формуле на выходе получилось d=3,01559
Работает.