Фазовый измеритель

Тед
Пн 16 июля 2018 г. 14:52
Привет
Я пытаюсь добавить в программу фазового измерителя (#1) еще одна (#2), которая вычитает два прямоугольных сигнала.
Программа № 2 работает OK, и у меня есть сигнал на PC13, когда добавлена ​​в программу № 1, на PC13 нет сигнала нет сигнала.
Любая идея, что я не прав ?

Программа № 1 #include LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5); int pin = PA6; ////////////////////// int ledPin = PC13; int u1 = PB10; // input U1 - pulses int u2 = PB11; //input U2 - pulses int val = 0; // variable to store the read value ///////////////////// float rads = 57.29577951; // 1 radian = approx 57 deg. //float degree = 360; float degree = 360; float frequency = 50; //float frequency = 10000; float nano = 1 * pow (10, -6); // Multiplication factor to convert nano seconds into seconds // Define floats to contain calculations float pf; float angle; float pf_max = 0; float angle_max = 0; int ctr; void setup() { //////////////////////////////// pinMode(u1, INPUT_PULLDOWN); pinMode(u2, INPUT_PULLDOWN); pinMode(PC13, OUTPUT); //////////////////////////////// pinMode(pin, INPUT); Serial.begin(9600); lcd.begin(16, 2); } void loop() { ////////////////////////// val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin digitalWrite(ledPin, val); // sets the LED to the value ///////////////////////// for (ctr = 0; ctr <= 4; ctr++) // Perform 4 measurements then reset { // 1st line calculates the phase angle in degrees from differentiated time pulse // Function COS uses radians not Degree's hence conversion made by dividing angle / 57.2958 angle = ((((pulseIn(pin, HIGH)) * nano) * degree) * frequency); // pf = cos(angle / rads); if (angle > angle_max) // Test if the angle is maximum angle { angle_max = angle; // If maximum record in variable "angle_max" pf_max = cos(angle_max / rads); // Calc PF from "angle_max" } } if (angle_max > 360) // If the calculation is higher than 360 do following... { angle_max = 0; // assign the 0 to "angle_max" pf_max = 1; // Assign the Unity PF to "pf_max" } if (angle_max == 0) // If the calculation is higher than 360 do following... { angle_max = 0; // assign the 0 to "angle_max" pf_max = 1; // Assign the Unity PF to "pf_max" } Serial.print(angle_max, 2); // Print the result Serial.print(","); Serial.println(pf_max, 2); //lcd.clear(); lcd.setCursor(0, 0); lcd.print("PF="); // lcd.setCursor(4, 0); lcd.print(pf_max);// lcd.print(" "); // lcd.setCursor(0, 1); lcd.print("Ph-Shift="); // lcd.setCursor(10, 1); lcd.print(angle_max); lcd.print(" "); //delay(500); angle = 0; // Reset variables for next test angle_max = 0; }

Стивестронг
Пн 16 июля 2018 г. 15:28
Прокомментируйте строку с функцией pulsein () и проверьте, что происходит...

Тед
Пн 16 июля 2018 г. 16:59
Я отключил эту линию и имею импульсы на PC13, но импульсы ширины не стабильны.
angle = ((((pulseIn(pin, HIGH)) * nano) * degree) * frequency);

Стивестронг
Пн 16 июля 2018 г., 17:15
Сделайте короткую программу для проверки простой функциональности Pulsein (). Я предполагаю, что ваш входной сигнал не в порядке.
Если вам удастся получить стабильную работу этой функции, добавьте дополнительные части в код.

Тед
Пн 16 июля 2018 г., 17:28
Каждая программа работает только хорошо, проблема возникает, когда я их объединяю.

Стивестронг
Пн 16 июля 2018 г., 17:49
Я не вижу никакой программы с одним Пульсином.

Во всяком случае, это может быть своевременным совпадением, что после завершения Pulsein () два контакта PB10 и PB11 являются всегда как идентичные, так и разные, поэтому PC13 всегда будет иметь одинаковое значение и, следовательно, не будет мигать.

Тед
Пн 16 июля 2018 г., 18:38
Программа № 2 производит импульсы 5 мсек.
Фаза PB10 и PB11ARE сдвинулась, поэтому после вычитания импульсы на осциллографе (5 с. длинный )

Пито
Вт 17 июля 2018 г. 6:40
Это работает нормально?? val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin

Тед
Вт 17 июля 2018 г. 7:13 утра
У меня есть: на PB10 "V", на PB11 "I" на PC14 "XOR" Импульсы.
Странно то, что программа № 2 работает только над этими булавками независимо от того, что я даю им.
Если я поставлю программу PA6 и PA7 не работает для этих булавок, но все же работает с PB10, PB11 = RX3, TX3 ?


Изображение

Стивестронг
Вт 17 июля 2018 г. 7:17 утра
int pin = PA6;

Тед
Вт 17 июля 2018 г. 8:45 утра
Pa6 = v, pa7 = i, pc13 = 0

Стивестронг
Вт 17 июля 2018 г. 8:49
Вы смешиваете булавки, в своем опубликованном коде, PINS PB10 и PB11 были «V» и «I», и результат был выведен на PC13.
Я спросил о входном сигнале на переменной «PIN», который был назначен PA6 в вашем коде и который был прочитал Pulsein (). Как выглядит этот сигнал относительно «V» и «I»?

Тед
Вт 17 июля 2018 г. 9:12
PA6 принадлежит к фазовому метру, который совпадал, когда я показываю пример, поэтому имя может быть PB8 и PB9, а на PC13 нет импульсов, когда я применяю сигналы к этим булавкам, но когда я ставлю сигнал PB10 и PB11 Импульсы на PC13, даже если эти булавки не объявляются.
int ledPin = PC13; //int ledPin = PB14; // LED connected to digital pin 13 //int u1 = PB10; // input U1 - pulses //int u2 = PB11; //input U2 - pulses int u1 = PA10; // input U1 - pulses int u2 = PA9; //input U2 - pulses int val = 0; // variable to store the read value void setup() { pinMode(u1, INPUT_PULLDOWN); pinMode(u2, INPUT_PULLDOWN); pinMode(PC13, OUTPUT); // pinMode(PB14, OUTPUT); } void loop() { val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin digitalWrite(ledPin, val); // sets the LED to the button's value }

Тед
Вт 17 июля 2018 г. 9:16 утра
PA6 (вход измерителя) будет подключен к PC13 (вывод вычитания I и V)

Тед
Вт 17 июля 2018 г. 9:38 утра
Проблема с названием PIN -кода, я не внес изменения в эту линию
val = (digitalRead(PB8) - digitalRead(PB9)) / 2; // read the input pin

Тед
Вт 17 июля 2018 г. 9:53 утра
Я сделал программу № 2 проще int ledPin = PC13; int val = 0; // variable to store the read value void setup() { pinMode(PC13, OUTPUT); } void loop() { // make "var" local instead of global, it is more efficient uint8_t val = ( digitalRead(PB8) ^ digitalRead(PB9) ) & BIT0; // XOR of "V" and "I" digitalWrite(ledPin, val); }

Хейсан
Вт 17 июля 2018 г. 11:08
[Пито - Вт 17 июля 2018 г. 6:40 утра] - Это работает нормально?? val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin

Стивестронг
Вт 17 июля 2018 г. 11:33 утра
[Тед - Вт 17 июля 2018 г. 9:16 утра] - PA6 (вход измерителя) будет подключен к PC13 (вывод вычитания I и V)
Это означает, что вы хотите измерить сигнал XOR высокий период, справа?

Этот код будет измерять ширину как высоких, так и низких импульсов в микросекундной разрешении.
Если вы хотите Milliseconds вместо этого, замените «Micros» на «Millis». int ledPin = PC13; int u1 = PB8; // input U1 - pulses int u2 = PB9; //input U2 - pulses int old_val = 0; // variable to store the old read value int t; // to measure time int pulse; // to measure pulse period void setup() { pinMode(u1, INPUT_PULLDOWN); pinMode(u2, INPUT_PULLDOWN); pinMode(ledPin, OUTPUT); t = micros(); } void loop() { uint8_t val = ( digitalRead(u1) ^ digitalRead(u2) ) & BIT0; // XOR of "V" and "I" if ( old_val != val ) // detect change of the signal { old_val = val; int t0 = micros(); pulse = t0 - t; // here you have the pulse width in microseconds t = t0; // update time reference for next measurement // here you can use the "pulse" value, do what you want... digitalWrite(ledPin, val); // example to show signal change } }

Тед
Вт 17 июля 2018 г. 16:52
[Стивестронг - Вторник 17 июля 2018 г. 11:33 утра] -
[Тед - Вт 17 июля 2018 г. 9:16 утра] - PA6 (вход измерителя) будет подключен к PC13 (вывод вычитания I и V)
Это означает, что вы хотите измерить сигнал XOR высокий период, справа?
Да,
Я запускаю ваш код, импульсы на PC13 встряхивают, ширина их зависит от фазового сдвига между i и v = ok, я пытался что -то получить на ЖК -дисплее, у меня есть: pf = 0, ноль мигает с задержкой (Чтобы стабилизировать чтение) Импульсы на PC13 исчезли.

Это на 50 Гц, когда я изменяю частоту (100, 1000, Гц), импульсы на ПК13 более не стабильны.

Похоже, нет синхронизации с входными импульсами.

Тед
Вт 17 июля 2018 г. 16:55
#include LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5); int ledPin = PC13; int u1 = PB8; // input U1 - pulses int u2 = PB9; //input U2 - pulses int old_val = 0; // variable to store the old read value int t; // to measure time int pulse; // to measure pulse period void setup() { pinMode(u1, INPUT_PULLDOWN); pinMode(u2, INPUT_PULLDOWN); pinMode(ledPin, OUTPUT); t = micros(); lcd.begin(16, 2); } void loop() { uint8_t val = ( digitalRead(u1) ^ digitalRead(u2) ) & BIT0; // XOR of "V" and "I" if ( old_val != val ) // detect change of the signal { old_val = val; int t0 = micros(); pulse = t0 - t; // here you have the pulse width in microseconds t = t0; // update time reference for next measurement // here you can use the "pulse" value, do what you want... digitalWrite(ledPin, val); // example to show signal change } //////////////////////// lcd.setCursor(0, 0); lcd.print("PF="); // lcd.setCursor(4, 0); lcd.print(val); //delay(100); /* lcd.print(pf_max);// lcd.print(" "); // lcd.setCursor(0, 1); lcd.print("Ph-Shift="); // lcd.setCursor(10, 1); lcd.print(angle_max); lcd.print(" "); */ ///////////////////////// }

Тед
Вт 17 июля 2018 г., 19:44
Чтобы прочитать значение импульса с добавлением ЖК -дисплея, который вызывает импульсы нестабильности на PC13.
Эта линия вызывает это.
//lcd.print(pulse);

Тед
Вт 17 июля 2018 г. 8:08 вечера
Эта программа работает OK до 10 кГц, когда последние 4 строки отключены, активация любого из них вызывает утрат импульсов на PC13. #include LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5); int ledPin = PC13; int val = 0; // variable to store the read value int old_val = 0; // variable to store the old read value int t; // to measure time int pulse; // to measure pulse period void setup() { pinMode(PC13, OUTPUT); t = micros(); lcd.begin(16, 2); } void loop() { // make "var" local instead of global, it is more efficient uint8_t val = ( digitalRead(PB8) ^ digitalRead(PB9) ) & BIT0; // XOR of "V" and "I" if ( old_val != val ) // detect change of the signal { old_val = val; int t0 = micros(); pulse = t0 - t; // here you have the pulse width in microseconds t = t0; // update time reference for next measurement digitalWrite(ledPin, val); } //////////////////////// //lcd.setCursor(0, 0); // lcd.print("PF="); // // lcd.setCursor(4, 0); //lcd.print(pulse); }

Тед
Вторник 17 июля 2018 г. 8:18 вечера
[Хейсан - Вт 17 июля 2018 г. 11:08] -
[Пито - Вт 17 июля 2018 г. 6:40 утра] - Это работает нормально?? val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin

Хейсан
Вт 17 июля 2018 г., 21:10
[Тед - Вторник 17 июля 2018 г. 8:08 вечера] - Эта программа работает OK до 10 кГц, когда последние 4 строки отключены, активация любого из них вызывает утрат импульсов на PC13. #include LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5); int ledPin = PC13; int val = 0; // variable to store the read value int old_val = 0; // variable to store the old read value int t; // to measure time int pulse; // to measure pulse period void setup() { pinMode(PC13, OUTPUT); t = micros(); lcd.begin(16, 2); } void loop() { // make "var" local instead of global, it is more efficient uint8_t val = ( digitalRead(PB8) ^ digitalRead(PB9) ) & BIT0; // XOR of "V" and "I" if ( old_val != val ) // detect change of the signal { old_val = val; int t0 = micros(); pulse = t0 - t; // here you have the pulse width in microseconds t = t0; // update time reference for next measurement digitalWrite(ledPin, val); } //////////////////////// //lcd.setCursor(0, 0); // lcd.print("PF="); // // lcd.setCursor(4, 0); //lcd.print(pulse); }

Хейсан
Вт 17 июля 2018 г., 21:12
[Тед - Вторник 17 июля 2018 г. 20:18] -
[Хейсан - Вт 17 июля 2018 г. 11:08] -
[Пито - Вт 17 июля 2018 г. 6:40 утра] - Это работает нормально?? val = (digitalRead(PB10) - digitalRead(PB11)) / 2; // read the input pin

Тед
Вт 17 июля 2018 г., 21:25
Я разделен на 2, чтобы иметь 1 импульс.

Дэнниф
Вторник 17 июля 2018 г., 21:29
Если сигнал не слишком быстрый, используйте прерывания на двух входе и вычислите XOR в ISRS.

Тед
Вт 17 июля 2018 г. 22:28
Я добавил 5 микрос секунды. Задержка на конце = импульсы начинают терять форму - размытие delayMicroseconds(5);

Стивестронг
Ср. 18 июля 2018 г., 7:30 утра
Если вам нужна более стабильная версия, вы должны использовать прерывания.
Глядя на сигнал, можно начать измерение времени на краях «V» и остановить измерение по краям "I".

Я бы попробовал так:
int u1 = PB10; int u2 = PB11; int ledPin = PC13; volatile uint32_t t, pulse; void U1_isr() { t = micros(); } // start measurement void U2_isr() { pulse = micros() - t; } // finish measurement, read value void blink() { digitalWrite(ledPin, !digitalRead(ledPin)); } void setup() { pinMode(u1,INPUT); pinMode(u2,INPUT); pinMode(ledPin, OUTPUT); pulse = 0; // reset attachInterrupt(u1, CHANGE, U1_isr); attachInterrupt(u2, CHANGE, U2_isr); } void loop() { if ( pulse>0 ) // new measurement finished { uint32_t read_value = pulse; pulse = 0; // reset blink(); // process here the "read_value" value // ... } }

Тед
Ср. 18 июля 2018 г. 16:24
Спасибо, Стивестронг
У меня была та же идея, но я не знал, как это сделать, я думаю, что небольшая коррекция в вашей программе должна работать.
Это ошибка,

Статус выхода 1
Нет соответствующей функции для Call to 'Catchinterrupt (int&, Extinttriggermode, void (&) ()) '

вызвано этими двумя линиями. attachInterrupt(u1, CHANGE, U1_isr); attachInterrupt(u2, CHANGE, U2_isr);

Стивестронг
Ср. 18 июля 2018 г., 17:20
Извините, это должно быть:
attachInterrupt(u1, U1_isr, CHANGE); attachInterrupt(u2, U2_isr, CHANGE);

Тед
Ср. 18 июля 2018 г. 18:07
Импульсы на ПК13
для сдвига 0 град: 0 В/1.65 В
для 45 градусов сдвиг: 0 В-3.3 В/1.65 В

0 В-3.3V = первая часть импульса не стабильна, она нерегулярно прыгает от 0 В до 3.3V, вероятно, эффект шума ПК.

Тед
Ср. 18 июля 2018 г. 18:29
Есть что -то интересное.
Для аналоговых входов, когда используется синусоидальная волна в качестве входа, смещение 1.65V требуется, для этой цели используется два резистора.65 В вместо импульсов смещение может быть связано с помощью программного обеспечения = Нет делителя напряжения ?

Стивестронг
Ср. 18 июля 2018 г., 19:00
Теоретически вам не нужен делитель, если напряжение ниже 3.3В.

Тед
Ср. 18 июля 2018 г., 19:18
Коррекция
По ошибке я положил перемычку на R PIN -код вместо PB11, однако, если PIN -код может дать 1/2 VCC на PC13, может быть, код может сделать то же самое ?

Тед
Ср. 18 июля 2018 г., 19:21
[Стивестронг - Ср. 18 июля 2018 г., 19:00] - Теоретически вам не нужен делитель, если напряжение ниже 3.3В.
Я говорю о негативном вводе, который не терпимы микроконтроллерами

Тед
Ср. 18 июля 2018 г., 19:35
Изображение

Стивестронг
Чт 19 июля 2018 г. 8:24 утра
В каком диапазоне напряжения является ваш входной аналоговый сигнал?

Пито
Чт, 19 июля 2018 г., 11:47
Есть 2 дополнительных вопроса:
1. Что является импедансом вашего источника сигнала (как этот делитель представляет собой нагрузку 500OM)
2. Какова частота вашего сигнала (так как 100NF и 500OM создает фильтр высокого прохождения с углом в F = 1/(2PI*100E-9*500) = 3 кГц, таким образом, сигналы с F<3 кГц будет ослаблен..

Когда вы хотите, чтобы AC соединили сигнал, вы должны использовать делитель BIAS. Конденсатор толкает сигнал ниже 0, поэтому вы должны вернуть его с делителем, такое среднее, остается в VCC/2.
Вы должны рассмотреть значение резисторного резистора и конденсатора, критическое, когда вы хотите измерить фазовые различия сигнала.
Я бы порекомендовал 2x20KOM (или 2x18K, или 2x22K), что дает вам импеданс 10 кома <10K).
Тогда вы должны рассчитать конденсатор:

C = 1/(2Pi*freq*r) [f, hz, ohm], где Freq является самой низкой частотой, r = 10 ком,

и сделать конденсатор в несколько раз больше, чем рассчитано значение..

Например, (пример R1 является выходным импедансом генератора сигналов), также существует фильтрация VCC для делителя смещения:
AC связан adc.jpg
AC Copled Adc.JPG (58.66 киб) просмотрено 161 раз

Пито
Чт, 19 июля, 2018 13:05
AC связан ADC 2.JPG
AC связан ADC 2.JPG (51.77 киб) просмотрено 163 раза

Тед
Чт, 19 июля, 2018, 15:37
Спасибо за объяснения, я знаю, что я использую 100 тыс. Резисторов для делителя напряжения и 10NF -конденсатора, чтобы сделать высокий импеданс для приложенного синусного сигнала.....
Известно, что штифт может быть установлен как высокий или низкий (0 В/3.3v), когда я сею, этот сброс PIN может доставлять 1/2 VCC, я думал, что программное обеспечение может сделать это также.

Что касается последнего кода, я думаю, что я буду работать, мне нужно добавить что -то, чтобы сделать менее чувствительным к шуму, импульсы на ПК13 хороши - нет размытия.

Blue Pill Breakout Board ?