Sunday, December 20, 2015

Omron PLC USB to 485 Converter and Siemens PLC




This application about how to Omron PLC USB to 485 converter and communication with Siemens PLC using Arduino, USB Host Module and MAX 485 Converter Module .
in detail how it works is:
  1. Read data from Omron PLC USB with Arduino plus USB Host Shield Module.
  2. Transfer data from Arduino to Siemens PLC through MAX 485 converter Module.
  3. Received data from Siemens PLC to Arduino through MAX 485 converter.
  4. Write data from Arduino to Omron PLC USB through USB Host Shield.
Communication between Arduino and Omron PLC using Omron PLC USB Protocol and communication between Arduino and Siemens PLC using 485 Modbus communication.

PLC USB to 485 Converter


Video demonstration:

Omron PLC USB to 485 Converter and Siemens PLC using Arduino




Hardware:

  1. Omron PLC USB Programming, I use CP1L-L10 Omron PLC
  2. Siemens PLC with Modbus Support, I use S7-200 Siemens PLC
  3. 485 Converter / Transceiver Module
  4. Arduino UNO
  5. Arduino USB Host Shield Module
  6. 1 resistor 220 ohm
  7. 2 resistor 330 ohm
  8. DB9 male connector
  9. Adapter for Arduino UNO
  10. Optional Hardware for testing: Push button

Hardware of Omron PLC USB to 485 Converter and Siemens PLC


Hardware connections:

A. Arduino plus USB Host Shield and Omron PLC

Arduino USB Host Shield connected to Omron PLC using USB Cable


B. Arduino USB Host and 485 Converter Module

USB Port from USB Host connect to Omron PLC USB, and for 485 communication connect to 485 device, for device I use Siemens PLC.

Arduino USB Host and 485 Converter Module


C. 485 Converter Module and Siemens PLC

For connection between 485 converter module and Siemens PLC, check link :
http://program-plc.blogspot.com/2015/11/plc-modbus-master-arduino-modbus-slave.html



Software for Arduino Programming:

  1. Arduino IDE : https://www.arduino.cc/en/Main/Software
  2. I use Arduino Version 1.6.6
  3. Library : click here
  4. Unzip and Copy Paste folder name USBHostShield2 and ModbusSlaveLib to ..\arduino-nightly\libraries


Project file:

  1. Download Project File for Arduino, click here
  2. Download Project File for Omron PLC, click here
  3. Download Project File for Siemens PLC, click here


Read/Write data from/to Omron PLC and Siemens PLC

  1. Read from D0 Omron PLC and Write to VW0 (VB0 and VB1) Siemens PLC
  2. Read from VW2 (VB2 and VB3) Siemens PLC and Write to D2 Omron PLC
Read Write data from to Omron PLC and Siemens PLC


Arduino Code for Omron PLC USB to 485 Converter

#include <usbhub.h>
#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
modbusDevice regBank;
modbusSlave slave;

#define RS485TxEnablePin 2
#define RS485Baud 9600
#define RS485Format SERIAL_8E1


USB Usb;
USB_DEVICE_DESCRIPTOR buf;
uint8_t addr;
uint8_t rcode;
uint8_t PLC_State;
uint16_t Omron_PLC_D0_Value;
uint16_t Omron_PLC_D2_Value;
bool PLC_USB_to_485_Converter_RUN = false;

void setup() {
    if (Usb.Init() == -1){
      //PLC USB to 485 Converter did not start
      while(1);   
    }

  PLC_State=0;

regBank.setId(1);
regBank.add(40001);  
regBank.add(40002);
slave._device = &regBank;
slave.setBaud(&Serial,RS485Baud,RS485Format,RS485TxEnablePin);
}

void loop() {
  Usb.Task();
  slave.run();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
  PLC_USB_to_485_Converter_RUN = true;

            switch(PLC_State) {
                    case 0: //Configuration for PLC USB to 485 Converter
                            rcode = PLC_USB_to_485_Converter_Configuration();
                            if(rcode){
                              //PLC USB to 485 Converter did not Ready
                              asm volatile ("  jmp 0");
                            }else{
                              PLC_State=1;
                            }
                            break;

                            
                      case 1: //Omron PLC USB to RUN Mode
                            rcode = Omron_PLC_USB_TO__RUN_Mode() ;
                            if(rcode==0)PLC_State=2;    
                            break;

                      case 2 : //Omron PLC USB Read D0
                          rcode = Omron_PLC_USB_D_Read(0,&Omron_PLC_D0_Value);                          
                          if(rcode==0)PLC_State=3;
                          break;


                        case 3 : // set get modbus data
                          regBank.set(40001, (word) Omron_PLC_D0_Value);
                          Omron_PLC_D2_Value = regBank.get(40002);
                          PLC_State=4;
                          break;

                        case 4 : //Omron PLC USB Write D2
                          rcode = Omron_PLC_USB_D_Write(2, Omron_PLC_D2_Value)  ;                        
                          if(rcode==0)PLC_State=2;
                          break;                                          
            }
            
  }else{
    if(PLC_USB_to_485_Converter_RUN){
        //PLC USB to 485 Converter error
        asm volatile ("  jmp 0"); 
    }
  }


}


void Omron_PLC_USB_to_485_Converter_GetAddresses(UsbDevice *pdev)
{
    UsbDeviceAddress adr;
    adr.devAddress = pdev->address.devAddress;
    addr = adr.devAddress;
}

uint8_t PLC_USB_to_485_Converter_Configuration() {
  uint8_t rcode;
  Usb.ForEachUsbDevice(&Omron_PLC_USB_to_485_Converter_GetAddresses);
  rcode = Usb.getDevDescr(addr, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
  if (rcode) {
    return (rcode);
  }else{
    rcode = Usb.setConf(addr, 0, buf.bNumConfigurations);
    return (rcode);            
  }        
  return (USB_STATE_ERROR);
}


uint8_t Omron_PLC_USB_TO__RUN_Mode() {
  uint8_t rcode;
  uint8_t msg[20] =  {0xAB,0x00,0x11,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00};
  randomSeed(analogRead(0));
  msg[12] = random(1, 255);
  msg[13]  =0x04;
  msg[14]  =0x01;
  msg[15]  =0xFF;
  msg[16]  =0xFF;
  msg[17]  =0x04;
  uint16_t sumcheck=0;
  for(uint16_t i=0; i < 18; i++ ) {
    sumcheck +=msg[i];
  }
        
  msg[18]  =((sumcheck >> 8) & 0xFF);
  msg[19]  =(sumcheck & 0xFF); 

 rcode =  BULK_OUT(0x21,sizeof(msg),msg); 
 if(rcode)
    return rcode;


uint8_t  buf[64];
uint16_t rcvd=0;
rcode = BULK_IN(0x02,&rcvd, buf, 100);
if(rcode)
  return rcode;  

    if (rcvd==19){
        uint8_t val1=buf[rcvd-1];
        uint8_t val2=buf[rcvd-2];
        uint16_t sum1 = val2<<8 | val1;
      uint16_t sum2=0;
      for(uint16_t i=0; i < 17; i++ ) {
      sum2 +=buf[i];
      }
      
        if (sum1==sum2){           
        uint8_t revc[17] = {0xAB,0x0,0x10,0xC0,0x0,0x2,0x0,0x0,0xFB,0x0,0x0,0x0,0x30,0x4,0x1,0x0,0x0};
        for(uint16_t i=0; i < 17; i++ ){
          if(revc[i]!=buf[i] && i!=12)return (2);
        }
        return (0);
    }else{
      return (1);
    }
  }
    
return (1);
}



uint8_t Omron_PLC_USB_D_Read(uint16_t D_number,uint16_t *D_value) {
  uint8_t rcode;
  uint8_t msg[25] =  {0xAB,0x00,0x16,0x80,0x00,0x2,0x00,0x00,0x00,0x00,0x00,0x00};
  randomSeed(analogRead(0));
  msg[12] = random(1, 255);
  msg[13]  =0x01;
  msg[14]  =0x04;
  msg[15]  =0x07;
  msg[16]  =0x00;
  msg[17]  =0x00;
  msg[18]  =0x00;   
  msg[19]  =0x82;
  msg[20]  =(D_number >> 8);
  msg[21]  =(D_number & 0xFF);
  msg[22]  =0x00;
  
  uint16_t sumcheck=0;
  for(uint16_t i=0; i < 23; i++ ) {
    sumcheck +=msg[i];
  }
        
  msg[23]  =((sumcheck >> 8) & 0xFF);
  msg[24]  =(sumcheck & 0xFF);                 

 rcode =  BULK_OUT(0x21,sizeof(msg),msg); 
 if(rcode)
    return rcode;


uint8_t  buf[64];
uint16_t rcvd=0;
rcode = BULK_IN(0x02,&rcvd, buf, 100);
if(rcode)
  return rcode;  

    if (rcvd==24){
        uint8_t val1=buf[rcvd-1];
        uint8_t val2=buf[rcvd-2];
        uint16_t sum1 = val2<<8 | val1;
      uint16_t sum2=0;
      for(uint16_t i=0; i < 22; i++ ) {
      sum2 +=buf[i];
      }

     if (sum1==sum2){  
        uint8_t revc[18] = {0xAB,0x0,0x15,0xC0,0x0,0x2,0x0,0x0,0xFB,0x0,0x0,0x0,0x9C,0x1,0x4,0x0,0x0,0x7};
        for(uint16_t i=0; i < 18; i++ ){
          if(revc[i]!=buf[i] && i!=12)return (2);
        }   
                uint8_t val1=buf[rcvd-3];
                uint8_t val2=buf[rcvd-4];
                uint16_t value = val2<<8 | val1;
        *D_value = value;
        return (0);
    }else{
      return (1);
    }
  }
  

return (1);
}


uint8_t Omron_PLC_USB_D_Write(uint16_t D_number, uint16_t D_value) {
  uint8_t rcode;
  uint8_t msg[25] =  {0xAB,0x00,0x16,0x80,0x00,0x2,0x00,0x00,0x00,0x00,0x00,0x00};
  randomSeed(analogRead(0));
  msg[12] = random(1, 255);
  msg[13]  =0x01;
  msg[14]  =0x02;
  msg[15]  =0x82;
  msg[16]  =(D_number >> 8);
  msg[17]  =(D_number & 0xFF);
  msg[18]  =0x00;   
  msg[19]  =0x00;
  msg[20]  =0x01;
  msg[21]  =(D_value >> 8);
  msg[22]  =(D_value & 0xFF);
  
  uint16_t sumcheck=0;
  for(uint16_t i=0; i < 23; i++ ) {
    sumcheck +=msg[i];
  }
        
  msg[23]  =((sumcheck >> 8) & 0xFF);
  msg[24]  =(sumcheck & 0xFF);          

 rcode =  BULK_OUT(0x21,sizeof(msg),msg); 
 if(rcode)
    return rcode;


uint8_t  buf[64];
uint16_t rcvd=0;
rcode = BULK_IN(0x02,&rcvd, buf, 100);
if(rcode)
  return rcode;  
  

if(rcode)
   return rcode; 
    
    if (rcvd==19){
        uint8_t val1=buf[rcvd-1];
        uint8_t val2=buf[rcvd-2];
        uint16_t sum1 = val2<<8 | val1;
      uint16_t sum2=0;
      for(uint16_t i=0; i < 17; i++ ) {
      sum2 +=buf[i];
      }

        if (sum1==sum2){           
        uint8_t revc[17] = {0xAB,0x0,0x10,0xC0,0x0,0x2,0x0,0x0,0xFB,0x0,0x0,0x0,0x6F,0x1,0x2,0x0,0x0};
        for(uint16_t i=0; i < 17; i++ ){
          if(revc[i]!=buf[i] && i!=12)return (3);
        }
        return (0);
    }else{
      return (2);
    }
  }


return (1);
}


uint8_t BULK_OUT(uint8_t vHXFR,uint16_t nbytes, uint8_t* data) {
    Usb.bytesWr(rSNDFIFO, nbytes, data);
    Usb.regWr(rSNDBC, nbytes);
    Usb.regWr(rHXFR, vHXFR);
    while(!(Usb.regRd(rHIRQ) & bmHXFRDNIRQ));
    Usb.regWr(rHIRQ, bmHXFRDNIRQ);           
  return (0);
}


uint8_t BULK_IN(uint8_t vHXFR,uint16_t *pktsize, uint8_t* data, unsigned long timeout) {
  unsigned long timeout_start = millis() + timeout;
    
  while((long)(millis() - timeout_start) < 0L) {
    Usb.regWr(rHXFR, vHXFR);
      if((Usb.regRd(rHIRQ) & bmRCVDAVIRQ)==bmRCVDAVIRQ){
      uint16_t buff_pktsize = Usb.regRd(rRCVBC);
      *pktsize = buff_pktsize;
      data = Usb.bytesRd(rRCVFIFO, buff_pktsize, data);
      Usb.regWr(rHIRQ, bmRCVDAVIRQ);
      return (0);   
      }   
   }      
             
  return (1);
}


Labels:










Newer Post Older Post Home

You may also like these ebook:

Get Free PLC eBook directly sent to your email,
and email subscription to program-plc.blogspot.com




We hate SPAM. Your information is never sold or shared with anyone.

Your Email Will Be 100% Secured !

Your email is stored safely on Google FeedBurner