Коэффициент мощности - детектор с нулевым пересечением

Тед
Пн 18 июня 2018 г., 21:14
Этот код работает нормально при условии, что амплитуда сигнала составляет 3.3V, который составляет 1/2 смещения напряжения на PA7.
Это устраняет два операционных усилителя.
Как сделать этот код для работы для любой амплитуды сигнала, WCHICH является целью нулевого детектора пересечения ?
Другие слова, как получить импульс при амплитуде 1/2 приспособленного сигнала ?
//unsigned long time; const int buttonPin = PA7; void setup() { pinMode(PB1, OUTPUT); pinMode(buttonPin, INPUT_PULLDOWN); //pinMode(buttonPin, INPUT_PULLUP); } void loop() { if (digitalRead(buttonPin) == HIGH) { while (digitalRead(buttonPin) == HIGH) { } digitalWrite(PB1, HIGH); //delay micros(50); delayMicroseconds(100); //delay(1000); digitalWrite(PB1, LOW); delayMicroseconds(100); } }

Fredbox
Пн 18 июня 2018 г., 22:23
Это скорее аппаратная проблема. Я не верю, что LM358 предназначен для работы в качестве компаратора так, как он связан. Вам нужны резисторы на входах, чтобы установить напряжение примерно на половину вашего источника питания. Вам также нужно устройство, предназначенное для работы 3.3В. Если бы я это делал, я бы, вероятно, использовал оптокуплер вместо opamps. На ум приходит H11AA1, но есть много других. Видеть http: // www.Bristolwatch.com/ele2/Zero_crossing.htm

Тед
Пн 18 июня 2018 г. 11:07 вечера
Идея: заменить оборудование на программное обеспечение

Пито
Вт 19 июня 2018 г., 7:47 утра
Вы должны сдвинуть уровень входного напряжения, такой его «ноль» будет вписаться где -то в диапазон АЦП.

«Ноль пересечение» означает, что вы получаете от положительного до отрицательного (или наоборот), где «негатив» означает отрицательный против «земли».

У вас нет аппаратного обеспечения в STM32, которое может работать с негативными напряжениями против земли.

Тед
Вт 19 июня 2018 12:58
Вы имеете в виду - измените предвзятость на PA7 ?
Это будет работать только для другой фиксированной амплитуды, поэтому детектор все еще зависит от амплитуды.
Я могу добавить вольтметр к коду, который будет измерить амплитуду, тогда я узнаю значение 1/2, Wchich дает точку запуска.
Я знаю, как добавить счетчик, но не знаю, как вводить точку инициирования наполнения.
Или используйте пиковый детектор в качестве точки запуска ?

Хейсан
Вт 19 июня 2018 г. 14:26
Что именно вы пытаетесь измерить? Большинство сигналов, на которые вы хотели бы измерить коэффициент мощности, будут опасны для непосредственного соединения наземной ссылки. Не берите в голову трудности сдвигания и масштабирования сигналов.

Простые опто изолированные схемы показывают выше, должно работать очень хорошо в большинстве реальных ситуаций.

Хейсан
Вт 19 июня 2018 г. 14:47
Речь идет о самом простом «уровне смены», о котором я могу подумать.
Screenshot_2018-06-19_16-39-29.png
Screenshot_2018-06-19_16-39-29.PNG (10.74 киб) просмотрено 818 раз

Хейсан
Вт 19 июня 2018 г. 15:04
Я солгал, это самое простое, но, очевидно, может работать, только если ввод изолирован от подачи Arduino...
Screenshot_2018-06-19_17-03-28.png
Screenshot_2018-06-19_17-03-28.PNG (7.03 киб) просмотрено 812 раз

Тед
Вт 19 июня 2018 г. 15:26
Спасибо, Хейсан
Я знаю, что проблема в модификации кода не в электронике.

Дэнниф
Вторник 19 июня 2018 г. 18:48
Самая простая схема ZC будет состоять из одного резистора.

В большинстве случаев, однако, резистор плюс Zener выполнит работу.

Тед
Ср 20 июня 2018 г. 12:02
Теперь я пытаюсь объединить две программы, это то, что я сделал, и оригинал второй программы, по какой -то причине у меня нет ответа на PB1, чтобы сигнализировать о применении к PA7.
Может ли кто -нибудь помочь мне найти ошибку ? const int sampleWindow = 250; // Sample window width in mS (250 mS = 4Hz) unsigned int knock; //int ledPin = 13; ///////////////////// int ledPin = PB1; ///////////////////// void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); } void loop() { unsigned long start= millis(); // Start of sample window unsigned int peakToPeak = 0; // peak-to-peak level unsigned int signalMax = 0; unsigned int signalMin = 1024; // collect data for 250 miliseconds while (millis() - start < sampleWindow) { ////////////////////////////////// // knock = analogRead(0); knock = analogRead(PA7); ///////////////////// if (knock < 1024) //This is the max of the 10-bit ADC so this loop will include all readings { if (knock > signalMax) { signalMax = knock; // save just the max levels } else if (knock < signalMin) { signalMin = knock; // save just the min levels } } } peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude double volts = (peakToPeak * 3.3) / 1024; // convert to volts Serial.println(volts); if (volts >=1.0) { //turn on LED digitalWrite(ledPin, HIGH); delay(500); Serial.println("Knock Knock"); } else { //turn LED off digitalWrite(ledPin, LOW); } }

Хейсан
Ср 20 июня 2018 г. 15:09
Аналигер возвращает число 0..4095 (12 бит).

Замените все случаи «1024» на «4096», и это может работать?

Тед
Чт 21 июня 2018 г., 2:23
Я сделал таким образом = это детектор амплитуды синуса, а не детектор по пересечению синуса //Replace every occurrence of '1024' with '4096' and it may work? //http://stm32duino.com/viewtopic.php?f=19&t=3778&start=10 const int sampleWindow = 250; // Sample window width in mS (250 mS = 4Hz) unsigned int knock; //int ledPin = 13; ///////////////////// int ledPin = PB1; int analog = PA7; ///////////////////// void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); } void loop() { unsigned long start= millis(); // Start of sample window unsigned int peakToPeak = 0; // peak-to-peak level unsigned int signalMax = 0; unsigned int signalMin = 1024; // collect data for 250 miliseconds while (millis() - start < sampleWindow) { ////////////////////////////////// // knock = analogRead(0); knock = analogRead(PA7); ///////////////////// // if (knock < 1024) //This is the max of the 10-bit ADC so this loop will include all readings if (knock < 4096) //This is the max of the 10-bit ADC so this loop will include all readings { if (knock > signalMax) { signalMax = knock; // save just the max levels } else if (knock < signalMin) { signalMin = knock; // save just the min levels } } } peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude // double volts = (peakToPeak * 3.3) / 1024; // convert to volts double volts = (peakToPeak * 3.3) / 4096; // convert to volts Serial.println(volts); if (volts >=1.0) { //turn on LED digitalWrite(ledPin, HIGH); delay(5); Serial.println("Knock Knock"); } else { //turn LED off digitalWrite(ledPin, LOW); } }

Rogerclark
Sun 24 июня 2018 г., 21:46
Это’все были сделаны раньше

Просто найдите проект открытой энергии

Aka emonlib

Отлично работает на STM32, у меня есть хотя бы несколько человек, использующих доски, которые я построил, которые контролируют мощность, коэффициент мощности и т. Д

Тед
Пн 25 июня 2018 г., 19:24
Я искал, все время сигнал преобразуется в прямоугольники перед входом в микроконтроллер. Пожалуйста, посмотрите на мой второй пост, я пытаюсь исключить OP AMP LM358, как показано в первом посте.

Стивестронг
Ср 27 июня 2018 12:40
Я бы использовал библиотеку STM32ADC, в которой у вас есть возможность установить пороговый уровень для наблюдения за тем, чтобы запустить прерывание, когда уровень аналогового сигнала входного сигнала выходит за рамки этого значения.

Тед
Ср 27 июня 2018 12:53
Спасибо, что указали на это, теперь я должен найти примеры, как это сделано.