I2C questo sconosciuto

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èèè :astonished:) 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

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

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.

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..

allora ho provato ma senza risultati =( =(:

#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

BMA180-DataSheet-v2.5.pdf (1.16 MB)

Così hai inviato la richiesta per leggere dal registro 2 per 6 registri. Però dopo non fai le read!!!

devo fare cosi?

void loop() {

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

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

}

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

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.

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

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:

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:

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.

allora ho fatto ome mi ha detto leo72 cioè :

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

x iscrizione

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)

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

Seguendo i vari link attraverso il sito della droytek sono approdato qui → arduino/bma180_demo.pde at master · sodnpoo/arduino · GitHub
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.

paolo, attento a non confondere le inizializzazioni necessarie a far funzionare il sensore con le inizializzazioni di scale di lettura, numero di sample, modalità di funzionamento etc...

@Micky: tu dici che leggi -1 -1 -1 -1... ma:

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

Inoltre compili su 1.0. E su 0022/0023 hai provato?

allora ho provato a caricare il codice suggeritomi da PaoloP dopo averlo confrontato con il datasheet.devo dire che alcune cose le ho interpretate altre funzioni no comunque ho voluto testare il codice cosi com’è con IDE 0023 e per ora l’unica cosa che ho cambiato è l’indirizzo dell bma180 da 0x40 a 0x64:

Codice allegato…

ora non capisco perchè mi da un errore nel serial monitor:

Id = 104
PROBLEM… Result code is 2
X:

i collegamenti sono

IMU Arduino
SDA pin4
SCL pin5
+5v 5v
GND gnd

poi ho messo una resistenza da 4.7KOhm tra SDA e 5v e un altra tra SLC e 5v.

prova.pde (5.09 KB)

L'IDE 1.0 attiva di default le pull-up interne. Non so se devi diminuire il valore di quelle esterne o disattivare le interne. Per quanto riguarda l'errore, esso deriva dalla funzione twi_writeTo che è richiamata da Wire.EndTrasmission().

/* 
 * Function twi_writeTo
 * Desc     attempts to become twi bus master and write a
 *          series of bytes to a device on the bus
 * Input    address: 7bit i2c device address
 *          data: pointer to byte array
 *          length: number of bytes in array
 *          wait: boolean indicating to wait for write or not
 * Output   0 .. success
 *          1 .. length to long for buffer
 *          2 .. address send, NACK received
 *          3 .. data send, NACK received
 *          4 .. other twi error (lost bus arbitration, bus error, ..)
 */

Il codice 2 si riferisce ad una mancata risposta: o hai sbagliato Address oppure ci sono problemi di comunicazione. Per gli indirizzi c'era uno sketch per elencare tutte le periferiche presenti sul bus. Non trovo il link però. :roll_eyes:

ho trovato questo : http://todbot.com/arduino/sketches/I2CScanner/I2CScanner.pde

il risultato è questo:

I2CScanner ready! starting scanning of I2C bus from 1 to 100... addr: 1 addr: 2 addr: 3 addr: 4 addr: 5 addr: 6 addr: 7 addr: 8 addr: 9 addr: 10 addr: 11 addr: 12 addr: 13 addr: 14 addr: 15 addr: 16 addr: 17 addr: 18 addr: 19 addr: 20 addr: 21 addr: 22 addr: 23 addr: 24 addr: 25 addr: 26 addr: 27 addr: 28 addr: 29 addr: 30 found! addr: 31 addr: 32 addr: 33 addr: 34 addr: 35 addr: 36 addr: 37 addr: 38 addr: 39 addr: 40 addr: 41 addr: 42 addr: 43 addr: 44 addr: 45 addr: 46 addr: 47 addr: 48 addr: 49 addr: 50 addr: 51 addr: 52 addr: 53 addr: 54 addr: 55 addr: 56 addr: 57 addr: 58 addr: 59 addr: 60 addr: 61 addr: 62 addr: 63 addr: 64 found! addr: 65 addr: 66 addr: 67 addr: 68 addr: 69 addr: 70 addr: 71 addr: 72 addr: 73 addr: 74 addr: 75 addr: 76 addr: 77 addr: 78 addr: 79 addr: 80 addr: 81 addr: 82 addr: 83 addr: 84 addr: 85 addr: 86 addr: 87 addr: 88 addr: 89 addr: 90 addr: 91 addr: 92 addr: 93 addr: 94 addr: 95 addr: 96 addr: 97 addr: 98 addr: 99 addr: 100

done come mai trova 2 indirizzi? 0x30 e 0x64?

edit: l'indirizzo 30 è un altro sensore sulla IMU dovevano essere 4 ma dato che fa la scansione fino al 100 gli altri due non li vede il 105 e il 119.