Comunicação Modbus TCP/IP entre Arduino e ScadaBR

Boa tarde,

Quando realizei a comunicação Modbus Serial entre o Arduino e o ScadaBR funcionou perfeitamente, mas o mesmo não acontece quando eu tento estabelecer a comunicação Modbus TCP/IP.

A seguir vou disponibilizar o código no Arduino e as fotos de configuração do ScadaBR, e os erros apresentados.

Arduino:

#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusIP.h>

//Modbus Registers Offsets (0-9999)
const int LAMP1_COIL = 100;

//Used Pins
const int ledPin = 13;

//ModbusIP object
ModbusIP mb;

void setup() {

// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  

// The IP address for the shield
byte ip[] = { 192, 168, 0, 102 };   

//Config Modbus IP 
mb.config(mac, ip);

//Set ledPin mode
pinMode(ledPin, OUTPUT);

// Add LAMP1_COIL register - Use addCoil() for digital outputs
mb.addCoil(LAMP1_COIL);

}

void loop() {

//Call once inside loop() - all magic here
mb.task();

//Attach ledPin to LAMP1_COIL register
digitalWrite(ledPin, mb.Coil(LAMP1_COIL));
}

Pra desenvolver esse exemplo eu segui um tutorial, mas aparece esse erro de “Ilegal data address”.
Alguém consegue me dizer o que pode estar errado? Todas as outras alternativas que eu encontrei em outros posts e fóruns não me deram nenhum resultado.

Obrigada.

Boa tarde amigo,

Voce consegue realizar um ping no ip 192.168.0.102?

Boa tarde,

Sim, eu consigo realizar normalmente.

Estou utilizando uma Shield Ethernet e antes de testar com o ScadaBR, eu fiz um pequeno exemplo de um código html no Arduino justamente com esse IP, e funcionou. Quando eu tento comunicar com o ScadaBR não funciona.

Quando tenta comunicar com o ScadaBR, ele responde no ping?
Eu utilizo a biblioteca MudBus, bem simples.
https://code.google.com/archive/p/mudbus/source

Sim, ele responde.

Essa biblioteca MudBus tem o mesmo funcionamento? Não a conhecia!

Sim, funciona muito bem

Eu tentei executar um código exemplo aqui, mas continua com o mesmo erro.

Testa o exemplo MB, é pra funcionar tranquilo

Bom dia,

Poderia, por gentileza, me auxiliar neste exemplo por favor?

Eu alterei o exemplo MB para ler apenas um potenciômetro no A0 e alterar a saída PWM através do valor atribuído no ScadaBR no Mb.R[6]. Após esse procedimento, no ScadaBR eu criei um point link para alterar o PWM de acordo com o valor lido no potenciômetro.
Por um breve período os valores no watch list do ScadaBR foram corretos, mas depois começou a aparecer os seguintes erros:

com.serotonin.modbus4j.exception.ModbusInitException: java.net.SocketTimeoutException: connect timed out

com.serotonin.modbus4j.exception.ModbusTransportException: com.serotonin.messaging.TimeoutException: request=com.serotonin.modbus4j.serial.rtu.RtuMessageRequest@6e269cd4

Estou fazendo da maneira correta?

Arduino:

#include <SPI.h>
#include <Ethernet.h>

#include “Mudbus.h”

Mudbus Mb;
//Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register)
//signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C
//Port 502 (defined in Mudbus.h) MB_PORT

#define led 13

void setup()
{
uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
uint8_t ip[] = { 192, 168, 0, 102 };
uint8_t gateway[] = { 192, 168, 0, 1 };
uint8_t subnet[] = { 255, 255, 255, 0 };
Ethernet.begin(mac, ip, gateway, subnet);
//Avoid pins 4,10,11,12,13 when using ethernet shield

delay(5000);
Serial.begin(9600);

pinMode(7, INPUT);
pinMode(8, OUTPUT);
pinMode(led, OUTPUT);
}

void loop()
{
Mb.Run();

//Analog inputs 0-1023
Mb.R[0] = analogRead(A0); //pin A0 to Mb.R[0]
//Mb.R[1] = analogRead(A1);
//Mb.R[2] = analogRead(A2);
//Mb.R[3] = analogRead(A3);
//Mb.R[4] = analogRead(A4);
//Mb.R[5] = analogRead(A5);

//Analog outputs 0-255
//analogWrite(6, Mb.R[6]); //pin ~6 from Mb.R[6]
analogWrite(led, Mb.R[6]); //pin ~6 from Mb.R[6]

//Digital inputs
//Mb.C[7] = digitalRead(7); //pin 7 to Mb.C[7]

//Digital outputs
//digitalWrite(8, Mb.C[8]); //pin 8 from Mb.C[8]

}

Olá amigo,

Primeiramente, você conseguiu comunicar o ScadaBr com o arduíno via Modbus TCP ? Sem este exemplo acima, o código exemplo da biblioteca?

Olá,

Não consegui não, aparecem os mesmos erros descritos acima.

Te chamei no privado, preciso conectar na sua máquina e ver o que está acontecendo.
Aqui eu faço upload do exemplo MB e já conecta na hora.
Aguardo seu retorno.

No ScadaBR o tipo de transporte deixa em TCP e não TCP com manter vivo

Print do Data Source:

Manda print do ping no IP 102.
Já tentou desativar o firewall? Vai que…

Você está utilizando um Ethernet Shield W5100 ?

Sim, estou utilizando.

Bom dia, Consegui fazer a comunicação tudo certinho, mas precisava botar um botão físico para também fazer um acionamento. Resumindo preciso acionar uma saída do Arduíno tanto pelo Modbus TCP IP quanto por pulsador como entrada digital do Arduíno. Alguém tem algum exemplo de código para isso ?

OIa amigo,

Fiz um exemplo MUITO simples, sem filtro de entrada digital(tempo minimo, para eliminar ruídos), sem eeprom.
Você pode ter como base esse exemplo para desenvolver o algorítimo desejado.

Lembrando que você deve mandar apenas um pulso do ScadaBR, escreve 1 depois muda para 0, você pode usar um botão do tipo script.

Script
dp.writeDataPoint(‘DP_663288’,1);
dp.writeDataPoint(‘DP_663288’,0);

Arduino
#include < SPI.h >
#include < Ethernet.h >
#include “Mudbus.h”
const int entrada6 = 6;
const int saida7 = 7;
Mudbus Mb;
void setup()
{
uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
uint8_t ip[] = { 192, 168, 1, 8 };
uint8_t gateway[] = { 192, 168, 1, 1 };
uint8_t subnet[] = { 255, 255, 255, 0 };
Ethernet.begin(mac, ip, gateway, subnet);
delay(5000);
pinMode(entrada6, INPUT);
pinMode(saida7, OUTPUT);
digitalWrite(saida7, 0);
}

    void loop()
    {
      Mb.Run();
      int scada_btn;
      int externo_btn;
      scada_btn = Mb.R[1];
      externo_btn = digitalRead(entrada6);
      if ((scada_btn == 1) or (externo_btn == 1)) {
        digitalWrite(saida7, !saida7);
      }


    }