Система контроля напряжения 220v

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Не совсем понимаю, но всеже рабочая точка немного раскачивается?

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

 

Мы меряем на выходе двухполупериодного выпрямителя, начальная точка измерений может быть и такой жеж

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Logik пишет:

Ну я. НЧ конечно. Первого, зуб даю что не третьего и не половинного. Только порядок у цифровых и аналоговых - немного сильно отличаются;) А чего сомнения у Вас? Зачем он там- ну он не помешает. Вобще если автор посчитал и всунул - знач нужно.

А энергокомпанию тыкать носом ненадо. Она вас в ответ как тыкнет - век без ликтричества будете. Так шо хавайте ток того качества, что дают или вобще не хавайте.  И вобще, ваша поделка сертификат имеет? метрологически поверена? В реестре средств измерения числится? Пломбы целы? срок поверки не истек? И що Вы своей марахайкой сможете показать после всего этого? 

Лирическое отступление №1:

любой энергосбыт я могу поставить на колени, имея лампу накаливания, старенький щитовой Э421, подписи соседей и заключение магазина, по какой причине сгорел мой скважинный насос. Будут дежурить на вышке круглосуточно у моего ввода и сдувать пыль с проводов. Но энергосбыт, зная, что рожа у них всегда в "пушку", идут навстречу, всегда вежливо работают с населением и пытаются исправить положение.

Лирическое отступление №2:

Сложные вещи всегда можно изъяснить простым языком.

А теперь к сути - если read_sensor - это фильтр, то чему равна частота его среза? И еще, каков физический смысл значения, которое возвращает функция?  

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ulis пишет:

 теперь к сути - если read_sensor - это фильтр, то чему равна частота его среза? И еще, каков физический смысл значения, которое возвращает функция?  

по сути функция возвращает "сглаженное" значение действующего напряжения

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ua6em пишет:

по сути функция возвращает "сглаженное" значение действующего напряжения

Ок, спасибо ... :) я, ради интереса попробую этой функции подсунуть прямоугольный сигнал, посмотрю, что выдйет ...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ulis пишет:

ua6em пишет:

по сути функция возвращает "сглаженное" значение действующего напряжения

Ок, спасибо ... :) я, ради интереса попробую этой функции подсунуть прямоугольный сигнал, посмотрю, что выдйет ...

и что вышло???

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ua6em пишет:

и что вышло???

static unsigned long G;  // Переменная для накопления входных значений
int sensorPin = A0;
unsigned int sensorValue = 0;
double S;
float S1;

void read_sensor()
{
  //sensorValue = 0;
  for(int j = 1; j <=96; j++)
  {    
    // Попытка дать на вход случайное значение
    //sensorValue = random(0x00, 0xff);
    
    // Даем на вход прямоугольный импульс: с 1 до 20 sensorValue = 0, с 21 до 40 sensorValue = 0хff, с 41 по 96 sensorValue = 0
    // Функция вернет 0x31 - это почти среднее значение
    if(j <= 20)
    {
      sensorValue = 0;
    }
    
    if(j > 20 && j <= 40)
    {
      sensorValue = 0xff;
    }

    if(j > 40)
    {
      sensorValue = 0;
    }

    /*
    sensorValue = 0xfe;

    Serial.print("j = ");
    Serial.println(j,HEX);
    
    Serial.print("sensorValue = ");
    Serial.println(sensorValue,HEX);
    */
    
    G+=sensorValue-(G>>8);
    sensorValue=G>>8;
  }
  
}

/*
void read_RMS()
{
   G=0;
   for (int k=1; k <= 100; k++) {
   sensorValue = analogRead(sensorPin);
   G+=(sensorValue*2);
   G+=(sensorValue+sensorValue);
   G+=sq(sensorValue);
   }
   S1=G/100;  
   S=sqrt(S1);                
}
*/


void setup()
{
  Serial.begin(9600);
  //randomSeed(analogRead(sensorPin));
}

void loop()
{
  read_sensor();
  /*
  Serial.print("sensorValue after filter = ");
  Serial.println(sensorValue,HEX);
  //delay(3000);  
  */
}

Судите сами, результат на выходе функции почти равен среднему значению входного сигнала ... мне только не понятно, почему результат вычисления получается не сразу, а приближается за несколько проходов (возможно, объявлять переменные нужно не глобально - не проверял)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

потому, что использует метод накопления

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ua6em пишет:

потому, что использует метод накопления

Имхо результат мы должны получать сразу, а уж что там функция накапливает - это ее дело

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ulis пишет:

ua6em пишет:

потому, что использует метод накопления

Имхо результат мы должны получать сразу, а уж что там функция накапливает - это ее дело


 это особенность цифрового фильтра )))

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ua6em пишет:

 это особенность цифрового фильтра )))

Пусть будет так, хотя я с вами не согласен :)

nik182
Онлайн
Зарегистрирован: 04.05.2015

dimax пишет:

Lachin, тогда уж так:

входом МК собирать квадратные корни, и считать rms :)

Для контроля напряжения это самый правильный совет, с одним дополнением. Трансформатор должен быть расчитан на напряжение заведомо превышающее макимально ожидаемое. Стандартный на 220 вольт не пойдет. На больших напряжениях у него загибается передаточная характеристика. В идеале делитель должен быть вообще подключен без трансформатора прямо к сети. На ардуине такое можно реализовать только на меге. Без аппаратной плавующей математики микроконтроллеру не потянуть обработку. В серии msp430 есть срециальные микроконтроллеры, заточенные под измерение сетевого напряжения, тока, энергии. Appnote для них просто песня для всех, кто хочет правильно измерить параметры сети. Вот например статья про них http://www.rlocman.ru/review/article.html?di=144260 обратите внимание на рисунок 3 и особенно ссылка из статьи http://www.ti.com/lit/an/slaa494a/slaa494a.pdf это конечно ватт метр но что бы померить ватты сначала нужно померить напряжение.    

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

nik182 пишет:

http://www.rlocman.ru/review/article.html?di=144260 обратите внимание на рисунок 3 и особенно ссылка из статьи http://www.ti.com/lit/an/slaa494a/slaa494a.pdf это конечно ватт метр но что бы померить ватты сначала нужно померить напряжение.    

А интересно, как выполнены вот эти измерители http://www.ebay.com/itm/161890659367?_trksid=p2055119.m1438.l2649&ssPageName=STRK%3AMEBIDX%3AIT ?

Хочу поставить такие на каждую фазу у себя в доме

nik182
Онлайн
Зарегистрирован: 04.05.2015

Кто ж его знает? Без описания или схемы не скажешь.

Logik
Offline
Зарегистрирован: 05.08.2014

ulis пишет:

Лирическое отступление №1:

любой энергосбыт я могу поставить на колени

)))

Трындеть - не мешки ворочать! Списочек энергосбытоов поставленных на колени с илюстрациями процесса стояния приложите. Кстати в Вашем списке потребного отсутствует самодельный прибор о котором изначально речь шла.

 

ulis пишет:

Лирическое отступление №2:

каков физический смысл значения, которое возвращает функция?  

Физический смысл математических операций создается и существует только в голове человека ищущего этот самый смысл. Т.е. какой сами вложите тот и будет,  МК принципиально не обрабатывает физический смысл. Ваш подход к рассмотрению работы функции в программе совершенно левый и отдает диким старперством. Завязывайте, программирование более абстрактная вещь, в ней нельзя рассматривать физические смыслы (хотя в цифровой обработке сигналов это не так сильно вредит, сказывается близость этих самых сигналов).

При подаче на вход рассматриваемой функции прямоугольников получим результат в точности как на интегрирующей RC цепи (в пределах дискретности и разрядности разумеется) - фронт растянется по експоненте. Ей крутизна (т.е. постоянная времени) регулируется коэффициентом в фильтра. Частотные же св-ва меряют в относительной частоте - по отношению к частоте дискретизации, потому просто для функции они не определены в герцах.

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

Logik пишет:

Трындеть - не мешки ворочать! Списочек энергосбытоов поставленных на колени с илюстрациями процесса стояния приложите. Кстати в Вашем списке потребного отсутствует самодельный прибор о котором изначально речь шла.

Челябэнерго ... процесс стояния я не фиксировал. Приборчик, если еще раз прочитать мой пост - я только хотел бы (сослагательное наклонение) создать ... но, похоже, уже не нужно, челябэнерго до сих пор на коленях :) 

Logik пишет:

Физический смысл математических операций создается и существует только в голове человека ищущего этот самый смысл.

Спорить с вами не буду, ибо вы не правы :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Еще оддна реализация, через защёлку и поиск максимума )))
Остапа понесло )))
 

int sensorPin = A0; // аналоговый вход
int RelePin = 12;  // управление реле на 12 пине
int SysPin = 11;  // это пин соединить с 12, цифровой вход, защита от ногодрыга
int RsPin = 10;  // этот пин для разряда конденсатора защёлки

unsigned int sensorValue = 0; // переменная напряжения сенсора
static unsigned long G;       // Переменная для накопления показаний датчика сенсора
//double S = 1.25;
//float S1=0;

int b = 8;  //объявляем переменную с номером пина, на который подключен biper
int Pin_Vmin_led = 7;
int Pin_Vmax_led = 6;
int Pin_V_ok_led = 5;
int V_min = 352;      // коэффициент для минимального напряжения равного 170 вольт
int V_max = 525;      // коэффициент для максимального напряжения равного 250 вольт
int V_gist = 20;      // гистерезис, без цифровой обработки значения входящего напряжения не может быть менее 7
                      // если будем использовать цифровой фильтр, то можно уменьшить, предположительно до значения 3
int V_gistv = 20;     // гистерезис для высокого напряжения  
                      // коэффицент ориентировочный 2 единицы на вольт (рабочая зона 180-240 вольт)              

byte Vin_OK = 0;  //эта переменная служит для проверки входного напряжение, входит ли оно в наши установки, если входит, то 1, нет 0
byte Flag_T1 = 0;  //этот флаг информирует,что было зафиксировано правильное входное напряжение и запущен счетчик выдержки паузы на включение реле
unsigned int T1 = 10000;  // время задержки реле включения
unsigned long previousMillis = 0;

/* следующая ниже конструкция по идее должна бы высвободить 2 байта памяти занятые под переменные
* и будет более правильной, так как использует команды препроцессора и по сути является макросом
* заменяя в нужных местах слова на цифровые значения
* при использовании реле с прямой логикой просто заменить 0 на 1, а 1 на ноль
*/
#define ReleON  0  // реле включено
#define ReleOFF 1  // реле выключено


/* высокий тон высокачая частота мигания светодиода - напряжение завышено */
void bipers() {
 tone (b, 3000); //включаем тон 3000 Гц
 delay(200); //ждем 200 Мс
 noTone(b ); // отключаем
}

/* высокий тон высокачая частота мигания светодиода - напряжение завышено */
void bipers2() {
 tone (b, 7000); //включаем тон 7000 Гц
 delay(73); //ждем 73 Мс
 noTone(b ); // отключаем
}

void read_sensor(){
  for (int j=1; j <= 96; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>8);
  sensorValue=G>>8;                      // показания сенсора после цифрового фильтра
}
 }

void read_RMS(){
  G=0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  G+=sq(sensorValue);
  }
  float S1=(G/100);
  double S=sqrt(S1);
  sensorValue =  S;  
  }

void read_VMAX(){
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
}

void read_VMAX1(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(10);                            // Заряжаем конденсатор до пикового напряжения
  sensorValue = analogRead(sensorPin);  // Измеряем 
 }

 void read_VMAX_M(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(20);                            // Заряжаем конденсатор до пикового напряжения
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
 }


 
void setup() {
 Serial.begin(9600); // скорость порта
 pinMode(RelePin, OUTPUT);
 pinMode(SysPin, INPUT);
 pinMode(RsPin, OUTPUT);
 pinMode(Pin_Vmin_led, OUTPUT); // заниженное напряжение
 pinMode(Pin_Vmax_led, OUTPUT); // завышенное напряжение
 pinMode(Pin_V_ok_led, OUTPUT); // напряжение в норме
 
/*   for (int s=1; s <= 16; s++) {
   read_sensor();
   } */
}

void loop() {
// sensorValue = analogRead(sensorPin);  // получение амплитуды входного напряжения прямым чтением порта ацп
// read_sensor();                        // получение амплитуды входного напряжения чтением через цифровой фильтр
// read_RMS();                           // получение амплитуды входного напряжения через рассчёт RMS
// read_VMAX();                          // получение амплитуды входного напряжения через поиск экстремума
// read_VMAX1();                         // получение амплитуды входного напряжения через защёлки, по сути аналогичен предыдущему
                                         // но с применением аппартной защёлки 
                                         // отсюда - http://arduino.ru/forum/programmirovanie/izmerenie-amplitudy-impulsa#com...
   read_VMAX_M();                        // Комбинированная, защёлка + поиск экстремума (максимум в максимуме)
    

 if (sensorValue <= (V_min) || sensorValue >= (V_max)) {  //тут делаем сравнение двух значении если в сети 170в  или 250в  то сбрасываем флаг
   Vin_OK = 0;
   Flag_T1 = 0;
 
    }

 else if (sensorValue > (V_min + V_gist) && sensorValue < (V_max - V_gistv)) {  // напряжение включения реле сдвигаем на величину гистерезиса
   Vin_OK = 1;
   if (Flag_T1 == 0) {
     previousMillis = millis();  //реле задержки включения
     Flag_T1 = 1;
   }
 }

// командами digitalRead(SysPin)==ReleOFF и digitalRead(SysPin)==ReleON избавляемся от повторной установки (НОГОДРЫГ)
// состояния реле, если уже установлено, надо ли это делать можно посмотреть осциллографом
// или триггером ловушкой оценить состояние пина в установившемся состоянии реле

 if (digitalRead(SysPin) == ReleOFF && Vin_OK == 1 && Flag_T1 == 1 && (millis() - previousMillis) >= T1) digitalWrite(RelePin, ReleON);
 else if (digitalRead(SysPin) == ReleON && Vin_OK == 0) digitalWrite(RelePin, ReleOFF);   //else digitalWrite(RelePin, ReleOFF);

 if(digitalRead(SysPin) == ReleON){digitalWrite(Pin_V_ok_led, HIGH);}
 else {digitalWrite(Pin_V_ok_led, LOW);}

 Serial.println(sensorValue); // выводим информацию в сериал порт

/* попищим и помигаем светодиодами если с напряжением что-то не так */
     if (sensorValue <= (V_min+V_gist) && digitalRead(SysPin) == ReleOFF){  // тут пищим бузером если напряжение ниже нормы
     digitalWrite(Pin_Vmin_led, HIGH);
     bipers(); // Если напряжение не в норме то сработал biper
     digitalWrite(Pin_Vmin_led, LOW);
    }
    if (sensorValue >= (V_max-V_gistv) && digitalRead(SysPin) == ReleOFF){ // здесь пищим бузером если напряжение выше нормы
     digitalWrite(Pin_Vmax_led, HIGH);
     bipers2(); // Если напряжение не в норме то сработал biper
     digitalWrite(Pin_Vmax_led, LOW);
    }
 delay(100);
}

 

ulis
ulis аватар
Offline
Зарегистрирован: 09.03.2011

ua6em пишет:

Еще оддна реализация, через защёлку и поиск максимума )))
Остапа понесло )))

Где вы хотите применить это устройство?

Logik
Offline
Зарегистрирован: 05.08.2014

ulis пишет:

Logik пишет:

Трындеть - не мешки ворочать! Списочек энергосбытоов поставленных на колени с илюстрациями процесса стояния приложите. Кстати в Вашем списке потребного отсутствует самодельный прибор о котором изначально речь шла.

Челябэнерго ... процесс стояния я не фиксировал.

И с подобными заявлениями чегото у всех всегда именно так и обстоит дело ;)

ulis пишет:

Logik пишет:

Физический смысл математических операций создается и существует только в голове человека ищущего этот самый смысл.

Спорить с вами не буду, ибо вы не правы :)

Ну найдете где в процессоре хранится физический смысл и по какому алгоритму и в каком модуле обрабатывается - тогда продолжим.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ulis пишет:

ua6em пишет:

Еще оддна реализация, через защёлку и поиск максимума )))
Остапа понесло )))

Где вы хотите применить это устройство?

лично я нигде - автор темы в устройтве защиты от пере и недо напряжения в сети (реле)

Logik
Offline
Зарегистрирован: 05.08.2014

Коль мы уж вспомнили о теме темы скажу. Подход изначально не верный. Выпрямитель в цепи измерения - сильно неленейная штука, а при попытках еще и запитать схему от того выпрямителя, с которого и измеряем - вобще атас. Как впрочем и от того же трансформатора. Потому если хочется контролить величину (читай амплитуду) напряжения в сети, то мерять через отдельный трансформатор если нужна гальваноразвязка, или просто резистивный делитель типа 100КОм к 100Ом, если не нужна или она создана в другом месте схемы. С выхода  либо получать переменку амплитудой до 0,5В, чтоб не открывались защитные диоды по минусу, либо смещаем 0 в положительное напряжение.

Я бы делал на делителе без смещения 0. Как наиболее простое.

Алгоритм, если цель именно контроль напряжения 50Гц, а не единичные выбросы ловим - проще пареной репы. Когда МК нечего делать, присваеваем М=0 и начинаем часто опрашивать АЦП, с него значения легонько фильтруем и сравниваем с М. Если результат больше М, то сохраняем его в М. Т.е. ищем максимум сразу по ходу ввода. Так крутимся дольше периода сети. В результате в М - максимум за период, оно же амплитуда. Его тоже пускаем в фильтр. На выходе - средняя амплитуда за некоторое последнее время. Сравниваем с уставками, типа 250*корень(2) + смещение нуля, если есть (тут тоже есть варианты, можна просто откалибровать при наличии латра - установить 250В на нем, посмотреть сколько выходит - то и уставка). Делаем гистерезис по вкусу, чтоб не скакало при нахождении вблизи границы.

Lachin
Offline
Зарегистрирован: 02.10.2016

Что скажете по поводу таких схем?

Применял такие трансформаторы.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Нижная - как раз вариант трансформаторный с смещением нуля. Годная. Верхная - "зачем ты мама меня родила" - в топку сразу. Оптрон на входе не обеспечит стабильность передачи амплитуды аналогового сигнала. Но как вариант без ардуины, можна сделать, только оптроны на выходах ">250" и "<170". Там они только логический сигнал пропустят. И запитать ОУ можна без трансформатора тогда. В общем симпатично может получится. Хотя гистерезис еще нужно придумывать.. В общем с ардуиной проще в целом, и решения без ардуины, на форуме ардуины - злостный офтоп;)

Трансформаторы годные.

Lachin
Offline
Зарегистрирован: 02.10.2016

Схемы эти нашел на просторах инета,вот только не понятно по нижней схеме зачем R1-10к идет на Vcc? согласен с Ардуино проще,для этого и показал схемы что бы услышать ваше мнения что лучше а что нет. 

Logik
Offline
Зарегистрирован: 05.08.2014

А R1-R2 как раз делитель задающий смещение нуля  на уровне половины Vcc. Получится когда переменка с трансформатора будет 0, на входе АЦП будет Vcc/2. При положительной волне получим Vcc/2+, при отрицательной Vcc/2-Vа, где Vа-амплитуда переменки с выхода трансформатора деленая делителем R3-R4. Схема позволяет и на отрицательной полуволне тоже мерить, хотя оно врядли нужно.

nik182
Онлайн
Зарегистрирован: 04.05.2015

Это  стандартная схема смещения. На вход АЦП поступит синус смещённый на Uпит/2. После оцифровки убираем постоянную составляющую - получаем чистую огибающую напряжения. Её уже можно обрабатывать.   

Logik
Offline
Зарегистрирован: 05.08.2014

nik182 пишет:

Это  стандартная схема смещения. На вход АЦП поступит синус смещённый на Uпит/2. После оцифровки убираем постоянную составляющую - получаем чистую огибающую напряжения. Её уже можно обрабатывать.   

А я первей ;)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Я бы делал на делителе без смещения 0. Как наиболее простое.

Алгоритм, если цель именно контроль напряжения 50Гц, а не единичные выбросы ловим - проще пареной репы. Когда МК нечего делать, присваеваем М=0 и начинаем часто опрашивать АЦП, с него значения легонько фильтруем и сравниваем с М. Если результат больше М, то сохраняем его в М. Т.е. ищем максимум сразу по ходу ввода. Так крутимся дольше периода сети. В результате в М - максимум за период, оно же амплитуда. Его тоже пускаем в фильтр. На выходе - средняя амплитуда за некоторое последнее время. Сравниваем с уставками, типа 250*корень(2) + смещение нуля, если есть (тут тоже есть варианты, можна просто откалибровать при наличии латра - установить 250В на нем, посмотреть сколько выходит - то и уставка). Делаем гистерезис по вкусу, чтоб не скакало при нахождении вблизи границы.

Так что ли???

void read_DFILTER(){
  int vmax =0;
  for (int j=1; j <= 200; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>3);
  sensorValue=G>>3;                       // показания сенсора после цифрового фильтра
  if (sensorValue >vmax){vmax=sensorValue;}
}
  sensorValue =  vmax; 
 }

 

Logik
Offline
Зарегистрирован: 05.08.2014

Похоже. А 200 раз не маловато для периода 20мсек?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Похоже. А 200 раз не маловато для периода 20мсек?

чтение из порта АЦП осуществляется за 100 микросекунд + затраты, можно и увеличить, но вроде и так должно быть 20+ миллисекунд

и конечно же скетч, как без него )))
 

int sensorPin = A0; // аналоговый вход
int RelePin = 12;  // управление реле на 12 пине
int SysPin = 11;  // это пин соединить с 12, цифровой вход, защита от ногодрыга
int RsPin = 10;  // этот пин для разряда конденсатора защёлки

unsigned int sensorValue = 0; // переменная напряжения сенсора
static unsigned long G;       // Переменная для накопления показаний датчика сенсора
//double S = 1.25;
//float S1=0;

int b = 8;  //объявляем переменную с номером пина, на который подключен biper
int Pin_Vmin_led = 7;
int Pin_Vmax_led = 6;
int Pin_V_ok_led = 5;
int V_min = 352;      // коэффициент для минимального напряжения равного 170 вольт
int V_max = 525;      // коэффициент для максимального напряжения равного 250 вольт
int V_gist = 20;      // гистерезис, без цифровой обработки значения входящего напряжения не может быть менее 7
                      // если будем использовать цифровой фильтр, то можно уменьшить, предположительно до значения 3
int V_gistv = 20;     // гистерезис для высокого напряжения  
                      // коэффицент ориентировочный 2 единицы на вольт (рабочая зона 180-240 вольт)              

byte Vin_OK = 0;  //эта переменная служит для проверки входного напряжение, входит ли оно в наши установки, если входит, то 1, нет 0
byte Flag_T1 = 0;  //этот флаг информирует,что было зафиксировано правильное входное напряжение и запущен счетчик выдержки паузы на включение реле
unsigned int T1 = 10000;  // время задержки реле включения
unsigned long previousMillis = 0;

/* следующая ниже конструкция по идее должна бы высвободить 2 байта памяти занятые под переменные
* и будет более правильной, так как использует команды препроцессора и по сути является макросом
* заменяя в нужных местах слова на цифровые значения
* при использовании реле с прямой логикой просто заменить 0 на 1, а 1 на ноль
*/
#define ReleON  0  // реле включено
#define ReleOFF 1  // реле выключено


/* высокий тон высокачая частота мигания светодиода - напряжение завышено */
void bipers() {
 tone (b, 3000); //включаем тон 3000 Гц
 delay(200); //ждем 200 Мс
 noTone(b ); // отключаем
}

/* высокий тон высокачая частота мигания светодиода - напряжение завышено */
void bipers2() {
 tone (b, 7000); //включаем тон 7000 Гц
 delay(73); //ждем 73 Мс
 noTone(b ); // отключаем
}

void read_sensor(){
  for (int j=1; j <= 96; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>8);
  sensorValue=G>>8;                      // показания сенсора после цифрового фильтра
}
 }

void read_DFILTER(){
  int vmax =0;
  for (int j=1; j <= 200; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>3);
  sensorValue=G>>3;                       // показания сенсора после цифрового фильтра
  if (sensorValue >vmax){vmax=sensorValue;}
}
  sensorValue =  vmax; 
 }

 
void read_RMS(){
  G=0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  G+=sq(sensorValue);
  }
  float S1=(G/100);
  double S=sqrt(S1);
  sensorValue =  S;  
  }

void read_VMAX(){
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
}

void read_VMAX1(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(10);                            // Заряжаем конденсатор до пикового напряжения
  sensorValue = analogRead(sensorPin);  // Измеряем 
 }

 void read_VMAX_M(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(20);                            // Заряжаем конденсатор до пикового напряжения
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
 }


 
void setup() {
 Serial.begin(9600); // скорость порта
 pinMode(RelePin, OUTPUT);
 pinMode(SysPin, INPUT);
 pinMode(RsPin, OUTPUT);
 pinMode(Pin_Vmin_led, OUTPUT); // заниженное напряжение
 pinMode(Pin_Vmax_led, OUTPUT); // завышенное напряжение
 pinMode(Pin_V_ok_led, OUTPUT); // напряжение в норме
 
/*   for (int s=1; s <= 16; s++) {
   read_sensor();
   } */
}

void loop() {
// sensorValue = analogRead(sensorPin);  // получение амплитуды входного напряжения прямым чтением порта ацп
// read_sensor();                        // получение амплитуды входного напряжения чтением через цифровой фильтр
// read_RMS();                           // получение амплитуды входного напряжения через рассчёт RMS
// read_VMAX();                          // получение амплитуды входного напряжения через поиск экстремума
// read_VMAX1();                         // получение амплитуды входного напряжения через защёлки, по сути аналогичен предыдущему
                                         // но с применением аппартной защёлки 
                                         // отсюда - http://arduino.ru/forum/programmirovanie/izmerenie-amplitudy-impulsa#com...
//  read_VMAX_M();                       // Комбинированная, защёлка + поиск экстремума (максимум в максимуме)
   read_DFILTER();                       // Поиск максимума с предварительной обработкой в цифровом фильтре 
    

 if (sensorValue <= (V_min) || sensorValue >= (V_max)) {  //тут делаем сравнение двух значении если в сети 170в  или 250в  то сбрасываем флаг
   Vin_OK = 0;
   Flag_T1 = 0;
 
    }

 else if (sensorValue > (V_min + V_gist) && sensorValue < (V_max - V_gistv)) {  // напряжение включения реле сдвигаем на величину гистерезиса
   Vin_OK = 1;
   if (Flag_T1 == 0) {
     previousMillis = millis();  //реле задержки включения
     Flag_T1 = 1;
   }
 }

// командами digitalRead(SysPin)==ReleOFF и digitalRead(SysPin)==ReleON избавляемся от повторной установки (НОГОДРЫГ)
// состояния реле, если уже установлено, надо ли это делать можно посмотреть осциллографом
// или триггером ловушкой оценить состояние пина в установившемся состоянии реле

 if (digitalRead(SysPin) == ReleOFF && Vin_OK == 1 && Flag_T1 == 1 && (millis() - previousMillis) >= T1) digitalWrite(RelePin, ReleON);
 else if (digitalRead(SysPin) == ReleON && Vin_OK == 0) digitalWrite(RelePin, ReleOFF);   //else digitalWrite(RelePin, ReleOFF);

 if(digitalRead(SysPin) == ReleON){digitalWrite(Pin_V_ok_led, HIGH);}
 else {digitalWrite(Pin_V_ok_led, LOW);}

 Serial.println(sensorValue); // выводим информацию в сериал порт

/* попищим и помигаем светодиодами если с напряжением что-то не так */
     if (sensorValue <= (V_min+V_gist) && digitalRead(SysPin) == ReleOFF){  // тут пищим бузером если напряжение ниже нормы
     digitalWrite(Pin_Vmin_led, HIGH);
     bipers(); // Если напряжение не в норме то сработал biper
     digitalWrite(Pin_Vmin_led, LOW);
    }
    if (sensorValue >= (V_max-V_gistv) && digitalRead(SysPin) == ReleOFF){ // здесь пищим бузером если напряжение выше нормы
     digitalWrite(Pin_Vmax_led, HIGH);
     bipers2(); // Если напряжение не в норме то сработал biper
     digitalWrite(Pin_Vmax_led, LOW);
    }
 delay(100);
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

 После оцифровки убираем постоянную составляющую - получаем чистую огибающую напряжения.

методом простого вычитания?

nik182
Онлайн
Зарегистрирован: 04.05.2015

Да. Алгоритм примерно такой. Заряжаем АЦП по таймеру на считывание 50 точек за период - 400мкс - этого достаточно. Запуск синхронизируем с нулём сети - это важно. В прерывании АЦП суммируем значения и по окончании периода 20 мс сумму делим на 50 и вычитаем из оцифрованных значений. Запускаем оцифровку снова, а полученный массив обрабатываем - корень квадратный из суммы квадратов деленных на 50. Получаем действующее значение напряжения. Без всяких фильтров и с учётом всех гармоник.

Вопрос только сколько милисекунд будет происходить обработка. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

Да. Алгоритм примерно такой. Заряжаем АЦП по таймеру на считывание 50 точек за период - 400мкс - этого достаточно. Запуск синхронизируем с нулём сети - это важно. В прерывании АЦП суммируем значения и по окончании периода 20 мс сумму делим на 50 и вычитаем из оцифрованных значений. Запускаем оцифровку снова, а полученный массив обрабатываем - корень квадратный из суммы квадратов деленных на 50. Получаем действующее значение напряжения. Без всяких фильтров и с учётом всех гармоник.

Вопрос только сколько милисекунд будет происходить обработка. 

такие вещи лучше в коде приводить, со слов, нам кузнецам, сие действо неведомо )))

к примеру - как можно померить ардуиной 50 точек за 400 микросекунд

nik182
Онлайн
Зарегистрирован: 04.05.2015

Не за 400мкс а за 20мс.   0.4*50=20мс - период сетевого напряжения.

У АЦП есть регистр ADCSRB. В нем можно активировать биты 

ADTS[2:0] Trigger Source
000 Free Running mode
001 Analog Comparator
010 External Interrupt Request 0
011 Timer/Counter0 Compare Match A
100 Timer/Counter0 Overflow
101 Timer/Counter1 Compare Match B
110 Timer/Counter1 Overflow
111 Timer/Counter1 Capture Event
Мне нравится Timer/Counter1 Compare Match B.  Заряжаем таймер 1 на 400мкс. Компаратором ждем переход через 0, по событию запускаем таймер.  После 50 срабатываний прерывания АЦП преинициализируем АЦП и идем обрабатывать полученный массив данных.
 
Идея есть. Написать код не проблема. Кусков на форуме полно. Кузнецам почитать что типа ATmega328/P DATASHEET COMPLETE и проблемы с написанием уйдут.    
Logik
Offline
Зарегистрирован: 05.08.2014

К периоду в 20мсек нельзя привязыватся. Он не выдерживается с высокой точностью. от 49 до 51 Гц по стандарту. Брать квадрат от мгновенного нефильтрованого значения - фигня полная, можна попасть на выброс короткий, там в разы больше значение напряжения, а в квадрате это затмит все остальные отсчеты. Вобще считать RMS там где он не нужен - не нужно ;)

nik182
Онлайн
Зарегистрирован: 04.05.2015

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

nik182 пишет:

Не за 400мкс а за 20мс.   0.4*50=20мс - период сетевого напряжения.

У АЦП есть регистр ADCSRB. В нем можно активировать биты 

ADTS[2:0] Trigger Source
000 Free Running mode
001 Analog Comparator
010 External Interrupt Request 0
011 Timer/Counter0 Compare Match A
100 Timer/Counter0 Overflow
101 Timer/Counter1 Compare Match B
110 Timer/Counter1 Overflow
111 Timer/Counter1 Capture Event
Мне нравится Timer/Counter1 Compare Match B.  Заряжаем таймер 1 на 400мкс. Компаратором ждем переход через 0, по событию запускаем таймер.  После 50 срабатываний прерывания АЦП преинициализируем АЦП и идем обрабатывать полученный массив данных.
 
Идея есть. Написать код не проблема. Кусков на форуме полно. Кузнецам почитать что типа ATmega328/P DATASHEET COMPLETE и проблемы с написанием уйдут.    

Ардуина тем и хороша, что позволяет "кузнецам" сделать задуманное, без чтения даташитов на процессор, строго в рамках концепции IDE, а то, что процессор хорош я и так знаю, это только у задорнова американцы тупые.
Речь идёт о простом реле напряжения с гистерезисом в котором выбросы должны быть срезаны варисторами на входе реле. Я пробовал сравнить разные алгоритмы в рамках незначительных аппаратных изменений.
Из них лучшими (точность лучше 1 вольт) оказались простой поиск экстремума и поиск экстремума с предварительной цифровой обработкой (сглаживанием)...может я что в коде накосячил, так не программист и не математик от слова совсем...но никто не поправил...значит с алгоритмами всё нормально

1. Цифровой фильтр
 

void read_sensor(){
  for (int j=1; j <= 200; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>8);
  sensorValue=G>>8;                      // показания сенсора после цифрового фильтра
}
 }

2. Поиск максимума с предварительной цифровой обработкой (сглаживанием)
 

void read_DFILTER(){
  int vmax =0;
  for (int j=1; j <= 200; j++) {
  sensorValue = analogRead(sensorPin);
  G+=sensorValue-(G>>3);
  sensorValue=G>>3;                       // показания сенсора после цифрового фильтра
  if (sensorValue >vmax){vmax=sensorValue;}
}
  sensorValue =  vmax; 
 }

3. Расчёт RMS (поправил, с учетом высказываний LOGIK, меряем в течении периода)
 

void read_RMS(){
  G=0;
  for (int k=1; k <= 200; k++) {
  sensorValue = analogRead(sensorPin);
  G+=sq(sensorValue);
  }
  float S1=(G/100);
  double S=sqrt(S1);
  sensorValue =  S;  
  }

4. Простой поиск экстремума
 

void read_VMAX(){
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
}

5. Аппаратная защёлка
 

void read_VMAX1(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(10);                            // Заряжаем конденсатор до пикового напряжения
  sensorValue = analogRead(sensorPin);  // Измеряем 
 }

6. Аппаратная защёлка с поиском экстремума

void read_VMAX_M(){
  digitalWrite(RsPin, ReleON); 
  delay(1);
  digitalWrite(RsPin, ReleOFF);         // Разрядили конденсатор защёлки 
  delay(20);                            // Заряжаем конденсатор до пикового напряжения
  int vmax =0;
  for (int k=1; k <= 100; k++) {
  sensorValue = analogRead(sensorPin);
  if (sensorValue >vmax){vmax=sensorValue;}
  }
  sensorValue =  vmax; 
 }

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Интересен рассчёт R3 и R4 в этой схеме и от чего запитывать Vcc учитывая, что на +5 ардуины "грязи" от 200 до 320 милливольт

Logik
Offline
Зарегистрирован: 05.08.2014

nik182 пишет:
Вы не правы. По вашим ответам видно, что к электричеству и к обработке данных вы имеете очень опосредованное отношение.

Упились в канун дня победы? Здесь оценки Вам я ставлю, и они как правило не очень.

nik182 пишет:
Как раз RMS хорош тем, что отдельные выбросы не приводят к фатальному искажению результата, в отличии от поиска максимума за период.

А сейчас посмотрим с практической стороны (тем кто не дружит с математикой можна дальше пропустить до п.3). 50 отсчетов на период, по выше описаному Вами алгоритму. Слева идеальная синусоида, справа с одним выбросом в самом первом отсчете, остальные 49 абсолютно идентичны.

  RMS= 222,8   RMS= 249,9
    49637,52     62437,52
0 0 0   800 640000
0,1256 39,46006 1557,096   39,46006 1557,096
0,2512 78,29844 6130,646   78,29844 6130,646
0,3768 115,9033 13433,57   115,9033 13433,57
0,5024 151,6821 23007,45   151,6821 23007,45
0,628 185,0712 34251,34   185,0712 34251,34
0,7536 215,5446 46459,45   215,5446 46459,45
0,8792 242,6221 58865,49   242,6221 58865,49
1,0048 265,8772 70690,71   265,8772 70690,71
1,1304 284,9436 81192,84   284,9436 81192,84
1,256 299,5207 89712,67   299,5207 89712,67
1,3816 309,379 95715,39   309,379 95715,39
1,5072 314,3632 98824,23   314,3632 98824,23
1,6328 314,3947 98844,02   314,3947 98844,02
1,7584 309,473 95773,54   309,473 95773,54
1,884 299,6757 89805,52   299,6757 89805,52
2,0096 285,1571 81314,56   285,1571 81314,56
2,1352 266,1459 70833,66   266,1459 70833,66
2,2608 242,9418 59020,7   242,9418 59020,7
2,3864 215,9101 46617,18   215,9101 46617,18
2,512 185,4769 34401,68   185,4769 34401,68
2,6376 152,1216 23140,97   152,1216 23140,97
2,7632 116,3696 13541,88   116,3696 13541,88
2,8888 78,78428 6206,963   78,78428 6206,963
3,0144 39,95774 1596,621   39,95774 1596,621
3,14 0,501686 0,251689   0,501686 0,251689
3,2656 -38,9623 1518,059   -38,9623 1518,059
3,3912 -77,8124 6054,77   -77,8124 6054,77
3,5168 -115,437 13325,61   -115,437 13325,61
3,6424 -151,242 22874,2   -151,242 22874,2
3,768 -184,665 34101,15   -184,665 34101,15
3,8936 -215,178 46301,76   -215,178 46301,76
4,0192 -242,302 58710,18   -242,302 58710,18
4,1448 -265,608 70547,54   -265,608 70547,54
4,2704 -284,729 81070,8   -284,729 81070,8
4,396 -299,365 89619,41   -299,365 89619,41
4,5216 -309,284 95656,78   -309,284 95656,78
4,6472 -314,331 98803,93   -314,331 98803,93
4,7728 -314,425 98863,32   -314,425 98863,32
4,8984 -309,566 95831,22   -309,566 95831,22
5,024 -299,83 89897,96   -299,83 89897,96
5,1496 -285,37 81435,96   -285,37 81435,96
5,2752 -266,414 70976,4   -266,414 70976,4
5,4008 -243,261 59175,81   -243,261 59175,81
5,5264 -216,275 46774,94   -216,275 46774,94
5,652 -185,882 34552,18   -185,882 34552,18
5,7776 -152,561 23274,76   -152,561 23274,76
5,9032 -116,836 13650,57   -116,836 13650,57
6,0288 -79,2699 6283,72   -79,2699 6283,72
6,1544 -40,4553 1636,633   -40,4553 1636,633

Думаю излишне говорить что при применении фильтра никакого "фатальному искажению результата" действительно небыло бы. А ведь "игла" в 800В далеко не предел того что есть в сети.

Кстати аналитически влияние единичного выброса тож легко показывается, но утруждать Вас формулами с перепоя думаю было бы безчеловечно ;)

Теперь к теории, Вы конечно владеете ею лучше чем в среднем по форуму, знаете про RMS, даже умеете его посчитать, наверно даже подозреваете что изложеное вами называется численое интегрирвание, но к сожелению.

1. Интеграл периодической функции на периоде не зависит от положения границ интегрирования. Это чистая математика. Что от перехода через ноль при наростании до следующего такого перехода, что от максимума до максимума, что от фи=33 до фи=33. Значение будет одинаковым. Потому ваше "Запуск синхронизируем с нулём сети - это важно" - бред. Если не помните математику - легко из екселевского результата убедится. Но принципиально важно считать именно ровно на периоде. А при плавающей частоте сети это уже отдельная задача, которую вы игнорируете.

2. Теперь почему еденичный выброс так повлиял. При численном интегровании на функцию накладывается ограничение - она должна быть достаточно гладкой. Очевидно выброс его нарушил. При этом алгоритм численного интегрирования принимает что значение функции в окресности отсчета близко к значению в точке отсчета. Помните там, столбики и трапеции препод рисовал на доске, пока Вы в морской бой играли? Ото оно было. Т.е. если импульс даже 100нсек зарядит емкость АЦП и будет оцифрован, то в расчете он эквивалентен длительности в 1/50 от периода. Потому про RMS по 50 точкам на период без предварительной фильтрации просто забудте. Это хрень собачья а не RMS.

3. А нужна ли RMS здесь? RMS вещь хорошая, но не универсальная. Имеет свою область применения, но есть и места где она безполезна и даже вредна. Тем вы и отличаетесь от специалиста, что не понимаете где заканчивается область применения. Помните старый грузинский фильм про то как веревкой мужика с дерева стащили потому как до этого так же веревкой из колодца вытягивали ))) Ваш случай.

Где RMS необходима:

- для оценки теплового и энергетического действия тока. Она собственно и определена как эквивалент по теплу.

- припреобразованиях форм тока - (постоянка в переменку и наоборот, в импульсной технике). Здесь она отражает закон сохранения энергии.

Где RMS безполезна и вредна:

- оценка электрической прочности (изоляцию пробивает амплитуда а не действующее)

- расчет работы выпрямительной нагрузки (конденсатор за выпрямителем заряжается до амплитуды)

- расчет цепей чувствительных к форме сигнала гармоникам и пикфактору (запитать движек от инвертора выдающего прямоугольник или трапецию - спалить его. Хоть с RMS полный порядок будет.)

С учетом этого очевидно что для определения выхода напряжения сети за пределы RMS скорей вредна.

 

Потому бросайте гнать пургу, и лучше научитесь считать RMS ровно на периоде (или целом их кол-ве). 

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Logik пишет:

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

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

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

Интересен рассчёт R3 и R4 в этой схеме и от чего запитывать Vcc учитывая, что на +5 ардуины "грязи" от 200 до 320 милливольт

R3R4 - делитель из 6В по схеме в диапазон АЦП. Для точніх измерений опорное АЦП 1.1В сильно лучше, грязи меньше.

Logik
Offline
Зарегистрирован: 05.08.2014

SLKH пишет:

Logik пишет:

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

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

Не то чтоб не мешала. Мешает. Но действительно можна ей учесть. Только вот зачем, если без выпрямителя цепь становится линейной. Ну а если от него и питатся - то ничего уже не выйдет учесть.

Lachin
Offline
Зарегистрирован: 02.10.2016

Logik пишет:

А R1-R2 как раз делитель задающий смещение нуля  на уровне половины Vcc. Получится когда переменка с трансформатора будет 0, на входе АЦП будет Vcc/2. При положительной волне получим Vcc/2+, при отрицательной Vcc/2-Vа, где Vа-амплитуда переменки с выхода трансформатора деленая делителем R3-R4. Схема позволяет и на отрицательной полуволне тоже мерить, хотя оно врядли нужно.

Да это конечно все понятно,не понятно зачем и куда подключать Vcc надо же знать какому выводу ардуинки его цеплять.

Logik
Offline
Зарегистрирован: 05.08.2014

На +5В разумеется. Тогда правда не получится использовать внутреней опорник и более точно оцифровывать. Ну для начала так глянем. Получим ноль измеряемого расположеный на половине Vcc, т.е. на 2,5В, а переменка должна уложится по амплитуде с запасом в +-2,5В.

Для трансформатора 6В (это вероятно как раз RMS;) амплитуда будет в корень из 2 больше т.е. 8,4В, значеть делитель 8,4/2,5=3,36 раз округляем с запасом к примеру до 5. Т.е надо (R3+R4)/R3=5. удобно R3=1КОм а R4=3,9КОм - распостраненный номинал. Пересчитываем обратно коэффициент делителя выходит (3,9+1)/1=4,9. Учтем трансформатор с коэффициентом 220/6=36,67 Получим общий коэффициент деления схемы 36,67*4,9=179,67. Т.е. 1 вольт на входе АЦП будет при мгновенном напряжении в сети 179,67В а общий диапазон +-2,5В будет соответствовать мгновенным напряжениям в сети 179,67*2,5= +-450В. Вполне нормас.

Для работы с внутреним опорником 1,1В надо задать смещение о 0,55В для чего пересчитать делитель R1R2, и аналогично пересчитать R3R4.

 

Lachin
Offline
Зарегистрирован: 02.10.2016

Logik пишет:

На +5В разумеется. Тогда правда не получится использовать внутреней опорник и более точно оцифровывать. Ну для начала так глянем. Получим ноль измеряемого расположеный на половине Vcc, т.е. на 2,5В, а переменка должна уложится по амплитуде с запасом в +-2,5В.

Для трансформатора 6В (это вероятно как раз RMS;) амплитуда будет в корень из 2 больше т.е. 8,4В, значеть делитель 8,4/2,5=3,36 раз округляем с запасом к примеру до 5. Т.е надо (R3+R4)/R3=5. удобно R3=1КОм а R4=3,9КОм - распостраненный номинал. Пересчитываем обратно коэффициент делителя выходит (3,9+1)/1=4,9. Учтем трансформатор с коэффициентом 220/6=36,67 Получим общий коэффициент деления схемы 36,67*4,9=179,67. Т.е. 1 вольт на входе АЦП будет при мгновенном напряжении в сети 179,67В а общий диапазон +-2,5В будет соответствовать мгновенным напряжениям в сети 179,67*2,5= +-450В. Вполне нормас.

Для работы с внутреним опорником 1,1В надо задать смещение о 0,55В для чего пересчитать делитель R1R2, и аналогично пересчитать R3R4.

 

 

Так трансформаторы у меня все на 12в или на 15,тогда придется пересчитать просто делитель? 

Тогда получается на Vcc подаем прям с ардуинки +5в? и дальше все по схеме.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Lachin пишет:

Logik пишет:

На +5В разумеется. Тогда правда не получится использовать внутреней опорник и более точно оцифровывать. Ну для начала так глянем. Получим ноль измеряемого расположеный на половине Vcc, т.е. на 2,5В, а переменка должна уложится по амплитуде с запасом в +-2,5В.

Для трансформатора 6В (это вероятно как раз RMS;) амплитуда будет в корень из 2 больше т.е. 8,4В, значеть делитель 8,4/2,5=3,36 раз округляем с запасом к примеру до 5. Т.е надо (R3+R4)/R3=5. удобно R3=1КОм а R4=3,9КОм - распостраненный номинал. Пересчитываем обратно коэффициент делителя выходит (3,9+1)/1=4,9. Учтем трансформатор с коэффициентом 220/6=36,67 Получим общий коэффициент деления схемы 36,67*4,9=179,67. Т.е. 1 вольт на входе АЦП будет при мгновенном напряжении в сети 179,67В а общий диапазон +-2,5В будет соответствовать мгновенным напряжениям в сети 179,67*2,5= +-450В. Вполне нормас.

Для работы с внутреним опорником 1,1В надо задать смещение о 0,55В для чего пересчитать делитель R1R2, и аналогично пересчитать R3R4.

 

 

Так трансформаторы у меня все на 12в или на 15,тогда придется пересчитать просто делитель? 

Тогда получается на Vcc подаем прям с ардуинки +5в? и дальше все по схеме.

Камал, не парься, схема хорошая но в твоём случае сложно реализуемая!
1. В идеале на Vcc в таком случае надо подавать напряжение от источника именуемого "нормальный элемент" или от источника с очень малым уровнем пульсаций, явно не от питания ардуины, в твоем случае опорное будет "скакать" с размахом 160 милливольт.
2. Посмотри в нете схемы бп с пульсациями в 5 милливольт, оно тебе надо?

3. Предлогаемые решения в ценовом диапазоне выходят за рамки уже существующих для этого изделий
 

Вывод - или делать совсем просто или не заморачиваться и покупать готовый блок защиты

Logik
Offline
Зарегистрирован: 05.08.2014

делитель пересчитать. +5В с ардуинки, хоть оно и недостаточно стабильно. За неименеем гербовой бумаги приходится писать на обычной ))))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

делитель пересчитать. +5В с ардуинки, хоть оно и недостаточно стабильно. За неименеем гербовой бумаги приходится писать на обычной ))))

у него на 5 вольтах 320 милливольт пульсации

Lachin
Offline
Зарегистрирован: 02.10.2016

А на каком коде остановится? или тот что последний был?

SLKH
Offline
Зарегистрирован: 17.08.2015

Logik пишет:

SLKH пишет:

Logik пишет:

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

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

Не то чтоб не мешала. Мешает. Но действительно можна ей учесть. Только вот зачем, если без выпрямителя цепь становится линейной. Ну а если от него и питатся - то ничего уже не выйдет учесть.

ЛАТР с вольтметром на входе и подстроечник на компараторе*  - больше ничего не надо,  нелинейность вообще не интересна. 

========

* или же экспериментально установленное(!) значение, с которой будем сравнивать результат analogRead().

 
Logik
Offline
Зарегистрирован: 05.08.2014

То понятно. Проблема в том что значение не будет стабильным. От температуры и нагрузки будет менятся. И неудобно иметь только фиксированую точку, если надо изменить порог - снова с латром возится.

Ответьте на простой вопрос, зачем? Зачем мерить и отрицательную полуволну, она от положительной сильно отличается?

ПС. Понимаете ситуацию, в схему добавляется нечто, без чего все тоже работает, а на вопрос "а нафига?"  - ответ ну с ним тоже можна получить все тоже, но надо немного повозится ))) Мазохизм?