M5Stack#LANモジュールでSiemensPLCと通信

M5Stack W5500 LAN モジュール

このモジュールはM5BaseでW5500のChipが入っており、TCP/IP Ethernet Controllerでインタネット接続などを簡単に実現できます。そしてHT3.96のコネクタ・485Interfaceもありあます。あとそのHT3.96コネクタで他の回路とつながることもできます。

このLinkは紹介があります。

https://docs.m5stack.com/en/base/lan_base

購入LINK:

https://www.switch-science.com/catalog/3994/

Settimino Library 

今回使うのはそのSettiminoライブラリです。そのライブラリはOpen-sourceのEthernet ライブラリでArduino・ESP8266・NodeMCU・ESP32とシーメンス社のPLCと通信するのためです。(S7-1200,1500,300,400,200,LOGOもSupportします。)

http://settimino.sourceforge.net/

インストール

下記のLinkクリックします。

https://sourceforge.net/projects/settimino/files/

Download Latest Versionします。

Ethernet2 Library

このライブラリはW5500 Ethernet shieldsを使用するときに使うライブラリで、ServerとClientもOKです。注意するのはW5100より古いバージョンが使えません。

Download Link:

https://www.arduino.cc/reference/en/libraries/ethernet2/

実装

まず最初にExampleを入れてコンパイルするとエラーが出てきますので、Settimino.hを編集する必要があると思います。

今回使ってるのはM5StackとLANモジュールなので、Line111からですね。

M5StackがM5Core2になるので、Codeの編集します。

Ethernet2.hも必要なので、先インストールしておきましたもんね。

Code

/*———————————————————————-
M5Stack Sentron emulation

Created 09 Mar 2019
by Davide Nardella

———————————————————————— 
This demo is only for M5Stack hardware.
You need to define M5STACK_WIFI or M5STACK_LAN (see platform.h)

———————————————————————-*/
#include <Platform.h>
#include <Settimino.h>

//———————————————————————
// Defining USE_DISPLAY the display will be used for service messages
//———————————————————————
#define USE_DISPLAY

#ifdef USE_DISPLAY
  #define stdout M5.Lcd
#else 
  #define stdout Serial
#endif 

//**********************************************************************
// Connection Variables
//**********************************************************************
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE1 };

// Cabled Network (M5STACK_LAN defined in platform.h)
IPAddress Local(192,168,0,10);  // Local Address
IPAddress Gateway(192, 168, 0, 1);
IPAddress Subnet(255, 255, 255, 0);

// WIFI Network (M5STACK_WIFI defined in platform.h)
// Following constants are needed only if you are connecting via WIFI
// The ssid is the name of my WIFI network (the password obviously is wrong)
char ssid[] = “SKYNET-AIR”;    // Your network SSID (name)
char pass[] = “password”;  // Your network password (if any)

// Remote Address
IPAddress PLC(192,168,0,12);   // PLC Address

//**********************************************************************
// Process Variables
//———————————————————————-
// We assume that DB100 contains 9 Reals starting from 0
// V1,V2,V3 Voltage
// C1,C2,C3 Current
// P1,P2,P3 Power
//**********************************************************************
int DBValues   = 100; // DB containing Data
int OFSValues  = 0;   // Offset of first value
int SizeValues = 36;  // 9 Reals = 36 Byte
//**********************************************************************
// Program Variables
//**********************************************************************
// Pages
#define VOLTAGE 1
#define CURRENT 2
#define POWER   3
#define SERVICE 4

#define PageSwitchTime 4000 // Change Page every 4s if no button was pressed
long Elapsed =0;

int PageColors[4] = {TFT_GREEN,    // Voltage page text color
                    TFT_YELLOW,   // Current page text color
                    TFT_WHITE,    // Power page text color
                    TFT_WHITE};     // Error page text color

// Leading
int xl[3]={15,  15, 15};
int yl[3]={36, 108,180};
// Values
int xv[3]={84, 84,  84};
int yv[3]={10, 82, 154};
// Umes
int xu[3]={260,260,260};
int yu[3]={36, 108,180};

float V[3]={0.0,0.0,0.0}; // TENSION
float C[3]={0.0,0.0,0.0}; // CURRENT
float P[3]={0.0,0.0,0.0}; // POWER

S7Client Client;
int CurrentPage = -1; // To force the first switch

//———————————————————————-
// Checks the elapsed time
//———————————————————————-
bool IsElapsed(long Time)
{
  long Delta=millis()-Elapsed;
  if (Delta<0) // Check millis() rollover (after 49 days)
  {
    Elapsed=millis(); 
    Delta=0;
  }   
  return Delta>=Time;
}
//———————————————————————-
// Mark current time
//———————————————————————-
void MarkTime()
{
  Elapsed=millis();
}
//———————————————————————-
// Switches to a selected page
//———————————————————————-
void SwitchTo(int Page)
{
  if (Page!=CurrentPage) // Avoid unneeded redraw
  {
    PreparePage(Page,PageColors[Page-1]);
    MarkTime();
    CurrentPage=Page;
  }
}
//———————————————————————-
// Draw Sigma symbol (no font available to do it)
//———————————————————————-
void DrawSigma(int x, int y, int Color)
{
  M5.lcd.drawLine(x,y,x+18,y,Color);        
  M5.lcd.drawLine(x,y+1,x+18,y+1,Color);

  M5.lcd.drawLine(x,y,x+9,y+9,Color);
  M5.lcd.drawLine(x+1,y,x+10,y+9,Color);

  M5.lcd.drawLine(x,y+18,x+9,y+9,Color);
  M5.lcd.drawLine(x+1,y+18,x+10,y+9,Color);

  M5.lcd.drawLine(x,y+18,x+18,y+18,Color); 
  M5.lcd.drawLine(x,y+17,x+18,y+17,Color); 
}
//———————————————————————-
// Prepares the page
//———————————————————————-
void PreparePage(int Page, int Color)
{

  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(Color, TFT_BLACK);
  if (Page==SERVICE)
  {
    M5.Lcd.setTextSize(2);
    m5.Lcd.setCursor(0,0);
  }
  else
    M5.Lcd.setTextSize(1);

  switch (Page){
    case VOLTAGE:
      // Lead
      M5.Lcd.drawString(“L1”, xl[0], yl[0], 4);
      M5.Lcd.drawString(“L2”, xl[1], yl[1], 4);
      M5.Lcd.drawString(“L3”, xl[2], yl[2], 4);
      // Umes
      M5.Lcd.drawString(“V”, xu[0], yu[0], 4);
      M5.Lcd.drawString(“V”, xu[1], yu[1], 4);
      M5.Lcd.drawString(“V”, xu[2], yu[2], 4);
      break;
    case CURRENT:    
      // Lead
      M5.Lcd.drawString(“L1”, xl[0], yl[0], 4);
      M5.Lcd.drawString(“L2”, xl[1], yl[1], 4);
      M5.Lcd.drawString(“L3”, xl[2], yl[2], 4);    
      // Umes
      M5.Lcd.drawString(“A”, xu[0], yu[0], 4);
      M5.Lcd.drawString(“A”, xu[1], yu[1], 4);
      M5.Lcd.drawString(“A”, xu[2], yu[2], 4);
      break;
    case POWER:
      // Lead
      DrawSigma(xl[0], yl[0], Color);
      M5.Lcd.drawString(“S”, xl[0]+22, yl[0], 4);
      DrawSigma(xl[1], yl[1], Color);
      M5.Lcd.drawString(“P”, xl[1]+22, yl[1], 4);
      DrawSigma(xl[2], yl[2], Color);
      M5.Lcd.drawString(“Q1”, xl[2]+22, yl[2], 4);
      // Umes
      M5.Lcd.drawString(“kVA”, xu[0], yu[0], 4);
      M5.Lcd.drawString(“kW”, xu[1], yu[1], 4);
      M5.Lcd.drawString(“kvar”, xu[2], yu[2], 4);
      break; 
  }
}
//———————————————————————-
// Displays a single floating point value
//———————————————————————-
void WriteValue(int x, int y, float Value)
{
  char sValue[6]={0,0,0,0,0,0};
  dtostrf(Value, 6, 1, sValue);
  M5.Lcd.drawString(sValue, x, y, 7);
}
//———————————————————————-
// Displays 3 values in accord to the current page
//———————————————————————-
void DisplayValues()
{
  M5.Lcd.setTextColor(PageColors[CurrentPage-1], TFT_BLACK);
  switch (CurrentPage){
    case VOLTAGE:
      for (int c=0;c<3;c++)
        WriteValue(xv[c],yv[c],V[c]);  
    break;
    case CURRENT:
      for (int c=0;c<3;c++)
        WriteValue(xv[c],yv[c],C[c]);  
    break;
    case POWER:
      for (int c=0;c<3;c++)
        WriteValue(xv[c],yv[c],P[c]);  
    break;  
  }
}
//———————————————————————-
// Switches to next page
//———————————————————————-
void NextPage()
{
  int Page=CurrentPage+1;
  if (Page>POWER)
    Page=VOLTAGE;
  SwitchTo(Page); 
}
//———————————————————————-
// Setup : Init Ethernet and Serial port
//———————————————————————-
void setup() {
#ifdef M5STACK_LAN
    M5.begin(true, false, true);
#endif   
#ifdef M5STACK_WIFI
    M5.begin(true, false, true);
#endif   

    // Open serial communications and wait for port to open:
    Serial.begin(115200);
   
    SwitchTo(SERVICE); // Service Page
   
#ifdef S7WIFI
//——————————————— ESPXX Initialization   

    stdout.println();
    stdout.println(“Connecting to “);
    stdout.println(ssid);
    WiFi.begin(ssid, pass);
    WiFi.config(Local, Gateway, Subnet);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(“.”);
    }
    stdout.println(“”);
    stdout.println(“WiFi connected”); 
    stdout.println(“Local IP address : “);
    stdout.println(WiFi.localIP());
    delay(3000); // Just to see the message
#else
//——————————–Wired Ethernet Shield Initialization   
    EthernetInit(mac, Local);     
    delay(1000);
    stdout.println(“”);
    stdout.println(“Cable connected”); 
    stdout.println(“Local IP address : “);
    stdout.println(Ethernet.localIP());
    delay(3000);  // Just to see the message
#endif  
}
//———————————————————————-
// Connects to the PLC
//———————————————————————-
bool Connect()
{
    int Result=1;
    SwitchTo(SERVICE);
   
    stdout.println(“Connecting to “);
    stdout.println(PLC); 
   
    while (Result!=0)
    {
      Result=Client.ConnectTo(PLC,
                                0,  // Rack (see the doc.)
                                1); // Slot (see the doc.)
      if (Result==0)
      {
        stdout.println(“”);
        stdout.println(“Connected, PDU Length = “);
        stdout.println(Client.GetPDULength());
        delay(300);
        SwitchTo(VOLTAGE);
      }
      else
      {
        stdout.print(“.”);
        delay(500);
      }
    } 
    return Result==0;
}
//———————————————————————-
// Prints the Error number
//———————————————————————-
void CheckError(int ErrNo)
{
  int LastPage = CurrentPage;

  SwitchTo(SERVICE);
  stdout.print(“Error No. 0x”);
  stdout.println(ErrNo, HEX);

  // Checks if it’s a Severe Error => we need to disconnect
  if (ErrNo & 0x00FF)
  {
    stdout.println(“SEVERE ERROR disconnecting”);
    Client.Disconnect();
  }
  else
  {
    delay(1000);
    SwitchTo(LastPage);
  }
}
//———————————————————————-
// Main Loop
//———————————————————————-
void loop()
{

  // Connects (if needed)
  if (!Client.Connected)
    Connect();

  int Result=Client.ReadArea(S7AreaDB,
                            DBValues,   // DB containing Sentron Data
                            OFSValues,  // Offset of first value
                            SizeValues, // Data Packet size
                            NULL);      // Use internal buffer (PDU.DATA[]), small and faster

  if (Result==0)
  {
    V[0]=S7.FloatAt(0);   // Voltage L1
    V[1]=S7.FloatAt(4);   // Voltage L2
    V[2]=S7.FloatAt(8);   // Voltage L3
    C[0]=S7.FloatAt(12);  // Current L1
    C[1]=S7.FloatAt(16);  // Current L2
    C[2]=S7.FloatAt(20);  // Current L3
    P[0]=S7.FloatAt(24);  // Sigma S
    P[1]=S7.FloatAt(28);  // Sigma P
    P[2]=S7.FloatAt(32);  // Sigma Q1
    DisplayValues();
  }
  else
    CheckError(Result);
         
  if (Result==0)
  {
    // Change page detection
    if (M5.BtnA.wasPressed())
      SwitchTo(VOLTAGE);   

    if (M5.BtnB.wasPressed())
      SwitchTo(CURRENT);   
     
    if (M5.BtnC.wasPressed())
      SwitchTo(POWER);   
   
    // Auto page switch to avoid display damage on long time
    if (IsElapsed(PageSwitchTime))
    {
      NextPage();
    }
  }

  delay(200); 
  M5.update();
}

Ping

うん、とりあえず大丈夫そうですね。

通信テスト前の設定

結果

こんな感じですね!

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

  • このエントリーをはてなブックマークに追加

フォローする