Ver la versión completa : Comunicación Protcolo ModBus por TCP/IP
Buenas!
El caso es que tengo un trasto aqui (un modulo de adquisicion de datos):
http://www.lima.com.tr/Advantech%20eAutomation/Images/ADAM-6050.GIF
El cual tiene una serie de entradas y salidas digitales a las cuales se las puede comandar por TCP usando un cablecito ethernet. El protocolo que usa es ModBus sobre ethernet (podria ser sobre Serial) trabaja sobre el puerto 502.
Mi idea es hacer una aplicacion en Java que mediante sockets que comande el dispositivo para activar/desactivar las salidas (las entradas serian para sensores de movimiento, luz...pero de momento no me importan).
El problema:
No consigo comunicarme bien con el cacharro, es decir: Utilizando la aplicacion que viene con el me conecto por red y activo las salidas y lo configuro pero si me conecto por telnet al 502 le mando comandos que he copiado del manual y no me responde nada.
Con el Etherreal/Wireshark (un sniffer) veo que la aplicacion del dispositivo se conecta al cacharro pero no consigo ver ninguna trama en ASCII (si pruebo un telnet a cualquier lado puedo ver las tramas en ASCII asi que no creo que sea cosa de no saber usas el Sniffer).
Alguien conoce este protocolo y me puede echar un cable? Mientras seguire tirando de manuales y tal a ver si consigo sacar algo :loco:.
Gracias y lo siento por el ladrillo :brindis::brindis:
Modbus... comunicaciones industriales... las hodio
asegurate de tener un master modbus con el que pueda comunicarse...
http://www.lammertbies.nl/comm/info/modbus.html
Modbus... comunicaciones industriales... las hodio
asegurate de tener un master modbus con el que pueda comunicarse...
http://www.lammertbies.nl/comm/info/modbus.html
Habia entendido mal la arquitectura, entonces necesitamos un master modbus en medio que haga de interfaz entre el cliente y el dispositivo...
Gracias tio :brindis::brindis:
< - >
Creo que me retracto, el tema del master modbus es cuando conectas el dispositivo por RS232, entonces si que necesitas utilizar un servidor, pero en este caso la informacion al ir por TCP/IP el propio aparato hace las veces de servidor...o eso entiendo yo...
Estoy en lo cierto o no me entero de nada :loco:
:brindis::brindis:
Bueno a ver, que ya he visto como va...
La arquitectura es Slave - Master.
Los Slaves son los dispositivos que estan a la escucha esperando que llegue un Master y les controle...
He encontrado esta libreria en java:
http://sourceforge.net/projects/jamod/
Me he empezao a pegar con ella hace un rato, siguiendo los ejemplos he conseguido conectar entre un master y un slave programados con esa libreria...pero cuando lo hago con el dispositivo real...tela jeje empiezan a pegar excepciones...logico, hay que leerse la documentacion antes :D.
:brindis::brindis:
Bueno a ver, que ya he visto como va...
La arquitectura es Slave - Master.
Los Slaves son los dispositivos que estan a la escucha esperando que llegue un Master y les controle...
He encontrado esta libreria en java:
http://sourceforge.net/projects/jamod/
Me he empezao a pegar con ella hace un rato, siguiendo los ejemplos he conseguido conectar entre un master y un slave programados con esa libreria...pero cuando lo hago con el dispositivo real...tela jeje empiezan a pegar excepciones...logico, hay que leerse la documentacion antes :D.
:brindis::brindis:
Y no puedes abrir el puerto en escucha e implementar solo la parte de los comandos que te interesa si esa libreria casca mucho??
Es decir, dejar en escucha puertos en java es trivial.
Saludos
las comunicaciones industriales tipo modbus, profibus, devicenet etc son un HORROR. Sobre el papel todo va guay, pero nada mas lejano a la realidad... codigos fuente proporcionados por el fabricante que no funcionan, ni compilan ni ostias, conectores propietarios chungos y/o demasiado simples y rompibles...
Y no puedes abrir el puerto en escucha e implementar solo la parte de los comandos que te interesa si esa libreria casca mucho??
Es decir, dejar en escucha puertos en java es trivial.
Saludos
Mi idea original era esa, conectarme por tcp usando Java y comandarlo manualmente...lo intente utilizando telnet, conectaba al puerto del dispositivo (502) y le mandaba supuestos comandos (churros en hexadecimal) que venian en la documentacion del dispositivo...y ni me contestaba ni enviaba nada...también he probado a escuchar el tráfico con etherreal utilizando una aplicación que viene con el dispositivo y es que se realizan un webo de peticiones antes de hacer nada...y para leerlas tela... :(.
Por eso he descartado de momento el hacerlo así y ahora con la libreria esta parece que se pueden hacer cosillas :D.
Creo que casca por que estoy accediendo a entradas/salidas que no existen, aún no entiendo muy bien lo que hace cada metodo de las tropecientas clases que hay :rolleyes:.
las comunicaciones industriales tipo modbus, profibus, devicenet etc son un HORROR. Sobre el papel todo va guay, pero nada mas lejano a la realidad... codigos fuente proporcionados por el fabricante que no funcionan, ni compilan ni ostias, conectores propietarios chungos y/o demasiado simples y rompibles...
Las utilizaron en un proyecto en el que estuve aunque no llegue a tocar el codigo y por lo que vi utilizando estos dispositivos les iba bastante bien...ahora bien, por lo poco que llevo intentandolo te doy toda la razón :confused:.
El fabricante no da nada en java, solo un applet ya compilado al que no se le puede meter mano...buff :(
:brindis::brindis:
Bueno tios solucionado,
Decompile un .class que venia en el ejemplo de un applet (el cual no iba :rolleyes:) y ahi viendo los metodos consegui destripar su funcionamiento, de momento he conseguido activar desactivar las salidas digitales...con las entradas tampoco sera mucho problema ya que tambien hay un metodo específico para ello...
Bueno, gracias por la ayuda :brindis::brindis:
mw_modbus
24/09/2009, 12:13
Buenas
Estoy tratando de hacer algo parecido con lo que tenias problemas, comunicarme con Modbus TCP/IP a un cacharro, jeje.
Estoy trasteando con la libreria jamod, pero llevo un par de días atascado. He conseguido realizar la conexion (El equipo está directamente conectado por ethernet al cacharro en cuestion), peor al ejecutar una transaccion me peta por tiemout, le he dado mas timeout pero nada. Si os suena os agradeceria cualquier ayuda.
Un saludo y gracias.
PD: os pongo parte del código, sacado de un ejemplo de la documentación de jamod
//1. Abriendo conexion
con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect();
if(con.isConnected()){
System.out.println("Conectado correctamente al dispositivo...");
System.out.println(" -Puerto: "+con.getPort());
System.out.println(" -Timeout: "+con.getTimeout());
System.out.println(" -Address: "+con.getAddress());
}else{
System.out.println("Error conectando al dispositivo");
}
//2. Preparando consulta
req = new ReadMultipleRegistersRequest(ref, count);//ReadInputDiscretesRequest(ref, count);
//3. Preparando transaction
trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
if (con.isConnected()){
System.out.println(" -Validez de la request: "+trans.isCheckingValidity());
}
//4. Ejecutando la transaccion repetidas veces
int i = 0;
while (i < repeat){
trans.execute(); //Aqui me peta
res = (ReadMultipleRegistersResponse) trans.getResponse();
System.out.println("Digital Hex Message=" + res.getHexMessage());
i++;
}
//5. Cerrando conexion
con.close();
En cuanto llegue a casa le echo un ojo a tu codigo y lo comparo con el mio que al final consegui echarlo a andar ;)
:brindis::brindis:
mw_modbus
24/09/2009, 13:08
Muchas gracias de verdad :rever:
Buenas,
El cacharro en cuestion es un Adam de estos?
Veamos yo la conexion no la hago utilizando la libreria Jamod sino usando una clase que pille de uno de los ejemplos del dispositivo.
package Adam.Modbus;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class ModBus
{
static InetAddress target;
Socket echoSocket = null;
DataOutputStream out = null;
DataInputStream in = null;
String myHost;
byte[] ModBusRTUCmd = new byte[128];
byte ModBusID;
static boolean IsRuning = false;
public ModBus(String paramString, int paramInt)
{
if (IsRuning) Close();
IsRuning = true;
this.myHost = chkHostIP(paramString);
this.ModBusID = (byte)paramInt;
try {
TCPInit();
} catch (Exception localException) {
localException.printStackTrace();
}
}
public boolean IsModBusAlive() {
return IsRuning;
}
public ModBus(String paramString) {
if (IsRuning) Close();
IsRuning = true;
this.myHost = chkHostIP(paramString);
this.ModBusID = 1;
try {
TCPInit();
} catch (Exception localException) {
localException.printStackTrace();
}
}
public String GetHostIP() {
return this.myHost;
}
public void TCPInit() throws Exception {
try {
this.echoSocket = new Socket(this.myHost, 502);
this.echoSocket.setSoTimeout(1000);
this.out = new DataOutputStream(this.echoSocket.getOutputStream() );
this.in = new DataInputStream(this.echoSocket.getInputStream());
}
catch (UnknownHostException localUnknownHostException) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException localIOException) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
}
public boolean ForceCoil(int paramInt, boolean paramBoolean) {
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0; this.ModBusRTUCmd[5] = 6;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 5;
this.ModBusRTUCmd[8] = 0;
this.ModBusRTUCmd[9] = (byte)paramInt;
if (paramBoolean) {
this.ModBusRTUCmd[10] = -1;
}
else
this.ModBusRTUCmd[10] = 0;
this.ModBusRTUCmd[11] = 0;
return SendCmd2Adam(this.ModBusRTUCmd, 12);
}
public boolean ReadCoil(int paramInt1, int paramInt2, byte[] paramArrayOfByte)
{
if (paramInt1 <= 1)
{
paramInt1 = 0;
}
else --paramInt1;
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0; this.ModBusRTUCmd[5] = 6;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 1;
this.ModBusRTUCmd[8] = 0;
this.ModBusRTUCmd[9] = (byte)paramInt1;
this.ModBusRTUCmd[10] = 0;
this.ModBusRTUCmd[11] = (byte)paramInt2;
if (SendCmd2Adam(this.ModBusRTUCmd, 12))
{
for (int i = 0; i < this.ModBusRTUCmd[8]; ++i)
{
for (int j = 0; j < 8; ++j)
{
if ((this.ModBusRTUCmd[(9 + i)] >> j & 0x1) > 0)
paramArrayOfByte[(i * 8 + j)] = 1;
else paramArrayOfByte[(i * 8 + j)] = 0;
}
}
}
else return false;
return true;
}
public boolean PresetRegister(int paramInt1, int paramInt2) {
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0; this.ModBusRTUCmd[5] = 6;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 6;
this.ModBusRTUCmd[8] = 0;
this.ModBusRTUCmd[9] = (byte)paramInt1;
this.ModBusRTUCmd[10] = (byte)((paramInt2 & 0xFF) >> 8);
this.ModBusRTUCmd[11] = (byte)(paramInt2 & 0xFF);
return SendCmd2Adam(this.ModBusRTUCmd, 12);
}
public boolean ReadRegister(int paramInt1, int paramInt2, byte[] paramArrayOfByte) {
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0; this.ModBusRTUCmd[5] = 6;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 3;
this.ModBusRTUCmd[8] = 0;
this.ModBusRTUCmd[9] = (byte)paramInt1;
this.ModBusRTUCmd[10] = 0;
this.ModBusRTUCmd[11] = (byte)paramInt2;
return SendCmd2Adam(paramArrayOfByte, 12);
}
public boolean Adam5kASCCmd(byte[] paramArrayOfByte, int paramInt)
{
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 16;
this.ModBusRTUCmd[8] = 39;
this.ModBusRTUCmd[9] = 15;
if (paramInt % 2 == 1)
{
++paramInt;
}
this.ModBusRTUCmd[5] = (byte)(7 + paramInt);
this.ModBusRTUCmd[10] = 0;
this.ModBusRTUCmd[11] = (byte)(paramInt / 2);
this.ModBusRTUCmd[12] = (byte)paramInt;
for (int i = 0; i < paramInt; ++i)
{
this.ModBusRTUCmd[(13 + i)] = paramArrayOfByte[i];
}
if (!(SendCmd2Adam(this.ModBusRTUCmd, 13 + paramInt)))
{
return false;
}
this.ModBusRTUCmd[0] = 0; this.ModBusRTUCmd[1] = 0; this.ModBusRTUCmd[2] = 0;
this.ModBusRTUCmd[3] = 0; this.ModBusRTUCmd[4] = 0; this.ModBusRTUCmd[5] = 6;
this.ModBusRTUCmd[6] = this.ModBusID;
this.ModBusRTUCmd[7] = 3;
this.ModBusRTUCmd[8] = 39;
this.ModBusRTUCmd[9] = 15;
this.ModBusRTUCmd[10] = 0;
this.ModBusRTUCmd[11] = 50;
if (SendCmd2Adam(this.ModBusRTUCmd, 12))
{
for (int j = 0; j < 100; ++j)
{
paramArrayOfByte[j] = this.ModBusRTUCmd[(9 + j)];
if (paramArrayOfByte[j] == 13)
return true;
}
return true;
}
return false;
}
public void Close()
{
try
{
this.echoSocket.close();
this.out.close();
this.in.close();
}
catch (IOException localIOException) {
IsRuning = false;
}
}
private String chkHostIP(String paramString) {
String str = "";
if (paramString.length() < 15) return paramString;
for (int i = 0; i < 16; i += 4) {
str = str + String.valueOf(Long.valueOf(paramString.substring( i, i + 3), 16)) + '.';
}
return str.substring(0, str.length() - 1);
}
private boolean SendCmd2Adam(byte[] paramArrayOfByte, int paramInt)
{
try
{
this.out.write(this.ModBusRTUCmd, 0, paramInt);
int i = this.in.read(paramArrayOfByte, 0, 128);
if (i <= 0) return false;
} catch (IOException localIOException) {
return false; }
return true;
}
}
Y bueno la forma de utilizarla:
package Mi.Modbus;
import Adam.Modbus.ModBus;
public class Inicio {
/**
* @param args
*/
public static String direccion = "190.168.0.100";
public static void main(String[] args) {
// TODO Auto-generated method stub
ModBus miModBus = new ModBus(direccion);
for(int i =16; i<22;i++){
miModBus.ForceCoil(i, false);
}
}
}
Es un ejemplo chorra que lo que hace es desactivar las salidas digitales mediante ese for.
Ya me diras si por lo menos has conseguido conectar :D
mw_modbus
25/09/2009, 08:46
Ok, muchas gracias, a ver si consigo dar con la clave. El cacharro no es un Adam, es un PM810 de PowerLogic, para medir tensiones e intensidades, y necesito monitorizarlas. El problema es el que comentaba, consigo conectarme pero al hacer peticiones de lectura me dice que tarari.
Gracias de nuevo y ya contare si consigo dar con la tecla.;)
Ok tio a ver si tienes suerte, ya me diras ;)
:brindis::brindis:
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.