ModbusSlave Arduino UNO + Softlogix5800 (PLC Allen bradley)

Que tal ings.

estoy haciendo un proyecto hobby, he intentado comunicar Arduino UNO R3 por modbus rtu hacia softlogix 5800 por puerto USB/serial a TTL para el arduino, se que funciona un ing. conocido ya lo hizo pero oh! sorpresa no me quiere pasar el sketch por mas que hicimos un trato apalabrado se echo para atras XD jaja lo comprendo le tomo mucho desarrollarlo según el(con librerias y el .acd del rslogix5000 tomadas de internet gratuitas etc etc lo que logro hacer el, que yo no, es la conexion con el softlogix. por que no entiendo quizas si me falta algo en el sketch de arduino(soy muy nuevo en arduino) o no configuro bien el Archivo maestro modbus en rslogix5000.

yo he desarrollado mi sketch con librerias gratuitas de internet ya logre que el arduino hable modbus rtu probandolo con el software Mtester leeo y escribo sin problemas en el arduino.

leeo las entradas y salidas en 2 palabras de 16 bits una para entradas y una para salidas en modbus los registros 40001 y 40002.

asi como otros 9 registros mas 6 entradas analogas en los registros 40003 al 40007 y 3 salidas analogas en los registros 40008 al 40010.

por que utilice solo holdingregisters por la sencilla razon de que no se usar bien la libreria simple modbus y modificar mucho el sketch ya que no le se casi nada al arduino.

en otra libreria habia logrado comunicar con el Mtester registros de bits inputs y coils pero me daba muchos problemas de comunicacion por lo que deje de lado esa libreria.

el sketch es el siguiente:

#include <SimpleModbusSlave.h>

enum 
{     
  ADC_VAL,     
  PWM_VAL,    
  HOLDING_REGS_SIZE = 11 // leave this one

};

unsigned int holdingRegs[HOLDING_REGS_SIZE];

void setup()
{
  
	
  modbus_configure(&Serial, 9600, SERIAL_8N2, 2, 2, HOLDING_REGS_SIZE, holdingRegs);

  modbus_update_comms(9600, SERIAL_8N2, 2);
  
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);

  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);


 // Pines 9, 10 y 11 son salidas analogas 

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

}

void loop()
{

  
  modbus_update();
  
// leer pineas de entradas
  boolean p1 = digitalRead(3);
  boolean p2 = digitalRead(4);
  boolean p3 = digitalRead(5);
  boolean p4 = digitalRead(6);

  
  int total = (p1 * 1) + (p2 * 2) + ( p3 * 4) + ( p4 * 8); // + ( p5 * 16) + ( p6 * 32);  //Aqui se supone que pasa de binario a decimal y suma cada entrada 

// Entradas digitales del pin 3 al 6
     holdingRegs[0] = total;

// Salidas digitales del pin 7,8,12 y 13   

int WordOutputs = holdingRegs[1];

int uno = 1;
int intPin7 = WordOutputs & uno;
int Pin7 = intPin7/1;

digitalWrite(7, Pin7);

int dos = 2;
int intPin8 = WordOutputs & dos;
int Pin8 = intPin8/2;

digitalWrite(8, Pin8);

int cuatro = 4;
int intPin12 = WordOutputs & cuatro;
int Pin12 = intPin12/4;

digitalWrite(12, Pin12);

int ocho = 8;
int intPin13 = WordOutputs & ocho;
int Pin13 = intPin13/8;

// Entrdas Analogas

   holdingRegs[2] = analogRead(A0);
   holdingRegs[3] = analogRead(A1);
   holdingRegs[4] = analogRead(A2);
   holdingRegs[5] = analogRead(A3);
   holdingRegs[6] = analogRead(A4);
   holdingRegs[7] = analogRead(A5);

// Salidas Analogas

    analogWrite(9, holdingRegs[8]/4);
    analogWrite(10, holdingRegs[9]/4);
    analogWrite(11, holdingRegs[10]/4);
  
}

este es el ModbusMaster.ACD V16 que es la que estoy usando(la misma que usa el ing. que conosco) de rockwell lo puedes bajar de la pagina de rockwell pero para facilitarles les paso el enlace de google drive.

Doctos para que me ayuden

si alguien puede ayudarme le puedo pasar los software para trabajar en el desarrollo.

Y cual es tu problema porque dices que con Holding Registers funciona, entonces?

Te mandé privado, por favor edita el enlace.

Buenas veo que tienes problemas con el modbus, yo llevo trabajando varios meses con un sin numero de dificultad y no logro entender de todo cual es tu problema.
Por lo que veo tienes problemas para utilizar la libreria simplemodbus, yo la utilizo con exito y para ayudarte te adjuntare el codigo que utilizo, espero que sea de ayuda

#include <SimpleModbusMaster.h>
#include <Wire.h>


// -------------------------------------------------------------  Datos a extraer ---------------------------------------------------------//

unsigned long Status;       // Lee el status del inversor (1 si esta funcionando, 0 si esta apagado o no funciona)


// --------------------

//////////////////// Informacion del puerto ///////////////////
#define baud 19200               // baud rate
#define timeout 1000              //tiempo de expiracion si esque la comunicacion no se establece
#define polling 200      // tiempo de scaneo
#define retry_count 20       // Numero de intentos de conexion en caso de fallar  

#define TxEnablePin 2         // Pin que habilita y deshabilita la transmision   



#define TOTAL_NO_OF_REGISTERS 20       // Cantidad de registros



// Creacion de packetes de datos
enum
{
 PACKET1,
 PACKET2,
 TOTAL_NO_OF_PACKETS // leave this last entry
};




// Creacion de un array que contiene los packetes de datos
Packet packets[TOTAL_NO_OF_PACKETS];


// Matriz donde se guardan los datos
unsigned int datos[2];



void setup()
{
 

Wire.begin(1);                // Abrimos la comunicacion I2C en el canal 1
// Wire.onRequest(peticion);      // Si se recibe un request comienza con el ciclo peticion

 Serial.begin(9600);          // Iniciamos comunicacion serial a 19200
 // Initialize each packet
  modbus_construct(&packets[PACKET1], // packete modbus
  10,    // direccion modbus del dispositivo que te quieres comunicar
  READ_INPUT_REGISTERS,       // funcion modbus a realizar
  173,         // registro al que te quieres comunicar
  1,            // cantidad de registros que quieres leer o escribir
  datos[0]); // Lugar donde se almacenaran los datos
  
  // Construimos el packete de datos modbus donde los datos se almacenearan en la direccion de memoria PACKET1, leerá la direccion 10 modbus, ejecutara el comando read_input_register, solicitara el registro 173 del equipo(corresponde al status del equipo), solicitara un 1 en ese registro y lo almacenara en la matriz datos

 
 
 // Initialize the Modbus Finite State Machine
 modbus_configure(&Serial,  // Aqui se define a que puerta serie va dirigida la  comunicacion modbus
 baud,  // baud rate del equipo
 SERIAL_8N1,      // configuracion modbus 8 datos, 1 de parada y no parity
 timeout,         // tiempo de espera maximo para establecer comunicacion
 polling,         // tiempo scaneo
 retry_count,       // numero de intentos que hara para comnunicarse, en caso de fallar
 TxEnablePin,        // definir el pin que iniciara y cortara la comunicacion (Ver mas info sobre el MAX485)
 packets, 
 TOTAL_NO_OF_PACKETS, 
 datos);       //lugar donde guardara los datos
 // Configura los parametros modbus, configuran baud rate, configuracion serial de 8 bits, 1 de parada,ninguno de paridad y los demas parametros


 
}

void loop(){

 modbus_update();           // Envia constantemente el packete configuracion anteriormente

 Status = datos[0];            //Guarda el valor leido por modbus en la variable status
 Serial.print("El estado del inversor es:  ");
 Serial.println(Status);

 
}




void peticion(){
 
// Serial.print("Mensaje solicitado");
 Wire.write(Status);       // escribe el valor de status por i2c

 }

Basicamente me comunico a un equipo con modbus que lo tengo registrado con la direccion modbus 10 y leo el registro 173 de ese equipo.

Gracias por sus pronta respuesta...

el problema es que el PLC en este caso el Softlogix5800 me leea las entradas y salidas tanto digitales como analogas del arduino. ya hice que funcionara el arduino es decir habla modbus leer y escribir con un simulador (Mtester) trabaja el arduino sin problemas. pero al querer leerlo y escribirle con el archivo Maestro(Softlogix5800) el .adc diseñado por rockwell automation para que sus PLCs leean Modbus RTU, no logro hacerlos comunicar Arduino con Softlogix5800.

esta persona que les comento lo tiene trabajando sin problemas(entiendo que no lo quiera pasar se quemo las pestañas un buen rato supongo) yo de maloso le compre 2 arduinos ya grabados es decir ahorita puedo hacer copias de ellos pero no me interesa asi ya que quiero yo mismo cambiar los ID principalmente, las configuraciones de los pines es decir el me dejo 5 entradas digitales, 4 salidas digitales etc etc. yo quiero configurarlos a mi gusto un arduino que sea puras entradas digitales otro puras salidas digitales, es por eso que busco una solucion la cual no he encontrado, aun con los .hex que extraje del arduino ya grabado y configurado(tengo entendido que es casi imposible descompilarlo)

como nota importante Se utiliza la EEPROM para almacenar algun dato importante el cual no se cual sea o que variables sinceramente soy muy nuevo en arduino no se como utilizar la eeprom he leeido un buen pero nada que me pueda ayudar a esta aplicacion.

es decir tengo el archivo .hex y .eep pero si grabo solamente el .hex en un arduino nuevo no funciona, pero si grabo primero el .eep y luego el .hex. se complemeta y funciona el sistema.

(tuve que comprarle uno jeje pero no tengo como para cada que quiera cambiar el ID tenga que comprarle otro grabado)

Si requieren los softwre (softlogix5800 + rslinx + rslogix5000) para hacer sus pruebas se los paso sin problema.

saludos y gracias.

Bien. Esta claro que es Modbus RTU. Esta claro también que pudiste hacer que el Arduino se comunique con el Mtester. Lo que no leo es que comuniques el Softlogix5800 con el Mtester. Lo intentaste? A veces hay pequeños cambios para poder leer una dirección o un registro. Yo he encontrado que usando 1 posición menos a veces se resuelve el problema. Supongamos que tu registro esta en 30001, y prueba si con el Mtester usando 30001 no lees o no el registro, si es negativo prueba con 30000.

Bueno intentare comunicar softlogix5800 y mtester, solo que como mteaster es simulador Master, tendre que usar el archivo slave de allen bradley el cual pues si es un poco diferente al archivo Master.

haber si alguien tiene mas ideas de los agradeceria.

saludos cordiales.

Bueno pero hay muchos que tambien actuan como clientes Modbus, yo tenia uno que se llamaba MBUS pero no se si con Win7 o 10 funcionará lo busco.. pero debe tener problemas.

ya cheque la comunicacion entre un Modbus Slave virtualizado + conexiones virtual del puerto del tester con con el puerto del softlogix.

y funciona bien las configuraciones del rslogix5000 puedo leer y escribir desde el Master hacia el simulador virtual y al revez en caso de los registros lectura y escritura.

bien el arduino funciona con el probador modbus, el softlogix funciona con el probador modbus.

pero arduino y softlogix aun no funcionan :( jaja me sigo quemando las pestañas tiene que quedar jeje

ahorita investigare sobre la EEPROM y intentare guardar y leer desde la eeprom las configuraciones de la comunicacion es decir ID, Baudios, paridad etc. no se que mas pueda guardar que requiera para comunicarse con el Master(PLC).

algun otro aporte? gracias.

EEPROM eso te lleva tanto como buscar en GOOGLE: Arduino EEPROM ir a la opción del playground y usa los ejemplos EEPROM.read(posición), o EEPROM.write(dirección, valor (tipo byte)) Luego tenés las nuevas funciones EEPROM.get() y EEPROM.put() que permiten guardar cualquier cosa.

Respecto de MODBUS, me sorprende que te comuniques con el programa en ambos sentidos pero no puedas con el PLC. Sinceramente esperaba me dijaras que tenías algun detalle por ahi. A ver si se me ocurre algo.

ya por fiinn!!! sabes la comunicacion con arduino y softlogix era problema de configuración del archivo maestro es decir el programa del PLC.

gracias al consejo de probar con el Modbus Slave virtual pude notar y encontrar el detalle del por que no me comunicaba el PLC con Arduino. y era solamente decirle en el Maestro cuantos registros exactamente pretendía leer.

ahora puliré el sketch y buscare la mejor configuracion de comunicación y de lectura de los datos ya que tengo varios detalles mas.

Primer nuevo problema: Leeo las entradas pero no puedo escribir las salidas del arduino, aun no le encuentro la mejor programacion para ello.

Segundo Nuevo Problema: Las entradas Analogas que escriben en los registros tienen un voltaje flotante no se van a cero completamente pero supongo que eso lo resuelvo colocando una resistencia a tierra o algo por el estilo(no cuento con una a la mano luego pruebo) o alguna sugerencia para solucionarlo?

muchas gracias por sus aportes ayudaron mucho.

Segundo Nuevo Problema: Las entradas Analogas que escriben en los registros tienen un voltaje flotante no se van a cero completamente pero supongo que eso lo resuelvo colocando una resistencia a tierra o algo por el estilo(no cuento con una a la mano luego pruebo) o alguna sugerencia para solucionarlo?

Resistencia de 10k a GND. Correcto

Siempre envia y recibe paquetes multiplos de 1,2,4,8,16,32,64 bytes se comprende?
A mi eso me funciona

surbyte: Resistencia de 10k a GND. Correcto

Siempre envia y recibe paquetes multiplos de 1,2,4,8,16,32,64 bytes se comprende? A mi eso me funciona

am no me perdí, a que te refieres enviar paquetes? los registros entre maestro(PLC) y esclavo(Arduino)?

claro que sean grupos de 8 registros o 16