Проблема с I2C Arduino DUE
- Войдите на сайт для отправки комментариев
Всем привет! Ломаю голову уже неделю! Проблема в следующим: у меня есть датчик ITG3200 в исполнении GROVE system, датчик исправный, подключаю я его у arduino due к линиям scl1, sda1, +3.3 и gnd соответственно и все бы хорошо, но ардуино с датчиком отказывается общаться, точнее она это делает но только один раз после сброса питания ардуино.
Исползую следующий элементарный код:
#include <Wire.h>
void setup()
{
Wire1.begin(); // join i2c bus (address optional for master)
//delay(5000); //задержка в 5 секунд
}
void loop()
{
Wire1.beginTransmission(0x68);
Wire1.write(0);
Wire1.endTransmission(false);
Wire1.requestFrom(0x68, 1); // request 6 bytes from slave device #2
while(Wire1.available()) // slave may send less than requested
{
unsigned char data = Wire1.read(); // receive a byte as character
}
delay(500);
}
в этом листенге запрашивается ID датчика ITG3200
Сразу после включения питания:

тут все хорошо! Далее более подробные фотографии
байт адреса и адрес регистра:

байт адреса с битом R/W=1 и собственно данные:

тут все замечательно, принимаеться 0x69 это ID которое у меня записано регист 0 (WHO_I_AM) в ITG3200.
А ВОТ ДАЛЕЕ ВОЗНИКАЕТ ПРОБЛЕМА! НЕ СМОТРЯ НА ТО ЧТО ЧТЕНИЕ ПАРАМЕТРА ДАТЧИКА НАХОДИТЬСЯ В void loop() ардуино не желает общаться с ITG3200 и на осцыле я наблюдаю следующее:

А тепер вопрос: в чем дело, почему DUE себя так ведет? и еще одна деталь, если добавить в void setup() задержку 3-5 секунд, меньше не проверял, то на линии ничего не просходит, как на последней фотке. Спасибо
Сложно сказать в чем причина, так как DUE - новая платформа, может что-то не "допилили" при обертывании в Арнуино-функции, может еще чего. Попробуйте не на SCL1 и SDA1, а на SCL и SDA. И вот этот пример.
#include <Wire.h> // ITG3200 Register Defines #define WHO 0x00 #define SMPL 0x15 #define DLPF 0x16 #define INT_C 0x17 #define INT_S 0x1A #define TMP_H 0x1B #define TMP_L 0x1C #define GX_H 0x1D #define GX_L 0x1E #define GY_H 0x1F #define GY_L 0x20 #define GZ_H 0x21 #define GZ_L 0x22 #define PWR_M 0x3E #define GYRO_ADDRESS 0x68 void setup() { Wire.begin(); Gyro_Init(); Serial.begin(9600); } void loop() { Serial.print("Gyrox: "); Serial.println(ITG3200Read(TMP_H,TMP_L),DEC); Serial.println(ITG3200Read(GX_H,GX_L),DEC); Serial.println(ITG3200Read(GY_H,GY_L),DEC); Serial.println(ITG3200Read(GZ_H,GZ_L),DEC); Serial.println(ITG3200Readbyte(WHO),HEX); Serial.println(ITG3200Readbyte(0x16),BIN); Serial.println(ITG3200Readbyte(0x15),BIN); Serial.println(ITG3200Readbyte(0x3E),BIN); Serial.println("*************"); delay(1000); } char ITG3200Readbyte(unsigned char address) { char data; Wire.beginTransmission(GYRO_ADDRESS); Wire.send((address)); Wire.endTransmission(); Wire.requestFrom(GYRO_ADDRESS,1); if (Wire.available()>0) { data = Wire.receive(); } return data; Wire.endTransmission(); } char ITG3200Read(unsigned char addressh,unsigned char addressl) { char data; Wire.beginTransmission(GYRO_ADDRESS); Wire.send((addressh)); Wire.endTransmission(); Wire.requestFrom(GYRO_ADDRESS,1); if (Wire.available()>0) { data = Wire.receive(); } Wire.beginTransmission(GYRO_ADDRESS); Wire.send((addressl)); Wire.endTransmission(); if (Wire.available()>0) { data |= Wire.receive()<<8; } return data; // Wire.endTransmission(); } void Gyro_Init(void) { Wire.beginTransmission(GYRO_ADDRESS); Wire.send(0x3E); Wire.send(0x80); //send a reset to the device Wire.endTransmission(); //end transmission Wire.beginTransmission(GYRO_ADDRESS); Wire.send(0x15); Wire.send(0x00); //sample rate divider Wire.endTransmission(); //end transmission Wire.beginTransmission(GYRO_ADDRESS); Wire.send(0x16); Wire.send(0x18); // ±2000 degrees/s (default value) Wire.endTransmission(); //end transmission // Wire.beginTransmission(GYRO_ADDRESS); // Wire.send(0x17); // Wire.send(0x05); // enable send raw values // Wire.endTransmission(); //end transmission // Wire.beginTransmission(GYRO_ADDRESS); // Wire.send(0x3E); // Wire.send(0x00); // Wire.endTransmission(); //end transmission }Так же могу предположить что нужно добавить строку
Wire1.endTransmission();после того как прочитали данные:#include <Wire.h> void setup() { Wire1.begin(); // join i2c bus (address optional for master) //delay(5000); //задержка в 5 секунд } void loop() { Wire1.beginTransmission(0x68); Wire1.write(0); Wire1.endTransmission(); Wire1.requestFrom(0x68, 1); // request 6 bytes from slave device #2 while(Wire1.available()) // slave may send less than requested { unsigned char data = Wire1.read(); // receive a byte as character } Wire1.endTransmission(); delay(500); }в конце endTransmission() можно не вызывать, так как requestFrom() делает тоже самое, после приема данных.
Все запутываеться еще и тем, что если вставить Serial.println("разный текст") в ключевые точки кода, например
... void setup() { Wire1.begin(); // join i2c bus (address optional for master) Serial.begin(9600); } void loop() { Serial.println("start loop"); Wire1.beginTransmission(0x68); Wire1.write(0); Wire1.endTransmission(false); Wire1.requestFrom(0x68, 1); // request 6 bytes from slave device #2 while(Wire1.available()) // slave may send less than requested { Serial.print("read byte: "); unsigned char data = Wire1.read(); // receive a byte as character Serial.println(data); } delay(500); Serial.println("end loop"); }и после этого включить монитор порта, то в мониторе мы увидем ожидаемый результат, но на асцыле ничего не будет происходить.
И кстати подключался к датчику с помощью PIC18f452 и вообщем проблем не было. IDE Arduino 1.5 находиться на beta тесте, может дело в этом