Проблема с I2C Arduino DUE

shepherd4
Offline
Зарегистрирован: 30.01.2013

Всем привет! Ломаю голову уже неделю! Проблема в следующим: у меня есть датчик 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 секунд, меньше не проверял, то на линии ничего не просходит, как на последней фотке. Спасибо 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Сложно сказать в чем причина, так как 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);
}

 

shepherd4
Offline
Зарегистрирован: 30.01.2013

 

с sda scl все тоже самое. 

  Wire1.beginTransmission(0x68);
  Wire1.write(0);
  Wire1.endTransmission(false); //обязательно false, иначе вообще не пашет, в данном случае это состояние "рестарт" / поворный старт  на линии 

   

в конце 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 тесте, может дело в этом