как усреднить 100 значений датчика за секунду
- Войдите на сайт для отправки комментариев
Пнд, 13/04/2020 - 18:02
Добрый день.
собрал аппарат для измерения мощности нагрузки. мощность регулируется по шим симистором. получив значения вольт и ампер перемножаю их,
но на экране мощность постоянно прыгает либо ноль либо максимальная. понимаю, что это шим дает импульсы - отсюда скачущие значения.
подскажите как в коде задать измерять 100 значений и усреднить их за секунду, чтобы отображалось постоянное текущее значение мощности?
например ампер (220v переменное)
#include <ACS712.h>
ACS712 sensor(ACS712_30A, A1);
void setup() {
sensor.calibrate();
}
void loop(){
float I = sensor.getCurrentAC(); //Амперы
}
Это как, симистором по ШИМ???
Это как, симистором по ШИМ???
суть не в этом. как подсчитать и усреднить амперы (код выше)?
суть не в этом. как подсчитать и усреднить амперы (код выше)?
это вопрос из детского сада?
Усреднить - сложить N измерений и потом разделить на N... в классе примерно пятом изучают.
Скользящее среднее будет лучше. ИМХО.
суть не в этом. как подсчитать и усреднить амперы (код выше)?
это вопрос из детского сада?
Усреднить - сложить N измерений и потом разделить на N... в классе примерно пятом изучают.
да. возможно из детского. вариантов много. но они размыты по длинному коду. и я новичек чтобы читать такие коды "с листа". поэтому обратился за помощью. нужен просто кусок кода.
нужен просто кусок кода.
#include <ACS712.h> ACS712 sensor(ACS712_30A, A1); #define K 100 // число измерений void setup() { sensor.calibrate(); } void loop(){ static int N =0; static float summ =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == K) { float average = summ/ K; // среднее N =0; summ =0; } }нужен просто кусок кода.
#include <ACS712.h> ACS712 sensor(ACS712_30A, A1); #define K 100 // число измерений void setup() { sensor.calibrate(); } void loop(){ static int N =0; static float summ =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == K) { float average = summ/ K; // среднее N =0; summ =0; } }странно, но значения амперметра всё-равно скачут. не скачут при 0 и больше 250. пробовал не 100 а 1000 подсчетов делать - безрезультатно...
странно, но значения амперметра всё-равно скачут. не скачут при 0 и больше 250. пробовал не 100 а 1000 подсчетов делать - безрезультатно...
и что, размах "скачков" тот же? - не верю
Покажите свой реальный код - как вы читаете данные с амперметра и как выводите данные на экран. в монитор или еще куда
Библиотека уже считает RMS-ток как надо. Ошибка где-то еще. Скорее всего, в непонимании математики такого измерения.
и что, размах "скачков" тот же? - не верю
Покажите свой реальный код - как вы читаете данные с амперметра и как выводите данные на экран. в монитор или еще куда
#include <ACS712.h> //для амперметра ACS712 sensor(ACS712_30A, A1); //для амперметра 30Ампер (5A, 20A, 30A) #define K 100 //для амперметра - кол-во измерений #include <LiquidCrystal.h> //для экрана 16х2 LiquidCrystal lcd(8, 7, 6, 5, 4, 3); //для экрана 16х2 //----------------------ENCODER----------------------------------------- int wattencoder = 120; // мощность, начинаем с половины int stepW = 5; // шаг изменения мощности unsigned long currentTime; unsigned long loopTime; const int pin_A = 9; // pin 9 const int pin_B = 10; // pin 10 unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; //-----------------------------VOLTMEMTR-------------------------------- const int analogInPin = A0; int Volt = 0; float popravkaV = 0.3455; //коэффициент под текущий блок питания void setup() { Serial.begin (9600); lcd.begin(16, 2); //------------------------------ENCODER--------------------------------- pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); currentTime = millis(); loopTime = currentTime; //----------------------СИМИСТОР--------------------------------- pinMode(11, OUTPUT); // устанавливаем pin 11 как выход на симистор (ШИМ D3,5,6,9,10,11) //-----------------------------AMPERMETR-------------------------------- sensor.calibrate(); } void loop(){ //----------------------ENCODER----------------------------------------- currentTime = millis(); if(currentTime >= (loopTime + 5)){ // проверяем каждые 5мс (200 Гц) encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера encoder_B = digitalRead(pin_B); // считываем состояние выхода B энкодера if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю if(encoder_B) { // выход В в полож. сост., значит вращение по часовой стрелке // увеличиваем яркость, не более чем до 1000 if(wattencoder - stepW >= 0) {wattencoder -= stepW;} } else { // выход В в 0 сост., значит вращение против часовой стрелки // уменьшаем яркость, но не ниже 0 if(wattencoder + stepW <= 255) {wattencoder += stepW;} } } encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла loopTime = currentTime; } //-----------------------------VOLTMEMTR----------------------------------- Volt = analogRead(analogInPin); //Вольты //-----------------------------AMPERMETR----------------------------------- static int N =0; static float summ =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == K) { float average = summ/ K; // среднее N =0; summ =0; } float W = Volt*popravkaV * I; // Ватты analogWrite(11, wattencoder); lcd.clear(); lcd.setCursor(0, 0); lcd.print(wattencoder, 1); //установленная мощность lcd.setCursor(0, 2); lcd.print(W, 0); //реальная мощность lcd.setCursor(6, 2); lcd.print(Volt*popravkaV,0); // V lcd.setCursor(12, 2); lcd.print(I, 2); // A }ACS712 не для слабаков. К нему хорошее психическое здоровье нужно и башка с мозгами.
ACS712 не для слабаков. К нему хорошее психическое здоровье нужно и башка с мозгами.
интересно то, что с покупным тиристорным диммером работает идеально (), а вот после тиристор+ШИМардуино - скачет "аки конь"
интересно то, что с покупным тиристорным диммером работает идеально (), а вот после тиристор+ШИМардуино - скачет "аки конь"
вас в самом начале спрашивали уже - вы что тиристором с помощью ШИМа управляете? - где вы такое вычитали?
Поставь кондер на 1мкф хотяб (для начала) на управляющий электрод тиристора. А вообще - не плохо было бы схему глянуть.
управление киловатной электроплитой. контроль нагрева спирали симисором - не противозаконно. ТЭНами ещё управляют.
управление киловатной электроплитой. контроль нагрева спирали симисором - не противозаконно. ТЭНами ещё управляют.
я вас не об этом спрашивал, я спрашивал кто вас надоумил управлять симистором с помощью ШИМ?
Вы в курсе, как работает симистор? а как ШИМ? и главное, чем они отличаются?
Поставь кондер на 1мкф хотяб (для начала) на управляющий электрод тиристора. А вообще - не плохо было бы схему глянуть.
схема:
конденсатор (RC цепочку) вот по этой схеме добавил:
управление киловатной электроплитой. контроль нагрева спирали симисором - не противозаконно. ТЭНами ещё управляют.
я вас не об этом спрашивал, я спрашивал кто вас надоумил управлять симистором с помощью ШИМ?
Вы в курсе, как работает симистор? а как ШИМ? и главное, чем они отличаются?
намекаете что он может работать только как реле?
Намекает на обратное - шим это быстро включавшееся и выключающееся реле, а тиристору нужно аналоговое напряжение управления.
Намекает на обратное - шим это быстро включавшееся и выключающееся реле, а тиристору нужно аналоговое напряжение управления.
вот обратное мнение. и скетч рабочий. так что аналоговое управление возможно и правильнее, но и по цифре ТЭНами тоже получается управлять. вопрос как заставить не скакать показания амперметра.....
"""""""
Итак, имелась плата Arduino ProMini, к ней все и подключим. Код получается мелкий и простой, надеюсь, что сообщество извинит, что я его выкладываю прямо тут:
byte pers; // Переменная для получения данных порта
int x; // Переменная координат алгоритма Брезенхема
int y; // Переменная координат алгоритма Брезенхема
int onoff ; // Переменная сигнала на плату симистора
void setup() {
pinMode(12, OUTPUT); // Назначаем пин на выход (плата симистора)
}
void loop() {
pers = analogRead(pinPot); // Положение потенциометра
pers = map(pers, 0, 1013, 0, 100); // Переводим показания потенциометра в проценты
if (pot > 100) {pot = 100; } // Ограничиваем значение
y = 0;
for (int i = 1; i <= 100; i++){ // Алгоритм Брезенхема
x = i * pers / 100 ;
if (x == y) {onoff = 0;}
else {onoff = 1;}
digitalWrite(12, onoff);
delay(10);
y = x;
}
}
Ну вот, отлично работает эта схема. Крутим потециометр и смотрим на мигание лампочки на электрическом чайнике. Красота. Получился прекрасный диммер - регулятор мощности переменного тока, нагрузкой, если верить даташиту симистора, до 40A и напряжением до 600В при наличии хорошего радиатора.
"""""""
denis160374@gm , после просмотра вашего кода я уже ни на что не намекаю.
Зачем я вам давал код для усреднения значений? Вы вставили мой код в свой скетч, как будто сбоку изолентой примотали. Какой смысл от этого усреднения в вашем коде, если вы результат его нигде не используете? Вы программировать-то умеете ? Или скачали код в интернете и ни строчки в нем не понимаете?
Знаете. у нас на форуме есть правило - готовый код новичкам не давать. С вами я отступил от правил - вы показались мне разумным человеком. я вижу. что я ошибся, вы еще не готовы писать собственные программы.
Идите светодиодиком помигайте
Код получается мелкий и простой, надеюсь, что сообщество извинит, что я его выкладываю прямо тут:
не извинит. Во-первых, вставлен неверно, во-вторых - он даже не компилируется.
Код получается мелкий и простой, надеюсь, что сообщество извинит, что я его выкладываю прямо тут:
не извинит. Во-первых, вставлен неверно, во-вторых - он даже не компилируется.
это не мой текст. а человека который его написал. и он не целый - поэтому не компилируется. вставлен для примера, что симистор и шим дружат.
он не целый - поэтому не компилируется.
не поэтому, а потому что в нем с логикой проблемы. А вы что, даже в таком, как сами пишете, "простом коде" - не видите явной ошибки? И с такими знаниями беретесь работать с электричеством?
я уж не знаю, тут смеятся или плакать. Во-первых, этот код имеет принципиальное отличие от ардуиновского ШИМ. Так что хотя в нем ошибка - его можно поравить... а ваш нет.
Ну а главное, что для вас все эти строчки - как иероглифы. Вы в них ничего не смыслите. Купите готовый диммер и не мучайтесь
он не целый - поэтому не компилируется.
не поэтому, а потому что в нем с логикой проблемы. А вы что, даже в таком, как сами пишете, "простом коде" - не видите явной ошибки? И с такими знаниями беретесь работать с электричеством?
вставлен для примера, что симистор и шим дружат.
я уж не знаю, тут смеятся или плакать. Во-первых, этот код имеет принципиальное отличие от вашего. Так что хотя оба этих кода сейчас нерабочие - этот можно поравить... а ваш нет.
Ну а главное, что для вас все эти строчки - как иероглифы. Вы в них ничего не смыслите. Купите готовый диммер и не мучайтесь
так я и пишу в "песочницу" а не в "программирование". т.к. не программист. что я изолентой то прикрутил? кто тут спец я или тот кто отвечает? и я не прошу весь код "на блюдечке". это разные просьбы.
С электричеством дружу и все сделал - только прыгают показания амперметра. ...и причем тут моргать диодиками...
я не прошу весь код "на блюдечке". это разные просьбы.
А что вы просите, интересно? как вам помочь, если вы элементарных вещей не понимаете? вы получили готовый код усреднения и даже не смогли его вставить в свой скетч.
Я повторяю вопрос - где вы в своем коде используете усредненное значение, чтобы утверждать, что "усреднение не помогло"? - Вы как читали с датчика единичное значение тока - так и читаете, никакого усреднения 100 значений у вас и в помине нет.
Понимаете, мало спросить - надо еще понять ответ. Вам надо для начала научиться хотя бы понимать чужой код. А для этого стоит прочесть какую-то книжку по языку С, прежде чем задавать вопросы.
понятно, что вместо I нужно указывать average
static int N =0; static float summ =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == Ka) { float average = summ/ Ka; // среднее N =0; summ =0; } float W = Volt*popravkaV * average;но тогда выходит ошибка: 'average' was not declared in this scope
Шо_опять? :)))
Шо_опять? :)))
ДА! думаю вдруг тебе грустно так решил повеселить на ночь
denis160374@g
Попробуй вот так
#include <ACS712.h> //для амперметра ACS712 sensor(ACS712_30A, A1); //для амперметра 30Ампер (5A, 20A, 30A) #define K 100 //для амперметра - кол-во измерений #include <LiquidCrystal.h> //для экрана 16х2 LiquidCrystal lcd(8, 7, 6, 5, 4, 3); //для экрана 16х2 //----------------------ENCODER----------------------------------------- int wattencoder = 120; // мощность, начинаем с половины int stepW = 5; // шаг изменения мощности unsigned long currentTime; unsigned long loopTime; const int pin_A = 9; // pin 9 const int pin_B = 10; // pin 10 unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; //-----------------------------VOLTMEMTR-------------------------------- const int analogInPin = A0; int Volt = 0; float popravkaV = 0.3455; //коэффициент под текущий блок питания void setup() { Serial.begin (9600); lcd.begin(16, 2); //------------------------------ENCODER--------------------------------- pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); currentTime = millis(); loopTime = currentTime; //----------------------СИМИСТОР--------------------------------- pinMode(11, OUTPUT); // устанавливаем pin 11 как выход на симистор (ШИМ D3,5,6,9,10,11) //-----------------------------AMPERMETR-------------------------------- sensor.calibrate(); } void loop(){ //----------------------ENCODER----------------------------------------- currentTime = millis(); if(currentTime >= (loopTime + 5)){ // проверяем каждые 5мс (200 Гц) encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера encoder_B = digitalRead(pin_B); // считываем состояние выхода B энкодера if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю if(encoder_B) { // выход В в полож. сост., значит вращение по часовой стрелке // увеличиваем яркость, не более чем до 1000 if(wattencoder - stepW >= 0) {wattencoder -= stepW;} } else { // выход В в 0 сост., значит вращение против часовой стрелки // уменьшаем яркость, но не ниже 0 if(wattencoder + stepW <= 255) {wattencoder += stepW;} } } encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла loopTime = currentTime; } //-----------------------------VOLTMEMTR----------------------------------- Volt = analogRead(analogInPin); //Вольты //-----------------------------AMPERMETR----------------------------------- analogWrite(11, wattencoder); static int N =0; static float summ =0; float W =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == K) { float average = summ/ K; // среднее N =0; summ =0; float W = Volt*popravkaV * average; // Ватты } lcd.clear(); lcd.setCursor(0, 0); lcd.print(wattencoder, 1); //установленная мощность lcd.setCursor(0, 2); lcd.print(W, 0); //реальная мощность lcd.setCursor(6, 2); lcd.print(Volt*popravkaV,0); // V lcd.setCursor(12, 2); lcd.print(I, 2); // A }нужен просто кусок кода.
#include <ACS712.h> ACS712 sensor(ACS712_30A, A1); #define K 100 // число измерений void setup() { sensor.calibrate(); } void loop(){ static int N =0; static float summ =0; float I = sensor.getCurrentAC(); //Амперы N++; summ += I; if (N == K) { float average = summ/ K; // среднее N =0; summ =0; } }всё заработало. больше не прыгает. нужно было вверху строчку дописать:
остановился на 64 опросах. дальше тормозит. 64 делает за 5,5сек
остановился на 64 опросах. дальше тормозит.
опять значит код "изолентой примотали"