Domanda:
Comunicazione a 2 vie I2C tra Arduino Uno e Arduino Mega
srinivas
2014-06-23 13:22:23 UTC
view on stackexchange narkive permalink

Se rimuovo il codice di trasmissione dallo slave funziona correttamente ma devo trasmettere dallo slave.

Ecco il mio codice principale

  #include <Wire.h>void setup () {Wire.begin (3); Wire.onReceive (receiveEvent);} byte x = 0; void loop () {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); }}  

Ecco il mio codice slave:

  #include <Wire.h>void setup () {Wire.begin (9); // entra nel bus i2c con l'indirizzo # 9 Wire.onReceive (receiveEvent); // registra l'evento Serial.begin (9600); // avvia la seriale per l'output} 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); // trasmette al master Wire.beginTransmission (3); Wire.write (1); Wire.endTransmission (); } altro {Wire.read (); }}}  

È possibile non utilizzare Wire.onRequest (requestCallback); inviare dati al master? Gentile aiuto.

Quando uno schizzo chiama Wire.begin () e passa un numero, si è designato come schiavo sul bus. Quindi sembra che tu abbia due schiavi. Normalmente si avrebbe un padrone e uno schiavo.
Quello che sembri desiderare è una combinazione del tutorial di Arduino Wire http://arduino.cc/en/Tutorial/MasterReader e http://arduino.cc/en/Tutorial/MasterWriter sei d'accordo?
ho dato un'occhiata ma non sono riuscito a implementarlo a dovere qualche suggerimento? se do 2 fili. scrivi il master non lo sta leggendo correttamente
Non so cosa intendi, scusa.
Wire.requestFrom ha un solo wire.write ho bisogno di più wire.write che non è supportato, quindi ci sono soluzioni alternative?
Tre risposte:
#1
+6
Wayne
2014-06-27 04:14:51 UTC
view on stackexchange narkive permalink

Per entrare nel bus come master non è possibile fornire un indirizzo slave a 7 bit, quindi il codice ha due slave.

Di seguito troverai 2 schizzi che inviano correttamente i dati a uno schiavo. Ti suggerirei di iniziare a guardare il protocollo I2C e capire che ci sono 4 modalità:

  • Master->Transmitter
  • Master->Receiver
  • Slave -> Trasmettitore
  • Slave-> Ricevitore

Tutte le comunicazioni indipendentemente da come i dati vengono trasferiti richiedono un master. È il master che controlla gli impulsi dell'orologio, ecco perché è sempre il master che avvia la comunicazione.

I tutorial di MasterReader / MasterWriter sul forum di arduino ora dovrebbe forse iniziare ad avere un po 'più senso quando si comprendono queste modalità.

Questo codice mostra come un master invia i dati a uno slave, e quindi come richiede i dati dallo slave. Se guardiamo questo codice dal punto di vista del master, puoi vedere che essenzialmente dice, invia questo byte al client (m-> t & s-> r), quindi richiedi i dati dallo slave (m-> r, s-> t)

Codice principale

  #include <Wire.h> # define SLAVE_ADDRESS 0x60void setup () {Wire.begin ( ); randomSeed (analogRead (3)); Serial.begin (9600); } byte x = 0; void loop () {x = random (0,255); Serial.print ("Inviato:"); Serial.print (x, HEX); Serial.print ("\ n"); Wire.beginTransmission (0x60); Wire.write (x); Wire.endTransmission (); ritardo (500); Serial.println ("Richiesta di dati"); Wire.requestFrom (SLAVE_ADDRESS, 1); int bytes = Wire.available (); Serial.print ("Slave inviato"); Serial.print (byte); Serial.print ("di informazioni \ n"); for (int i = 0; i< byte; i ++) {x = Wire.read (); Serial.print ("Slave Sent:"); Serial.print (x, HEX); Serial.print ("\ n"); } delay (500);}  

Codice slave

  #include <Wire.h> # define SLAVE_ADDRESS 0x60byte x = 0x00; void setup () {Wire.begin (SLAVE_ADDRESS);
Wire.onReceive (receiveEvent); Wire.onRequest (requestEvent); Serial.begin (9600);} void loop () {delay (100);} void requestEvent () {Serial.print ("Request from Master. Sending:"); 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 ("Ricevuto:"); Serial.print (x, HEX); Serial.print ("\ n"); }}}  
Sul master è possibile eseguire la scansione dell'intervallo di indirizzi per il dispositivo collegato. Questo sarebbe un approccio corretto.
In entrambi i gestori di eventi: non eseguire stampe seriali all'interno di un ISR. Potrebbe funzionare finché il buffer seriale non si riempie, quindi si bloccherà.
Non è necessario testare `if (Wire.available ()! = 0)` perché la variabile `bytes` ha il numero di byte ricevuti. Semmai, prova se `bytes> 0`, tuttavia presumo che un evento di ricezione avrebbe almeno un byte.
#2
+1
Camilo
2015-09-30 12:28:00 UTC
view on stackexchange narkive permalink

Di recente ho riscontrato questo problema. Il tuo slave ha bisogno di due funzioni: una per l'invio e l'altra per la ricezione dei dati.

  // funzione: cosa fare quando ti viene chiesto datavoid requestEvent () {Wire.write (t); } // cosa fare quando si ricevono dati da mastervoid receiveEvent (int howMany) {Val = Wire.read ();}  

Ecco un codice che funziona in entrambi i modi di comunicazione i2c in un codice singolo

Invio e ricezione di diversi tipi di dati tramite I2C in Arduino

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

Avevi:

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

Ci sono una serie di problemi con il tuo codice slave.

  1. Non eseguire stampe seriali in un ISR (interrompi routine di servizio)
  2. Non eseguire beginTransmission / endTransmission in un evento di ricezione.
  3. Non eseguire operazioni di scrittura
  4. Per restituire i dati utilizzare una requestEvent not a receiveEvent.

Meglio sarebbe:

  // add in setup () Wire.onRequest (requestEvent); // gestore di interrupt per quando si vogliono dati ... byte volatile cosa; void receiveEvent (int howMany) {if (howMany < 2) return; char c = Wire.read (); se (c! = 's') ritorna; cosa = Wire.read (); // ricorda cosa abbiamo ottenuto} // fine di receiveEventvoid requestEvent () {Wire.write (1); // restituisce una risposta} // fine di requestEvent  

Wire.requestFrom ha un solo Wire.write. Ho bisogno di più Wire.write che non sono supportati, quindi ci sono soluzioni alternative?

Raccogli la risposta ed esegui una scrittura:

  void requestEvent () {byte buf [4] = {1, 2, 3, 4}; Wire.write (buf, sizeof buf); // invia risposta} // end of requestEvent  

Riferimento

Ci sono molti esempi in I2C - Two-Wire Peripheral Interface - per Arduino



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...