Skip to content

Instantly share code, notes, and snippets.

@pral2a
Last active March 26, 2024 03:58
Show Gist options
  • Save pral2a/f3b4760431761dd8f8b5 to your computer and use it in GitHub Desktop.
Save pral2a/f3b4760431761dd8f8b5 to your computer and use it in GitHub Desktop.
KUKA IO
/*
_ __
/__// //__//_| // )
/ )(__// )( | ((__/
Send values to KUKA from Arduino by encoding them as 1-Byte (0-255) outputing them as
8 digital ouputs in parallel to a KUKA digital IN module. Value is received in KUKA KRC as BYTE
by setting the IO Mapping to 1-Byte output.
*/
const byte totalIO = 8;
const byte parallelIO[totalIO] = {
2,3,4,5,6,7,8,12
};
void setup() {
Serial.begin(9600);
setupParallelByte();
}
void loop() {
int sensor = analogRead(A0);
sensor = map(sensor, 0, 1023, 0, 255);
setParallelByteEnd(sensor);
delay(100);
}
void setParallelByte(byte value){
// Unsigned Char to Parallel Bit register
Serial.print("V: ");
Serial.print(value);
Serial.print("\t|\t ");
for (int i = 0; i < totalIO; i++){
byte thisBit = bitRead(value, i);
Serial.print(thisBit);
digitalWrite(parallelIO[i], !thisBit);
}
Serial.print("\n");
}
void setParallelByteEnd(byte value){
Serial.print("V: ");
Serial.print(value);
Serial.print("\t|\t ");
for (int i = totalIO-1; i >= 0; i--){
byte thisBit = bitRead(value, i);
Serial.print(thisBit);
digitalWrite(parallelIO[i], !thisBit);
}
Serial.print("\n");
}
void setupParallelByte(){
for (int i = 0; i < totalIO; i++){
pinMode(parallelIO[i], OUTPUT);
}
}
/* Test Functions */
void setParallelByteAllOff(){
for (int i = 0; i < totalIO; i++){
digitalWrite(parallelIO[i], HIGH);
}
}
void setParallelByteAllOn(){
for (int i = 0; i < totalIO; i++){
digitalWrite(parallelIO[i], LOW);
}
}
;==========================================================
; IOSYS.INI - Configuration file for the IO-System
;==========================================================
; For configuration help go to the end of this file.
;----------------------------------------------------------
; ATTENTION !!!! Since V5.0 Build13 we have removed the DeviceNet
; driver "dndrv.o". Now you have to use the driver
; "dn2drv.o" and the appropriate syntax (form 2)
[CONFIG]
VERSION=2.00
[DRIVERS]
;CNKE2=21,cnke2CPInit,cnke2drv.o
;DNSC6=20,dnsc6Init,dnsc6drv.o
;DNSC5=19,dnsc5Init,dnsc5drv.o
;DNSC4=18,dnsc4Init,dnsc4drv.o
;DNSC3=17,dnsc3Init,dnsc3drv.o
;CNKE1=16,cnke1CPInit,cnke1drv.o
;INTERBUSPCI=15,ibsCPPciInit,ibpcidrv.o
;DSEIO=14,dseIoInit,dseiodrv.o
;DNSC2=13,dnsc2Init,dnsc2drv.o
;DNSC1=12,dnsc1Init,dnsc1drv.o
;PBMASL=11,pbmsInit,pfbmsdrv.o
DEVNET=2,dnInit,dn2drv.o
;INTERBUS=1,ibusInit,ibusdrv.o
;MFC=0,mfcEntry,mfcdrv.o
[MFC]
INW0=0 ;$IN[1-16]
OUTW0=0 ;$OUT[1-16]
OUTW2=2 ;$OUT[17-32]
[INTERBUS]
INW50=896 ;$IN[401-416]
INW52=898 ;$IN[417-432]
INW54=900 ;$IN[433-448]
INW56=902 ;$IN[449-464]
OUTW50=896 ;$OUT[401-416]
OUTW52=898 ;$OUT[417-432]
OUTW54=900 ;$OUT[433-448]
OUTW56=902 ;$OUT[449-464]
[DEVNET]
;BECKHOFF KL5250 I/O MODULES (MAC_ID 5)
ANOUT2=5,0,12,3 ;$ANOUT[02] - KL4002 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/2 KL modules)
ANOUT3=5,2,12,3 ;$ANOUT[03] - KL4002 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/2 KL modules)
ANIN2=5,0,12,3 ;$ANIN[02] - KL3064 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/4 KL modules)
ANIN3=5,2,12,3 ;$ANIN[03] - KL3064 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/4 KL modules)
ANIN4=5,4,12,3 ;$ANIN[04] - KL3064 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/4 KL modules)
ANIN5=5,6,12,3 ;$ANIN[05] - KL3064 #1 (WORD is 2-Byte, 16-Bits, 1 ANALOG (12 bits), 1/4 KL modules)
INW0=5,0 ;$IN[01-16] - KL1408 #1 - KL1408 #2 (WORD is 2-Byte, 16-Bits, 16 I/O, 2 KL modules)
INW2=5,2 ;$IN[17-33] - KL1408 #3 - KL1408 #4 (WORD is 2-Byte, 16-Bits, 16 I/O, 2 KL modules)
OUTW0=5,4 ;$OUT[01-16] - KL2408 #1 - KL2408 #2 (WORD is 2-Byte, 16-Bits, 16 I/O, 2 KL modules)
OUTB2=5,6 ;$OUT[17-24] - KL2408 #3 (BYTE is 1-Byte, 8-Bits, 8 I/O, 1 KL modules)
;EMERSON SPINDLE CONTROLLER (MAC_ID 9)
INW20=9,0
INW22=9,2
INW24=9,4
INW26=9,6
INW28=9,8
INW30=9,10
INW32=9,12
INW34=9,14
OUTW20=9,0
OUTW22=9,2
OUTW24=9,4
OUTW26=9,6
OUTW28=9,8
OUTW30=9,10
OUTW32=9,12
OUTW34=9,14
[PBMASL]
[DNSC1]
[DNSC2]
[DNSC3]
[DNSC4]
[DNSC5]
[DNSC6]
[DSEIO]
INDW0=0 ;$IN[1-32]
OUTDW0=0 ;$OUT[1-32]
[INTERBUSPCI]
INW50=896 ;$IN[401-416]
INW52=898 ;$IN[417-432]
INW54=900 ;$IN[433-448]
INW56=902 ;$IN[449-464]
OUTW50=896 ;$OUT[401-416]
OUTW52=898 ;$OUT[417-432]
OUTW54=900 ;$OUT[433-448]
OUTW56=902 ;$OUT[449-464]
[CNKE1]
; =ConNo, additional offset,xSize
[CNKE2]
; =ConNo, additional offset,xSize
[VIO]
;INW0=0 ;$IN[1-16]
;INW8=2 ;$IN[65-80]
;OUTW0=0 ;$OUT[1-16]
;OUTW2=2 ;$OUT[17-32]
[O2I]
;INW4=0 ;$IN[33-48]
;INW6=2 ;$IN[49-64]
;OUTW4=0 ;$OUT[33-48]
;OUTW6=2 ;$OUT[49-64]
[IOLINKING]
;==========================================================
;Valid entries have the following formats.
;Arguments in squared brackets are optional.
;If nothing else is mentioned, arguments are decimal.
;Digital Inputs and Outputs:
;
; Form 1:
; {token}{offset}={byte}[,{multip}]
;
; {token} INB (byte), INW (word), INDW (double word)
; OUTB, OUTW, OUTDW
; {offset} byte offset of robot IO System (0..m)
; {byte} byte offset over all peripheral devices (0..m)
; Offset starts with 0 at the first device and
; ends with m at the end of the last device.
; {multip} creats n dataobjects of {token}
; Example:
; OUTW4=2,x3
; Three words of the periphery, starting at byte 2,
; are mapped to the outputs 33-80.
;
; Form 2:
; {token}{offset}={address},{byte}[,{multip}]
;
; {token} INB, INW, INDW, OUTB, OUTW, OUTDW
; {offset} byte offset of robot IO System
; {address} address of a peripheral device (0..m)
; driver specific information, see descr. below
; {byte} byte offset at this peripheral device (0..m)
; Offset starts with 0 at the every device
; driver specific information, see descr. below
; {multip} creats n dataobjects of {token}
; Example:
; INW4=10,0,x2
; Two words of the peripheral device with address 10 and
; up from byte 0 are mapped to the inputs 33-80.
;Analog Inputs and Outputs:
;
; Form 1:
; {token}{num}={byte},{res},{type}[,CAL{factor}]
;
; {token} ANIN or ANOUT
; {num} number of the analog channel (1..i)
; {byte} byte offset over all peripheral devices (0..m)
; Offset starts with 0 at the first device and
; ends with m at the end of the last device.
; {res} resolution of the analog value (number of bits)
; {type} type of analog value
; 0 : right justified without sign
; 1 : right justified with sign
; 2 : left justified without sign
; 3 : left justified with sign
; {factor} maximum analog value, decimal without prefix,
; hexadec. with prefix 0x or octal with prefix 0
; "CAL 0" or no entry sets factor to its maximum
; Example:
; ANIN1=10,12,3
; The analog input No.1 is used. The byte offset on
; peripheral side is 10, the resolution is 12 bit and the
; type of analog value is 3 (left justified with sign).
; The maximum binary analog value is 2047.
;
; Form 2:
; {token}{num}={address},{byte},{res},{type}[,CAL{factor}]
;
; {token} ANIN or ANOUT
; {num} number of the analog channel (1..i)
; {address} address of a peripheral device (0..m)
; driver specific information, see descr. below
; {byte} byte offset at this peripheral device (0..m)
; Offset starts with 0 at the every device
; driver specific information, see descr. below
; {res} resolution of the analog value (number of bits)
; {type} type of analog value
; 0 : right justified without sign
; 1 : right justified with sign
; 2 : left justified without sign
; 3 : left justified with sign
; {factor} maximum analog value, decimal without prefix,
; hexadec. with prefix 0x or octal with prefix 0
; "CAL 0" or no entry sets factor to its maximum
; Example:
; ANIN3=30,0,16,2,CAL 0x6C00
; The analog input No.3 is used. The device address is 30,
; the byte offset at this device is 0, the resolution is
; 16 bit and the type of analog value is 2 (left justified
; without sign). The maximum binary analog value is 27648.
; The CAL-factor is especially required in case of using
; Profibus analog modules.
;particularities:
;[MFC] MFC-IO with KRC1 / CAN-IO-Modul with KRC2
; Entries in form 1
;
;[INTERBUS/INTERBUSPCI] Interbus Phoenix Mast./Slave Cu/LWL
; Entries in form 1
; $IN/OUT[n_1]=(n+1)*8-7
; $IN/OUT[n_8]=(n+1)*8
;[DEVNET] DeviceNet on the KUKA MFC
; Entries in form 2 for driver dn2drv.o
; {address}=DeviceNet MACID
;[DNSC1] DeviceNet LPDN scanner channel 1
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH1 ==> Slave part of LPDN CH1
;
;[DNSC2] DeviceNet LPDN scanner channel 2
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH2 ==> Slave part of LPDN CH2
;
;[DNSC3] DeviceNet LPDN scanner channel 1
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH1 ==> Slave part of LPDN CH1
;
;[DNSC4] DeviceNet LPDN scanner channel 2
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH2 ==> Slave part of LPDN CH2
;
;[DNSC5] DeviceNet LPDN scanner channel 1
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH1 ==> Slave part of LPDN CH1
;
;[DNSC6] DeviceNet LPDN scanner channel 2
; Entries in form 2
; {address} = DeviceNet slave MACID
; {address} = MACID of CH2 ==> Slave part of LPDN CH2
;
;[PBMASL] ProfiBus Siemens Master/Slave CP5614
; Entries in form 2
; {address} = Slave DP-address
; {address} = 127 ==> Slave part of CP5614
;
;[DSEIO] Digital inputs/outputs for KR C3A
; Entries in form 1
;
;[CNKE1] ControlNet 1784PCIC LP-Elektronik
; Entries in form 2
; {address} = ConNo
; {byte} = additional offset
;
;[CNKE2] ControlNet 1784PCIC LP-Elektronik
; Entries in form 2
; {address} = ConNo
; {byte} = additional offset
;
;[VIO] inputs/outputs for Virtual IO driver over TCP/IP
; Entries in form 1
;
;VIO=30,vioInit,vio_drv.o
;
;[O2I] inputs/outputs for 'output to input for software developers'
; Entries in form 1
;
;O2I=31,o2iInit,o2i_drv.o
;
;[IOLINKING] Outputs follow inputs
; Special form:
; $OUT[{bitoffset}]=$IN[{bitoffset}]
;
; {bitoffset} Bit(!)offset in the robot I/O-System,
; starting with 1 (1..MAXIO)
;
; Example: $OUT[512]=$IN[401]
; In this case output nr. 512 (bit 8 of byte 63)
; is linked to input nr. 401 (bit 1 of byte 50)
;
; Notes:
; IOLINKING means outputs follow inputs in the robot
; I/O-system (within ipo-cycle), regardless if they
; are mapped to drivers.
; Port ranges cannot be specified, each bit must be
; linked by itself.
; Only a maximum of MAX_IOLINKS can be configured (set
; in progress.ini, if this value is increased, robot
; functionality cannot be guaranteed!).
;----------------------------------------------------------
; 04/02/02 section [IOLINKING] added
[END SECTION]

KUKA IO

This is a WIP documentation on the setup and usage of KUKA IO modules

IO Bus and Modules

Industrial IO Modules come in different filed buses depending on the KRC setup. DeviceNet, Profibus and EtherCat standards are available depending on the KRC. Most KRC use Beckhoff modules. Most common modules are digital IN, digital OUT, analog IN and analog OUT.

KRC IO Configuration

Important notice: Digital IO can be accessed individually as bits or can be addressed together as byte, representing the 8 IO on a module as a single value.

KR C3 and below

Configuration is defined on the iosys.ini file at KRC/ROBOTER/INIT/iosys.ini. Documentation is provided at the end of the same file. See an example iosys.ini.

KR C4 and after

Configuration can be done using the WorkVisual software from KUKA, accessing the robot KRC via LAN. By knowing the Robot KRC LAN IP we can download the configuration on our local WorkVisual software. KRC bus structure is provided as a tree structure on the GUI. The IO Mapping tool is used to assign bus modules addresses to the KRC IOs.

KUKA WorkVisual

Basic Arduino tests

Simple bidirectional communication between KUKA industrial IO modules and Arduino. Optocouplers are used to isolate both circuits for safety and to deal with the two different logic voltage levels: Arduino 5V and KUKA IO's 24V. This is a basic test circuit and should not be use for production.

KUKA WorkVisual

Download the Fritzing

@elektro-slobbo
Copy link

Hi
and thanks for sharing!

I'm a bit confused, please help me.
The text says you send 1 Byte over 8 outputs.
The pins 2,3,4,5,6,7,8,12 are config. as output
but only 4 are connected in the schematic.
What is the serail command for?
Which sensor ( analogRead(A0)) is connected?
What are you doing in you main routine?

Can I use 2 Analog INPUT/OUPUTS to get
a serial communcation running with KRC2?

Best regards & thanks for an answer
Bernd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment