CP1L-L10 Omron PLC use USB only for communication with other device such as Arduino, Raspberry Pi and other devices.
For communication with CP1L-L10 using Omron PLC USB Protocol.
This PLC application about Omron PLC USB and connected to Arduino.
Iin Arduino, usually connect to output analog, expand I/O, reading sensor, SCADA communication and others applications.
This application same with the application on my previous article about Omron PLC USB Protocol and Raspberry Pi
Sample case:
The image below about Omron PLC and Arduino that are discussed in this article:
Video demonstration :
For communication with CP1L-L10 using Omron PLC USB Protocol.
This PLC application about Omron PLC USB and connected to Arduino.
Iin Arduino, usually connect to output analog, expand I/O, reading sensor, SCADA communication and others applications.
This application same with the application on my previous article about Omron PLC USB Protocol and Raspberry Pi
Sample case:
- Arduino to CP1L-L10 Omron PLC (D2 memory): Turning potentiometer (Analog Input) and moving the CP1L PLC outputs.
- CP1L-L10 Omron PLC (D0 memory) to Arduino: Pressing the switch (PLC Input) and increase the numbers on voltmeter /multi tester (Analog Output)
The image below about Omron PLC and Arduino that are discussed in this article:
Video demonstration :
USB Communication between CP1L-L10 Omron PLC USB and Arduino plus USB Host Shield
Hardware for Omron PLC USB and Arduino
- CP1L-L10 Omron PLC
- Arduino UNO
- Arduino USB Host Shield is based on the MAX3421E
- Optional for testing :
- 1 piece potentiometer
- 2 pieces switch
- Voltmeter / multi tester
Hardware Connections of Omron PLC USB and Arduino
Software for Omron PLC USB and Arduino
- Arduino Software (IDE), I use Arduino 1.6.6 Hourly Build : https://www.arduino.cc/en/Main/Software
- Arduino USB Host Shield Library, click here Copy paste : USBHostShield2 folder to .. \arduino-nightly\libraries
Project File for Omron PLC USB and Arduino
- for Upload to Arduino, click here
- for Transfer to CP1L-L10 Omron PLC, click here
How does the work of Omron PLC USB and Arduino
- Press Switch 1 (PLC Input I0.00 is ON) and then Voltmeter value is ~ 1.60 Volt
- Press Switch 2 (PLC Input I0.01 is ON) and then Voltmeter value is ~ 3.20 Volt
- Press both switches ( I0.00 ON and I0.01 ON) ) and then Voltmeter value is ~ 4.80 Volt
- Turning the potentiometer on Arduino and then light is lit on PLC Output (based on binary value from 0 to 15)
Arduino Code for Access Omron PLC USB
#include <usbhub.h> #define VendorID 0x0590 #define ProductID 0x005B 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 USB_RUN = false; static unsigned long timeout=1000; const int analogInPin = A0; // Potentiometer const int analogOutPin = 5; // VoltMeter uint16_t PotentiometerValue = 0; uint16_t VoltMeterValue = 0; void setup() { Serial.begin(115200); if (Usb.Init() == -1){ Serial.println("OSC did not start and Will be Reset"); while(1); } randomSeed(analogRead(0)); Serial.println("PLC START"); PLC_State=0; } void loop() { Usb.Task(); if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) { USB_RUN = true; switch(PLC_State) { case 0: // Omron PLC Find rcode = Omron_PLC_Find(VendorID, ProductID); if(rcode){ Serial.println("Omron PLC Not Found"); while(1); }else{ PLC_State=1; } break; case 1: //Command Omron PLC for RUN Mode rcode = Command_Omron_PLC_RUN_Mode(); if(rcode==0)PLC_State=2; break; case 2: // Received Omron PLC RUN Mode rcode = Receive_Omron_PLC_RUN_Mode(); if(rcode==0)PLC_State=3; break; case 3: // Command Omron PLC for D memory Read rcode = Command_Omron_PLC_D_Read(0); if(rcode==0)PLC_State=4; break; case 4: // Received Omron PLC from D memory Read // Save to Omron_PLC_D0_Value rcode = Receive_Omron_PLC_D_Read(&Omron_PLC_D0_Value); Serial.println(Omron_PLC_D0_Value,DEC); VoltMeterValue = map(Omron_PLC_D0_Value, 0, 255, 0, 255); analogWrite(analogOutPin, VoltMeterValue); if(rcode){ PLC_State=3; // error goto command again }else{ PLC_State=5; // no error goto next } break; case 5: // Command Omron PLC for D memory Write //Omron_PLC_D2_Value = Omron_PLC_D0_Value ; PotentiometerValue = analogRead(analogInPin); Omron_PLC_D2_Value = map(PotentiometerValue, 0, 1020, 0, 255); rcode = Command_Omron_PLC_D_Write(2,Omron_PLC_D2_Value); if(rcode==0)PLC_State=6; break; case 6: // Received Omron PLC for D memory Write rcode = Receive_Omron_PLC_D_Write(); if(rcode){ PLC_State=5; // error goto command again }else{ PLC_State=7; // no error goto next } break; case 7: // Finish PLC_State=3; break; } }else{ if(USB_RUN){ Serial.println("USB Not RUN and Will be Reset"); asm volatile (" jmp 0"); } } } void GetAddresses(UsbDevice *pdev) { UsbDeviceAddress adr; adr.devAddress = pdev->address.devAddress; addr = adr.devAddress; } uint8_t Omron_PLC_Find(uint16_t Vendor_ID, uint16_t Product_ID) { uint8_t rcode; Usb.ForEachUsbDevice(&GetAddresses); rcode = Usb.getDevDescr(addr, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf); if (rcode) { return (rcode); }else{ if(buf.idVendor == Vendor_ID && buf.idProduct == Product_ID){ rcode = Usb.setConf(addr, 0, buf.bNumConfigurations); return (rcode); }else{ return (USB_STATE_ERROR); } } return (USB_STATE_ERROR); } uint8_t Command_Omron_PLC_RUN_Mode() { uint8_t rcode; uint8_t msg[20] = {0xAB,0x00,0x11,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00}; 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 = OmronPLCsend(sizeof(msg),msg); if(rcode) return rcode; return ( rcode); } uint8_t Receive_Omron_PLC_RUN_Mode() { uint8_t rcode; uint8_t buf[64]; uint16_t rcvd=0; rcode = OmronPLCreceived(&rcvd,buf); // RecPrintHEX(rcvd,buf); 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 ( rcode); } uint8_t Command_Omron_PLC_D_Read(uint16_t D_number) { uint8_t rcode; uint8_t msg[25] = {0xAB,0x00,0x16,0x80,0x00,0x2,0x00,0x00,0x00,0x00,0x00,0x00}; 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 = OmronPLCsend(sizeof(msg),msg); return ( rcode); } uint8_t Receive_Omron_PLC_D_Read(uint16_t *D_value) { uint8_t rcode; uint8_t buf[64]; uint16_t rcvd=0; rcode = OmronPLCreceived(&rcvd,buf); //RecPrintHEX(rcvd,buf); 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 Command_Omron_PLC_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}; 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 = OmronPLCsend(sizeof(msg),msg); return ( rcode); } uint8_t Receive_Omron_PLC_D_Write() { uint8_t rcode; uint8_t buf[64]; uint16_t rcvd=0; rcode = OmronPLCreceived(&rcvd,buf); //RecPrintHEX(rcvd,buf); 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); } void RecPrintHEX(uint16_t nbytes, uint8_t* data){ if(nbytes==0)return; for(uint16_t i=0; i < nbytes; i++ ) { Serial.print(" ,0x"); Serial.print(data[i],HEX); } Serial.println(""); } uint8_t OmronPLCsend(uint16_t nbytes, uint8_t* data) { Usb.bytesWr(rSNDFIFO, nbytes, data); Usb.regWr(rSNDBC, nbytes); Usb.regWr(rHXFR, 0x21); while(!(Usb.regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ Usb.regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ return (0); } uint8_t OmronPLCreceived(uint16_t *pktsize, uint8_t* data) { //unsigned long timeout_start = millis() + USB_XFER_TIMEOUT; unsigned long timeout_start = millis() + timeout; while((long)(millis() - timeout_start) < 0L) { Usb.regWr(rHXFR, 0x2); 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); // Clear the IRQ & free the buffer return (0); } } return (1); }