фазомерт на arduino

fantikov4
Offline
Зарегистрирован: 17.12.2016

Доброго времени суток.
Поставленна задача сделать фазометр на базе ардуино. Но возникли некотоыре проблемы.
Что есть.
1) Принципиальная схема 
      А1 - само ардуино( uno r3), А2 - индикация, А3 - таймер NE 555  настроенный на генерацию прямоуголных импульсов.
2) Сам скетч 

#include <LiquidCrystal.h> 
LiquidCrystal lcd(4,5,6,7,8,9); 
unsigned long a = 0; 
unsigned long b = 0; 
unsigned long c = 0; 
unsigned long d = 0; 
unsigned long e = 0; 
volatile int state = HIGH; 
void setup() 
{ 
lcd.begin(5,2); 
pinMode(2, INPUT); 
pinMode(3, INPUT); 
} 

void loop() 
{ 
while(b==0 && d==0) 
{ 
if(digitalRead(2)==1 && a==0) 
{ 
a=micros(); 
} 
if(digitalRead(2)==0 && a!=0) 
{ 
b=micros(); 
} 
if(digitalRead(3)>0 && c==0) 
{ 
c=micros(); 
} 
if(digitalRead(3)>0 && c!=0) 
{ 
d=micros(); 
} 
} 
if(a>b) 
{ 
e=(a-c)*360/(a-b); 
} 
else 
{ 
e=(a-c)*360/(b-a); 
} 
lcd.setCursor(0,0); 
lcd.print( e); 
//выводишь на дисплей e 
a = 0; 
b = 0; 
c = 0; 
d = 0; 
} 
Суть работы в чем в Arduino приходит импульс, он включает таймер и считает время до прихода второго импульса, как только второй импульс пришел, он выключает таймер и считает разность фаз.
Вроде бы все просто и понятно, однако на выходе у меня получается несуразица, может поможите найте ошибку?    
nik182
Offline
Зарегистрирован: 04.05.2015

В описанном алгоритме работы таймер считает один раз. С чем этот один раз сравнивать? Относительно чего сравнивать разность фаз? Вы смотрели в сторону функции pulseIn? 

fantikov4
Offline
Зарегистрирован: 17.12.2016

nik182 пишет:

В описанном алгоритме работы таймер считает один раз. С чем этот один раз сравнивать? Относительно чего сравнивать разность фаз? Вы смотрели в сторону функции pulseIn? 

Он записывает время прихода первого и второго импульса и вычисляет. Хотя может я где-то и не прав.

if(a>b)
{
e=(a-c)*360/(a-b);
}
else
{
e=(a-c)*360/(b-a);

 

nik182
Offline
Зарегистрирован: 04.05.2015

Меня напрягает фраза включает таймер. Может быть просто запоминает время? Фаза это такое понятие, которое иммеет много разных толкований. Например фаза луны или фаза развития общества. Какую конкретно фазу вы хотите измерить? Для одного прямоугольного колебания, как у вас, фаза не может определена на всем протяжении постоянного уровня сигнала. У вас есть только понятие период.   

Приведённая схема не соответствует скетчу.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
1- Если нужна точность то необходимо делать на прерывании
2- Вам мнужно измерить 1 импульс или серию. Если серию то какая частота
Алгоритм я предлагаю такой: В прерывании пришол 1й импульс - Проверили (fl_gener == 0) подняли флаг (fl_gener = 1), засекли время (a=micros();). Пришол 2й импульс Проверили (fl_gener == 1) сбросили флаг (fl_gener = 0;) засекли время (с = micros();). ну а дальше считаем. 
fantikov4
Offline
Зарегистрирован: 17.12.2016

nik182 пишет:

Меня напрягает фраза включает таймер. Может быть просто запоминает время? Фаза это такое понятие, которое иммеет много разных толкований. Например фаза луны или фаза развития общества. Какую конкретно фазу вы хотите измерить? Для одного прямоугольного колебания, как у вас, фаза не может определена на всем протяжении постоянного уровня сигнала. У вас есть только понятие период.   

Приведённая схема не соответствует скетчу.

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

fantikov4
Offline
Зарегистрирован: 17.12.2016

vosara пишет:

1- Если нужна точность то необходимо делать на прерывании
2- Вам мнужно измерить 1 импульс или серию. Если серию то какая частота
Алгоритм я предлагаю такой: В прерывании пришол 1й импульс - Проверили (fl_gener == 0) подняли флаг (fl_gener = 1), засекли время (a=micros();). Пришол 2й импульс Проверили (fl_gener == 1) сбросили флаг (fl_gener = 0;) засекли время (с = micros();). ну а дальше считаем. 

Серию. от 10 до 10^3

nik182
Offline
Зарегистрирован: 04.05.2015

Через выводы 0,1 в ардуину льется программа. Их использовать можно, но очень осторожно. В новой схеме уже два входа используется. Вот только не понял какую фазу нужно посчитать. В этой схеме разницы нежду сигналами не будет. Если не поставить какой нибудь резистор за конденсатором.   

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Создаем масив (unsigned long raschet[10])
И каждий раз заганяем туда значение (c - a)
А дальше работае как Вам надо
Просхему промолчу, не вникал
fantikov4
Offline
Зарегистрирован: 17.12.2016

nik182 пишет:

Через выводы 0,1 в ардуину льется программа. Их использовать можно, но очень осторожно. В новой схеме уже два входа используется. Вот только не понял какую фазу нужно посчитать. В этой схеме разницы нежду сигналами не будет. Если не поставить какой нибудь резистор за конденсатором.   

За резистр спасибо, исправил.
С NE 555 получаем прямоугольные импульсы. на один пин "чистые" на второй через кондер-резистор и считаем между ними фазовый сдвиг.

nik182
Offline
Зарегистрирован: 04.05.2015

У вас схема диффиринцирования. Ваш резистор ничего не изменит. У ардуино высокое входное сопротивление и добавка еще... Резистор надо на землю. Тогда вы получите короткие импульсы на фронтах. Причем на заднем фронте отрицательные, которые съест защита ардуины. Чтобы затянуть фронт, нужно конденсатор за резистором посадить на землю. Тогда фронты будут завалены на время 2Pi/(RC).   

fantikov4
Offline
Зарегистрирован: 17.12.2016

vosara пишет:

Создаем масив (unsigned long raschet[10])
И каждий раз заганяем туда значение (c - a)
А дальше работае как Вам надо
Просхему промолчу, не вникал


Я слишком недавно занимаюсь этим, не смогу реализовать. 
Может есть какие-нибудт еще варианты?

fantikov4
Offline
Зарегистрирован: 17.12.2016

nik182 пишет:

У вас схема диффиринцирования. Ваш резистор ничего не изменит. У ардуино высокое входное сопротивление и добавка еще... Резистор надо на землю. Тогда вы получите короткие импульсы на фронтах. Причем на заднем фронте отрицательные, которые съест защита ардуины. Чтобы затянуть фронт, нужно конденсатор за резистором посадить на землю. Тогда фронты будут завалены на время 2Pi/(RC).   


Не ругайте, если не правильно, я слишком глуп еще) Вот так?

nik182
Offline
Зарегистрирован: 04.05.2015

Нет, конденсатор перенесите одной ногой к ноге 2 ардуины, второй на землю. Так вы выход заземлили :-)

fantikov4
Offline
Зарегистрирован: 17.12.2016

nik182 пишет:

Нет, конденсатор перенесите одной ногой к ноге 2 ардуины, второй на землю. Так вы выход заземлили :-)

nik182
Offline
Зарегистрирован: 04.05.2015
fantikov4
Offline
Зарегистрирован: 17.12.2016
fantikov4
Offline
Зарегистрирован: 17.12.2016

Со скетчем все еще ахинея.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

fantikov4, во первых на подобных примитивных алгоритмах можно измерять только сравнительно длинные импульсы. Во вторых на ваш смотреть просто неприятно, т.к. нету форматирования. По хорошему это должно выглядеть внешне примерно так:

 while(b==0 && d==0) { 
     if(digitalRead(2)==1 && a==0) { a=micros(); } 
      if(digitalRead(2)==0 && a!=0) { b=micros(); } 
      if(digitalRead(3)>0  && c==0) { c=micros(); } 
     if(digitalRead(3)>0  && c!=0) { d=micros(); } 
  } //end while

Тогда информация будет восприниматься легче. В этом фрагменте сразу бросается несуразность условий то вы сраниваете с единицей, то потом зачем то >0 , зачем? И  очевидно второй опрос  третьего входа всё таки нужно было с нулём сравнить?

И переменных с именами a b c d не должно быть, это тоже мешает восприятию. Переменные лучше называть в соответствии с их логикой, например start_tim_1, end_tim_1 и.т.п. 

 

fantikov4
Offline
Зарегистрирован: 17.12.2016

dimax пишет:

fantikov4, во первых на подобных примитивных алгоритмах можно измерять только сравнительно длинные импульсы. Во вторых на ваш смотреть просто неприятно, т.к. нету форматирования. По хорошему это должно выглядеть внешне примерно так:

 while(b==0 && d==0) { 
     if(digitalRead(2)==1 && a==0) { a=micros(); } 
      if(digitalRead(2)==0 && a!=0) { b=micros(); } 
      if(digitalRead(3)>0  && c==0) { c=micros(); } 
     if(digitalRead(3)>0  && c!=0) { d=micros(); } 
  } //end while

Тогда информация будет восприниматься легче. В этом фрагменте сразу бросается несуразность условий то вы сраниваете с единицей, то потом зачем то >0 , зачем? И  очевидно второй опрос  третьего входа всё таки нужно было с нулём сравнить?

И переменных с именами a b c d не должно быть, это тоже мешает восприятию. Переменные лучше называть в соответствии с их логикой, например start_tim_1, end_tim_1 и.т.п. 

 


 

да, там ощибка должно быть
if(digitalRead(3)==1 && c==0)
{
c=micros();
}
if(digitalRead(3)==0 && c!=0) {
d=micros();
}

Тед
Offline
Зарегистрирован: 06.11.2017

1

Slamos666
Offline
Зарегистрирован: 29.08.2018

Если автор темы ещё следит за ней, отпиши мне пожалуйста