Go Down

Topic: inviare due dati su i2c (Read 3813 times) previous topic - next topic

farstar1965

Salve a tutti, probabilmente il titolo rende l'idea della mia preparazione.
Sto realizzando due schede, una dotata di sensori si temperatura e rele per attivare alcune pompe di un impianto di riscaldamento, l'alttra dotata di display SD e RTC per visualizzare il funzionamento e salvare i dati.
Il collegamento fra le due schede avviene tramite bus I2C (che non conosco).
La scheda master (display) legge l'RTC e se richiede una temperatura alla slave funziona, ma se cerco di leggere piu di una temperatura non funziona . (il bus quindi è funzionante)
Ho caricato questi due sketch per effetuare prove di comunicazione e imparare a gestire il bus ma quando il master richiede due byte allo slave che gli invia x e y nel master vedo (monitor seriale) num che ha assunto il valore di y e num1 che ha valore 255.
Le ho provate tutte ( compatibilmente con le mie conoscenze) sono due settimane che cerco su google, ma niente.
Mi sembrava di aver capito che effettuando due wire.read dal master avrei letto i due wire.write dello slave, evidentemente ho capito male.
Qualche anima buona ha voglia di spiegarmi dove sbaglio ?

leo72

Ma onRequest non è da usarsi lato master? Sullo slave dovrebbe esserci solo onReceive.

farstar1965

on request non attiva la funzione in risposta al Wire.requestFrom(0x04, 2) del master ?

leo72

Premetto che non l'ho mai usata (mi creo sempre un piccolo protocollo di trasmissione per lo scambio di dati via I2C).
Leggendo il reference pare abbia ragione tu  :smiley-sweat:

nibbio99

Crea un array di dati da ricevere e poi utilizza un ciclo di for per ricevere i dati tipo :
Code: [Select]
Wire.requestFrom(0x04,2);
  for(i=0;i<2;i++){
    datiinput[i]=Wire.read();
    Serial.println(datiinput[i]);
}
if (datiinput[0]==a quello che vuoi) fai

  }

farstar1965

Grazie appena posso provo, almeno per vedere se mi invia e se ricevo ste due variabili.
E' che volevo fare una cosa tipo "variabileuno = wire.read(); variabiledue = Wire.read(); etc" pensavo che dato che lo
faccio leggendo i dati dell'RTC  potervo farlo anche nella comunicazione tra arduini in modo da buttare i valori direttamente nelle variabili con lo stesso nome su tutte e due le schede.

farstar1965

#6
Nov 06, 2013, 06:17 pm Last Edit: Nov 06, 2013, 08:06 pm by farstar1965 Reason: 1
nibba! il continua a restituirmi  il primo valore che si incrementa di 1  partendo però da 2, quindi il secondo byte inviato dallo slave mentre il secondo valore rimane 255.  :~
allego sketch modificato

madmatt71

Code: [Select]

#include

const byte AnalogueInputPin = 0;
const byte SlaveDeviceId = 1;

void setup()
{
  // Start I²C bus as a slave
  Wire.begin(SlaveDeviceId);
  // Set the callback to call when data is requested.
  Wire.onRequest(requestCallback);
}

void loop()
{
}

void requestCallback()
{
  // Contrived example - transmit a value from an analogue pin.
  int input = analogRead(AnalogueInputPin);

  // To send multiple bytes from the slave,
  // you have to fill your own buffer and send it all at once.
  uint8_t buffer[2];
  buffer[0] = input >> 8;
  buffer[1] = input & 0xff;
  Wire.write(buffer, 2);
}

Manda i dati dallo slave con una sola write e usando un buffer,
E controlla il numero di byte ricevuti sul master per non andare a leggere fuffa, poi puoi usare singole read e associarle alle singole variabili:
Code: [Select]

void loop()
{
  // Request data from slave.
  Wire.beginTransmission(SlaveDeviceId);
  int available = Wire.requestFrom(SlaveDeviceId, (uint8_t)2);

  if(available == 2)
  {
    int receivedValue = Wire.read() << 8 | Wire.read();
    Serial.println(receivedValue);
  }
  else
  {
    Serial.print("Unexpected number of bytes received: ");
    Serial.println(available);
  }

  Wire.endTransmission();

  delay(1000);
}


farstar1965

#8
Nov 07, 2013, 09:53 pm Last Edit: Nov 07, 2013, 09:56 pm by farstar1965 Reason: 1
okkkkey funziona.
Grazie.
Ho solo leggermente modificato per inviare due byte ma funziona, qunidi il problema era come inviare i dati, perchè eseguendo due Wire.read ricevo correttamente i valori.

Dato che con l'hardware non ci sono problemi ma col software sono proprio a zero ,
Domanda di contorno: :D
Queste due cose, buffer[0] = input >> 8;  buffer[1] = input & 0xff; , cioè ">>8" e "& 0xff" che  da quanto o capito servono a scomporre/selezionare una parte di byte ,ma dove me le vado a studiare?
L'Arduino reference non le cita come non ho trovato "const byte" per esempio, e molte altre cose.
Dove posso studiare queste cose?

rigrazie almeno due volte

madmatt71

>>8 e' un right shift di otto bit, &0xff e' un and binario con una maschera del valore massimo ottenibile con un byte.
Se hai un valore intero (16 bit in arduino equivalenti a due byte) e devi trasmetterlo tramite una funzione che capisce solo singoli byte devi scomporre il valore ( per un intero in due parti). La prima operazione, dato un intero a 16 bit, memorizza in un byte la parte piu' significativa ( i primi otto bit) spostando verso destra la sua rappresentazione binaria di otto posizioni. La seconda operazione ottiene dallo stesso intero la parte meno significativa ( i secondi otto bit) facendo un and binario con una maschera che ha valore 0 nei primi otto bit e 1 nei restanti 8 ( 0xff e' la rappresentazione esadecimale di 256 che equivale a 2^8 o 11111111 in binario). Sono nozioni che puoi trovare su qualsiasi testo di informatica di base (http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/07Operatori.html ) e che se apprese quando la mente e' fresca di calcoli matematici poi rimangono per sempre ...

farstar1965

#10
Nov 07, 2013, 10:29 pm Last Edit: Nov 07, 2013, 10:32 pm by farstar1965 Reason: 1
Qualcosa di informatica l'ho studiato sia a scuola che per lavoro ma ,come tradisce il mio nik non ho proprio la mente fresca di calcoli matematici !
Comunque non disperiamo a 48 anni non ho mai smesso di studiare non sono un genio di niente ma mi arrangio con tutto.

Many thanks.

P.S. Bel link  ( detto da un genovese sembra quasi una brutta parola)

madmatt71


Qualcosa di informatica l'ho studiato sia a scuola che per lavoro ma ,come tradisce il mio nik non ho proprio la mente fresca di calcoli matematici !
Comunque non disperiamo a 48 anni non ho mai smesso di studiare non sono un genio di niente ma mi arrangio con tutto.


Potrei dire che qui ad Ivrea l'informatica la studiano tutti da piccoli ma sarebbe una palla da primato :)
L'importante e' non perdere la voglia di imparare..

Quote

P.S. Bel link  ( detto da un genovese sembra quasi una brutta parola)

:smiley-yell: ;)

Go Up