Comunicación arduino múltiple (1 maestro, n esclavos)

8

Me gustaría desarrollar una red maestro / esclavo que consista en:

  • 1 maestro Arduino que lee sensores y genera perfiles de rampa de velocidad basados ​​en las señales del sensor y luego envía esas rampas a los esclavos

  • 3 (o más) esclavos Arduino que controlan la velocidad de los servomotores de 12V siguiendo las rampas enviadas por el maestro

¿Cuál es un buen protocolo de comunicación para lograr esto? Serie (SPI)? I2C? ¿Algo más? Si es serial, ¿es el nuevo Arduino Leonardo una buena opción? ¿Qué problemas debo considerar al seleccionar un protocolo?

Me estoy imaginando algo como:

Maestro:

void loop() {
    update_ramps()
    for(int i=0; i< num_slaves; i++) {
        send_to_all(i, ramps[i]);
    }
}

Esclavo 1:

const int id = 1;
int recived_id, recived_value;
void loop() {
    read_data();
    if(recived_id == id) { 
        do_motor_step(recived_value);
    }
}

Y comunicación en serie en la que RX / TX del maestro se envía a todos los esclavos.

¿Parece esto una solución razonable?

nkint
fuente
¿Solo quieres enviar exactamente la misma información a todos los esclavos? ¿Los esclavos necesitan responder?
Oli Glaser
no, no necesitan responder!
nkint
¿A qué distancia estarán los esclavos?
geometrikal
Creo que no más de 15 metros
nkint

Respuestas:

12

Según tengo entendido, desea enviar datos diferentes a cada uno de los esclavos, pero los esclavos no tienen que enviar datos de vuelta.

I2C es un bus direccionado, por lo que si asigna una dirección I2C diferente a cada uno de los esclavos, solo necesitará dos cables para enviar los datos. Si es necesario, también puede solicitar la devolución de datos. Los AVR de Arduino tienen un bus serie compatible con I2C. Y puede extenderse a más de 3 esclavos sin hardware adicional, hasta un máximo de 127.

Los UART no tienen direccionamiento, por lo que necesitaría 3 UART (que el AVR no tiene) o agregar lógica externa para cambiar entre líneas UART (que cuesta dinero). Cada esclavo adicional significa un costo adicional. No recomendado.
editar
Como Chris dice que puedes usar UART para crear un bus multipunto. Y luego tendrá que agregar direccionamiento, lo que hace que su UART funcione un poco como I2C, pero luego asíncrono y sin hardware de coincidencia de direcciones como lo ha hecho el I2C. Entonces todavía no es realmente una ventaja. fin de edición

SPI también utiliza líneas compartidas para datos: un solo MOSI y las líneas MISO conectadas. Para abordar cada esclavo individualmente, necesitará una línea SS (selección de esclavo) por esclavo. Entonces eso es al menos 5 E / S: MOSI, SCK, 3 SS y MISO si también desea leer datos de los esclavos. Cada esclavo adicional agrega 1 pin de E / S en el maestro. ×

ingrese la descripción de la imagen aquí

Creo que el I2C es la mejor solución, ya que requiere la menor cantidad de cables. El protocolo es un poco más complejo que UART o SPI, pero dado que el AVR tiene el hardware para ello, debería ser fácil de usar.

stevenvh
fuente
2
La afirmación de que se requerirían múltiples UART o lógica externa no es precisa. La comunicación UART en bus se realiza todo el tiempo, utilizando el direccionamiento de software. Con transmisión y recepción compartidas, esto no requiere más pines que I2C.
Chris Stratton
@ Chris - Buen punto, actualizaré mi respuesta.
stevenvh
1
@capcom: agregué un diagrama de bloques para el SPI. MOSI se emite para el maestro y la entrada para los esclavos. MISO se emite para los esclavos y la entrada para el maestro. Sí, hace que el SS sea bajo para el esclavo al que desea enviar datos. El SS no solo sirve para indicar el inicio y el final de la comunicación, sino que también un esclavo no seleccionado debe hacer que su MISO sea de alta impedancia para detectar conflictos de bus.
stevenvh
2
@nkint: 8 m tendrá una capacitancia de alrededor de 800 pF, e I2C solo permite que 400 pF obtenga la velocidad de borde requerida. Tendrá que usar un extensor de bus como el P82B715 , que conducirá el bus con hasta 50 m de cable.
stevenvh
1
@stevenvh ¡el P82B715 funciona muy bien y es realmente fácil de enchufar!
nkint
5

Supongo que por serie te refieres a UART? Tenga en cuenta que UART, SPI, I2C son todos protocolos en serie.

SPI o I2C estarían bien para esto, ya que ambos usan la arquitectura maestro / esclavo.
Sin incluir tierra, para 3 esclavos, SPI requeriría 6 pines (MOSI, MISO, CLK + 3 pines SS) e I2C solo dos (SDA y SCK)
Probablemente elegiría I2C, suponiendo que no necesite una transferencia de datos muy alta tasas (<400kHz)

Cuantos más esclavos agregue, menos conveniente será el SPI, ya que necesita otro SS (selección de esclavos) para cada nuevo esclavo. Con I2C, esto no es un problema, ya que el direccionamiento es parte del protocolo, por lo que solo necesita las 2 líneas (más tierra).

Para Arduino, debería haber una gran cantidad de tutoriales con bibliotecas I2C / SPI y código de ejemplo para ambos de los anteriores, lo que debería hacer que sea bastante fácil comenzar a trabajar.

Oli Glaser
fuente
Tienes razón, los datos son diferentes para cada esclavo. Fui engañado por el nombre de la función "send_to_all", pero parece usar una rampa diferente para cada uno (están indexados). Eliminé mi primera respuesta.
stevenvh
1

Los esquemas de señalización asíncrona compartidos similares a RS485 también deberían ser posibles.

Si no está utilizando controladores / receptores de línea (solo los pines ATMEGA desnudos), debe hacer que el UART TX sea una entrada cuando no sea su turno para hablar. Si está utilizando controladores de línea, debe usar un pin adicional para controlar la habilitación de tristado en el controlador de línea cuando no sea su turno de hablar.

También tenga en cuenta que no puede tristar el transmisor cuando se acepta el último byte en el registro de transmisión (el punto en el que podría enviar otro carácter), en su lugar, debe asegurarse de mantener habilitado el transmisor o el controlador de línea hasta que se haya activado la palabra completamente desplazado.

En los esquemas donde transmite y recibe en el mismo cable (o par diferencial) tenga en cuenta que escuchará sus propias transmisiones.

Chris Stratton
fuente
1

En el caso especial que desea conectarse a través de UART , puede usar el UART RS485 MODBUS . Este es un protocolo de comunicación con direcciones de software, función, suma de verificación.

Creo que es más confiable que I²C o SPI debido a RS-485 y utiliza menos cables que SPI.

NOTA: Puede implementarse como estándar, con algunas bibliotecas, pero puede ser costoso ya que necesita un módulo RS485 para cada esclavo y uno para el maestro, PERO es compatible con una red existente. Pero puede hacerlo menos costoso utilizando componentes heredados y creando su propio dispositivo. El MAX 485 podría ser el componente base para hacer un bus Hardware 485 o mediante el uso de un software RS485

Alexis Paques
fuente
0

La solución más simple para los requisitos específicos sería un transmisor RS-422 en una línea TX en el maestro (controlador de bus). Esto se desplegaría en múltiples receptores (terminales remotos).

Todos los RT escucharían los mensajes de difusión, pero solo autenticarían y ejecutarían los comandos dirigidos a través de la dirección RT.

Si se utilizara un protocolo de bus similar al 1553, sería fácil de implementar.

Stu
fuente