Go Down

Topic: I2C questo sconosciuto (Read 2 times) previous topic - next topic

micky861

ciao,dato che ho appena ordinato un IMU 10DOF LLC - ITG3200 + BMA180 + HMC5883 + MS5611 + LLC ,ed ho visto che lavora con protocollo i2c,volevo chiedervi se esiste una guida o tutorial su come usare questo protocollo con arduino.
Googlando (ke termine hhèèè :smiley-eek:) ho trovato varie documentazioni su cosè il protocollo i2c ma non come usarlo con arduino,ho trovato vari esempi che però si sono dimostrati molto complessi da intepretare compresi quelli del sito di drotek.
grazie

lucadentella

Ciao

il protocollo i2c è gestito da una libreria Core di Arduino (Wire, http://arduino.cc/it/Reference/Wire): dialogare con dispositivi i2c è quindi decisamente facile con i comandi disponibili.

Tieni conto che i2c è solo il protocollo di comunicazione, quello che i dati significano dipende dal singolo dispositivo i2c, devi quindi guardare il datasheet dei sensori che compongono la tua IMU per capire come leggere (e in quali celle di memoria) i valori disponibili.

bye
lucadentella.it

lesto

l'i2c in realtà è abbastanza semplice. prima di tutto ti serve il datasheet del sensore che vuoi usare. esso possiede un indirizzo, tipo 0x2A.
ogli sensore ha un elenco di registri, anche loro con un indirizzo simile a quello di prima.

quindi se vuoi modificare un registro, apri una comunicazione con l'indirizzo del sensore, invii l'indirizzo del registro che vuoi modificare, invii il nuovo valore che il registro deve avere, ed infine chiudi la comunicazione.

per leggere è molto simile: apri la comunicazione con l'indirizzo del sensore, invii il numero di registro da cui PARTIRE a leggere, il numero di byte (ogni registro è un byte) che vuoi leggere, e poi ti metti in ascolto. ricevuti i messaggi chiudi la comunicazione.

molto spesso negli esempi su internet non usano la libreria Wire, perchè ha una grossa limitazione: se qualcosa non funziona bene, essa rimane bloccata. invece altre librerie restano bloccate solo un tot di tempo, dopodiché rilevano il timeout e permettono al programma di andare avanti. molto utile per evitare che se un cavo con la imu si stacca, o un disturbo particolarmente forte, facciano impazzire completamente la tua applicazione.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

micky861

per esempio come faccio a recuperare le info dell'asse x di questo accelerometro per poi scriverle su un servo?
http://omapworld.com/BMA180_111_1002839.pdf
I2C addres: 64
Sò che la risposta sarà complessa ma porta pazienza non l'ho mai fatto..

micky861

allora ho provato ma senza risultati =( =(:
Quote

#include <Wire.h>

#define BMA180              0x64

int x,y,z,temp;

void setup()
{
  Wire.begin();
  Serial.begin(115200);

}

void loop()
{

  Wire.beginTransmission(BMA180);
  x=Wire.requestFrom(2, 6);

}

void printAccel()
{
  Serial.print("X = ");
  Serial.println(x);

}



1: il codice lo compila ma non ricevo niente sulla seriale
2:se includo la sua librerie del bma180 mi da errore di compilazione

C:\Users\Desktop\arduino-1.0\libraries\bma180\bma180.cpp: In member function 'int BMA180::getIDs(int*, int*)':
C:\Users\Desktop\arduino-1.0\libraries\bma180\bma180.cpp:139: error: call of overloaded 'write(int)' is ambiguous
C:\Users\Desktop\arduino-1.0\libraries\Wire/Wire.h:55: note: candidates are: virtual size_t TwoWire::write(uint8_t)
C:\Users\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Print.h:49: note:                 size_t Print::write(const char*)

allego il datasheet per gli indirizzi di registro a pagina 22

lesto

Così hai inviato la richiesta per leggere dal registro 2 per 6 registri. Però dopo non fai le read!!!!
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

micky861

devo fare cosi?
Quote

void loop()
{

  Wire.beginTransmission(BMA180);
  x=Wire.requestFrom(2, 6);
  Wire.read();
}

void printAccel()
{
  Serial.print("X = ");
  Serial.println(x);

}


leo72

No, devi assegnare il byte letto con Wire.read ad una variabile.

PS: ti suggerisco di rileggerti per bene qui:
http://arduino.cc/en/Reference/Wire

PaoloP

Dagli errori sembra che la libreria non sia aggiornata alla versione 1.0 dell'IDE.
Puoi risolvere o cercando una libreria aggiornata o usando una vecchia versione dell'IDE, ad esempio la 023 -->  http://arduino.cc/en/Main/Software --> Previous IDE Versions.
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

leo72

@Pablos:
uhm, forse non hai visto il codice che usa:

Code: [Select]

x=Wire.requestFrom(2, 6);
Wire.read();

Non è questione di versione dell'IDE, se non assegna ciò che legge a qualcosa. Al max alla rovescia, ossia Wire.request(ecc) e poi x=Wire.Read().

@micky:
estratto dalle pagine presenti nel link che ti ho suggerito:
Quote
Wire.requestFrom()

Description
Used by the master to request bytes from a slave device. The bytes may then be retrieved with the available() and read() functions.


Ed ancora:
Quote
read()

Description
Reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted from a master to a slave.

micky861

allora ho fatto ome mi ha detto leo72 cioè :
Quote

void loop()
{

  Wire.beginTransmission(BMA180);
  Wire.requestFrom(2, 6);
  x=Wire.read();
  Serial.print("X = ");
  Serial.println(x);

}


ora il codice lo compila senza errori però dal segnale ricevo solo:
x=-1
x=-1
x=-1
x=-1
x=-1
ecc..
forse ho sbagliato a richiamare il registro?(requestFrom(2, 6)) è che da sto datasheet non ci capisco una mazza

Testato

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

lesto

can la read leggi un registstro (un byte) alla volta.  tu hai fatto richiesta per 6 byte, quindi ci vogliono 6 read.

se non ricordo male, un valore in quel sensore occupa 2 registri, quindi tu stai leggendo i 3 valori X, Y e Z (sempre che l'indirizzo di lettura sia giusto... e dubito)
quindi devi unire i due byte che corrispondono al valore in un valore (int) unico.

Ah, molto sensori non i2c non leggono in automatico, ma prima bisogna scrivere in un registro dei particolari valori (in pratica degli dirgli di partire a leggere)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

leo72

Inoltre un tipo byte non può essere negativo, che tipo stai usando? Char o int?

PaoloP

Seguendo i vari link attraverso il sito della droytek sono approdato qui --> https://github.com/sodnpoo/arduino/blob/master/bma180_demo/bma180_demo.pde
Si vede chiaramente che prima di leggere i dati dal sensore questo deve essere inizializzato: initBMA180()
Inoltre, è presente anche una funzione per leggere i valori relativi all'accelerazione. Studiandole insieme al datasheet del sensore si può capirne il funzionamento.
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Go Up