Conectar un Arduino MEGA a dos NANOS

Hola a todos, recien estoy empezando con Arduino, y ya he hecho un par de miniproyectos, pero tengo problemas con este por mi inexperiencia. He buscado por Internet en español o ingles, escribiré en el foro ingles también para buscar ayuda.

Resulta que necesito que una MEGA envíe datos a dos NANOs, que simplemente ejecutaran su programa según el código que escuchen... pero por dónde, esa es la cuestión. ¿Cómo comunico estas tres placas como he explicado? He visto por ahí el I2C, pero no se como se implementaría en mi caso, de todos modos seguiré viendo material, no soy de los que se pierden mucho con la programación. También había pensado en enviar datos por dos puertos ethernet conectados a MEGA, cada uno hacia una NANO distinta, ¿es viable?

El mayor problema lo tengo al saber donde hacer las conexiones si quisiera hacerlo por I2C por ejemplo, además de que no tengo ni idea si se podría por ethernet como he dicho.

Gracias de antemano!

¿Que dos Nanos reciban el mismo dato? ¿O que dos estén conectados pero solo uno a la vez lo reciba?
Bueno, tienes un Mega; lo puedes hacer con cualquiera de los tres tipos de comunicación serial. Lo de ejecutar un programa según código recibido, eso ya es implementación tuya.

Usar un módulo Ethernet sería viable con estas dos condiciones:

  • La distancia entre los dispositivos es grande (> 5 m).
  • El lugar físico en cuestión posee una infraestructura de red de área local (o más amplia si se aplican las configuraciones correspondientes).

Si solo cumples con la primera condición, entonces quizá debas considerar la comunicación inalámbrica o con integrados que codifiquen/decodifiquen señales digitales de mayor voltaje.

La comunicación sería algo así (ya descartando la red LAN):

ANDROID ----> envía por OTG o Bluetooth datos ----> MEGA ----> si recibe "1a" (por ejemplo) envía una señal a NANO1 para que ejecute su programa y si recibe "2a" pues a NANO2 lo mismo

Ahora mi cuestión era la de como conectar dos NANOS para que puedan recibir información distintas la una de la otra, ya que nunca lo he hecho. He pensado en usar I2C y he visto que la conexión sería de los pines RX-TX de la MEGA a las NANOS (aprovechando que MEGA tiene varios RX-TX) pero a la hora de programar aún estoy por averiguar cómo distinguir si el mensaje se le envía a una u otra NANO. Resumiendo: en el sketch, tanto de MEGA como de ambas NANOS, como determinaría la comunicación entre las placas.

Gracias

jm24cule@gmail.com:
pero a la hora de programar aún estoy por averiguar cómo distinguir si el mensaje se le envía a una u otra NANO. Resumiendo: en el sketch, tanto de MEGA como de ambas NANOS, como determinaría la comunicación entre las placas.

El comando se distingue con métodos de comparación de cadenas de caracteres. A quién debe reenviárselo, eso depende de quien use Serial1 y Serial2.

¿Esto responde tu pregunta?

¿Pero al usar I2C no usa Serial no? Usaría la librería wire, o al menos eso he visto.

Pero mi pregunta es donde conectar los cables entre la MEGA y las otras dos placas NANO, ya que SCL y SDA solo hay para una conexion I2C, a menos que pueda conectar mas de un aparato para la comunicacion I2C en los pines SCL/SDA.

Y si se pudiera conectar ambas NANOs a la MEGA, en sus pines SCL/SDA (según esto los pines 20 y 21) en el sketch como sabría identificar el dispositivo 1, 2 o 3 por ejemplo si están en la misma conexión que los demás. Me refiero al momento de especificar la comunicación:

Wire.beginTransmission("numero del dispositivo"); <---- aquí cómo podría saber qué numero identifica a la NANO1 o NANO2

Puede que me esté haciendo un lío y sea mejor usar los pines RX1-TX1 de MEGA con una NANO y TX2-RX2 de la MEGA para la otra NANO, ¿que es a lo que te refieres no?, declarar Serial1.write() a NANO1 y Serial2.write() a NANO2.

Si no usara I2C y la librería correspondiente, y tuviese que usar Serial, ¿quedaría así?

MEGA:

Serial.begin(9600);
Serial1.begin(9600);

Serial.write(9600); <--- Para enviar cadena de texto a NANO1
Serial1.write(9600);<--- Para enviar cadena de texto a NANO2

NANO1:

Serial.begin(9600);
Serial.read(9600);

NANO2:

Serial.begin(9600);
Serial.read(9600);

Siento las molestias pero aquí me pierdo :confused:

jm24cule@gmail.com:
¿Pero al usar I2C no usa Serial no? Usaría la librería wire, o al menos eso he visto.

La confusión quizá venga del hecho de que ambos son "comunicación serial". I2C viene identificado por los pines SDA y SCL; y el que se identifica por RX y TX, en realidad se llama UART.
Por lo tanto, son buses de datos totalmente independientes.

Y sí, Wire es el que maneja el bus I2C.

jm24cule@gmail.com:
Pero mi pregunta es donde conectar los cables entre la MEGA y las otras dos placas NANO, ya que SCL y SDA solo hay para una conexion I2C, a menos que pueda conectar mas de un aparato para la comunicacion I2C en los pines SCL/SDA.

De hecho, la arquitectura y protocolo de I2C permite que tanto maestros como esclavos compartan la misma línea de datos y de reloj.
Si los quieres conectar por I2C, solamente tienes que unificar todos los SDA, SCL y GND.

jm24cule@gmail.com:
en el sketch como sabría identificar el dispositivo 1, 2 o 3 por ejemplo si están en la misma conexión que los demás. Me refiero al momento de especificar la comunicación:

Wire.beginTransmission("numero del dispositivo"); <---- aquí cómo podría saber qué numero identifica a la NANO1 o NANO2

Como la conexión es compartida (topología de bus), cada esclavo tiene un identificador de 7 bits llamado "dirección"; con un rango válido del 1 al 127 (el cero está reservado para el maestro; y el MSB sirve para diferenciar un envío de una petición).

Si no me equivoco, beginTransmission y requestFrom solamente el maestro lo puede utilizar. Los esclavos están limitados a recibir y enviar sólo cuando les corresponde.

Un Arduino puede hacer el rol de esclavo o maestro dependiendo de cómo hayas llamado a Wire.begin():

  • Sin parámetros: el controlador del I2C se inicia en la dirección cero, lo que lo convierte en el maestro.
  • Con un valor entre 1 y 127: el controlador del I2C se inicia en la dirección dada, lo que lo convierte en un esclavo identificado por dicha dirección.

Con esto último quiero decir que si un Nano inicia con:

Wire.begin(10);
// Escuchará solo las transmisiones que inicien con la dirección 10

Entonces el maestro se le referirá de esta manera:

Wire.beginTransmission(10);
// Envía datos a quien escuche en la dirección 10

jm24cule@gmail.com:
Puede que me esté haciendo un lío y sea mejor usar los pines RX1-TX1 de MEGA con una NANO y TX2-RX2 de la MEGA para la otra NANO, ¿que es a lo que te refieres no?, declarar Serial1.write() a NANO1 y Serial2.write() a NANO2.

Es lo recomendable ya que las líneas RX0 y TX0 comparten las del convertidor USB a UART.

Por cierto los puertos no se inicializan con write, es con begin.

jm24cule@gmail.com:
Si no usara I2C y la librería correspondiente, y tuviese que usar Serial, ¿quedaría así?

MEGA:

Serial.begin(9600);
Serial1.begin(9600);

Serial.write(9600); <--- Para enviar cadena de texto a NANO1
Serial1.write(9600);<--- Para enviar cadena de texto a NANO2

NANO1:

Serial.begin(9600);
Serial.read(9600);

NANO2:

Serial.begin(9600);
Serial.read(9600);

Todo correcto excepto por lo siguiente:

También debes conectar GND con GND, si no simplemente no va a funcionar o la señal se corrompe.

Serial.write(9600);

Espero que sea solo de ejemplo porque write solo enviará un byte/char; que por desbordamiento equivaldría a 127 (no es un caracter imprimible).

Serial.read(9600);

Eso es para dar un error de compilación. Serial no implementa ninguna función con la firma void Serial::read(int), pero sí una sin parámetros (la que se usa para leer un byte/caracter).

Además de que es una mala práctica asumir que el búfer siempre tendrá datos para leer; de antemano se debe corroborar con available.

Ignora el 9600 de los Serial, copié del ejemplo Serial.begin y se me olvidó quitar el baud xD. Gracias todo más claro entonces. Entonces mejor Serial con sus pines RX-TX o I2C, que escogerías si quisieras enviar cadenas de texto a ambas NANOS (éstos solo ejecutarán su sketch si MEGA les envía una cadena de texto en concreto, nada más).

Gracias por la ayuda amigo!

Por rendimiento (velocidad de ejecución), prefiero el UART; porque con I2C hay que llamar a dos funciones para hacer exactamente lo mismo.
Es más, si la comunicación no va a ser bidireccional, ¡te puedes ahorrar un par de cables!

gracias, eso haré. Usare los puertos TX_RX de MEGA para hablarles a los NANOS.

Ya que no puedo abrir otro tema (que esta relacionado, pero no es lo mismo) lo pongo por aquí:

Voy a conectarlo tal que así:

Y en el codigo de MEGA lo dedclararé así:

Serial.begin(9600);
Serial1.begin(9600); // Puerto serial que se conectará con NANO1 (Pines RX1-TX1 en MEGA)
Serial2.begin(9600); // Puerto serial que se conectará con NANO2 (Pines RX2-TX2 en MEGA)

Si está todo correcto por ahora bien, sino una ayudita me vendría de perlas.
Ahora viene otro problema:

En un principio, desde una aplicación desarrollada con App Inventor 2 iba a enviar por Bluetooth la señal a Mega para que realizara sus funciones, pero para evitar problemas de interferencias en la señal, o algun listillo conectandose a mi modulo Bluetooth he pensado dirigir desde mi Android a Mega los datos de control por Serial (OTG de Android a USB de Mega), pero el caso es que no encuentro cómo hacerlo desde App Inventor (enviar los datos por OTG-Serial).

¿Alguno me sabría decir?

Necesito ayuda. Tengo un plazo para poder enseñar el proyecto y aun no se como enviar la señal desde la app de AppInventor2 a mi Arduino Mega.

Antes iba a dar una respuesta pero no lo hice porque no ayudaba en nada.

Pero ya que insistes, lo diré: no tengo idea si AppInventor tiene alguna librería para interactuar con puertos seriales USB; pero sí te puedo asegurar que tiene con qué pero por Bluetooth.

Puertos seriales USB quizá alguna aplicación "terminal", o la que sugiere para "monitor serie" una IDE no oficial de Arduino para Android (donde justamente los sketch se cargan vía OTG).

El problema de APP INventor no es para este foro, eso deberías saberlo jm24cule@gmail.com!! De todas formas siempre brindamos ayuda en lo posible.

Hay ejemplos de todo tipo en Internet, como no puedes resolverlo?

Lo lógico con Android y Arduino es interactuar via BT o via WIFI, mas raro es usar el puerto USB que debe ser OTG para poder usarlo. Yo perdi como 15 dias en darme cuenta de semejante tontería hace como 2 años.

Bien, gracias a esto veo que jm24cule estaba bien orientado pero cambió su enfoque para avanzar. Muy bien.
Ahora necesita retomar la interfaz con Android.

En un principio, desde una aplicación desarrollada con App Inventor 2 iba a enviar por Bluetooth la señal a Mega para que realizara sus funciones, pero para evitar problemas de interferencias en la señal, o algun listillo conectandose a mi modulo Bluetooth he pensado dirigir desde mi Android a Mega los datos de control por Serial (OTG de Android a USB de Mega), pero el caso es que no encuentro cómo hacerlo desde App Inventor (enviar los datos por OTG-Serial).

No recordaba el párrafo.
Si buscas en Google : APP Inventor USB mira que simple y yo encontré esto

http://appinventor.mit.edu/explore/ai2/setup-device-usb.html
No lo miré en profundidad pero al menos te dará una guia de como hacerlo!!

No hay que tirar la pelota para los demás cuando solo debes saber como buscar la información.
Todo esta ahi en Internet, no lo olvides.