Ayuda proyecto Modbus, no funciona en Arduino Mega 2560

Buenas gente, escribo para ayuda con mi proyecto.

Llevo algun tiempo ya desarrollando en arduino y esto que me paso no lo entiendo.

El caso es que estoy comunicando arduino con el software Scada llamado "Mango Automation", muy bueno por cierto, mediante el protocolo de comunicacion Modbus.

Esto funciona muy bien con Arduino Uno, mediante las librerias modbus.h o modbusSlave.h ... pero cuando le cargo el mismo Sketch al Arduino Mega 2560 no funciona. al parecer recibe el dato desde el maestro pero no lo responde.

El caso es que necesito realizarlo con Arduino Mega ya que debo usar mas puertos seriales para otras cosas y este tiene 4.

Espero que alguien experimentado pueda ayudarme.

Saludos

mira a ver si esas rutinas que refiers usan algun timer propio del UNO pero que tiene diferente configuración en el mega. Esa suele ser la causa de incompatibilidad entre ambos.

Una pregunta: ¿Modbus sobre que? ¿USB, RS232, RS485, TCP/IP,Bluetooth,XBee? Por favor coloca el código.

Saludos

Generalmente es RS485 o 422, tal vez TCP/IP pero esas rutinas para Arduino no tienen TCP/IP implementado.

Hola a todos, perdona podrias explicar que es el modbus para que sirve y utilidades que tiene, entiendo que se maneja desde un PC con Mango automation??

Perdona que te aborde asi, pero me ha parecido interesante y no tengo ni idea de que es.

Modbus es un protocolo de comunicación se que permite que un nodo MAESTRO le pregunte a sus nodos ESCLAVOS que hacer o que dato enviar. De ese modo tienes una manera de comunicar al nodo MASTER con sus SLAVES (esclavos) enviando datos enteros 16/32 bits, flotantes o booleanos (en modbus le dicen coils).

Es una extensión del sistema Serie pero generalmente se hace usando unos integrados que siempre estan o escuchando o transmitiendo. Los esclavos siempre estan en modo escucha o recepción y solo transmiten cuando el master los consulta y solo responden la consulta del master. Aun cuando deban decirle "no te entiendo' (en código modbus).

Con el tiempo se expandió su uso a TCP/IP asi que hoy puedes usar modbus via Ethernet.

mmmm muy interesante, yo siempre habia usado el puerto serie con un protocolo propio para comunicar maestro y esclavos pero calro este se puede usar via Ethernet que lo hace muy interesante :grinning:

Y otra cosa eso del software Scada llamado "Mango Automation" que es? y para que sirve?

Muchas gracias por contestar y la aclaracion

Estimados muchas gracias por sus respuestas y su interes, tratare de aclarar un poco mas mi proyecto.

lo que estoy realizando es un recolector de datos historicos en un computador desde sensores remotos.

Para esto estoy usando la plataforma scada " MANGO AUTOMATION " , que es una plataforma de codigo abierto que funciona muy bien y en la cual tengo bastante experiencia y he usado con PLC y equipos de automatizacion industrial.

http://infiniteautomation.com ... Vale la pena echarle un vistazo ya que tiene funcionalidades graficas y de analisis interesantes y es gratis en versiones light (mas que suficiente)

La gracia de un sistema Scada es que cuenta con protocolos de comunicacion estandarizados entre ellos el que uso yo MODBUS SERIAL osea por algun puerto COM.

Yo conecto a mi MANGO AUTOMATION un Arudino mediante cable USB y el puerto COM que crea el driver de arduino.

Yo solo conecto un esclavo via MODBUS, el valor de los sensores remotos los recibo en este arduino mediante XBEE. Es por esto que necesito usar un arduino mega ya que usare dos puertos seriales, uno para conectar al MANGO y el otro para XBEE.

Esto funciona muy bien por separado en arduino uno, pero el mismo codigo en arduino mega no responde a las consultas del maestro modbus.

Tambien hice pruebas en comunicar el MANGO con 6 esclavos ARDUINOS UNO, mediante MODBUS sobre XBEE (emulando el cable serial) y funciona bien pero solo a 9600 BPS , lo cual es muy lento para mi aplicacion... pero de que funciona funciona.

Eso es mas o menos mi proyecto..

La libreria que estoy usando es ModbusSlave.h hay algunas otras y todas funcionan en arduino uno pero no en mega.

No tengo experiencia haciendo ni revisando el codigo de librerias

Por mi parte revisare lo que me aconseja el amigo SURBYTE con respecto a los timers de los diferentes arduinos MEGA y UNO. tiene mucho sentido y posiblemente el problema valla por este lado.

Nuevamente gracias y quedo atento a cualquier consulta o ayuda por parte de la comunidad.

Saludos

A ver revisa los timers puede ser eso, pero tambien los pins, no coinciden todos los pins del uno al mega.
Mira este codigo de la libreria modbusslave.h esa tuya:

#define DEFAULT_TX_PIN 8
#define DEFAULT_SLAVE_ADDR 2
...
....
....
  ModbusSlave(HardwareSerial& s);
  ModbusSlave(HardwareSerial& s, char txenpin, unsigned char slave);

revisa dos cosas, una el pin 8 como tx (por donde transmite) y la otra pone hardwareserial es decir usa los pines serie hardware que serian pin0 rx y pin1 tx (estos pins coinciden en uno y mega)
esto nos deja que rx es pin0, pero tx no sabemos si pin1 o pin8

otra cosa que puerto usas para conectar por usb? debes usar el "Serial" en los pins rx-0 y tx-1, si no funciona prueba tx-8

para el Xbee debes usar "Serial1" rx-19 y tx-18 ó "Serial2" rx-17 y tx-16 ó "Serial3" rx-15 y tx-14

Yo conecto a mi MANGO AUTOMATION un Arudino mediante cable USB y el puerto COM que crea el driver de arduino.

Algo tonto, pero ¿tuviste en cuenta que a veces, dependiendo del sistema operativo, se crea direcciones de puertos COM diferentes , para diferentes placas de Arduino?

Yo utilizo la libreria Modbus slave y funciona bien sobre Arduino Mega 2560.

Saludos

PeterKantTropus:
Algo tonto, pero ¿tuviste en cuenta que a veces, dependiendo del sistema operativo, se crea direcciones de puertos COM diferentes , para diferentes placas de Arduino?

Yo utilizo la libreria Modbus slave y funciona bien sobre Arduino Mega 2560.

Saludos

Hola, si efectivamente cambia el puerto cada placa arduino que se conecta tengo esto en cuenta.

He llegado a pensar que mi arduino mega 2560 esta fallado, quiza pruebe con otro.
Saludos

Baje la librería que estas usando y cargue el ejemplo , comente la librería onewire, configure la comunicación y lo cargue en un Arduino mega

#include "ModbusSlave.h"
// for some misterious reason it has to be defined in the main file as well
//#include <OneWire.h> 
#include <string.h>


/* Modbus RTU common parameters, the Master MUST use the same parameters */
enum {
        MB_SLAVE = 0x02, /* modbus slave id */
};
/* slave registers example */
enum {        
        MB_REG0,
        MB_REG1,
        MB_REGS /* total number of registers on slave */
};

int regs[MB_REGS]; /* this is the slave's modbus data map */

ModbusSlave  mb(Serial);

//
// MAIN SETUP
//

/* 
 * configure(slave, baud, parity, txenpin)
 *
 * sets the communication parameters for of the serial line.
 *
 * slave: identification number of the slave in the Modbus network (1 to 127)
 * baud: baudrate in bps (typical values 9600, 19200... 115200)
 * parity: a single character sets the parity mode (character frame format): 
 *         'n' no parity (8N1); 'e' even parity (8E1), 'o' for odd parity (8O1).
 * txenpin: arduino pin number that controls transmision/reception
 *        of an external half-duplex device (e.g. a RS485 interface chip).
 *        0 or 1 disables this function (for a two-device network)
 *        >2 for point-to-multipoint topology (e.g. several arduinos)
 *
 *   void configure(unsigned char slave, long baud, char parity, char txenpin);
 */

void setup(void) {
  mb.configure(0, 1, 9600L, SERIAL_8N1);
  
  regs[MB_REG0] = 1234;
  regs[MB_REG1] = 5678;
}

void loop(void) {
   /* This is all for the Modbus slave */
   mb.update(regs, MB_REGS);
}

  //  Status API Training Shop Blog About

Luego con un programa que tengo hecho en "C" para otra aplicación, pude consultar sin ningún problema el valor cargado en el skech (estoy en Linux).

#include <stdio.h>
#include <modbus.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
uint16_t tab_reg[32];// array global donde se almacenan los datos obtenidos por modbus
int main()
{
int i;
/* Se abre el puero y se setea (no necesario en windows */
open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
/* Setup estructura de  control  */
 struct termios toptions;
/* Wait for the Arduino to reset */
 usleep(1000*1000);
for(i=1;i<200;i++){
   //creacion de contexto modbus.En windows hay que colocar COM1, COM2 o donde se encuentre el Arduino
    modbus_t *mb;
    mb = modbus_new_rtu("/dev/ttyACM0",9600 , 'N', 8, 1);
    if (mb == NULL) {
    fprintf(stderr, "imposible crear contexto modbus\n");
          return -1;
     }
   modbus_set_slave(mb,1); //setea el numero de esclavo a consultar. El arduino tiene que estar seteado igual
   modbus_connect(mb);//Conecta al contexto creado
   modbus_read_registers(mb,0,2, tab_reg);// lee 2 registros a partir del registro "0"y los almacena en tab_reg
   printf(" Registro  %u\n     ",tab_reg[0]);// imprime en pantalla el valor leído
   modbus_free(mb);// libera el contexto
   modbus_close(mb);// cierra la coneccion
  }
 return 1;
}

Que tal a todos, tenia el mismo problema.
Me he metido en la libreria modbusslave.cpp y he cambiado todos los Serial.xxxx por Serial1.xxxx
Ahora me funciona like a charm (conectando el RS485 a los pines TX1 RX1)