Pages: [1]   Go Down
Author Topic: I2C - passare valori dallo Slave al Master  (Read 511 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 49
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao. Sto implementando una comunicazione I2C tra due chip Atmega 328P, il cui circuito é su breadboard, e riesco a passare un valore dal Master allo Slave. Se poi voglio ottenere un certo valore dallo Slave, mediante un Wire.requestFrom() ottengo valori strani.
Oltre alla libreria Wire.h utilizzo anche la libreria I2C_Anything.h per convertire i valori letti e scritti, da byte a integer.
Posto il codice:
[Master]
Code:
#include <Wire.h>
#include <I2C_Anything.h>

#define LED 13
const byte SLAVE_ADDRESS = 42;
int timeBlink;
int blinkMaster;
byte highByte;
byte lowByte;
boolean checkX=false;

void setup()
{
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  Wire.begin ();
   timeBlink = 2000;
   
    Wire.beginTransmission (SLAVE_ADDRESS);
    I2C_writeAnything (timeBlink);
    Wire.endTransmission ();
    blinkMaster=0;
     
}  // end of setup

void loop()
{
  delay(1000);
  if(timeBlink > 0){
  timeBlink-=100;
  }else{
    timeBlink=2000;
   
  }
   timeBlink--;
   Wire.beginTransmission(42);      //inizio comunicazione
   I2C_writeAnything(timeBlink);    //scrivo timeBlink sullo stream
   Wire.endTransmission();           //chiudo comunicazione
   
    Wire.requestFrom(42,2);       //Richiedo 2 byte allo Slave
   // while(Wire.available()){
      I2C_readAnything(blinkMaster); // leggo i dati inviati dallo slave
   // }
    Serial.print("receive from SLAVE=");
    Serial.println(blinkMaster);
 }  /

[Slave]
Code:
#include <Wire.h>
#include <I2C_Anything.h>
#define LED 13
const byte MY_ADDRESS = 42;
int timeBlink;
void setup()
{
  Wire.begin (MY_ADDRESS);
  Serial.begin (115200);
  Wire.onReceive (receiveEvent);
  Wire.onRequest(requestEvent);
  pinMode(LED,OUTPUT);
   timeBlink=2000;

}  // end of setup


void loop()
{
  delay(1000);
   
Serial.print("slave timeblink="); 
Serial.println(timeBlink);


void receiveEvent (int howMany) //routine per dati in arrivo dal master
 {
  while(Wire.available()){
   I2C_readAnything (timeBlink);
   
  }
 
 }
 
 void requestEvent()
{
  //questo evento viene generato quando il master
  //richiede ad uno specifico slave
  //una richiesta di dati
 
  //spedisco il dato al Master
  I2C_writeAnything(timeBlink);
  Serial.print ("Sended to master requested = ");
    Serial.println (timeBlink);
 
}


La libreria I2C_Anything.h ha questo codice:
Code:
#include <Arduino.h>
#include <Wire.h>

template <typename T> int I2C_writeAnything (const T& value)
  {
    const byte * p = (const byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++)
          Wire.write(*p++);
    return i;
  }  // end of I2C_writeAnything

template <typename T> int I2C_readAnything(T& value)
  {
    byte * p = (byte*) &value;
    unsigned int i;
    for (i = 0; i < sizeof value; i++)
          *p++ = Wire.read();
    return i;
  }  // end of I2C_readAnything

Il problema é che ottengo in risposta dallo Slave valori tipo -249, -250 ecc, anziché valori del tipo 2000, 1900 ecc
Logged

0
Offline Offline
Faraday Member
**
Karma: 30
Posts: 2905
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Tutte le comunicazioni seriali inviano un byte per volta e il valore decimale massimo di un byte è 255. Un intero è grande 2 byte per cui ricevi prima io byte più significativo (quello a sinistra) e poi quello meno significativo, quindi ogni due byte devi ricomporre il valore unendo i due byte.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Tutte le comunicazioni seriali inviano un byte per volta e il valore decimale massimo di un byte è 255. Un intero è grande 2 byte per cui ricevi prima io byte più significativo (quello a sinistra) e poi quello meno significativo, quindi ogni due byte devi ricomporre il valore unendo i due byte.

Ciao.
Ma lui dovrebbe usare questa libreria I2CAnything che dovrebbe spezzettare nei singoli byte qualunque variabile e ricomporre il dato in ricezione. Difatti vedo:
I2C_readAnything (timeBlink);
nello sketch di ricezione.

Forse non c'è corrispondenza fra i tipi di dato trasmesso e quello in cui viene poi memorizzato il valore. Ma non avendo mai visto quella lib non so come operi.
Logged


0
Offline Offline
Faraday Member
**
Karma: 30
Posts: 2905
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Leo hai ragione.

Comunque non capisco il valore ritornato i che cosa contiene, dovrebbe contenere il numero di bit processato.

booh.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Offline Offline
Newbie
*
Karma: 0
Posts: 49
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho provato anche con :

Code:
byte highByte;
byte lowByte;
while(Wire.available()){
  highByte = Wire.read();           //reads the byte as an integer
   lowByte = Wire.read();
   int blinkMaster = ((highByte<<8)+lowByte)/10;
}

In questo caso anziché 2000, al primo ciclo, ottengo 2047.

Cmq potreste dirmi se nella:
Code:
Wire.requestForm(address,2)

I byte da ricevere sono sempre 2 per ottenere numeri maggiori di 255?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 49
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si, Wire.available() ritorna il numero di byte
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 110
Posts: 6974
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Controlla bene gli esempi applicativi della libreria
qui --> http://www.bajdi.com/i2c-communication-between-2-arduinos/
ma soprattutto qui --> http://www.gammon.com.au/forum/?id=10896

Prova a definire i tipi volatile.

L'argomento, anche se tratta I2C, è più da sezione Software.  smiley-wink
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Pages: [1]   Go Up
Jump to: