You are on page 1of 19


School of Electrical, Electronics and Computer




Submitted by:
AUDITOR, Marimar L.
DE DIOS, Neil Leander A.
DELOS REYES, Vladimer A.
DOMINGO, Ellaine Joy A.
JUMAQUIO, Yeoj Niko G.
ROBERTO, Edzel Daryl P.
ROXAS, Rinna Andrea B.
TALUSAN, Gio Louis C.
TEJADA, Don Albert U.
TIAMA, Paul Patrick M.
TUNGOL, Rachelle Geleen S.

EE163P A11

Submitted to:
Engr. Joseph Bryan Ibarra

January 11, 2017
Project Description
***** Yung pagbabasa ng data from plc to arduino and sending nung sa gsm.***

Problems and Solutions:

GSM Initialization Error

o Check if the sim card has a load
o Decrease the baudrate of GSM preferably 1200 or 2400
o Press the power button of GSM board for 2-3 sec
o Press the reset button to re-initialize

Data Synchronization Error Occurs

o Create a ciruit that convert PWM signal to Analog Signal
o Look for possible other settings in CX Programmer

When the output voltage of Gizduino-USB Board is measured using voltmeter,

correct value was displayed but when monitored using analog read of Gizduino,
HIGH and LOW voltage with different duration was monitored.

o The problem occurs because of different communication protocol
of PLC and Arduino. Their resolution is different so use Scaling.

Output of channel 200 is varying

o Restart the PLC and use another channel like channel 201 instead.
Project Objectives
The main objective of the project is monitoring voltage as obtained in the
Programmable Logic Controller connected to a GSM module using printer cable for
wireless monitoring. This project also aims to:

Be able to scale and convert the voltage obtained in the PLC to hexadecimal
with maximum of 255 for matching with the settings of the Arduino.
Be able to create a program for the GSM Board.
Be able to create a program for the PLC Arduino connection via printer cable.
Be able to inform the user of the reading as a reply after sending an SMS
containing the word Voltage.
Be able to inform the user via SMS when the reading exceeds the maximum
value as set.
Be able to inform the user via SMS when the whole module is ready to monitor
Be able to establish a connection between the PLC, Arduino, and the GSM






Module (Shield)

Explanations per rung (PLC)

Figure 1. Rung 0

The first rung shows the initialization and declaration of values for data
memories from D100 to D103 indicated by the use of the Always On Flag. The
indicated data memories D100 to D103 are set for scaling in the following rung. The
input ranges from #0 to #1770. The output ranges from #0 to #255. The maximum
output is set to #255 for matching purposes because the maximum value that can be
read by the Arduino is also #255.
Figure 2. Rung 1

In this rung, scaling starts from a data memory D200 for testing purposes. But
the projects main purpose, voltage analog inputs 200 or 201 from the PLC is to be
used as source word. The output of the scale is placed in a data memory D30.

Figure 3. Rung 2

The last rung uses the BCD to Binary converter from the output of the scaling
process which is the data memory D30. This conversion process, which eventually
becomes hexadecimal, is done because Arduino only accepts hexadecimal values in 2
bits. The conversion of 255 to hexadecimal is FF, making it the maximum hexadecimal
value read by the Arduino.
Microcontroller Codes (Arduino)

For GSM Board

#include <SIM900.h> //Library for the Initialization");//GSM Initialization by
GSM Module setting the baud rate with 4800 or
#include <GPRS_Shield_Arduino.h> lower for http uses
//Library for the GSM and GPRS Arduino if (gsm.begin(2400)) //GSM Baud Rate
Shield {
#include <usbhub.h>// Library dor USB Serial.println("\nStatus=Ready"); //
Serial Connection Print if the GSM baud rate was achie
#include <SoftwareSerial.h> //Library started=true; //variable started is
for Serial Monitor true
#include <sms.h> //Library to Send SMS }
#include <inetGSM.h> //Library for GSM else
Network Serial.println("\nStatus=Waiting"); // If
not true Display this line
if(started) //If started is true or
int numdata; started was achieved
boolean started=false; //initial state of {
variable started for initialization if (sms.SendSMS("+639959963176",
char sms_position; "Ready to Monitor Voltage")) //message
char phone_number[20]; //Phone will be send to my cellphone
Number character is stored in this Serial.println("\nSMS Sending
variable Successful"); // Print to serial monitor
char sms_text[100]; if the message was sent
char sms_voltage[20]; }
float input_voltage = 0.0; //Temporary };
Value of Output Voltage
float temp=0.0; // Variable void loop() //start of the programming
char charVal[10]; //voltage value loop
stored here temporarily {
char message[40]; //Maximum Number //Formula for Conversion
of characters in a message int analog_value = analogRead(A5); //
char pos; // Variable for Position The voltage will be read to the A0 value
number of SMS message of the Gizduino - Analog Input
temp = (analog_value* 5.0) /
void setup() 1023; //formula for the strored
{ temporary value. 5 because of 5V and
1023 because of the resolution
Serial.begin(9600); //Initialize Serial
input_voltage = temp;//temp value is
stored to input voltage variable
if (input_voltage < 0.1)
{ sms.GetSMS((int)pos,phone_number,sm
input_voltage=0.0; s_text,100); //get position/index,
} number of sender, and text message
dtostrf(input_voltage, 2, 2, Serial.println(sms_text); //display the
charVal); //4 is mininum width, 4 is text on serial monitor
precision; float value is copied onto
buff if(strstr(sms_text, "Voltage")) //Send
"Voltage" character to inquire
if(started) {
{ if (sms.SendSMS("+639959963176",
if (input_voltage > 4) //If the voltage charVal)) // Send the value of charVal
exceeds 4V, send Warning Message to the USER
Below Serial.println("\nSMS sent OK");
{ //print to serial monitor
if (sms.SendSMS("+639959963176", Serial.print("V = "); //print to serial
"Warning! Voltage is Greater than monitor
4V")) //Warning message Serial.print(input_voltage); //print to
Serial.println("\nSMS sent OK"); serial monitor
//print to serial monitor Serial.println(" V"); //print to serial
Serial.print("V = "); //print to serial monitor
monitor }
Serial.print(input_voltage); //print to sms.DeleteSMS((int)pos); //SMS will be
serial monitor deleted after being read
Serial.println(" V"); //print to serial }
monitor delay(3000); //The loop will be
} delayed for 3 seconds then repeat it
} again.

pos=sms.IsSMSPresent(SMS_ALL); };
//save to variable if there is an SMS
Serial.println((int)pos); //display
position number or index of the
if((int)pos>0) //if message from 0-20 is
Serial.print("Message Received,
INBOX="); //display an output on the
serial monitor
Serial.println((int)pos); //display the
position/index of the message 1 or 0
will be the output
message[0]='Waiting for Message';
//display '0' if no messages found
if (Usb.Init() == -1){

For USB and PLC connection

Serial.println("OSC did not start and
/* Will be Reset");
The program will work if the library while(1);
usbhub is downloaded form }

To simulate the program put HEX values randomSeed(analogRead(0));

of the Data Memory (DO) of OMRON PLC Serial.println("PLC START");
The Ouput Voltage Will be monitored to }
Digital Pin 5
void loop() {
Retrieved from https://program- Usb.Task(); if( Usb.getUsbTaskState() ==
omron-plc-usb-and-arduino-plus.html USB_STATE_RUNNING )
*/ USB_RUN = true;
switch(PLC_State) {
case 0: // Omron PLC Find
#include <usbhub.h> rcode =
#define VendorID 0x0590 Omron_PLC_Find(VendorID, ProductID);
#define ProductID 0x005B if(rcode){

USB Usb; Serial.println("Omron PLC Not Found");

uint8_t addr; }else{
uint8_t rcode; PLC_State=1;
uint8_t PLC_State; }
uint16_t Omron_PLC_D0_Value; break;
uint16_t Omron_PLC_D2_Value;
case 1: //Command
bool USB_RUN = false;
Omron PLC for RUN Mode
static unsigned long timeout=1000;
rcode =
const int analogOutPin = 5; // PWM
Output Voltage if(rcode==0)PLC_State=2;
uint16_t VoltMeterValue = 0; // Initial break;
Value of the Output Voltage
const int analogInPin = A0; // case 2: // Received
Potentiometer Omron PLC RUN Mode
uint16_t PotentiometerValue = 0; rcode =

void setup() { if(rcode==0)PLC_State=3;

Serial.begin(115200); break;
rcode =
case 3: // Command Command_Omron_PLC_D_Write(2,Omro
Omron PLC for D memory Read n_PLC_D2_Value);
rcode =
Command_Omron_PLC_D_Read(0); if(rcode==0)PLC_State=6;
break; case 6: // Received
Omron PLC for D memory Write
case 4: // Received rcode =
Omron PLC from D memory Read Receive_Omron_PLC_D_Write();
// Save to if(rcode){
Omron_PLC_D0_Value PLC_State=5; //
rcode = error goto command again
Receive_Omron_PLC_D_Read(&Omron_ }else{
PLC_D0_Value); PLC_State=7; //
no error goto next
Serial.println(Omron_PLC_D0_Value,DE }
C); break;
VoltMeterValue =
map(Omron_PLC_D0_Value, 0, 255, 0, case 7: // Finish
255); PLC_State=3;
analogWrite(analogOutPin, }
if(rcode){ }else{
PLC_State=3; // if(USB_RUN){
error goto command again Serial.println("USB Not RUN and
}else{ Will be Reset");
PLC_State=5; // asm volatile (" jmp 0");
no error goto next }
} }
case 5: // Command
Omron PLC for D memory Write
void GetAddresses(UsbDevice *pdev)
//Omron_PLC_D2_Value =
Omron_PLC_D0_Value ;
UsbDeviceAddress adr;
//PotentiometerValue = adr.devAddress = pdev-
analogRead(analogInPin); >address.devAddress;
addr = adr.devAddress;
Omron_PLC_D2_Value = }
map(PotentiometerValue, 0, 1020, 0,
255); uint8_t Omron_PLC_Find(uint16_t
Vendor_ID, uint16_t Product_ID) {
uint8_t rcode;
Usb.ForEachUsbDevice(&GetAddresses); return ( rcode);
rcode = Usb.getDevDescr(addr, 0, }
(uint8_t*) & buf); uint8_t
if (rcode) { Receive_Omron_PLC_RUN_Mode() {
return (rcode); uint8_t rcode;
}else{ uint8_t buf[64];
if(buf.idVendor == Vendor_ID && uint16_t rcvd=0;
buf.idProduct == Product_ID){
rcode = Usb.setConf(addr, 0, rcode =
buf.bNumConfigurations); OmronPLCreceived(&rcvd,buf);
return (rcode); // RecPrintHEX(rcvd,buf);
return (USB_STATE_ERROR); if(rcode)
} return rcode;
return (USB_STATE_ERROR); 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;
uint8_t for(uint16_t i=0; i < 17; i++ ) {
Command_Omron_PLC_RUN_Mode() { sum2 +=buf[i];
uint8_t rcode; }
uint8_t msg[20] =
{0xAB,0x00,0x11,0x80,0x00,0x02,0x00, if (sum1==sum2){
0x00,0x00,0x00,0x00,0x00}; uint8_t revc[17] =
msg[12] = random(1, 255); {0xAB,0x0,0x10,0xC0,0x0,0x2,0x0,0x0,0
msg[13] =0x04; xFB,0x0,0x0,0x0,0x30,0x4,0x1,0x0,0x0}
msg[14] =0x01; ;
msg[15] =0xFF; for(uint16_t i=0; i < 17; i++ ){
msg[16] =0xFF; if(revc[i]!=buf[i] && i!=12)return
msg[17] =0x04; (2);
uint16_t sumcheck=0; }
for(uint16_t i=0; i < 18; i++ ) { return (0);
sumcheck +=msg[i]; }else{
} return (1);
msg[18] =((sumcheck >> 8) & 0xFF); }
msg[19] =(sumcheck & 0xFF);
return ( rcode);
rcode = }
return rcode;
uint8_t uint8_t val1=buf[rcvd-1];
Command_Omron_PLC_D_Read(uint16_ uint8_t val2=buf[rcvd-2];
t D_number) { uint16_t sum1 = val2<<8 | val1;
uint8_t rcode; uint16_t sum2=0;
uint8_t msg[25] = for(uint16_t i=0; i < 22; i++ ) {
{0xAB,0x00,0x16,0x80,0x00,0x2,0x00,0 sum2 +=buf[i];
x00,0x00,0x00,0x00,0x00}; }
msg[12] = random(1, 255);
msg[13] =0x01; if (sum1==sum2){
msg[14] =0x04; uint8_t revc[18] =
msg[15] =0x07; {0xAB,0x0,0x15,0xC0,0x0,0x2,0x0,0x0,0
msg[16] =0x00; xFB,0x0,0x0,0x0,0x9C,0x1,0x4,0x0,0x0,
msg[17] =0x00; 0x7};
msg[18] =0x00; for(uint16_t i=0; i < 18; i++ ){
msg[19] =0x82; if(revc[i]!=buf[i] && i!=12)return
msg[20] =(D_number >> 8); (2);
msg[21] =(D_number & 0xFF); }
msg[22] =0x00; uint8_t val1=buf[rcvd-3];
uint8_t val2=buf[rcvd-4];
uint16_t sumcheck=0; uint16_t value = val2<<8 |
for(uint16_t i=0; i < 23; i++ ) { val1;
sumcheck +=msg[i]; *D_value = value;
} return (0);
msg[23] =((sumcheck >> 8) & 0xFF); return (1);
msg[24] =(sumcheck & 0xFF); }
rcode =
OmronPLCsend(sizeof(msg),msg); return (1);
return ( rcode);
} uint8_t
uint8_t t D_number, uint16_t D_value) {
Receive_Omron_PLC_D_Read(uint16_t uint8_t rcode;
*D_value) { uint8_t msg[25] =
uint8_t rcode; {0xAB,0x00,0x16,0x80,0x00,0x2,0x00,0
uint8_t buf[64]; msg[12] = random(1, 255);
uint16_t rcvd=0; msg[13] =0x01;
rcode = OmronPLCreceived(&rcvd,buf); msg[14] =0x02;
//RecPrintHEX(rcvd,buf); msg[15] =0x82;
msg[16] =(D_number >> 8);
if(rcode) msg[17] =(D_number & 0xFF);
return rcode; msg[18] =0x00;
msg[19] =0x00;
if (rcvd==24){
msg[20] =0x01; if(revc[i]!=buf[i] && i!=12)return
msg[21] =(D_value >> 8); (3);
msg[22] =(D_value & 0xFF); }
return (0);
uint16_t sumcheck=0; }else{
for(uint16_t i=0; i < 23; i++ ) { return (2);
sumcheck +=msg[i]; }
} }
msg[23] =((sumcheck >> 8) & 0xFF); return (1);
msg[24] =(sumcheck & 0xFF); }

rcode =
void RecPrintHEX(uint16_t nbytes,
return ( rcode); uint8_t* data){
} if(nbytes==0)return;
for(uint16_t i=0; i < nbytes; i++ ) {
Serial.print(" ,0x");
uint8_t Receive_Omron_PLC_D_Write() Serial.print(data[i],HEX);
uint8_t rcode; //Serial.println(Omron_PLC_D0_Value,
uint8_t buf[64]; //Serial.print(data[i],HEX);
uint16_t rcvd=0; }
rcode = OmronPLCreceived(&rcvd,buf); Serial.println("");
//RecPrintHEX(rcvd,buf); }

if(rcode) uint8_t OmronPLCsend(uint16_t nbytes,

return rcode; uint8_t* data) {
Usb.bytesWr(rSNDFIFO, nbytes,
if (rcvd==19){ data);
uint8_t val1=buf[rcvd-1]; Usb.regWr(rSNDBC, nbytes);
uint8_t val2=buf[rcvd-2]; Usb.regWr(rHXFR, 0x21);
uint16_t sum1 = val2<<8 | val1; while(!(Usb.regRd(rHIRQ) &
uint16_t sum2=0; bmHXFRDNIRQ)); //wait for the
for(uint16_t i=0; i < 17; i++ ) { completion IRQ
sum2 +=buf[i]; Usb.regWr(rHIRQ,
} bmHXFRDNIRQ); //clear IRQ
if (sum1==sum2){ return (0);
uint8_t revc[17] = }
; uint8_t OmronPLCreceived(uint16_t
for(uint16_t i=0; i < 17; i++ ){ *pktsize, uint8_t* data) {
//unsigned long timeout_start = *pktsize = buff_pktsize;
millis() + USB_XFER_TIMEOUT; data = Usb.bytesRd(rRCVFIFO,
unsigned long timeout_start = millis() buff_pktsize, data);
+ timeout; Usb.regWr(rHIRQ,
bmRCVDAVIRQ); // Clear the IRQ & free
while((long)(millis() - timeout_start) < the buffer
0L) { return (0);
Usb.regWr(rHXFR, 0x2); }
if((Usb.regRd(rHIRQ) & }
uint16_t buff_pktsize = return (1);
Usb.regRd(rRCVBC); }