You are on page 1of 11

http://program-plc.blogspot.com.es/2016/01/collaboration-between-arduino-robot-arm.html?

utm_source=feedburner&utm_medium=email&utm_campaign=Feed:+PLC-Learning-Ladder+(PLC,
+SCADA,+Automation,+PLC+Programming,+PLC+eBook,+Free+PLC+Training)

Collaboration between Arduino Robot Arm (MeArm) and PLC


(Programmable Logic Controller)
in this topic discusses learning robot arm and Arduino or Arduino Robot Arm controlled by
PLC.

for Arduino robot arm movement by the PLC with movement data from PLC memory.

Communication between Arduino Robot Arm with PLC using Modbus communication.

This application is used to learn a robotic arm controlled by PLC.

for Robot Arm using MeArm, and MeArm is Robot Arm with 4 DOF Robot Arm.

Build a Robot Arm


I use acrylic with 3 mm thick
for more details can be found in the link http://mearm.com

Video demonstration:
Arduino Robot Arm (MeArm) - Modbus - PLC
Hardware Required for Arduino Robot Arm
1. MeArm

2. 4 pieces Servo MG90S

3. 5 Volt Power Supply for Servos

4. Arduino UNO

5. Power Supply for Arduino

6. TTL to RS232 Module

7. PLC with Slave Modbus support, I use Siemens S7-200

8. RS232 PLC Cable

9. Limit switch for Object Detection


Hardware Connections for Arduino Robot Arm
1. Limit Switch connect to PLC Input I0.0

2. TTL - RS232 Module and Arduino UNO :

TTL - RS232 Module Arduino UNO


VCC 5V
GND GND
RX RX (Pin 0)
TX TX (Pin 1)

3. TTL - RS232 Module connect to RS232 PLC Cable

4. RS232 PLC Cable Connect to PLC

5. 4 pieces Servo and Power Supply :

Color servo cables Power Supply 5 Volt


Brown + 5 Volt
Red GND / - 5 Volt
All Servo do not connect to 5 Volt from Arduino,
If all servo connect to 5 volt Arduino there will be errors servo movement

6. 4 pieces Servo and Arduino UNO

MeArm Color servo cable Arduino UNO


Rotary Servo Orange Pin 10
Left Side Servo Orange Pin 5
Right Side Servo Orange Pin 6
Claw Servo Orange Pin 9

Software and Libraries


1. I use Arduino Software version 1.6.6
2. Libraries , click here
Copy paste libraries to Arduino software folder .. \libraries

Project File download


1. Arduino Project File, click here
2. Siemens PLC S7-200 Project File, click here

Modbus Communication between Arduino Robot Arm


(MeArm) and PLC
1. Arduino UNO such as Modbus Master
2. Siemens PLC S7-200 such as Modbus Slave

Arduino Robot Arm (MeArm) Movement from PLC


1. MeArm Rotary Servo movement from Modbus 40001 / VW0 of S7-200

2. MeArm Left Side Servo movement from Modbus 40002 / VW2 of S7-200
3. MeArm Right Side Servo movement from Modbus 40003 / VW4 of S7-200

4. MeArm Claw Servo movement from Modbus 40004 / VW6 of S7-200

5. Feed Rate movement from Modbus 40005 / VW8 of S7-200

6. Example of MeArm Movement :

o Rotary move to 90 degree

o Left Side move to 82 degree

o Right Side move to 60 degree

o Claw move to 25 degree

o Feed Rate is 20 degree per 100 milliseconds

o In PLC Ladder Programming is :

7. MeArm Movement Actual :

o Read Rotary from Modbus 40006 / VW10 of S7-200

o Read Left Side from Modbus 40007 / VW12 of S7-200


o Read Right Side from Modbus 40008 / VW14 of S7-200

o Read Claw from Modbus 40009 / VW16 of S7-200

o Read Feed Rate from Modbus 40010 / VW18 of S7-200

Arduino Robot Arm (MeArm) Movement Sequence from PLC


Movement Sequence from movement 1 to movement 12,
I use Sequence Programming for PLC

Arduino Code for Robot Arm


#include <Servo.h>
#include <SimpleModbusMaster.h>

#define MODBUSSlaveAddress 1
#define MODBUSbaud 9600
#define MODBUSformat SERIAL_8E1
#define MODBUStimeout 1000
#define MODBUSpolling 1
#define MODBUSretry_count 0
#define MODBUSTxEnablePin 13

enum
{
MODBUSPACKET1,
MODBUSPACKET2,
MODBUSTOTAL_NO_OF_PACKETS
};

Packet MODBUSpackets[MODBUSTOTAL_NO_OF_PACKETS];

packetPointer MODBUSpacket1 = &MODBUSpackets[MODBUSPACKET1];


packetPointer MODBUSpacket2 = &MODBUSpackets[MODBUSPACKET2];

unsigned int MODBUSreadRegs[5];


unsigned int MODBUSwriteRegs[5];

const int SERVOS = 4;


int PIN[SERVOS], MIN[SERVOS], MAX[SERVOS], INITANGLE[SERVOS];
int POSAngle[SERVOS];
Servo MeArmServo[SERVOS];
uint16_t FEED_RATE;

void setup() {
//Rotary Servo
PIN[0] = 10;
MIN[0] = 0;
MAX[0] = 180;
INITANGLE[0] = 90;

//Left Side
PIN[1] = 5;
MIN[1] = 20;
MAX[1] = 150;
INITANGLE[1] = 90;

//Right Side
PIN[2] = 6;
MIN[2] = 0;
MAX[2] = 110;
INITANGLE[2] = 10;

//Claw Servo
PIN[3] = 9;
MIN[3] = 0;
MAX[3] = 130;
INITANGLE[3] = 25;

modbus_construct(MODBUSpacket1, MODBUSSlaveAddress, READ_HOLDING_REGISTERS, 0,


5, MODBUSreadRegs);

modbus_construct(MODBUSpacket2, MODBUSSlaveAddress, PRESET_MULTIPLE_REGISTERS,


5, 5, MODBUSwriteRegs);

modbus_configure(&Serial, MODBUSbaud, MODBUSformat, MODBUStimeout,


MODBUSpolling, MODBUSretry_count, MODBUSTxEnablePin, MODBUSpackets,
MODBUSTOTAL_NO_OF_PACKETS);

MeArmServo[1].attach(PIN[1]);
MeArmServo[1].write(INITANGLE[1]);
delay(1000);
MeArmServo[2].attach(PIN[2]);
MeArmServo[2].write(INITANGLE[2]);
delay(1000);
MeArmServo[3].attach(PIN[3]);
MeArmServo[3].write(INITANGLE[3]);
MeArmServo[0].attach(PIN[0]);
MeArmServo[0].write(INITANGLE[0]);

MODBUSwriteRegs[0] = INITANGLE[0];
MODBUSwriteRegs[1] = INITANGLE[1];
MODBUSwriteRegs[2] = INITANGLE[2];
MODBUSwriteRegs[3] = INITANGLE[3];
yield();
}

void loop() {
modbus_update();
POSAngle[0] = MODBUSreadRegs[0];
POSAngle[1] = MODBUSreadRegs[1];
POSAngle[2] = MODBUSreadRegs[2];
POSAngle[3] = MODBUSreadRegs[3];
FEED_RATE = MODBUSreadRegs[4];
Move_Pos(POSAngle[0] ,POSAngle[1], POSAngle[2], POSAngle[3], FEED_RATE);

for (int i = 0; i < SERVOS; i++){


MODBUSwriteRegs[i] = MeArmServo[i].read();
}

MODBUSwriteRegs[4] = FEED_RATE;

}
void Move_Pos(uint16_t Rotary, uint16_t Left, uint16_t Right, uint16_t
Claw,uint16_t deg_per_100ms) {
if(deg_per_100ms==0)return;
if(Rotary<MIN[0])Rotary=MIN[0];
if(Rotary>MAX[0])Rotary=MAX[0];

if(Left<MIN[1])Left=MIN[1];
if(Left>MAX[1])Left=MAX[1];

if(Right<MIN[2])Right=MIN[2];
if(Right>MAX[2])Right=MAX[2];

if(Claw<MIN[3])Claw=MIN[3];
if(Claw>MAX[3])Claw=MAX[3];

int Axis_delta[4] = {0,0,0,0};

int Rotary_delta = MeArmServo[0].read() - Rotary;


if(Rotary_delta<0)Rotary_delta*=-1;
Axis_delta[0] = Rotary_delta;

int Left_delta = MeArmServo[1].read() - Left;


if(Left_delta<0)Left_delta*=-1;
Axis_delta[1] = Left_delta;

int Right_delta = MeArmServo[2].read() - Right;


if(Right_delta<0)Right_delta*=-1;
Axis_delta[2] = Right_delta;

int Claw_delta = MeArmServo[3].read() - Claw;


if(Claw_delta<0)Claw_delta*=-1;
Axis_delta[3] = Claw_delta;

int index_max = getIndexOfMaximumValue(Axis_delta, 4);

int Max_Deg_delta = Axis_delta[index_max];

float ms_factor = 100.0;


float buf_max_deg_delta = Max_Deg_delta * ms_factor;
float buf_max_time = buf_max_deg_delta /deg_per_100ms;
float buff_Rotary_time = buf_max_time/Axis_delta[0];
float buff_Left_time = buf_max_time/Axis_delta[1];
float buff_Right_time = buf_max_time/Axis_delta[2];
float buff_Claw_time = buf_max_time/Axis_delta[3];

uint8_t time_factor = 1;
uint16_t Rotary_time = (int) (buff_Rotary_time*time_factor);
uint16_t Left_time = (int) (buff_Left_time*time_factor);
uint16_t Right_time = (int) (buff_Right_time*time_factor);
uint16_t Claw_time = (int) (buff_Claw_time*time_factor);

bool Pos_Rotary = false;


bool Pos_Left = false;
bool Pos_Right = false;
bool Pos_Claw = false;

unsigned long Rotary_Millis = millis();


unsigned long Left_Millis = millis();
unsigned long Right_Millis = millis();
unsigned long Claw_Millis = millis();
uint16_t Rotary_target = MeArmServo[0].read();
uint16_t Left_target = MeArmServo[1].read();
uint16_t Right_target = MeArmServo[2].read();
uint16_t Claw_target = MeArmServo[3].read();

while(!Pos_Rotary || !Pos_Left || !Pos_Right || !Pos_Claw){

unsigned long currentMillis = millis();

if(MeArmServo[0].read()!=Rotary){
if(MeArmServo[0].read()>Rotary){
if(currentMillis>=Rotary_Millis){
Rotary_target-=1;
Rotary_Millis = millis()+Rotary_time;
}
if(MeArmServo[0].read()==Rotary)Rotary_target=Rotary;

if (!MeArmServo[0].attached()){
MeArmServo[0].attach(PIN[0]);
}
MeArmServo[0].write(Rotary_target);
}

if(MeArmServo[0].read()<Rotary){
if(currentMillis>=Rotary_Millis){
Rotary_target+=1;
Rotary_Millis = millis()+Rotary_time;
}
if(MeArmServo[0].read()==Rotary)Rotary_target=Rotary;
if (!MeArmServo[0].attached()){
MeArmServo[0].attach(PIN[0]);
}
MeArmServo[0].write(Rotary_target);
}
}else{
Pos_Rotary = true;
}

if(MeArmServo[1].read()!=Left){
if(MeArmServo[1].read()>Left){
if(currentMillis>=Left_Millis){
Left_target-=1;
Left_Millis = millis()+Left_time;
}
if(MeArmServo[1].read()==Left)Left_target=Left;
if (!MeArmServo[1].attached()){
MeArmServo[1].attach(PIN[1]);
}
MeArmServo[1].write(Left_target);
}

if(MeArmServo[1].read()<Left){
if(currentMillis>=Left_Millis){
Left_target+=1;
Left_Millis = millis()+Left_time;
}
if(MeArmServo[1].read()==Left)Left_target=Left;
if (!MeArmServo[1].attached()){
MeArmServo[1].attach(PIN[1]);
}
MeArmServo[1].write(Left_target);
}
}else{
Pos_Left =true;
}

if(MeArmServo[2].read()!=Right){
if(MeArmServo[2].read()>Right){
if(currentMillis>=Right_Millis){
Right_target-=1;
Right_Millis = millis()+Right_time;
}
if(MeArmServo[2].read()==Right)Right_target=Right;
if (!MeArmServo[2].attached()){
MeArmServo[2].attach(PIN[2]);
}
MeArmServo[2].write(Right_target);

if(MeArmServo[2].read()<Right){
if(currentMillis>=Right_Millis){
Right_target+=1;
Right_Millis = millis()+Right_time;
}
if(MeArmServo[2].read()==Right)Right_target=Right;
if (!MeArmServo[2].attached()){
MeArmServo[2].attach(PIN[2]);
}
MeArmServo[2].write(Right_target);
}
}else{
Pos_Right =true;
}

if(MeArmServo[3].read()!=Claw){
if(MeArmServo[3].read()>Claw){
if(currentMillis>=Claw_Millis){
Claw_target-=1;
Claw_Millis = millis()+Claw_time;
}
if(MeArmServo[3].read()==Claw)Claw_target=Claw;
if (!MeArmServo[3].attached()){
MeArmServo[3].attach(PIN[3]);
}
MeArmServo[3].write(Claw_target);

if(MeArmServo[3].read()<Claw){
if(currentMillis>=Claw_Millis){
Claw_target+=1;
Claw_Millis = millis()+Claw_time;
}
if(MeArmServo[3].read()==Claw)Claw_target=Claw;
if (!MeArmServo[3].attached()){
MeArmServo[3].attach(PIN[3]);
}
MeArmServo[3].write(Claw_target);
}
}else{
Pos_Claw =true;
}
}

int getIndexOfMaximumValue(int* array, int size){


int maxIndex = 0;
int arr_max = array[maxIndex];
for (int i=1; i<size; i++){
if (arr_max<array[i]){
arr_max = array[i];
maxIndex = i;
}
}
return maxIndex;
}

Software and Libraries


1. I use Arduino Software version 1.6.6
2. Libraries , click here
Copy paste libraries to Arduino software folder .. \libraries
Project File download
1. Arduino Project File, click here
2. Siemens PLC S7-200 Project File, click here