NRobinson2
Published © GPL3+

Ignition SCADA + MKR WiFi 1010

If you're trying to learn Ignition and want a source of actual data, this tutorial demonstrates how to feed Ignition with Arduino.

IntermediateShowcase (no instructions)2,742
Ignition SCADA + MKR WiFi 1010

Things used in this project

Hardware components

Arduino MKR WiFi 1010
Arduino MKR WiFi 1010
×1
Arduino MKR 485 Shield
Arduino MKR 485 Shield
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
Temperature Sensor
Temperature Sensor
×1
Push Button
×1

Software apps and online services

Ignition SCADA

Story

Read more

Schematics

Wiring for potentiometer, push button, and LM34 temp sensor

These components give you a way to create channels which can be viewed in Ignition

Modbus Address file

Import into Ignition Gateway

Code

MKR_WiFI_1010_Ignition_VFD

Arduino
Used to connect MKR WiFi 1010 to Ignition SCADA via Modbus TCP connection
// This sketch is for the following hardware:
//      - Arduino MKR WiFi 1010 + MKR RS-485 Shield
//      - Automation Direct GS2 VFD drive, model GS2-11P0
// The manual for the VDF can be read at: 
//      - https://cdn.automationdirect.com/static/manuals/gs2m/gs2m.html
// Written by: Nick Robinson, Last Updated 26-Mar-2020

#include <SPI.h>
#include <WiFiNINA.h>          
#include <utility/wifi_drv.h>
#include <ArduinoRS485.h>       // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

//Wifi network name and password
char ssid[] = "Kaisoku";       
char pass[] = "Tsunagaru";

//Modbus coil address mapping
const int modAddButton = 0x00;
const int modAddRedLED = 0x01;
const int modAddGreenLED = 0x02;
const int modAddBlueLED = 0x03;
const int modAddRunStop = 0x04;
const int modAddFwdRev = 0x05;

//Modbus holding register address mapping
const int modAddPotVal = 0x00;
const int modAddTempVal = 0x01;
const int modAddDriveFreq = 0x02;
const int modAddAccelDecel = 0x03;
const int modAddRpm = 0x04;
const int modAddDriveStatus = 0x05;

//VFD parameters and modbus addresses
const int vfd = 0x02;                   
const int driveRatio = 29;

const int Add_accel = 0x0101;           // Acceleration time
const int Add_decel = 0x0102;           // Deceleration time
const int Add_rpm = 0x2107;             // motor rpm 
const int Add_Status1 = 0x2100;         // Status monitor 1
const int Add_driveFreq = 0x091A;       // 0 to 60 Hz                 
const int Add_stopRun = 0x091B;         // 0 = stop, 1 = run
const int Add_fwdRev = 0x091C;          // 0 = forward, 1 = reverse

//VFD related input / output variables
int inputFreq;
int inputStopGo;
int inputDirection;
int inputAccelDecelTime;
int outputRpm;
int outputDriveStatus;

//Arduino hardware input / output variables
const int buttonPin = 5;                //pushbutton on D5
const int redLED = 26;                  //uses on board RGB LED
const int greenLED = 25;
const int blueLED = 27;
int buttonValue, prevButtonValue, buttonSwitch;

int status = WL_IDLE_STATUS;

WiFiServer wifiServer(502);             //TCP Modbus on port 502
ModbusTCPServer modbusTCPServer;

void setup() {
  Serial.begin(9600);
  ModbusRTUClient.begin(19200, SERIAL_8O1);
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(1000);
  }
  Serial.println("Modbus TCP Server");
  printWifiStatus();  //before start-up, open serial monitor in order to see the assigned IP address
  wifiServer.begin();

  if (!modbusTCPServer.begin()) {
    Serial.println("Failed to start Modbus TCP Server!");
    while (1);
  }
  pinMode(buttonPin, INPUT);
  WiFiDrv::pinMode(redLED, OUTPUT); 
  WiFiDrv::pinMode(greenLED, OUTPUT); 
  WiFiDrv::pinMode(blueLED, OUTPUT); 
  WiFiDrv::digitalWrite(redLED, LOW);
  WiFiDrv::digitalWrite(greenLED, LOW);
  WiFiDrv::digitalWrite(blueLED, LOW);

  modbusTCPServer.configureCoils(0x00, 10);
  modbusTCPServer.configureHoldingRegisters(0x00, 10);
}

void loop() {
  WiFiClient client = wifiServer.available();
  
  if (client) {
    Serial.println("Ignition! Connected");
    modbusTCPServer.accept(client);

    while (client.connected()) {
      modbusTCPServer.poll();
      updateButton();
      updateLED();
      updatePot();
      updateTemp();
      updateVFD();
    }
    Serial.println("disconnected");
  }
}

void updateButton() {
  buttonValue = digitalRead(buttonPin);
  if(buttonValue != prevButtonValue){
    if(buttonValue == HIGH){
      buttonSwitch = !buttonSwitch;
    }
  prevButtonValue = buttonValue;
  }
  modbusTCPServer.coilWrite(modAddButton, buttonSwitch);
}

void updateLED() {
  int coilValue_red = modbusTCPServer.coilRead(modAddRedLED);
  int coilValue_green = modbusTCPServer.coilRead(modAddGreenLED);
  int coilValue_blue = modbusTCPServer.coilRead(modAddBlueLED);

  WiFiDrv::digitalWrite(redLED, coilValue_red);
  WiFiDrv::digitalWrite(greenLED, coilValue_green);
  WiFiDrv::digitalWrite(blueLED, coilValue_blue);
}

void updatePot() {
  int potRawVal = analogRead(A4);
  //raw value is sent, conversion to voltage is done in Ignition
  modbusTCPServer.holdingRegisterWrite(modAddPotVal, potRawVal);  
}

void updateTemp() {
  int tempRawVal = analogRead(A3);
  //raw value is sent, conversion to temperature is done in Ignition
  modbusTCPServer.holdingRegisterWrite(modAddTempVal, tempRawVal);
}

void updateVFD() {
  inputStopGo = modbusTCPServer.coilRead(modAddRunStop);
  inputDirection = modbusTCPServer.coilRead(modAddFwdRev);
  inputFreq = (modbusTCPServer.holdingRegisterRead(modAddDriveFreq)) * 10;
  inputAccelDecelTime = modbusTCPServer.holdingRegisterRead(modAddAccelDecel); 
  
  if(inputAccelDecelTime == 0) 
    inputAccelDecelTime = 50;
  
  if(!ModbusRTUClient.holdingRegisterWrite(vfd, Add_driveFreq, inputFreq) ||
     !ModbusRTUClient.holdingRegisterWrite(vfd, Add_stopRun, inputStopGo) ||
     !ModbusRTUClient.holdingRegisterWrite(vfd, Add_fwdRev, inputDirection) ||
     !ModbusRTUClient.holdingRegisterWrite(vfd, Add_accel, inputAccelDecelTime) ||
     !ModbusRTUClient.holdingRegisterWrite(vfd, Add_decel, inputAccelDecelTime))
        errorFlash();
        
  outputRpm = ModbusRTUClient.holdingRegisterRead(vfd, Add_rpm);
  outputDriveStatus = ModbusRTUClient.holdingRegisterRead(vfd, Add_Status1);
  if(outputRpm == -1 || outputDriveStatus == -1)
    errorFlash();
  else outputRpm = outputRpm / driveRatio;
  
  modbusTCPServer.holdingRegisterWrite(modAddRpm, outputRpm);
  modbusTCPServer.holdingRegisterWrite(modAddDriveStatus, outputDriveStatus);
}

void errorFlash(){                    
  pinMode(LED_BUILTIN, OUTPUT);                 
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);
}

void printWifiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Credits

NRobinson2

NRobinson2

0 projects • 0 followers

Comments