วันอังคารที่ 18 กันยายน พ.ศ. 2561

ืืnode red power meter 1 phase






[{"id":"930aa933.ea3408","type":"ui_template","z":"8be9ce81.4223a","group":"a01311d3.c877c","name":"","order":0,"width":"6","height":"1","format":"<div layout=\"row\" layout-align=\"space-between\">\n<p>The number is</p>\n<p ng-style=\"{color: (msg.payload || 0) % 2 === 0 ? 'green' : 'red'}\">\n  {{(msg.payload || 0) % 2 === 0 ? 'even' : 'odd'}}\n</p>\n</div>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":320,"y":740,"wires":[[]]},{"id":"a01311d3.c877c","type":"ui_group","z":"","name":"Modbus Test","tab":"d0df777a.ca7fa8","order":1,"disp":true,"width":"6"},{"id":"d0df777a.ca7fa8","type":"ui_tab","z":"","name":"Modbus","icon":"dashboard"}]

วันอังคารที่ 14 สิงหาคม พ.ศ. 2561

C# show form2 in secondary monitor

            Form2 dlg = new Form2();
            Screen[] screens = Screen.AllScreens;
            Rectangle bounds = screens[1].Bounds;
            dlg.SetBounds(bounds.X, bounds.Y, bounds.Width, bounds.Height);
            dlg.StartPosition = FormStartPosition.Manual;
            dlg.Show();

วันศุกร์ที่ 16 กุมภาพันธ์ พ.ศ. 2561

MokaWriteWeely

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.amjoey.mokawriteweekly">

    <uses-permission android:name="android.permission.INTERNET" />

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


MainActivity.java

package com.amjoey.mokawriteweekly;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.TimePickerDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.Calendar;

import Moka7.S7;
import Moka7.S7Client;

public class MainActivity extends FragmentActivity {
    boolean timeView = true;

    int bMemoryValOnVal1,bMemoryValOffVal1;

    static final int START_TIME_ID=0;
    static final int END_TIME_ID=1;

    EditText onVal1,offVal1;

    ImageButton imgOnVal1,imgOffVal1;
    private int chour,cminute;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Calendar calendar=Calendar.getInstance();
        chour=calendar.get(Calendar.HOUR_OF_DAY);
        cminute=calendar.get(Calendar.MINUTE);

        onVal1 = (EditText) findViewById(R.id.txtOnValue1);
        offVal1 = (EditText) findViewById(R.id.txtOffValue1);

        imgOnVal1 = (ImageButton)  findViewById(R.id.imgOnVal1);
        imgOffVal1 = (ImageButton) findViewById(R.id.imgOffVal1);

        imgOnVal1.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View v) {
                showDialog(START_TIME_ID);
            }
        });

        imgOffVal1.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View v){
                showDialog(END_TIME_ID);
            }
        });
    }

    @Override    protected void onResume() {
        super.onResume();
        // we're going to simulate real time with thread that append data to the graph        new Thread(new Runnable() {

            @Override            public void run() {
                // we add 100 new entries                for (int i = 0; i < 100; i++) {
                    runOnUiThread(new Runnable() {

                        @Override                        public void run() {
                            new PlcReader().execute("");
                        }
                    });

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }).start();
    }


    S7Client client = new S7Client();

    public void writedb_val(View v){
        onVal1 = (EditText) findViewById(R.id.txtOnValue1);
        offVal1 = (EditText) findViewById(R.id.txtOffValue1);

        bMemoryValOnVal1=timetoint(onVal1.getText().toString());
        bMemoryValOffVal1=timetoint(offVal1.getText().toString());

        new PlcWriter().execute("");

        timeView =true;
    }

    //begin class PlcReader    private class PlcReader extends AsyncTask<String, Void, String> {

        String ret= "";
        int timeON1,timeOFF1;

        @Override        protected String doInBackground(String... params){

            try{
                client.SetConnectionType(S7.S7_BASIC);
                int res=client.ConnectTo("192.168.1.12",0,0);

                if(res==0){//connection OK

                    byte[] data = new byte[12];

                    byte[] data1 = new byte[4];
                    res = client.ReadArea(S7.S7AreaDB,1,1,12,data);

                    // Get time from PLC VM Address 988->Hour 989->Minute 990->Second                    res = client.ReadArea(S7.S7AreaDB,1,988,3,data1);

                    //  ret = "value of DB1.DBD25: "+ S7.GetFloatAt(data,0);                    //  ret = "value of DB1.DBD10: "+ S7.GetWordAt(data,0);                    //ret = "Value of DB1.DBD1: "+S7.GetWordAt(data1,0)/256 +":"+S7.GetWordAt(data1,1)/256 +":"+S7.GetWordAt(data1,2)/256 +"/"+ S7.GetWordAt(data,0)+"/"+ S7.GetWordAt(data,2)+"/"+ S7.GetWordAt(data,4)+"/"+ S7.GetWordAt(data,6)+"/"+ S7.GetWordAt(data,8)+"/"+ S7.GetWordAt(data,10);                    ret = "PLC Time : "+padding(S7.GetWordAt(data1,0)/256) +":"+padding(S7.GetWordAt(data1,1)/256) +":"+padding(S7.GetWordAt(data1,2)/256) ;

                    timeON1 = S7.GetWordAt(data,0);
                    timeOFF1 = S7.GetWordAt(data,2);
 /*                    byte[] dataWrite = new byte[2];                   // S7.SetBitAt(dataWrite, 0, 1, true);                   // S7.SetDIntAt(dataWrite,0,5);                    S7.SetWordAt(dataWrite,0,700);
                    client.WriteArea(S7.S7AreaDB, 1, 12, 2, dataWrite);                    ret = "WriteArea of DB1.DBD12: OK ";                    */


                }else{
                    ret = "ERR: "+ S7Client.ErrorText(res);
                }
                client.Disconnect();
            }catch (Exception e) {
                ret = "EXC: "+e.toString();
                Thread.interrupted();
            }
            return "executed";
        }

        @Override
        protected void onPostExecute(String result){

            TextView txout = (TextView) findViewById(R.id.textView);
            txout.setText(ret);

            if(timeView) {
                onVal1 = (EditText) findViewById(R.id.txtOnValue1);
                onVal1.setText(timeformat(timeON1));

                offVal1 = (EditText) findViewById(R.id.txtOffValue1);
                offVal1.setText(timeformat(timeOFF1));

                timeView =false;
            }

        }

    }
    //end class PlcReader
//begin class PlcWriter    private class PlcWriter extends AsyncTask<String, Void, String> {

        String ret= "";


        @Override
        protected String doInBackground(String... params){

            try{
                client.SetConnectionType(S7.S7_BASIC);
                int res=client.ConnectTo("192.168.1.12",0,0);

                if(res==0){//connection OK

                    byte[] dataWrite = new byte[4];
                    // S7.SetBitAt(dataWrite, 0, 1, true);                    // S7.SetDIntAt(dataWrite,0,5);                    S7.SetWordAt(dataWrite,0,bMemoryValOnVal1);
                    S7.SetWordAt(dataWrite,2,bMemoryValOffVal1);


                    client.WriteArea(S7.S7AreaDB, 1, 1, 4, dataWrite);

                    ret = "Updated";


                }else{
                    ret = "ERR: "+ S7Client.ErrorText(res);
                }
                client.Disconnect();
            }catch (Exception e) {
                ret = "EXC: "+e.toString();
                Thread.interrupted();
            }
            return "executed";
        }

        @Override
        protected void onPostExecute(String result){

            Context context = getApplicationContext();
            Toast.makeText(context, ret, Toast.LENGTH_LONG).show();

        }

    }
    //end class PlcWriter/*    public  void  selectTime (View v){        DialogFragment newFragment = new TimePickerFragment();        newFragment.show(getFragmentManager(),"TimePicker");    }*/
    private TimePickerDialog.OnTimeSetListener mStartTime=new TimePickerDialog.OnTimeSetListener()
    {
        public void onTimeSet(TimePicker view,int hourofday,int min)
        {
            onVal1.setText(new StringBuilder().append(padding(hourofday))
                    .append(":").append(padding(min)));
        }
    };

    private TimePickerDialog.OnTimeSetListener mEndTime=new TimePickerDialog.OnTimeSetListener()
    {
        public void onTimeSet(TimePicker view,int hourofday,int min)
        {
            offVal1.setText(new StringBuilder().append(padding(hourofday))
                    .append(":").append(padding(min)));
        }
    };

    @Override
    protected Dialog onCreateDialog(int id)
    {
        switch (id)
        {
            case START_TIME_ID:
                return new TimePickerDialog(this,mStartTime,chour,cminute,false);
            case END_TIME_ID:
                return new TimePickerDialog(this,mEndTime,chour,cminute,false);
        }
        return null;
    }

    public static String timeformat(int t){
        String intTime;
        intTime =String.valueOf(Integer.toHexString(t));
        String first = intTime.substring(0, intTime.length() / 2);
        String second = intTime.substring(intTime.length() / 2);
        return first+ ":"  +second;
    }

    public static int timetoint(String s){
        int setTime;
        String[] separated = s.split(":");

        String first = separated[0];
        String second =separated[1];
        setTime =Integer.parseInt(first+second,16);
        return setTime;
    }

    public static String padding(int c){
        if(c>=10)
            return String.valueOf(c);
        else            return "0"+ String.valueOf(c);
    }



}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.amjoey.mokawriteweekly.MainActivity"    tools:layout_editor_absoluteY="81dp">

    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginStart="32dp"        android:layout_marginTop="24dp"        android:text="PLC Time"        android:textColor="@color/colorPrimaryDark"        android:textSize="18sp"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="24dp"        android:onClick="writedb_val"        android:text="Update"        app:layout_constraintStart_toStartOf="@+id/txtOffValue1"        app:layout_constraintTop_toBottomOf="@+id/txtOffValue1" />

    <EditText        android:id="@+id/txtOnValue1"        android:layout_width="140dp"        android:layout_height="46dp"        android:layout_marginStart="16dp"        android:ems="10"        android:inputType="textPersonName"        android:text=""        app:layout_constraintBaseline_toBaselineOf="@+id/textView2"        app:layout_constraintStart_toEndOf="@+id/textView2" />

    <ImageButton        android:id="@+id/imgOnVal1"        android:layout_width="46dp"        android:layout_height="46dp"        android:layout_marginEnd="8dp"        android:layout_marginStart="16dp"        android:layout_marginTop="32dp"        android:onClick="selectTime"        android:src="@drawable/clock"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintHorizontal_bias="0.381"        app:layout_constraintStart_toEndOf="@+id/txtOnValue1"        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <EditText        android:id="@+id/txtOffValue1"        android:layout_width="140dp"        android:layout_height="46dp"        android:ems="10"        android:inputType="textPersonName"        android:text=""        app:layout_constraintBaseline_toBaselineOf="@+id/textView3"        app:layout_constraintEnd_toEndOf="@+id/txtOnValue1"        app:layout_constraintStart_toStartOf="@+id/txtOnValue1" />

    <ImageButton        android:id="@+id/imgOffVal1"        android:layout_width="46dp"        android:layout_height="46dp"        android:layout_marginTop="20dp"        android:src="@drawable/clock"        app:layout_constraintEnd_toEndOf="@+id/imgOnVal1"        app:layout_constraintHorizontal_bias="0.0"        app:layout_constraintStart_toStartOf="@+id/imgOnVal1"        app:layout_constraintTop_toBottomOf="@+id/imgOnVal1" />

    <TextView        android:id="@+id/textView2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="48dp"        android:text="@string/timer1_on"        app:layout_constraintStart_toStartOf="@+id/textView"        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView        android:id="@+id/textView3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="48dp"        android:text="@string/timer1_off"        app:layout_constraintEnd_toEndOf="@+id/textView2"        app:layout_constraintHorizontal_bias="0.0"        app:layout_constraintStart_toStartOf="@+id/textView2"        app:layout_constraintTop_toBottomOf="@+id/textView2" />

    <ImageView        android:id="@+id/imageView"        android:layout_width="0dp"        android:layout_height="0dp"        android:layout_marginBottom="16dp"        android:scaleType="centerCrop"        android:src="@drawable/plc_logo8"        app:layout_constraintBottom_toBottomOf="@+id/imageView2"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintHorizontal_bias="0.0"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent" />

    <ImageView        android:id="@+id/imageView2"        android:layout_width="36dp"        android:layout_height="36dp"        android:layout_marginEnd="16dp"        android:src="@mipmap/ic_launcher_round"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintVertical_bias="0.26" />

</android.support.constraint.ConstraintLayout>

วันอาทิตย์ที่ 28 มกราคม พ.ศ. 2561

Tools -> Parameter VM Mapping (0BA7 and later versions only)

VM overview

LOGO! Base Module uses VM (Variable Memory) as a local data communication interface for data exchange by means of connections/data-transfer configuration.
You can use LOGO!Soft Comfort with the Ethernet connections menu command following instructions in the Tools -> Ethernet Connections (0BA7 and later versions only) section to construct the network topology.
LOGO!Soft Comofort performs data exchange process as follows:
  • The server stores the required data into the VM area specified by the data connection and data transfer. This is defined as a "share" action in the following section.
  • The client unit reads the server's VM area and then updates the corresponding local VM area in its network process step.
  • After the local update, the circuit program in the client can use the information in the local VM originated from the Server.               
Note LOGO! 8.FS4 supports two types of connection, S7 and Modbus. LOGO! 0BA7 and LOGO! 0BA8 only supports S7 connection.





วันพุธที่ 24 มกราคม พ.ศ. 2561

moka7 example read/write logo 8




****************  Read  ************************


package com.amjoey.moka7connectlogoplc;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import moka7.*;

public class MainActivity extends AppCompatActivity {

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override    protected void onResume() {
        super.onResume();
        // we're going to simulate real time with thread that append data to the graph        new Thread(new Runnable() {

            @Override            public void run() {
                // we add 100 new entries                for (int i = 0; i < 100; i++) {
                    runOnUiThread(new Runnable() {

                        @Override                        public void run() {
                            new PlcReader().execute("");
                        }
                    });

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }).start();
    }

    S7Client client = new S7Client();

    public void readdb_val(View v){
        new PlcReader().execute("");
    }


    private class PlcReader extends AsyncTask<String, Void, String>{

        String ret = "";

        @Override        protected String doInBackground(String... params){

            try{
                client.SetConnectionType(S7.S7_BASIC);
                int res=client.ConnectTo("192.168.0.3",0,0);

                if(res==0){//connection OK
                    byte[] data = new byte[4];
                    res = client.ReadArea(S7.S7AreaDB,1,10,4,data);
                  //  ret = "value of DB1.DBD25: "+ S7.GetFloatAt(data,0);                  //  ret = "value of DB1.DBD10: "+ S7.GetWordAt(data,0);                    ret = "Value of DB1.DBD10: "+ S7.GetWordAt(data,0)+"/"+ S7.GetWordAt(data,2);
 /*                    byte[] dataWrite = new byte[2];                   // S7.SetBitAt(dataWrite, 0, 1, true);                   // S7.SetDIntAt(dataWrite,0,5);                    S7.SetWordAt(dataWrite,0,700);
                    client.WriteArea(S7.S7AreaDB, 1, 12, 2, dataWrite);                    ret = "WriteArea of DB1.DBD12: OK ";                    */

                }else{
                    ret = "ERR: "+ S7Client.ErrorText(res);
                }
                client.Disconnect();
            }catch (Exception e) {
                ret = "EXC: "+e.toString();
                Thread.interrupted();
            }
            return "executed";
        }

        @Override        protected void onPostExecute(String result){
            TextView txout = (TextView) findViewById(R.id.textView);
            txout.setText(ret);
        }
    }
}





****************  Write  ************************

package com.amjoey.mokawriteplc;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import Moka7.*;


public class MainActivity extends AppCompatActivity {

    int iMemoryAdd;
    int bMemoryVal;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    S7Client client = new S7Client();

    public void readdb_val(View v){
        EditText mwAdd = (EditText) findViewById(R.id.txtMWAddress);
        EditText mwVal = (EditText) findViewById(R.id.txtValue);

        if (!mwAdd.getText().toString().equals("")){
            iMemoryAdd = Integer.parseInt(mwAdd.getText().toString());
        }else{
            iMemoryAdd = 0;
        }

        if (!mwVal.getText().toString().equals("")){
            bMemoryVal = Integer.parseInt(mwVal.getText().toString());
        }else{
            bMemoryVal = 0;
        }


        new PlcReader().execute("");
    }

    private class PlcReader extends AsyncTask<String, Void, String>{

        String ret = "";



        @Override        protected String doInBackground(String... params){


            try{
                client.SetConnectionType(S7.S7_BASIC);
                int res=client.ConnectTo("192.168.0.3",0,0);

                if(res==0){//connection OK                     /*                    byte[] data = new byte[4];                    res = client.ReadArea(S7.S7AreaDB,1,10,2,data);                  //  ret = "value of DB1.DBD25: "+ S7.GetFloatAt(data,0);                    ret = "value of DB1.DBD10: "+ S7.GetWordAt(data,0);                    */
                    byte[] dataWrite = new byte[2];
                    // S7.SetBitAt(dataWrite, 0, 1, true);                    // S7.SetDIntAt(dataWrite,0,5);                    S7.SetWordAt(dataWrite,0,bMemoryVal);

                    client.WriteArea(S7.S7AreaDB, 1, iMemoryAdd, 2, dataWrite);
                    ret = "WriteArea of DB1.DBD" + iMemoryAdd + " : "+bMemoryVal;


                }else{
                    ret = "ERR: "+ S7Client.ErrorText(res);
                }
                client.Disconnect();
            }catch (Exception e) {
                ret = "EXC: "+e.toString();
                Thread.interrupted();
            }
            return "executed";
        }

        @Override        protected void onPostExecute(String result){


            TextView txout = (TextView) findViewById(R.id.textView);
            txout.setText(ret);
        }
    }

}

วันอาทิตย์ที่ 14 มกราคม พ.ศ. 2561

วันศุกร์ที่ 25 สิงหาคม พ.ศ. 2560

การต่อ SIMATIC HMI TP700 COMFORT กับ S7 300 CPU 315 2 dp (6es7 315-2ag10-0ab0) รุ่นเก่า

     วันนี้ได้ไปหน้างานซึ่งเป็นโรงงานเลื่อยไม้ได้ซื้อเครื่องจักรจากต่างประเทศ ใช้ PLC ยี่ห้อ Siemens รุ่น S7 300 CPU 315 2 dp เป็น CPU  รุ่นเก่าพอสมควร จึงทำให้การเชื่อมต่อกับจอ SIMATIC HMI TP700 COMFORT รุ่นใหม่ เป็นเรื่องที่จัดการยากพอสมควร

       เข้าเรื่องกันเลยนะครับ  ผมได้เขียนโปรแกรมด้วย Step V5.5+SP1 เนื่องจาก S7 300 CPU 315 2 dp ใช้ firmware 2.0 โปรแกรม TIA Protal ไม่ Support เนื่องจากใช้ firmware 2.6



ที่สำคัญอย่าลืมกำหนด Tag ใน Symbol Table ดังรูปด้านล่าง


*******  จากนั้น Download เข้าไปใน PLC  ************


ในส่วนของ SIMATIC HMI TP700 COMFORT  ให้ทำตามขั้นตอนดังนี้

1. เปิดโปรแกรม TIA  Portal V.13 สร้างโปรเจคใหม่ แล้วเพิ่มอุปกรณ์ใหม่(Add new device)


ไม่ต้องเชื่อมต่อกับ PLC ให้กดปุ่ม Finish ได้เลยครับ



2. สร้าง Connection ขึ้นมาเองตั้งชื่ออะไรก็ได้ ในตัวอย่างด้านล่าง ตั้งชื่อ Connection_1 เลือก Communication driver เป็น SIMATIC S7 300/400 และเลือก Online 


***SIMATIC HMI TP700 COMFORT  กับ S7 300 CPU 315 2 dp  เชื่อมต่อ ผ่าน MPI ***
เนื่องจากอุปกรณ์ทั้ง 2 ตั้งการเชื่อมต่อแบบ MPI เป็นค่าเริ่มต้นดังรูปด้านล่าง
รูป interface type: MPI ของ HMI

รูป interface type: MPI ของ PLC
3.สร้าง HMI tags  ให้ Address ตรงกับใน Symbol Table ดังรูปด้างล่าง อย่าลืมเลือก Connection ให้ตรงกับข้อ 2.


4.สร้างหน้าจอในส่วน Root screen


กำหนด Tag ให้ตรงกับ ข้อ 3.


5. ให้ทำการ Download เข้า HMI โดยการกดปุ่ม Download to device




นำสายต่อ HMI กับ PLC ผ่าน MPI