hmm - bisher musste ich
1.) erst gucken ob der i2c Bus frei ist
2.) wenn er frei ist, dann z.B. einen Array als i2c msg schicken mit verschiedenen Registeradressen und Datenarray, das dann vom Sensor gefüllt wird.
In einer C-ähnlichen Programmiersprache sah das so aus:
#define XGL_PORT S1
#define XGL_ADDR 0x02
#define XGL_DATA_REG 0x42
#define XGL_RESET_REG 0x60
#define XGL_ACC_SF_REG 0x61
#define XGL_DATA_PACKET 10
#define XGL_COMMAND 2
void XglReadPacket(XGLpacket &XglData)
{
byte data[XGL_DATA_PACKET];
byte cmd[XGL_COMMAND];
byte count=XGL_DATA_PACKET;
byte n_read=0;
ArrayBuild(cmd,XGL_ADDR, XGL_DATA_REG);
while (I2CStatus(XGL_PORT, n_read) == STAT_COMM_PENDING);
if (I2CBytes(XGL_PORT, cmd, count, data))
{//Assemble data
XglData.mAng = data[0] + data[1]*256;
XglData.mRate = data[2] + data[3]*256;
XglData.mAccX = data[4] + data[5]*256;
XglData.mAccY = data[6] + data[7]*256;
XglData.mAccZ = data[8] + data[9]*256;
}
}
Beschreibung:
The CruizCore® XG1300L I2C address is set to 0x02. Sensor data is stored internally in different registers
that the NXT can access by sending read commands to the appropriate registers (see Table 1).
In addition to the register read operations, the CruizCore® XG1300L provides some additional
functions that can be accessed by sending write commands to specific registers as shown in Table
2. These functions allow resetting the sensor as well as changing the accelerometers scale factor.
[u]Table 1: The CruizCore® XG1300L internal registers[/u]
REGISTER (Hex value) Sensor Value
0x42 Accumulated Angle LSB
0x43 Accumulated Angle MSB
0x44 Rate of Turn LSB
0x45 Rate of Turn MSB
0x46 X-Accelerometer LSB
0x47 X-Accelerometer MSB
0x48 Y-Accelerometer LSB
0x49 Y-Accelerometer MSB
0x4A Z-Accelerometer LSB
0x4B Z-Accelerometer MSB
[u]Table 2: The CruizCore® XG1300L special function registers[/u]
REGISTER (Hex value) XG1300L ACTION
0x60 Reset device
0x61 Select ±2G accelerometer range
0x62 Select ±4G accelerometer range
0x63 Select ±8G accelerometer range
Kompletter Code:
/*
* Microinfinity CO. LTD.
* Test program for the XGL1300L device
* This program displays the complete data package from the device
* it resets the sensor when the user press the left button
* it changes the accelerometer SF when the user press the right button
*/
//Define constants
#define XGL_PORT S1 // first of 4 NXT sensor ports
#define XGL_ADDR 0x02
#define XGL_DATA_REG 0x42
#define XGL_RESET_REG 0x60
#define XGL_ACC_SF_REG 0x61
#define XGL_DATA_PACKET 10
#define XGL_COMMAND 2
#define XGL_TIME_OUT 500
//XGL1300L sensor data packet
struct XGLpacket
{
short mAng;
short mRate;
short mAccX;
short mAccY;
short mAccZ;
};
//Reset XGL1300L sensor
void XglReset()
{
byte cmd[XGL_COMMAND];
byte n_read=0;
ArrayBuild(cmd,XGL_ADDR, XGL_RESET_REG);
while (I2CStatus(XGL_PORT, n_read) == STAT_COMM_PENDING);
I2CWrite(XGL_PORT,0,cmd);
}
//Change scale factor, the accSf parameter can be
// 0 -> +/- 2G
// 1 -> +/- 4G
// 2 -> +/- 8g
void XglAccSF(byte accSf)
{
byte cmd[XGL_COMMAND];
byte n_read=0;
byte register= XGL_ACC_SF_REG+accSf;
ArrayBuild(cmd,XGL_ADDR, register);
while (I2CStatus(XGL_PORT, n_read) == STAT_COMM_PENDING);
I2CWrite(XGL_PORT,0,cmd);
}
//Reads the full packet from XGL1300L
void XglReadPacket(XGLpacket &XglData)
{
byte data[XGL_DATA_PACKET];
byte cmd[XGL_COMMAND];
byte count=XGL_DATA_PACKET;
byte n_read=0;
ArrayBuild(cmd,XGL_ADDR, XGL_DATA_REG);
while (I2CStatus(XGL_PORT, n_read) == STAT_COMM_PENDING);
if (I2CBytes(XGL_PORT, cmd, count, data))
{//Assemble data
XglData.mAng = data[0] + data[1]*256;
XglData.mRate = data[2] + data[3]*256;
XglData.mAccX = data[4] + data[5]*256;
XglData.mAccY = data[6] + data[7]*256;
XglData.mAccZ = data[8] + data[9]*256;
}
}
task main()
{
XGLpacket xgl;
string msg;
byte acc_sf=0;
ReadButtonType rbArgs;
//Initialize system
SetSensorLowspeed(XGL_PORT);
//Resets sensor and waits for hardware to settle
XglReset();
Wait(XGL_TIME_OUT);
//Main loop
while (1)
{
ClearScreen();
XglReadPacket(xgl);
TextOut(0, LCD_LINE1,"<RESET / ACC_SF>", false);
//Print Angle value
TextOut(0, LCD_LINE3,"ANGLE:");NumOut(40, LCD_LINE3,xgl.mAng);
//Print Rate value
TextOut(0, LCD_LINE4,"RATE:"); NumOut(40, LCD_LINE4,xgl.mRate);
//Print Acc x value
TextOut(0, LCD_LINE5,"ACC_X:"); NumOut(40, LCD_LINE5,xgl.mAccX);
//Print Acc y value
TextOut(0, LCD_LINE6,"ACC_Y:"); NumOut(40, LCD_LINE6,xgl.mAccY);
//Print Acc z value
TextOut(0, LCD_LINE7,"ACC_Z:"); NumOut(40, LCD_LINE7,xgl.mAccZ);
//Reset sensor if user press left key
rbArgs.Index = BTNLEFT;
SysReadButton(rbArgs);
if (rbArgs.Pressed)
{
XglReset();
TextOut(0, LCD_LINE2,"Reseting XGL ...", false);
Wait(XGL_TIME_OUT);
}
//Change accelerometer SF if user press right key
rbArgs.Index = BTNRIGHT;
SysReadButton(rbArgs);
if (rbArgs.Pressed)
{
acc_sf=(acc_sf==2)?0:acc_sf+1;
XglAccSF(acc_sf);
TextOut(0, LCD_LINE2,"Accel SF +/-");
NumOut(75, LCD_LINE2,2<<acc_sf);
Wait(XGL_TIME_OUT);
}
Wait(100);
}
}
Unmittelbar danach musste ich zunächst warten, bis der i2c Bus frei ist, dann konnte ich den nächsten Sensor mit der nächsten dev addr an verschiedenen Registreradressen auslesen. Mal muss man dazu die Registeradressen mit angeben (z.B. MAX127), mal auch nicht (PCF8574).