Problema MAX485

Hola a todos.

Tengo conectados 3 Arduinos mediante MAX485 Half duplex. El problema que tengo es que el 1 y el 3 no se comunican, pero el 1 con el 2 y el 2 con el 3 si. Si apago el Arduino 2, el 1 y 3 siguen sin comunicarse, incluso si desconecto el MAX485 del Arduino; pero si desconecto los cables a y b del MAX485, entonces si se comunican el 1 el 3.

Los cables que he usado para a y b son ethernet cat6 apantallados con un total de 20m. He probado con y sin resistencias de 120Ω en ambos extremos de las líneas a y b, pero siempre hace lo mismo: solo funciona 1-2 y 2-3 (o 1-3 si desconecto físicamente los cables a y b del 2) pero nunca funciona 1-2-3.

Adjunto código de prueba.

¿Alguien tiene alguna idea de qué puede ser? Gracias por vuestro tiempo.

ARDUINO 1:

//ARDUINO 1

#include <SoftwareSerial.h>

#define RX        10
#define TX        11
#define pinMAX    2

char varChar=' ';

String bufferIn="";  

SoftwareSerial rs485(RX, TX); 

void setup() {  
  pinMode(pinMAX, OUTPUT);
  Serial.begin(9600);
  rs485.begin(4800);
  delay(1000);
  enviarDato('-', 0); //Envía un dato para borrar suciedad el módulo
}

void loop() {  
  enviarDato('a', 1234);
  comprobarMAX();
  delay(1000);
}

void comprobarMAX(){      //Comprueba si nos ha llegado algún dato
  digitalWrite(pinMAX, LOW);  //Prepara el pin en modo recepción
  if(rs485.available()){         //Lee si hay algo en RS485      
    Serial.print("Datos recibidos: ");
    while(rs485.available()){    //Mientras haya datos en el buffer
      varChar=(char)rs485.read();
      Serial.print(varChar);
      bufferIn+=varChar;
      delay(1);
    }
    Serial.println("");
  }//if  
}

void enviarDato(char letra, int valor){ 
  digitalWrite(pinMAX, HIGH);       //Habilitar transmisión
  Serial.print("Datos enviados: ");
  Serial.print(letra);
  Serial.print(valor);
  Serial.println('#');
  rs485.print(letra);              //Enviar identificador de la letra
  rs485.print(valor);              //Enviar el valor del entero
  rs485.write("#");               //Finalizar el mensaje
  digitalWrite(pinMAX, LOW);      //Volver a recepción  
}

OTROS ARDUINOS:

//OTROS ARDUINOS

#include <SoftwareSerial.h>

#define RX        10
#define TX        11
#define pinMAX    2

char varChar=' ';

String bufferIn="";  

SoftwareSerial rs485(RX, TX); 

void setup() {  
  pinMode(pinMAX, OUTPUT);
  Serial.begin(9600);
  rs485.begin(4800);
  delay(1000);
  enviarDato('-', 0); //Envía un dato para borrar suciedad el módulo
}

void loop() {  
  comprobarMAX();
}

void comprobarMAX(){      //Comprueba si nos ha llegado algún dato
  digitalWrite(pinMAX, LOW);  //Prepara el pin en modo recepción
  if(rs485.available()){         //Lee si hay algo en RS485      
    Serial.print("Datos recibidos: ");
    while(rs485.available()){    //Mientras haya datos en el buffer
      varChar=(char)rs485.read();
      Serial.print(varChar);
      bufferIn+=varChar;
      delay(1);
    }
    Serial.println("");
  }//if  
}

void enviarDato(char letra, int valor){ 
  digitalWrite(pinMAX, HIGH);       //Habilitar transmisión
  Serial.print("Datos enviados: ");
  Serial.print(letra);
  Serial.print(valor);
  Serial.println('#');
  rs485.print(letra);              //Enviar identificador de la letra
  rs485.print(valor);              //Enviar el valor del entero
  rs485.write("#");               //Finalizar el mensaje
  digitalWrite(pinMAX, LOW);      //Volver a recepción  
}

Sube el esquema de conexiones sino se hace complicado ayudarte.

1 Like

Y como los identificas? Porque no usas una libreria 485 en lugar de reinventar la rueda.
tienes que establecer una comunicación 1 a 1 con los demás en modo recepción, siempre y solo responder a quien te diriges.

Acá tienes una librería

También debe haber un MAESTRO y los esclavos. Entiendo que eso has hecho.
El maestro es quien maneja todo el flujo de la comunicación, se comunica con 2 y con 3.
y si quieres que 3 le envie a 2, debe ser a traves de 1.

Otro opción es que uses Modbus para lo que tmb hay librerías muy robustas. El concepto no cambia, Maestro y esclavos con direcciones UNICAS.

1 Like

Al final he encontrado el problema, una de las resistencias de terminación estaba quemada, fue reemplazarla y empezar a funcionar. Gracias

Hola, gracias por responder.

Al final he encontrado el problema, una de las resistencias de terminación estaba quemada, fue reemplazarla y empezar a funcionar.

De todas formas, la idea es que todos envíen al detectar algo, por ejemplo, movimiento y luz cada x tiempo en el caso del 1 y lo envíen a los demás para que todos tengan la información. La forma en la que lo estoy haciendo es enviando una letra como identificador, un entero y # para finalizar. Un ejemplo sería que el 1 detecte movimiento en su sensor número 2 y se lo diga a todos como "m2#", entonces todos lo guardan. No he añadido todo el código porque era muy largo y el error me lo daba también con el de prueba (lógicamente al ser algo físico).

Bien.
Por otro lado, el código que nos presentaste tiene errores y no compilaría.
Por ej. las variables letr yvalr no están definidas (aunque no descarto que es error de tipeo son errores en el código).

1 Like

Cierto, me di cuenta al compilarlo pero no lo corregí al postearlo, lo edito

Podrías tener un gran problema con colisiones, el modelo de multimaestros es difícil de implementar ¿Por que no usas un modelo maestro-esclavo? Con modbus no tendrías problemas , además de ser mas variada la información que puedes intercambiar, posee algoritmos que controlan la integridad del mensaje.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.