Salve a tutti, ho cercato online su moltissimi siti web e forum ma non sono riuscito a risolvere il seguente problema, le soluzioni che ho trovato variano da resistenze di pull-up al semplice collegamento ma nessuna soluzione proposta ha funzionato. Il problema è questo:
Ho un accelerometro MPU-5060 ed un orologio DS3231 che devo collegare alle stesse porte: SCL e SDA dell'arduino mega. Come posso collegarli per farli funzionare assieme?
Grazie in anticipo
Semplicemente studiandoti come funziona un bus I2C, perché se poni questa domanda, evidentemente NON lo sai affatto ed usare cose che non si conoscono può sempre creare problemi.
Ecco, leggi QUESTO link ... dovrebbe chiarirti le idee ... ... dopo di che torna qui e poi le specifiche domande su ciò che ancora non ti è chiaro
Guglielmo
P.S:: Purtroppo, non riesco neanche a trovare il tuo post di presentazione nell'apposita sezione ... ... quindi, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO ... Grazie.
Ciao, grazie per la pagina nel link che è stata molto utile, per lo meno adesso arduino "vede" i due dispositivi. Mi sono anche presentato nell'apposita sezione (non ci avevo mai fatto caso) e mi sono letto le regole del forum.
Come ho già detto adesso arduino riesce a vedere i due dispositivi nella scansione fatta come dice qui, però quando vado ad eseguire un semplice sketch di prova non trova l'accelerometro. Per l'orologio invece la questione è diversa, crede di comunicare ma in realtà lo fa fino ad un certo punto.
Avvio il test della libreria e mi restituisce dei valori intermittenti, per capire meglio ecco cosa:
DS1307RTC Read Test
------------
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:00, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:01, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:00, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:01, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:00, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:01, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:00, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:01, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:00, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:01, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:11, Date(D/M/Y) = 30/10/2016
Ok, Time = 09:39:10, Date(D/M/Y) = 30/10/2016
etc.
Ho notato che i secondi sono del tipo: 01-00 per 10 volte, poi 11-10 per 10 volte e ricomincia una sequenza 01-00.
Cosa devo fare per risolvere il problema? Gli sketch utilizzati sono quelli di esempio delle librerie... funzionano con un dispositivo per volta ma non funzionano con entrambi.
Hai messo delle resistenze pullup da 4,7kOhm e cavetti di collegamneto corti (sotto 10 cm)? Oppure i moduli hanno giá i pullup integrati?
Se ci dai lo sketch e il link alla libreria che usi forse potremmo risponderti.
Ciao Uwe
Si, ho messo le resistenze tra SCL e 5V e SDA e 5V, però da 3,3K. I link delle librerie non li ho più in quanto le ho da diverso tempo. Comunque i nomi sono: I2CDev, MPU6050, Wire e Time.
Accelerometro:
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
// 2013-05-08 - added multiple output formats
// - added seamless Fastwire support
// 2011-10-07 - initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high
int16_t ax, ay, az;
int16_t gx, gy, gz;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO
// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO
#define LED_PIN 13
bool blinkState = false;
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// use the code below to change accel/gyro offset values
Serial.println("Updating internal sensor offsets...");
// -76 -2359 1688 0 0 0
Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
Serial.print("\n");
accelgyro.setXGyroOffset(121);
accelgyro.setYGyroOffset(-23);
accelgyro.setZGyroOffset(44);
accelgyro.setXAccelOffset(-2277);
accelgyro.setYAccelOffset(-980);
accelgyro.setZAccelOffset(1309);
Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
Serial.print("\n");
// configure Arduino LED for
pinMode(LED_PIN, OUTPUT);
avviamento();
}
int X;
int Y;
int Z;
int MX;
int MY;
int MZ;
void loop() {
for (int i = 1; i<5; i++) {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
/*
#ifdef OUTPUT_READABLE_ACCELGYRO
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g:\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az); Serial.print("\t");
Serial.print(gx); Serial.print("\t");
Serial.print(gy); Serial.print("\t");
Serial.println(gz);
#endif
#ifdef OUTPUT_BINARY_ACCELGYRO
Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
#endif
*/
X = X+ax;
Y = Y+ay;
Z = Z+az;
}
X = X/5;
Y = Y/5;
Z = Z/5;
Serial.print("X: ");
Serial.println(X);
/*Serial.print("Y: ");
Serial.println(Y);
Serial.print("Z: ");
Serial.println(Z);
*/
if (X > MX+40 or X < MX-40)
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
X = 0;
Y = 0;
Z = 0;
// blink LED to indicate activity
blinkState = !blinkState;
//digitalWrite(LED_PIN, blinkState);
delay(100);
}
void avviamento() {
Serial.println("Facendo la media avviamento... non toccare il sensore");
digitalWrite(13, HIGH);
for (int i = 1; i<50; i++) {
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
/*
#ifdef OUTPUT_READABLE_ACCELGYRO
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g:\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az); Serial.print("\t");
Serial.print(gx); Serial.print("\t");
Serial.print(gy); Serial.print("\t");
Serial.println(gz);
#endif
#ifdef OUTPUT_BINARY_ACCELGYRO
Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
#endif
*/
X = (X+ax);
Y = (Y+ay);
Z = (Z+az);
delay(50);
}
digitalWrite(13, LOW);
X = X/50;
Y = Y/50;
Z = Z/50;
MX = X;
MY = Y;
MZ = Z;
Serial.print("Media X: ");
Serial.println(MX);
X = 0;
Y = 0;
Z = 0;
loop();
}
I restanti due sketch li metto come allegati perché il sistema mi dice che il messaggio è troppo lungo.
testtime.ino (307 Bytes)
i2cscan.ino (1.09 KB)
Nessuno mi sa aiutare?
Gli sketch utilizzati sono quelli di esempio delle librerie... funzionano con un dispositivo per volta ma non funzionano con entrambi.
Quando lanci lo sketch di scannerI2C, che indirizzo ti danno tutti e due i moduli ?
Perchè di default, mi pare, che abbiano lo stesso indirizzo 0x68
TimoFran:
Nessuno mi sa aiutare?
Datti una calmata. Pretendi che in 24 minuti Ti ripondano?
Ciao Uwe
Datti una calmata. Pretendi che in 24 minuti Ti ripondano?
Oddio, @Uwe, a dire il vero e' passato più di un giorno
Brunello:
Oddio, @Uwe, a dire il vero e' passato più di un giorno
ops, errore mio. Ho cancellato (barrato) il mio post
Ciao Uwe
Brunello:
Quando lanci lo sketch di scannerI2C, che indirizzo ti danno tutti e due i moduli ?
Perchè di default, mi pare, che abbiano lo stesso indirizzo 0x68
No, i due indirizzi sono 0x57 e 0x68
Ecco cosa dice lo scanner:
Scanning...
I2C device found at address 0x57 !
I2C device found at address 0x68 !
done
Quelli sono gli indirizzi del solo RTC
0x68 = il DS3231
0x57 = la Eeprom 24c32 a bordo dell RTC
Di default la MPU ha come address 0x68.
E se leggessi all'interno degli sketch che carichi, vedresti che te lo fanno notare
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high
Quindi metti il piedino marcato AD0 ( o A0 ) della MPU al positivo e commenta/discommenta le righe presenti nello sketch
Non ho capito bene cosa devo fare... ho modificato il codice così:
//class default I2C address is 0x68
//specific I2C addresses may be passed as a parameter here
//AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
//AD0 high = 0x69
//MPU6050 mpu;
MPU6050 mpu(0x69); // <-- use for AD0 high
Però non funziona comunque
Oltre a modificare il codice devi collegare il pin AD0 al Vcc
Hai questo modello ?
Ah ok, pensavo fosse solo una modifica software.
Comunque grazie mille a tutti, adesso funziona tutto perfettamente.