Pregunta:
Comunicación bidireccional I2C entre Arduino Uno y Arduino Mega
srinivas
2014-06-23 13:22:23 UTC
view on stackexchange narkive permalink

Si elimino el código de transmisión del esclavo, esto funciona correctamente, pero necesito transmitir desde el esclavo.

Aquí está mi código maestro

  #include <Wire.h>void setup () {Wire.begin (3); Wire.onReceive (ReceiveEvent);} byte x = 0; bucle vacío () {Wire.beginTransmission (9); Wire.write ("s"); Wire.write (x); Wire.endTransmission (); x ++; delay (500);} void ReceiveEvent (int howMany) {if (Wire.available ()) {int x = Wire.read (); Serial.println (x); }}  

Aquí está mi código esclavo:

  #include <Wire.h>void setup () {Wire.begin (9); // unirse al bus i2c con la dirección # 9 Wire.onReceive (receiveEvent); // registra el evento Serial.begin (9600); // iniciar serial para la salida} void loop () {delay (100);} void receiveEvent (int howMany) {if (Wire.available ()) {char c = Wire.read (); Serial.print (c); if (c == 's') {int x = Wire.read (); Serial.println (x); // transmitir al maestro Wire.beginTransmission (3); Wire.write (1); Wire.endTransmission (); } else {Wire.read (); }}}  

¿Es posible no utilizar Wire.onRequest (requestCallback); enviar datos al maestro? Amablemente ayuda.

Cuando un boceto llama a Wire.begin () y pasa un número, se ha designado a sí mismo como esclavo en el bus. Entonces parece que tienes dos esclavos. Normalmente, uno tendría un maestro y un esclavo.
Lo que parece querer es una combinación de Arduino Wire Tutorial http://arduino.cc/en/Tutorial/MasterReader y http://arduino.cc/en/Tutorial/MasterWriter, ¿está de acuerdo?
He echado un vistazo pero no he podido implementarlo correctamente. si doy 2 cables, escriba que el maestro no lo está leyendo correctamente
No sé a qué te refieres, lo siento.
el Wire.requestFrom tiene solo un wire.write Necesito varios wire.write que no son compatibles, ¿hay alguna solución?
Tres respuestas:
#1
+6
Wayne
2014-06-27 04:14:51 UTC
view on stackexchange narkive permalink

Para unirse al bus como maestro, no puede proporcionar una dirección de esclavo de 7 bits, por lo que su código tiene dos esclavos.

A continuación encontrará 2 bocetos que envían datos con éxito a un esclavo. Le sugiero que empiece a mirar el protocolo I2C y comprenda que hay 4 modos:

  • Maestro-> Transmisor
  • Maestro-> Receptor
  • Esclavo -> Transmisor
  • Esclavo-> Receptor

Todas las comunicaciones, independientemente de cómo se transfieran los datos, requieren un maestro. Es el maestro que controla los pulsos del reloj, por eso siempre es el maestro el que inicia la comunicación.

Los tutoriales de MasterReader / MasterWriter en el foro de arduino ahora posiblemente debería comenzar a tener un poco más de sentido al comprender esos modos.

Este código muestra cómo un maestro envía datos a un esclavo, y luego cómo solicita datos al esclavo. Si miramos este código desde el punto de vista maestro, puede ver que esencialmente dice, envíe este byte al cliente (m-> t & s-> r), luego solicite datos al esclavo (m-> r, s-> t)

Código maestro

  #include <Wire.h> # define SLAVE_ADDRESS 0x60void setup () {Wire.begin ( ); randomSeed (analogRead (3)); Serial.begin (9600); } byte x = 0; bucle vacío () {x = aleatorio (0,255); Serial.print ("Enviado:"); Serial.print (x, HEX); Serial.print ("\ n"); Wire.beginTransmission (0x60); Wire.write (x); Wire.endTransmission (); retraso (500); Serial.println ("Solicitud de datos"); Wire.requestFrom (SLAVE_ADDRESS, 1); int bytes = Wire.available (); Serial.print ("Esclavo enviado"); Serial.print (bytes); Serial.print ("de información \ n"); para (int i = 0; i< bytes; i ++) {x = Wire.read (); Serial.print ("Esclavo enviado:"); Serial.print (x, HEX); Serial.print ("\ n"); } delay (500);}  

Código esclavo

  #include <Wire.h> # define SLAVE_ADDRESS 0x60byte x = 0x00; configuración vacía () {Wire.begin (SLAVE_ADDRESS);
Wire.onReceive (ReceiveEvent); Wire.onRequest (requestEvent); Serial.begin (9600);} void loop () {delay (100);} void requestEvent () {Serial.print ("Solicitud del maestro. Enviando:"); Serial.print (x, HEX); Serial.print ("\ n"); Wire.write (x);} void receiveEvent (int bytes) {if (Wire.available ()! = 0) {for (int i = 0; i< bytes; i ++) {x = Wire.read (); Serial.print ("Recibido:"); Serial.print (x, HEX); Serial.print ("\ n"); }}}  
En el maestro, puede escanear el rango de direcciones para el dispositivo conectado. Este sería un enfoque adecuado.
En ambos controladores de eventos: no realice impresiones en serie dentro de un ISR. Puede funcionar hasta que se llene el búfer en serie, luego se bloqueará.
No necesitas probar `if (Wire.available ()! = 0)` porque la variable `bytes` tiene el número de bytes que recibiste. En todo caso, pruebe si `bytes> 0`, sin embargo, supongo que un evento de recepción tendría al menos un byte.
#2
+1
Camilo
2015-09-30 12:28:00 UTC
view on stackexchange narkive permalink

Pasé por este problema recientemente. Su esclavo necesita dos funciones: una para enviar y otra para recibir datos.

  // función: qué hacer cuando se le pide datavoid requestEvent () {Wire.write (t); } // qué hacer al recibir datos de mastervoid receiveEvent (int howMany) {Val = Wire.read ();}  

Aquí hay un código que funciona en ambas formas de comunicación i2c en un código único

Enviar y recibir diferentes tipos de datos a través de I2C en Arduino

#3
  0
Nick Gammon
2015-07-23 04:48:08 UTC
view on stackexchange narkive permalink

Tenías:

  void receiveEvent (int howMany) {{if (Wire.available ()) {char c = Wire.read (); Serial.print (c); if (c == 's') {int x = Wire.read (); Serial.println (x); // transmitir al maestro Wire.beginTransmission (3); Wire.write (1); Wire.endTransmission (); } else {Wire.read (); }}}  

Hay una serie de problemas con su código esclavo.

  1. No haga impresiones en serie en un ISR (interrumpa rutina de servicio)
  2. No haga beginTransmission / endTransmission en un evento de recepción.
  3. No haga ninguna escritura
  4. Para enviar datos de vuelta use un requestEvent not un evento de recepción.

Mejor sería:

  // agregar setup () Wire.onRequest (requestEvent); // controlador de interrupciones para cuando se buscan datos ... byte volátil qué; void receiveEvent (int howMany) {if (howMany < 2) return; char c = Wire.read (); if (c! = 's') return; qué = Wire.read (); // recuerda lo que obtuvimos} // fin de evento de recepción de solicitud de evento de solicitud () {Wire.write (1); // devuelve una respuesta} // fin de requestEvent  

Wire.requestFrom solo tiene un Wire.write. Necesito varios Wire.write que no son compatibles, así que ¿hay alguna solución alternativa?

Reúna la respuesta y escriba una vez:

  void requestEvent () {byte buf [4] = {1, 2, 3, 4}; Wire.write (buf, tamaño de buf); // enviar respuesta} // fin de requestEvent  

Referencia

Hay muchos ejemplos en I2C - Interfaz periférica de dos cables - para Arduino



Esta pregunta y respuesta fue traducida automáticamente del idioma inglés.El contenido original está disponible en stackexchange, a quien agradecemos la licencia cc by-sa 3.0 bajo la que se distribuye.
Loading...