plc数据采集初探

来源:互联网 发布:js是什么文件格式 编辑:程序博客网 时间:2024/05/21 21:48

这段时间,项目需要,要采集plc上的数据,上传服务器,作为大数据采集方。

以前没有使用过plc,感觉plc是象单片机一样的存在。

从x部借来一台plc,西门子的s7-200smart ,据说这个是入门级的plc,但价钱还是很贵的,不是单片机能比的。

从外部接口来看,有一个网口,一组output接口,一组input接口,还有一个db9的rs485接口。还有一组指示灯。

具体如下图:



开发plc的小哥给我讲了一下读,这东西是破解才行,破解方法就是去抓组态软件的数据包,这些人家都做了。

plc的ip和port是可设置的,所以我拿过来,把这些当成一个Socket client读就可以了。

流程:

1.建Socket

2.握手

3.数据读写

4.关闭Socket


详细解说,第一步就是一个普通的socket建立,只是port号和ip要设好,tcp方式。

第2步握手:

static int plcnet_shake_hands()
{
int i,num;
unsigned char recvdata[1024];

unsigned char shake_hands1[] =   {0x03,0x00,0x00,0x16,0x11,0xE0,0x00,0x00,0x00,0x09,0x00,0xC1,0x02,0x01,0x01,0xC2,0x02,0x01,0x01,0xC0,0x01,0x0A};
unsigned char shakeret1[] = {0x03,0x00,0x00,0x16,0x11,0xD0,0x00,0x09,0x00,0x01,0x00,0xC0,0x01,0x0A,0xC1,0x02,0x01,0x01,0xC2,0x02,0x01,0x01};
unsigned char shake_hands_2_send[] =   {0x03,0x00,0x00,0x19,0x02,0xF0,0x80,0x32,0x01,0x00,0x00,0xCC,0xC1,0x00,0x08,0x00,0x00,0xF0,0x00,0x00,0x01,0x00,0x01,0x03,0xC0};

unsigned char shake_hands_2_return[] = {0x03,0x00,0x00,0x1B,0x02,0xF0,0x80,0x32,0x03,0x00,0x00,0xCC,0xC1,0x00,0x08,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x01,0x00,0x01,0x00,0xF0};

    if(send(sockfd, shake_hands1, sizeof(shake_hands1),0) == -1)
    {
          printf("ERROR: Failed to sent string.\n");
    }

memset(recvdata,0,1024);
num=recv(sockfd, recvdata, LENGTH, 0);
  if(send(sockfd, shake_hands2, sizeof(shake_hands2), 0) == -1)
    {
          printf("ERROR: Failed to sent string.\n");
    }
 

memset(recvdata,0,1024);
recv(sockfd, recvdata, LENGTH, 0);
return 0;
}

第3步是数据读写,但我们的数据采集都是读,所以只做了个读:

int plcread(unsigned int base,unsigned int kuai,unsigned  int qu,unsigned int lenths,unsigned char *data)
{
int i,j;
int num;
unsigned int tmp=0;
unsigned char recvdata[1024];
unsigned char cmd[512]={0x03,0x00,0x00,0x1f,0x02,0xf0,0x80,0x32,0x01,0x00,0x00,0x00,0x1b,0x00,0x0e,0x00,0x00,0x04,0x01,0x12,0x0a,0x10,0x02};//22

//lenths
tmp=lenths;cmd[23]=(tmp&0xff00)>>8;cmd[24]=tmp&0xff;  


//kuai
     tmp = kuai; cmd[25]=(tmp&0xff00)>>8;cmd[26]=tmp&0xff;  

//qu
tmp = qu;cmd[27]=(tmp&0xff00)>>8;cmd[28]=tmp&0xff;   

//addrbase
 tmp = base*8;cmd[29]=(tmp&0xff00)>>8;cmd[30]=tmp&0xff;   

//   printf("addr:0x%04x 0x%02x 0x%02x \n",tmp,cmd[29],cmd[30]);
      if((num = send(sockfd, cmd, 31, 0)) == -1)
      {
          printf("ERROR: Failed to sent string.\n");
      }
      

memset(recvdata,0,1024);
num = recv(sockfd, recvdata, LENGTH, 0);


j=0;
for(i=0;i<num;i++)
{
printf("0x%02x ",recvdata[i]);
}
printf("\n");

}

参数就是plc的区,块,读的起始地址,读的长度。数据返回是在包最后字节里面。

第4步是关闭,把socket关闭完事。


只玩了几天,理解不深,后面会有几种型号的plc支持。




原创粉丝点击