IMG_1715.jpg

LD1210DR.jpg
실행결과 : 시간대별 소비전력


watt.JPG
실행결과 : 누적전력량[wh]과 실시간소비전력
watth.JPG

LD1210DR-040 적산전력계에서 전력펄스 신호를 받아  파일로 저장하는 프로그램입니다.
파일은 날짜.kwh, 날짜.cnt, curpower.kwh 이렇게 만들어집니다.
날짜.* 은 하루에 하나씩만들어 집니다. curpower.kwh는 현재 전력량입니다.

출력파일예)
20090114.kwh
20090114 22:48:42 Wed, 4.078,   882.850,   635.652,  213988.0,
20090114 22:48:46 Wed, 4.017,   896.256,   645.304,  221054.3,
20090114 22:48:50 Wed, 4.049,   889.173,   640.205,  217320.9,
20090114 22:48:54 Wed, 3.997,   900.740,   648.533,  223418.1,
20090114 22:48:58 Wed, 3.888,   925.990,   666.713,  236728.0,
20090114 22:49:02 Wed, 4.025,   894.474,   644.022,  220115.4,
20090114 22:49:06 Wed, 3.351,  1074.366,   773.544,  314940.5,

20090114.cnt
206

curpower.kwh
pulsewidthSec,watt,monthKwh,MonthCost
 4.550,   791.273,   569.717,  165715.7,




power.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.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;
  int    pulsecount;
  float  tm,frq;
  FILE   *fw;
  struct tm *tm_ptr, time_struc;
  time_t the_time;
  char   buffer[255];
  char   filename[255];

  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;        
      
            (void) time(&the_time);
            tm_ptr = localtime(&the_time);

            strftime(buffer,23,"%Y%m%d %H:%M:%S %a",tm_ptr);
            strftime(filename,23,"./%Y%m%d.kwh",tm_ptr);
                   //  펄스폭,순간와트,한달예상kwh,한달예상요금
            fw=fopen(filename,"awt");
            fprintf(fw,"%s,%6.3f,%10.3f,%10.3f,%10.1f,\n",buffer,pulse_time_error_revision,watt,power_consumption_month,cost);
            fclose(fw);

            fw=fopen("./curpower.kwh","wt");
            fprintf(fw,"pulsewidthSec,watt,monthKwh,MonthCost\n");
            fprintf(fw,"%6.3f,%10.3f,%10.3f,%10.1f,\n",pulse_time_error_revision,watt,power_consumption_month,cost);
            fclose(fw);

            strftime(filename,23,"./%Y%m%d.cnt",tm_ptr);
//            printf("%s\n",filename);
           
            fw=fopen(filename,"rt");
            if(fw==NULL) pulsecount=0;
            else
            {
               fread(buffer,1,30,fw);
               pulsecount=atoi(buffer);
               fclose(fw);
            }  
  //          printf("%s\n",buffer);
            pulsecount++;
           
            fw=fopen(filename,"wt");
            fprintf(fw,"%d\n",pulsecount);
            fclose(fw);
                  
          } 
  }
  Closeprinterport(fd);

  return 0;
}

위의 소스를 컴파일 하여 power라는 파일로 만들었습니다.

$gcc power

$cp ./a.out /var/www/html/PowerMeasure

$vi /etc/rc.local
     cd /var/www/html/PowerMeasure
     ./power &

$/sbin/shutdown -r 0