/* *****************************************************************************

    Программа для снятия показаний счетчика ЦЭ6827М1 через преобразователь

    RS232-RS485 для роутера BR6104KP на базе процессора ADM5120 и Linux 2.4.32

                                V 0.15 05.05.2005 adm5120.narod.ru

   *****************************************************************************

Команды для счетчика:

T1      00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 80 40 04 86 03

T2      00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 80 44 04 FA 03

T3      00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 80 48 04 7E 03

T янв   00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 C3 B0 04 CA 03

T Фев   00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 C3 00 04 F2 03

T март  00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 C3 10 04 B7 03

М.Мощн. 00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 80 34 16 02 40 03

1/2 ч.  00 00 00 00 00 00 00 02 02 16 03 32 04 00 00 00 00 00 C2 6A 16 02 90 03

Ответы счётчика :





*/

      #include <sys/types.h>

      #include <sys/stat.h>

      #include <fcntl.h>

      #include <termios.h>

      #include <stdio.h>

        

      #define BAUDRATE B2400			/* скорость порта 2400 бод */

      #define MODEMDEVICE "/dev/ttyS1"	/* порт обмена */

      #define _POSIX_SOURCE 1 			/* POSIX-совместимый источник */

      #define ADD 26369.69			/* слагаемое для получения знач старого сч */

      

      //#define debug 1 

       

      main(int argc, char *argv[])

      {

        int fd,c,i,j,k,m,res;

	double t,t1,t2,t3;

        struct termios oldtio,newtio;

  /* Начальные байты блока передачи,содержащие адрес счётчика*/

         unsigned char pre[18] = {0,0,0,0,0,0,0,2,2,0x16,3,0x32,4,0,0,0,0,0};

  /* Длина,конечные байты блока передачи содержащие команду и контрольную сумму */       

	 unsigned char cmd[5][10]= {

		{5, 0x80, 0x40, 0x04, 0x86, 0x03}, /* T1 */

		{5, 0x80, 0x44, 0x04, 0xFA, 0x03}, /* T2 */

		{5, 0x80, 0x48, 0x04, 0x7E, 0x03}, /* T3 */

		{6, 0x80, 0x34, 0x16, 0x02, 0x40, 0x03}, /* M */

		{6, 0xC2, 0x6A, 0x16, 0x02, 0x90, 0x03}, /* H */

           };

   /* смещение от конца до первой цифры, множитель, количество знаков */

	unsigned char rec[7][10]= {

		{3, 1, 4}, /* T1 */

		{3, 1, 4}, /* T2 */

		{3, 1, 4}, /* T3 */

		{4,60, 1}, /* M */

		{3, 2, 2}, /* H */

        	{0, 0, 0}, /* OLD */

        	{0, 0, 0}, /* TS */

	 	   };

	unsigned char argu[7][10]= {

		{"T1"},

		{"T2"},

		{"T3"},

		{"M"},

		{"H"},

		{"OLD"},

		{"TS"},

		};

	unsigned char bufr[255];

      if  ( argc == 1 ) {

	    printf("program for CE6827M1\nversion 0.15\nCOM=%s\n",MODEMDEVICE);

	    printf("ce [T1][T2][T3][OLD][M][H][TS]\n ");

            exit(-1);

	}

	fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); 

        if (fd <0) { 

         perror(MODEMDEVICE);

         printf ("error_open %s\n",MODEMDEVICE);

         exit(-1);

          }

        tcgetattr(fd,&oldtio); /* сохранение текущих установок порта */

        bzero(&newtio, sizeof(newtio));

// 2400 bod, 8 bit data, 2-stop, no paritet

        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD |CSTOPB ;

        newtio.c_iflag = IGNPAR | ICRNL;

        newtio.c_oflag = 0;

/* set input mode (non-canonical, no echo,...) */

        newtio.c_lflag = 0;

        newtio.c_cc[VTIME]    = 0;   /* посимвольный таймер не используется */

        newtio.c_cc[VMIN]     = 0;   /* не блокированное чтение */        

        tcflush(fd, TCIFLUSH);

        tcsetattr(fd,TCSANOW,&newtio);

	for ( k = 1; k < argc; k++) 

	 for ( m = 0; m < 7; m++) {

	  if (strcmp(argv[k],argu[m]) == 0) {

	   printf("%3s ",argu[m]); 

	   t=0;

	   switch (m) {

	    case 5:t=ADD;

	    case 6:t=t+t1+t2;

	           printf("=%8.2f kW/h\n",t);

	           break;

	    default:

	    write(fd,pre,18);

	    write(fd,&cmd[m][1],cmd[m][0]);

	    sleep(1);			/* ждём секунду входных данных */

	    res = read(fd,bufr,255);	/* считываем что есть в буфере */

#if debug	

	    printf("\nbyte=%d\n",res);

	    for (i = 0;i < res; i++) { printf("%2X ",bufr[i]);}

#endif		   

	    if ( res < ( cmd[m][0]+19+rec[m][0]) ) { printf("timeout.. %d\n",res ); }

		else {

	     j = res - rec[m][0];

	     t = 0; 

	     for ( i = 0; i < rec[m][2]; i++){ 

	     t = bufr[j-i]+t*100;

	     switch (bufr[j-i]) { /*убираем лишний символ перед 2 и 3   */

	       case 2:case 3: --j ;

	       }

	      }

	     t = t/100*rec[m][1];

	     switch (m) {

	      case 0:t1 = t;break;

	      case 1:t2 = t;break;

	      case 2:t3 = t;break;	   

             }

	     printf("=%8.2f kW/h\n",t);

	    }

	   } 

	  }

	 }  

// востановить состояние порта

        tcsetattr(fd,TCSANOW,&oldtio);

        close(MODEMDEVICE);

#if debug	

	printf("\nclose\n");

#endif	

      }

      

    



Hosted by uCoz