가정용 전력분석 장치 개발
적산전력계는 LG산전의 LD1210DR을 사용했습니다. 가격은 대략 5만원 가량 한 것으로 기억합니다.
이 적산 전력계는 1Wh당 1pulse를 출력하고 펄스폭은 70msec입니다.
아래 파형은 적산전력계에서 출력되는 파형입니다. 시간 t 가 길어지면 전력을 적게 사용되고 있는것이고,
시간 t가 짧아지면 전력을 많이 사용하는 것입니다.
즉 주기가 전력에 관련이 있게 됩니다.

            주기[SEC]=논리'1' 펄스폭 + 논리'0'펄스폭(70msec)

전력량의 정의는 1watt가 1시간동안 소비되는 전력을 1wh 라 합니다. 그래서 LD1210DR의 전력은 아래와 같습니다.
 
            전력[W] =3600/주기             

RT.jpg
위의 펄스가 프린터 포트를 통해 pc로 들어오면, 반전이 되서 들어오게 됩니다. 본 실험에서는 pc용 프린터 포트의 busy 라는 입력 단자에
전력계 적산전력펄스 풀력을 연결하는데,  프린터포트의 내부 회로를 보면 반전(invert, notGate)회로로 되어 있습니다.
그래서 프로그램 할때 주의 해야합니다.

PULSE.jpg
                                              <디지털 적산전력계 LD1210DR 원격 검침 단자>

위의 그림은 적산 전력계의 원격검침단자이며, 출력은 OC(Open Collector) 형식으로 되어 있으므로 풀업저항이 필요합니다.
내부적으로는 포토컬플로러 전력부분과 외부펄스출력부분이 분리되어 있으므로 안전하게 사용할수 있을듯합니다.
만약 적산 전력계의 고장으로인해 전원이 pulse출력 쪽으로 흘러 들어 온다면 프린터포트와 pc에 칭명적이 고장을 일으킬수도 있을듯합니다. 독자분들이 설계 할때는 프린터 포트 쪽에 포토 커플러를 연결하여 사용하는것이 더욱 안전할것으로 생각합니다.
필자는 기초적인 전력분석장치를 만들기 위한것이므로 그냥 설계 하기로 합니다. 그리고 LG산전이라는 회사가 전력계 설계 노하우는 믿을만 하므로 그냥 믿고 설계한 면도 있습니다.

아래 회로도는 PC용 프린터 포트에 전력계를 연결하는 회로도 있습니다.
적산 전력계에서 펄스신호가 나오는 가느다란 선이 2개 나옵니다. 이선중에 흰색을 프린터 포트의 11번 핀으로 연결하고
검정색은 25번 핀으로 연결합니다. 프린터 포트의 25번핀은 gnd이고, 11번핀은 busy 입력 포트입니다.
D1의 LED는 전력계에서 1Wh당 펄스를 1번 발생시켜주므로 그때마다 LED가 점등하게 됩니다. 펄스폭시간은 70msec이므로
LED가 70msec동안 점등된후 꺼지게 됩니다.
D1-LED는 프린터 포트의 2번 핀에 연결하여 R1과 연결 후 흰색선과 연결하여 풀업 역할을 하도록 하였습니다.
프린터 포트 2번은 D0출력 포트인데, 이 포트의 신호는 항상 5V 가 출력 되도록 프로그램하여, LED에 전원을 항상 공급하도록 하였습니다.
이렇게 하지 않으면 플업용 전원어뎁터를 따로 부착해야 하는 번거러움 때문에 로직 출력 을 이용하였습니다.
C1의 0.1uF는 PC와 연결되는 케이블의 길이가 길어졌을 경우 노이즈의 발생율이 높아지므로 이를 방지 하기위해 부착되었습니다.
이로 인해 항상 깨끗한 펄스를 유지하게 되었습니다.

TTTT2.jpg

아래 프로그램은 Linux Centos4.4 에서 C언어로 프로그램 되었습니다.
프린터 포트를 직접제어하기 위한 내용은 지난 강좌에 올렸으므로 생략하기로 합니다.
아래 프로그램은 1wh당 펄수폭시간, 현재전력, 1달예상전력량, 1달예상전력요금 을 표시하는 프로그램입니다.
누적 전력 계산을 하지 않으므로 현재발생된 전력 양으로만 계산하게 되므로 예상 전력량및 예상 전력요금이 많은 차이를
보일것입니다. 이를 해결하기 위해서는 누적량의 분석하여 예상전력량을 구해야 할듯합니다.
본강좌에서는 어디 까지나 기초적인 전력계 이므로 여기까지만 하기로 합니다. 
그리고 전력요금계산은 아래표를 참고하여 프로그램하면 됩니다. 전기요금은 그때 그때 달라 질수 있으니 한전사이트를 수시로 들어가서 확인 해봐야 합니다.  아래 표는 일반 가정용 전기요금표이며 활인을 적용 않한 자료입니다. 자세한 사항은  한국전력http://cyber.kepco.co.kr/cyber/index.html 를 참고하세요.
ggg.jpg


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/time.h>
#define BASETIME 100000L

void Settimer(void)
{
    struct itimerval t;
    t.it_interval.tv_sec = 0;
    t.it_interval.tv_usec = 0;
    t.it_value.tv_sec = BASETIME; /* 1시간   */
    t.it_value.tv_usec = 0;
    if (setitimer(ITIMER_REAL, &t, NULL) == -1){ perror("Failed to set virtual timer"); }
}

float Gettimer(void)
{
    struct itimerval t;
    float  diftime;
    if (getitimer(ITIMER_REAL, &t) == -1){perror("Failed to get virtual timer");}
   
    diftime=(float)BASETIME-((float)(t.it_value.tv_sec)+((float)t.it_value.tv_usec/1000000.0));
    return(diftime);   
}

int Initprinterport(void)
{
   int fd;       // File Descripter
   fd = open("/dev/port", O_RDWR);       // open /dev/port in read & write mode 
   if(fd < 0)                                            // open error, fd must be unsigned.
   {
        perror("/dev/port open error");
   }
   return(fd);
}

void Closeprinterport(int fd)
{
  close(fd); 
}

void Outdataprinterport(int fd,unsigned char data)
{
  unsigned char buff[1];
  int op;
  buff[0]=data;
  lseek(fd,0x378,0);
  write(fd,buff,1);
}

int Getbusyprinterport(int fd)
{
  unsigned char buffr[1];
  int op;
  lseek(fd,0x379,0);
  read(fd,buffr,1);
  buffr[0]>>=7;
  op=(int)(0x01&buffr[0]);
  return(op);
}

int main(void)
{
  int i,j;
  float pulse_time_per_1wh,pulse_time_error_revision;
  float power_consumption_month,watt_cost,watt;
  float cost,basic_cost,tax,sum[7];
  int fd;
  float tm,frq;

  basic_cost=6410.0;
  tax=1.137;                               //부가가치세 10% + 전력기반기금 3.7% 즉 0.1+0.037=0.137 올라야하므로 1.137;
  fd=Initprinterport();
  Outdataprinterport(fd,0xff); // DATA PORT<-0XFF :D0 LED 전원공급및 전력계 OC 풀업용

  printf("Copyright MADIXON all reserved\n");
  // 전력계 펄스 초기화 ..
  printf("Init Pulse\n");
  while(1) if(Getbusyprinterport(fd)==0) break;
  while(1) if(Getbusyprinterport(fd)==1) break;
  printf("Measuring Watt\n");
  while(1)    
  {
          while(1) if(Getbusyprinterport(fd)==0) break;   //
          Settimer();
          while(1) if(Getbusyprinterport(fd)==1) break;
          pulse_time_per_1wh=Gettimer();
          if(pulse_time_per_1wh>=0.01)  // 0.01초 이전 데이터는 잡음에 의한 것이므로..
          {
            pulse_time_error_revision=pulse_time_per_1wh+0.070; // 0.070 Falling edge로 펄스 시간으로 측정하지 않으므로 펄스폭 70mSec을 더해준다. 
            watt=(3600.0/pulse_time_error_revision);            // 실시간 watt 계산...
            power_consumption_month=((60.0*60.0*24.0*30.0)/pulse_time_error_revision)/1000.0;  //kwh
            watt_cost=power_consumption_month;
            cost=0;
            for(i=0;i<=6;i++) sum[i]=0.0;
           
            if(watt_cost>500.0){ watt_cost=watt_cost-500.0; cost=(watt_cost*643.9); sum[6]=cost; watt_cost=500.0; }
            if(watt_cost>400.0){ watt_cost=watt_cost-400.0; cost=(watt_cost*366.4); sum[5]=cost; watt_cost=400.0; }
            if(watt_cost>300.0){ watt_cost=watt_cost-300.0; cost=(watt_cost*248.6); sum[4]=cost; watt_cost=300.0; }
            if(watt_cost>200.0){ watt_cost=watt_cost-200.0; cost=(watt_cost*168.3); sum[3]=cost; watt_cost=200.0; }
            if(watt_cost>100.0){ watt_cost=watt_cost-100.0; cost=(watt_cost*113.8); sum[2]=cost; watt_cost=100.0; }
            if(watt_cost>  0.0){ watt_cost=watt_cost-  0.0; cost=(watt_cost* 55.1); sum[1]=cost; watt_cost=  0.0; }
            sum[0]=sum[1]+sum[2]+sum[3]+sum[4]+sum[5]+sum[6];
            cost=(sum[0]*tax)+basic_cost;           
            
            printf(">T1wh=%6.3f[s] CWatt=%10.3f[W] Mkwh=%10.3f[kwh] Mcost=%10.1f[won]\n",pulse_time_error_revision,watt,power_consumption_month,cost);
          } 
  }
  Closeprinterport(fd);

  return 0;
}

실행화면
disp.jpg

실험에 사용된 LG산전 디지털 전력계
LD1210DR.jpg


IMG_1693.jpgIMG_1696.jpg
IMG_1705.jpg
IMG_1709.jpg
     콘덴서를 연결을 않해서 다시 연결하고 몰딩함
IMG_1706.jpg
IMG_1715.jpg