Wednesday, December 17, 2014

Internet of Things (IoT) for PLC Application Project





This project about internet of things, usually called with IoT.
I will share information about the use of IOT , to be used in the PLC application project.
See detail about IoT and my PLC Project:

Internet of Things IoT for PLC Application Project

I use Blogspot with JavaScript/JQuery for Read or Write Data from/To IoT Server, and I use IoT Server for free: thingspeak.com
See Video about PLC Remote Control via Blogspot:


Step By Step make Internet of Things (IoT) for PLC Application:
A. Hardware

Hardware for Internet of Things IoT in PLC Application

1. Arduino Atmega 2560: arduino.cc/en/Main/arduinoBoardMega2560
2.ESP8266 serial WIFI module ESP_05 with external antenna

ESP8266 serial WIFI module ESP_05 with external antenna

3. Male RS-232 Module

Male RS-232 Module

4. RS-232 PLC Cable for Micrologix 1000
5. Allen Bradley Micrologix 1000 PLC
6.For Internet Access use Modem with wireless router, Example:
- TP-LINK TL-MR3420 with USB 3G/4G Modem (I use this modem)
- MiFi 3G/4G mobile wireless router

TP-LINK TL-MR3420 with USB 3G Modem

B. Hardware Connection
Connection between ESP8266 to Arduino and Arduino to PLC

C. Project File
Download all project file:
1. For Upload to Arduino, click here

2.For Download to PLC, click here

3.For Posting to Blogspot (blogger.com), click here
besides blogspot, can also be posted to the website with JQuery support.

Demo in Blogspot, click here


D.How to Use Project File
See Video about:
1.Setup in thingspeak.com and Get Write API Key, Read API Key and CHANNEL_ID.
2. Change Value in Arduino and Blogspot project file.

ESP8266 AP SSID and AP PASSWORD in Arduino




E. JQuery Code for Internet of Things (IoT)
//https://thingspeak.com/channels
var Write_API_Key = "Your Write API Key";
var Read_API_Key = "Your Write API Key or Your Read API Key";
var CHANNEL_ID = "Your Channel Id";
var bgd ='background-color';
var bgd_on = '#6F0';
var bgd_off = '#FFF';
var bgd_req = '#FF0';
var writedata =0;
var ReadAPI = "http://api.thingspeak.com/channels/"+CHANNEL_ID+"/feed/last.json?key="+Read_API_Key;
var WriteAPI = "http://api.thingspeak.com/update?key="+Write_API_Key;

$(function(){
ReadCycle();
$("#WriteVal").text("0");
$(".wait").css( "display", "none" );
$("#Write").css( "display", "block" );
$(".waitr").css( "display", "none" );
$("#Read").css( "display", "block" );

$(".Out").click(function() {
writedata =0;
$(".Output").each(function(index) {
var bin=Math.pow(2, index);
writedata += $(this).prop("checked")*bin;
});
$("#WriteVal").text(writedata);
SetReq(writedata);
});

$("#Write").click(function() {
$("#Write").css( "display", "none" );
$(".wait").css( "display", "block" );
$(".Output").each(function(index) {
$(this).prop("disabled",true);
});
$(".response" ).html('
...wait...
');
var writeval = $("#WriteVal").text();
$.getJSON(WriteAPI+"&field2="+writeval,{format: "json"}).done(function( data ) {
if(data==0)alert("Try Again");
$(".response" ).html('
'+JSON.stringify(data)+'
');
$(".Output").each(function(index) {
$(this).prop("disabled",false);
});
$(".wait").css( "display", "none" );
$("#Write").css( "display", "block" );
});
});

$("#Read").click(function() {
ReadField();
});

function SetAct(value) {
$(".Out").each(function(index) {
var bin=Math.pow(2, index);
(((value&bin)==bin)?$(this).css(bgd, bgd_on):$(this).css(bgd, bgd_off));
});
}
function SetReq(value) {
$(".Out").each(function(index) {
var bin=Math.pow(2, index);
(((value&bin)==bin)?$(this).css(bgd, bgd_req):$(this).css(bgd, bgd_off));
});
}
function SetCheck(value) {
$(".Output").each(function(index) {
var bin=Math.pow(2, index);
(((value&bin)==bin)?$(this).prop("checked",true):$(this).prop("checked",false));
});
$("#WriteVal").text(value);
}

function ReadField() {
$(".response" ).text("...wait...");
$.getJSON(ReadAPI,{format: "json"}).done(function( data ) {
$(".response" ).html('
'+JSON.stringify(data)+'
');
var read1=data.field1;
var read2=data.field2;
$(".Req").text("Request Value = " + read2);
$(".Act").text("Actual Value = " + read1);
$(".RCrun").text("");
if( read1 != null && read2 != null){
SetAct(read1);
SetCheck(read1);
return;
}
if(read1 == null && read2 != null){
SetReq(read2);
SetCheck(read2);
return;
}
});
}

function ReadCycle(){
$(".RCrun").text(" RUN....");
ReadField();
setTimeout(ReadCycle, 15000); //cycle 15s
}
});


E. Arduino Code for Internet of Things (IoT)
#define ESP8266_resetPin 2
#define AP_SSID "Your SSID" //Wireless Network Name (Also called the SSID)
#define AP_PASSWORD "Your Wifi Password //Wireless Password
#define thingspeakIp "184.106.153.149" //api.thingspeak.com
String Write_API_Key = " Your Write API Key";
String Read_API_Key = " Your Write API Key or Your Read API Key;
String CHANNEL_ID = " Your Channel Id";
String ReadAPI = "GET /channels/"+CHANNEL_ID+"/feed/last.json?key="+Read_API_Key;
String WriteAPI = "GET /update?key="+Write_API_Key;
String data;
String endsend=" HTTP/1.0\r\n\r\n";

int interval;
int intervelset=15; //interval read per seconds
int Order_Inc = random(1, 75);

static unsigned int CRC16table[] = {0x0,0xc0c1,0xc181,0x140,0xc301,0x3c0,0x280, 0xc241, 0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440, 0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40, 0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040};

void setup()
{
pinMode(ESP8266_resetPin,OUTPUT);
digitalWrite(ESP8266_resetPin, HIGH);
Serial.begin(9600); //For Monitoring
Serial1.begin(9600); // For ESP8266 with External Antena
//Serial1.begin(115200); // For ESP8266 with Internal Antena
Serial1.flush();
Serial1.setTimeout(5000);
Serial2.begin(9600); // For Micrologix PLC
Serial2.flush();
Serial2.setTimeout(2000);
if(ATcmdWait("AT+RST","ready",5000)){
if(ATcmdWait("AT+CWMODE=1","no change",2000)==false)ESP8266_Reset(1);
ATcmdWait("AT+CIPMUX=0","OK",2000);
APconnect();
//IP Check
while(1){
Serial1.println("AT+CIFSR");
data = Serial1.readString();
if (data.indexOf("AT+CIFSR")!=-1)
{
data.replace("AT+CIFSR","");
data.trim();
Serial.print("My IP: ");
Serial.println(data);
}
if(data.indexOf("ERROR")==-1)break;
}
}else{
ESP8266_Reset(30);
}
IoTReadField();
interval=0;
}
void loop()
{
if(interval>=intervelset){
IoTReadField();
interval=0;
}
delay(1000);
interval++;
Serial.print(interval);
Serial.print(" ");
}

void ESP8266_Reset(byte delays)
{
Serial.println("Hardware Reset ");
byte times = 0;
while(times < delays){
digitalWrite(ESP8266_resetPin, LOW);
delay(1000);
times++;
Serial.print(times);
Serial.print(" ");
}
digitalWrite(ESP8266_resetPin, HIGH);
asm volatile (" jmp 0");
while(1);
}

boolean ATcmdWait(String AT, char *Wait,int delays){
Serial1.println(AT);
Serial.print(AT);
unsigned long starttime;
starttime = millis();
while (millis()-starttime if(Serial1.find(Wait)==true)
{
Serial.println(" => TRUE");
return true;
}
}
Serial.println(" => FALSE");
return false;
}

void APconnect(){
String cmd="AT+CWJAP=\"";
cmd+=AP_SSID;
cmd+="\",\"";
cmd+=AP_PASSWORD;
cmd+="\"";
if(ATcmdWait(cmd,"OK",8000)==false)
{
ESP8266_Reset(30);
}
}

void IoTReadField(){
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += thingspeakIp;
cmd += "\",80";
if(ATcmdWait(cmd,"Linked",5000)==false)
{
ESP8266_Reset(5);
}

cmd = ReadAPI;
cmd += endsend;
if(ATcmdWait("AT+CIPSEND="+String(cmd.length()),">",5000)){
Serial1.print(cmd);
data = "";
unsigned long start1;
unsigned long start2;
start1 = millis();
while(millis()-start1<5000 br=""> char plus = Serial1.read();
if(plus=='+'){
start2 = millis();

while (millis()-start2<5000 br="" erial1.available="" if=""> {
char temp = Serial1.read();
data += temp;
if (data.indexOf("\nOK")!=-1)break;
}
}
}
}

Serial.println(data);
if (data.indexOf("400 Bad Request")!=-1){
Serial.println("400 Bad Request");
Serial.println("Please Change endsend Variable");
return;
}

if(data.indexOf("IPD")==0 && data.indexOf(":null,")!=-1 && data.indexOf("\nOK")!=-1)
{
int from1 = data.indexOf("field2");
int to1 = data.indexOf("}");
String string1 = data.substring(from1+9,to1-1);
boolean isnumber = true;
for(byte i=0;i {
if(isDigit(string1.charAt(i))==false) {
isnumber = false;
break;
}
}
if(isnumber){
int fieldValue=(int)string1.toInt();
Serial.print("Value=");
Serial.println(fieldValue);
PLCSendData(fieldValue);
}
}
}else{
Serial1.println("AT+CIPCLOSE");
ESP8266_Reset(30);
}
}

void IoTWriteField(int value){
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += thingspeakIp;
cmd += "\",80";
if(ATcmdWait(cmd,"Linked",5000)==false)
{
ESP8266_Reset(5);
}
cmd = WriteAPI;
cmd += "&field1=";
cmd += String(value);
cmd += "&field2=";
cmd += String(value);
cmd += endsend;
if(ATcmdWait("AT+CIPSEND="+String(cmd.length()),">",5000)){
Serial1.print(cmd);
data = Serial1.readString();
Serial.println(data);
}else{
Serial1.println("AT+CIPCLOSE");
ESP8266_Reset(30);
}
}

void PLCSendData(int Value) {
byte PLCwritedata[20];
if (Order_Inc < 32767)
{
Order_Inc += 1;
}else{
Order_Inc = 1;
}

PLCwritedata[0] = (byte)0x10;
PLCwritedata[1] = (byte)0x2;
PLCwritedata[2] = (byte)0;
PLCwritedata[3] = (byte)0;
PLCwritedata[4] = (byte)0xf;
PLCwritedata[5] = (byte)0;
PLCwritedata[6] = (byte)(Order_Inc & 255);
PLCwritedata[7] = (byte)(Order_Inc >> 8);
PLCwritedata[8] = (byte)0xaa;
PLCwritedata[9] = (byte)2;
PLCwritedata[10] = (byte)7;
PLCwritedata[11] = (byte)0x89;
PLCwritedata[12] = (byte)0;
PLCwritedata[13] = (byte)0;
PLCwritedata[14] = (byte)(Value & 0xff);
PLCwritedata[15] = (byte)((Value >> 8) & 0xff);
byte dataforcrc[14];
for (int i = 2; i<=15; i++)
{
dataforcrc[i-2] = PLCwritedata[i];
}
//CRC Calculation
unsigned int CRC = 0;
byte bytT = 0;
for (int i = 0; i <14 br="" i=""> {
bytT = (byte)((CRC & 0xff) ^ dataforcrc[i]);
CRC = (unsigned int)((CRC >> 8) ^ CRC16table[bytT]);
}
bytT = (byte)(CRC & 0xff ^ 3);
CRC = (unsigned int)((CRC >> 8) ^ CRC16table[bytT]);
PLCwritedata[16] = 0x10;
PLCwritedata[17] = 0x3;
PLCwritedata[18] = (byte)(CRC & 255);
PLCwritedata[19] = (byte)(CRC >> 8);
Serial2.write(PLCwritedata, sizeof(PLCwritedata));
byte recdata[10];
unsigned long start1;
unsigned long start2;
byte cnt=0;
start1 = millis();
while(millis()-start1<5000 br=""> byte two = Serial2.read();
if(two==2){
start2 = millis();
while (millis()-start2<5000 br=""> if (Serial2.available())
{
recdata[cnt] = Serial2.read();
cnt++;
if (cnt>=10)break;
}
}
}
}
if (cnt<10 br=""> Serial.println("PLC No Response");
Serial.print("Order_Inc=");
Serial.println(Order_Inc);
return;
}
byte ACK[] = { 0x10, 0x6 };
Serial2.write(ACK, sizeof(ACK));
//CRC Checker
CRC = 0;
bytT = 0;
for (int i = 0; i <6 br="" i=""> {
bytT = (byte)((CRC & 0xff) ^ recdata[i]);
CRC = (unsigned int)((CRC >> 8) ^ CRC16table[bytT]);
}
bytT = (byte)(CRC & 0xff ^ 3);
CRC = (unsigned int)((CRC >> 8) ^ CRC16table[bytT]);
byte crc1 = (byte)(CRC & 255);
byte crc2 = (byte)(CRC >> 8);
//CRC OK
if(recdata[8]==crc1 && recdata[9]==crc2){
Serial.println("PLC OK");
Serial.print("Write Delay ");
byte times = 0;
while(times < 10){
delay(1000);
times++;
Serial.print(times);
Serial.print(" ");
}
IoTWriteField(Value);
}
}




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