Мониторинг потребляемой электроэнергии в реальном времени при помощи Arduino и LabView


Описываемое ниже устройство представляет собой измеритель потребляемой мощности для дома или квартиры.

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

Счётчик электрической энергии

Устройство работает следующим образом: контроллер Arduino считывает частоту миганий светодиода электросчетчика и передает данные через беспроводной модуль XBee. Модуль USB/Xbee, установленный на компьютере, принимает данные на ПК и передает их в LabView, позволяющей отображать и мониторить данные энергопотребления в реальном времени.
Контроллер Arduino пересылает данные о среднем энергопотреблении за последние 5 минут, а также данные энергопотребления в реальном времени.

Для детектирования мигания светодиода в схеме устройства применен фоторезистор. Он устанавливается на счетчик и прикрепляется к нему темным скотчем. Для чтения аналоговых данных от фоторезистора, применен простейший делитель напряжения.

Схема устройства

При мигании светодиода счетчика, на фоторезисторе создается падение напряжения. Arduino считывает это значение через АЦП и сравнивает его с значением напряжения после потенциометра, который подключен к выводу A0.
Полученные данные обрабатываются в программе, а затем передаются к компьютеру через Xbee модуль.

Фрагмент кода для сбора данных с счетчика:

delay(10); //10ms
val_pot = analogRead(POT);   
delay(10); //10ms
val_sensore = analogRead(SENSORE);
if((val_sensore > val_pot)&(flag_acquire == 0)){ 
	flag_acquire = 1;
	digitalWrite(LED, LOW);

В приведённом выше коде происходит сравнение двух напряжений, первое - снимаемое с делителя с фоторезистором, второе напряжение - с потенциометра. Если первое значение напряжения превышает значение напряжения с потенциометра, то устанавливается флаг "flag_acquire = 1". Затем происходит подсчет времени, которое прошло с последнего мигания светодиода.
Для этого, считывается значение внутреннего программного счетчика, которое возвращает количество миллисекунд, прошедшее с момента включения питания контроллера. Для этого, используется команда millis(), см. урок 3 (тайминг)

pre_tmS = cur_tmS;
cur_tmS = millis();
if( cur_tmS > pre_tmS ) {
	tm_diffS = cur_tmS  pre_tmS;
}

Здесь задействовано две переменных pre_tmS и cur_tmS, переменная "cur_tmS" необходима для чтения значения внутреннего счетчика: cur_tmS = millis (); Если условие cur_tmS> pre_tmS выполняется, то происходит замер времени между двумя циклами (вспышками светодиода на энергосчетчике), значение которого записывается в переменную "tm_diffS".
Далее, данные посылаются в ПК через модуль Xbee.

Serial.print("S"); 
Serial.println(tm_diffS); 
delay(10); //10ms

Arduino посылает флаг S, чтобы LabView понял, что передаваемые данные - это значения в реальном времени, а затем сами данные цикла в миллисекундах.
Теперь можно сбросить флаг, когда светодиод счетчика погас:

if((val_sensore < val_pot)&(flag_acquire == 1)){ 
	flag_acquire = 0;
	digitalWrite(LED, HIGH);
	impulsi++;         
	delay(10); //10ms 
}

Здесь мы проверяем установлен ли flag_acquire в 1, и если флаг установлен и напряжение на фоторезисторе упало ниже заданного, то сбрасываем флаг в ноль. Далее идет инкрементируем переменную impulsi, которая служит для подсчет среднего энергопотребления за последние 5 минут.
Данное значение в дальнейшем также передается в LabView с меткой "L".

Полный код программы:

#define POT 0
#define SENSORE 1
#define LED 13
#define LED1sec 12

#define TimeAcquire  1000      //1 сек.
#define Time5Minuts  300      //5 минут = 300 секунд

unsigned long cur_tm = millis();
unsigned long pre_tm = cur_tm;
unsigned int tm_diff = 0;  

unsigned long cur_tmS = millis();
unsigned long pre_tmS = cur_tmS;
unsigned int tm_diffS = 0;  

unsigned int time_flag=0;

unsigned int impulsi=0;
unsigned int val_pot=0;
unsigned int val_sensore=0;
char flag_acquire=0;
char flag_time=0;

void setup() {  

  pinMode(LED, OUTPUT);
  pinMode(LED1sec, OUTPUT);
  Serial.begin(115200);          //  setup serial 115200
  Serial.println("ENEL KW/h reader!");

}  

void loop() {

  //Acquisisco
   delay(10); //10ms
   val_pot = analogRead(POT);    // read the input pin
   delay(10); //10ms
   val_sensore = analogRead(SENSORE);    // read the input pin

  if((val_sensore > val_pot)&(flag_acquire == 0)){
      flag_acquire = 1;
      digitalWrite(LED, LOW);

      pre_tmS = cur_tmS;
      cur_tmS = millis();
      if( cur_tmS > pre_tmS ) {
        tm_diffS = cur_tmS - pre_tmS;
      }
      Serial.print("S");
      Serial.println(tm_diffS);  

      delay(10); //10ms

  }
  if((val_sensore < val_pot)&(flag_acquire == 1)){
      flag_acquire = 0;
      digitalWrite(LED, HIGH);
      impulsi++;          //Увеличиваем счетчик
      delay(10); //10ms
  }

  pre_tm = cur_tm;
  cur_tm = millis();
  if( cur_tm > pre_tm ) {
    tm_diff += cur_tm - pre_tm; //+=
  }
  if( tm_diff >= TimeAcquire ) {
    tm_diff = 0;

    time_flag++;

    if(flag_time==0){
      digitalWrite(LED1sec, HIGH);
      flag_time = 1;
    }else{
      digitalWrite(LED1sec, LOW);
      flag_time = 0;
    }

  }

  if(time_flag>=Time5Minuts){
  //Если прошло более 5 мин. то передаем данные
      Serial.print("L");
      Serial.println(impulsi);
      impulsi = 0;
      time_flag = 0;
  }
}

LabView

Для приема данных использовался модуль XBee UartSbee V3.1.

Интерфейс программы очень простой:

LabView

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

Скачать скетч PDE, файл для LabView (vi) и файл схемы Eagle

Оригинал статьи на английском языке (перевод Колтыков А.В.)


Добавил:  Павел (Admin)  [email protected] | 

Автор:  Неизвестно  Рейтинг@Mail.ru