ModbusIP Slave with Arduino (ethernet)

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi guys
I have an Arduino project with lots of real time data communicating with a SCADA application on my PC via the Arduino Ethernet Shield and a router, using Modbus protocol (Arduino Library). The router is wireless but I am currently using wired Ethernet connection.

I would like to make it a wireless setup by replacing the Ethernet shield & substituting either an ESP8266 board or the Adafruit Arduino WiFi Shield 101 (ATWINC1500 ). I've tried the ESP8266 and having problems so now considering the Adafruit shield.

Some questions first:
1. Will it work, ie Modbus TCP on the 101 shield?
2. Do you have examples?
3. Can you give me a heads up on what I need to do (and NOT to do!)

Thanks
Ross Dye

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by adafruit_support_rick »

There's no reason why modbus won't work with the 101 shield. But the library you're using may need modification. Which library are you using? There are several.

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi
Thanks for the response.
I am currently using a library I found on GitHub called ModbusIP. I have also used one called Mudbus. Both have pros & cons but I can use either (or switch to whatever you recommend for 101 board.

Modifying the libraries sounds daunting. What needs to be done?
Are you aware of anyone who has done it sucessfully?

Thanks
Ross

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by adafruit_support_rick »

I couldn't find those libraries. If you have links to them, that would be helpful.

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi
The Modbus library I am using is here: https://github.com/andresarmento/modbus-arduino

I have also used https://github.com/luizcantoni/mudbus/t ... ter/Mudbus

I'm not too worried which library you suggest, as long as it can work with Adafruit WIFI shield, with whatever mods you suggest.

As mentioned before, Modbus (wired) side of my project works fine. But I've spent best part of a week trying to get an ESP-01 to work, and have only got as far as sending "AT" command and getting "ERROR" response. Nothing else.

My project is now behind schedule so I will gladly switch to Adafruit 101 board, provided I have a reasonable confidence level that it will work, albeit with whatever library mods you recommend.

Thanks

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by adafruit_support_rick »

Didn't look at the mudbus library, because the ModBusIP library should work for you.
You will have to change wherever it #includes <Ethernet.h>. You will have to #include <WiFi101.h> instead.
Also, ModBusIP.h refers to "EthernetServer". This will become "WiFiServer".

The big difference will be in the config functions. Which version of the config function are you using now?

Do you have DHCP available on your wifi router, or will you be setting the IP parameters manually?

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Thanks Rick
The library mods sound ok

I don't understand your comment about config functions. Which config functions are you referring to?

The router has DHCP, but I am setting static IPs. In same subnet but outside the limits of the DHCP server (does that make sense?).

Thanks again

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by adafruit_support_rick »

The way I'm reading the library, you have to call one of these functions to get things started:

Code: Select all

        void config(uint8_t *mac);
        void config(uint8_t *mac, IPAddress ip);
        void config(uint8_t *mac, IPAddress ip, IPAddress dns);
        void config(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
        void config(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
Are you not doing that?


If you only want to set the IP, then you want to delete all but one of those functions, and then change it to be like this:
In modbusIP.h:

Code: Select all

void config(char* ssid, char* password, IPAddress ip);
In modbusIP.cpp

Code: Select all

void ModbusIP::config(char* ssid, char* password, IPAddress ip) {
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, password);

    // wait 10 seconds for connection:
    delay(10000);
  }

    WiFi.config(ip);  //set static IP
    _server.begin();  //start the server
}

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

ok, I misunderstood the question

I have following:

ModbusIP mb; //ModbusIP object
// MAC & IP for ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 2, 8 };
Ethernet.begin(mac, ip);
//Config Modbus Object
mb.config(mac, ip);

It seems to work

Thanks

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi
The Arduino WiFi Shield 101 is out of stock
What is the lead time?

Thanks

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Well, since 101 Shield is out of stock.......
I've been searching your site (& others) and found ATWINC1500 WiFi Breakout ! ! ! !

Can I assume it uses the same libraries & can be modified to support Modbus as you previously suggested?

Sorry... I need to keep my project moving so appreciate prompt response. I will order some units as soon as I get positive response

Thanks

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by adafruit_support_rick »

Yeah, the breakout is the same thing. Same library.
ross d wrote:ModbusIP mb; //ModbusIP object

Code: Select all

// MAC & IP for ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 
byte ip[] = { 192, 168, 2, 8 }; 
Ethernet.begin(mac, ip); 
//Config Modbus Object 
mb.config(mac, ip);
With the wifi, you don't have to set the mac address.

You'll still have to modify ModBusIP.h and ModBusIP.cpp to switch from ethernet to wifi. There's a little more work to starting WiFi than there is to starting ethernet, but otherwise, that code will be pretty similar

So, your setup code will look something like this:

Code: Select all

#include <WiFi101.h>

ModBusIP mb();
char ssid[] = "...your ssid here...";
char password[] = ".. your password here...";

void ConnectWiFi(char* ssid, char* password)
{
  // check for the presence of the WINC1500:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, password);

    // wait 10 seconds for connection:
    delay(10000);
  }
}

void setup()
{
  // MAC & IP for ethernet
  byte ip[] = { 192, 168, 2, 8 }; 
  ConnectWiFi(ssid, password); 
  //Config Modbus Object 
  mb.config(ip);
}

I took a pass at modifying the ModBus library files. Haven't tried it at all, but it should be close enough to get you started:

ModBusIP.h:

Code: Select all

/*
    ModbusIP.h - Header for Modbus IP Library
    Copyright (C) 2015 André Sarmento Barbosa
*/
#include <Arduino.h>
#include <Modbus.h>
#include <SPI.h>
#include <WiFi101.h>

#ifndef MODBUSIP_H
#define MODBUSIP_H

#define MODBUSIP_PORT 	  502
#define MODBUSIP_MAXFRAME 200

//#define TCP_KEEP_ALIVE

class ModbusIP : public Modbus {
    private:
        WiFiServer _server;
        byte _MBAP[7];

    public:
        ModbusIP();
        void config(IPAddress ip);
        void task();
};

#endif //MODBUSIP_H
ModBusIP.cpp

Code: Select all

/*
    ModbusIP.cpp - Source for Modbus IP Library
    Copyright (C) 2015 André Sarmento Barbosa
*/
#include "ModbusIP.h"

ModbusIP::ModbusIP():_server(MODBUSIP_PORT) {
}

void ModbusIP::config(IPAddress ip) {
    WiFi.cofig(ip);
    _server.begin();
}

void ModbusIP::task() {
    WiFiClient client = _server.available();

    if (client) {
        if (client.connected()) {
            int i = 0;
            while (client.available()){
                _MBAP[i] = client.read();
                i++;
                if (i==7) break;  //MBAP length has 7 bytes size
            }
            _len = _MBAP[4] << 8 | _MBAP[5];
            _len--;  // Do not count with last byte from MBAP

            if (_MBAP[2] !=0 || _MBAP[3] !=0) return;   //Not a MODBUSIP packet
            if (_len > MODBUSIP_MAXFRAME) return;      //Length is over MODBUSIP_MAXFRAME

            _frame = (byte*) malloc(_len);
            i = 0;
            while (client.available()){
                _frame[i] = client.read();
                i++;
                if (i==_len) break;
            }

            this->receivePDU(_frame);
            if (_reply != MB_REPLY_OFF) {
                //MBAP
                _MBAP[4] = (_len+1) >> 8;     //_len+1 for last byte from MBAP
                _MBAP[5] = (_len+1) & 0x00FF;

                byte sendbuffer[7 + _len];

                for (i = 0 ; i < 7 ; i++) {
                    sendbuffer[i] = _MBAP[i];
                }
                //PDU Frame
                for (i = 0 ; i < _len ; i++) {
                    sendbuffer[i+7] = _frame[i];
                }
                client.write(sendbuffer, _len + 7);
            }

#ifndef TCP_KEEP_ALIVE
            client.stop();
#endif
            free(_frame);
            _len = 0;
        }
    }
}

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Ok, Thank you
I have ordered a couple of units and will give it a try.
I'll report progress in a week or so when products received.
Thanks again

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi Rick
I ordered a couple of the ATWINC1500 WiFi Breakouts. But they got lost in transit.
Adafruit kindly replaced the items and they have just arrived.
There goes my project schedule !

Anyway, I should get back to it in the next week or so. I will keep you posted

Thanks again for your help

Ross

User avatar
ross d
 
Posts: 27
Joined: Wed Apr 10, 2013 12:37 am

Re: ModbusIP Slave with Arduino (ethernet)

Post by ross d »

Hi Rick
So far no good. I added a few obvious things, but then ran out of knowledge. So I went back to basics.
I am using wifi library found here: https://github.com/arduino-libraries/WiFi101
My board is an Arduino AtMega.

FIRST: I decided first to run the example "CheckWifi101FirmwareVersion" just to test board is powered up & ok etc.
I get the welcome message "WiFi101 firmware check. WiFi101 shield: " but that's all. So obviously I'm not communicating with the board.

First thing I notice: where is the SPI CS pin identified in this firmware check code? Also the Reset pin and IRQ pin.
I would think that it is necessary to specify the pins I am using, 47, 45 & 43 respectively.

Any ideas?

Thanks
Ross

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”