Arduino, Mindstorms y resistencias de pull-up Arduino Mega 2560

Hola,

Quería haceros una preguntilla. Como ya comenté en otro post (en el foro antiguo) estoy tratando de comunicar un Mindstorm NXT de LEGO con una placa Arduino Mega 2560 mediante I2C. El problema que tengo es que aparentemente no están llegando datos de un lado a otro.

Las conexiones que he hecho son:

Arduino GND -- Pines 2 y 3 (rojo y negro) del NXT
Arduino 5V -- Pin 4 del NXT (verde). Da la alimentación.
Arduino SDL -- Pin 6 del NXT (azul).
Arduino SCL -- Pin 5 del NXT (amarillo).

(El conector del NXT: Lego Mindstorms NXT - Wikipedia)

Tanto SDL como SCL los he conectado sin nada, y luego con una resistencia del pull-up a la señal de 5v. En ninguno de los dos casos he obtenido resultado. ¿Se os ocurre qué puedo estar haciendo mal? En principio la comunicación es bien sencilla. Sólo estoy intentando pasar datos en ambas direcciones pero parece que no llega ni en una ni en la otra.

En mi comunicación Arduino es el esclavo, y el Mindstorm es el maestro. Por si os hace falta, os dejo el código que uso en Arduino, pero no creo que sea ese el problema:

#include <Wire.h>

void setup(){
  Wire.begin(1); //Nos unimos como esclavos con dir. 1
  Wire.onRequest(requestEvent); //Rutinas para cuando llegue algo
  Wire.onReceive(receiveEvent);
}


void loop(){
}

void receiveEvent(int len){ //Devuelve el nº de bytes recibidos 
  while( 0 < Wire.available() ) {
    char c = Wire.receive();
  }
}

void requestEvent(){
  Wire.send("Arduino to Mindstorms");
}

Otra duda (relacionada con esto) es que he visto un post de alguien que ha hecho algo similar. Él tuvo el mismo problema, y fue porque usaba resistencias de Pull-up con Arduino Mega sin darse cuenta que las señales SDL y SCL ya tenían incorporadas 2 resistencias (que se ven en la placa). Aquí podéis ver su explicación (en inglés): http://mightor.wordpress.com/2009/08/04/connecting-the-nxt-to-an-arduinomega/
Bien, mi duda es, si miro mi placa (Arduino Mega 2560) ya no están estas resistencias de pull-up, pero en el esquemático si que aparecen. ¿Realmente están? No consigo localizarlas.

Bueno, mil gracias de antemano. A ver si consigo desatascarme ya que es para un proyecto y llevo varios días dándole vueltas a todo esto sin éxito.

Un saludo

Ésta función no se si la estás usando pero está incompleta ya que no devuelve nada:

void receiveEvent(int len){ //Devuelve el nº de bytes recibidos 
  while( 0 < Wire.available() ) {
    char c = Wire.receive();
  }
}

En el bus I2C no puedes mandar mensajes sin más como has hecho en el código, si no que tienes que decir a quien va dirigido y normalmente tienes que mandar después el registro al que lo mandas.

void requestEvent(){
  Wire.beginTransmission(NXT_ADDRESS);
  Wire.send(blablabla);
  Wire.endTransmission();
}

Échale un vistazo a los ejemplos de I2C de Arduino y mira cómo mandarle datos por I2C al NXT.

Las resistencias de pull-up siguen estando en el 2560, es esa cosita que pone '103' cerca de donde estaban las resistencias en el 1280.

Un saludo

Hola Chiva,

Primero darte las gracias porque siempre estás pendiente :slight_smile: Es la segunda vez que posteo una duda, y la segunda que acudes al rescate. Muchas gracias!

La función receiveEvent realmente lo único que quería ver era si llegaba algo, tiene más cosas dentro efectivamente. Pero probé por ejemplo algo tan sencillo como hacer parpadear el led 13 al recibir un dato, sin ni siquiera entrar en si lo que recibía era correcto o no. Pero no obtenía resultados. La que he copiado/pegado está incompleta, tienes razón. En cuanto a la otra, también probé como me comentas, pero la he cambiado tantas veces (pensando que era un problema de software) que al final se ve que la he dejado mal. Estuve viendo los ejemplos, pero claro, al pensar que el fallo estaba en el código he terminado cargándomela del todo.

En cuanto a las resistencias, si quito "esa cosita del 103", ¿sólo estoy quitando las resistencias? ¿o estoy tocando algo más? Imagino que si las quito no afecta a nada, no? ¿o están en serie y por lo tanto tengo que hacer un puente donde estaban? A ver si mañana vuelvo a mirar el esquemático con más detalle.

De nuevo gracias, y mañana cuando haga pruebas comentaré por aquí los resultados. En cuanto salga seréis los primeros en saberlo :smiley:

Se agradecen los agradecimientos XD

"Esa cosita del 103" :slight_smile: es un pack de 4 resistencias de 10K encapsuladas, por lo que he podido ver en las imágenes del Aruino 2560 sólo 3 de las 4 resistencias se usan, 2 de ellas siendo las de pull-up de SCL y SCK y la restante es la que controla la patilla de reset del Arduino y si quitas el pack de resistencias dejarás dicha patilla a nivel bajo, por lo que el Arduino nunca arrancará.

Puedes probar 'SoftI2C' que crea una interfaz I2C en cualquier par de pines, por lo que ya no tendrías dicha resistencia, aunque a lo mejor usa la interna del ATmega que es de 20K, pero algo mayor ya es.

Un saludo :wink:

chiva:
En el bus I2C no puedes mandar mensajes sin más como has hecho en el código, si no que tienes que decir a quien va dirigido y normalmente tienes que mandar después el registro al que lo mandas.

void requestEvent(){

Wire.beginTransmission(NXT_ADDRESS);
 Wire.send(blablabla);
 Wire.endTransmission();
}

Mmm, una dudilla tonta... Tras volver a ver los ejemplos y algún código en el que Arduino es esclavo (como el que hay por ahí de conectar 2 Arduinos) no veo que al enviar datos del esclavo al maestro usen la función BeginTransmission. ¿Se debe usar, o con la que puse era suficiente? Lo digo porque la dirección del maestro no se especifica cuando se conecta al bus.

A ver qué hago con las resistencias, visto que no se pueden quitar... Sino intentaré usar softI2C, a ver a ver ,qué lío me estoy haciendo entre hardware y software :sleeping:

He dicho ya que gracias? :slight_smile:

Edito con otra pregunta: Mirando softI2C (ya que parece que es lo que me va a quedar), veo ejemplos de cómo usarlo con Arduino como maestro, incluso la librería se llama Softi2cMater. ¿Es posible configurar Arduino como esclavo con ella?

Jur, perdona, razón llevas, no me había metido en la cabeza lo de esclavo...
Si, simplemente es hacer Wire.send() sin más como lo estabas haciendo.
Acabo de mirar lo del SoftI2C y como dices parece que sólo puede hacer de master, que chasco.

Como única alternativa sencilla, es hacerte con un ATmega328 que no cuesta mucho y montarlo en una placa sin más que lo necesario.

Un saludo

Pues sip, creo que tendré que hacer eso :frowning: De todas formas indagaré un poco más, igual retocando las librerías de Softi2c (aunque eso depende del tiempo que tenga). Ya os iré contando :slight_smile: Gracias por la ayuda!

De nada hombre!

Ya nos contarás si al final adaptas la librería SoftI2C :open_mouth:

Muy buenas :slight_smile:

Como os prometí, voy a comentaros la solución a la que he llegado. Al final no he modificado las librerías, sino que ha sido una solución "hardware". Simplemente (y tras muchas medidas, pruebas, etc) he "cortado" las pistas que unían las señales SDA y SCL con las resistencias de 10K en la plaquita. Lo he hecho mirando el mejor sitio con el esquema de PCB que está en la página de Arduino y tal. Ahora todo funciona bien :slight_smile:

Como esto contado así suena "cutre", he contado todo el proceso medidas, etc.) en este post: Mindstorms, Arduino y la conexión de sensores: Solución a los problemas entre Arduino Mega 2560 y el Mindstorm

(que es del blog que estoy llevando para el proyecto).

Espero que ha alguien más le pueda ser de ayuda. De nuevo gracias chiva, y a todos los que me habéis echado una mano con esto :slight_smile:

Pues no es mala solución, aunque quites las resistencias de pull-up de la placa, siempre las podrás poner externamente si te llegan a hacer falta.

Gracias a ti por dejarnos la explicación tan detallada :stuck_out_tongue:

Un saludo