I'm writing an article about Infineon's 3D Sensor Magnetic Field Sensor -- the TLV394D. I decoded the I²C bus in the development kit and used the data to write the Arduino code. I can communicate with bi-directionally with the chip without a problem.
The trouble arises in that I'm uncomfortable publishing my conversion routines. My experience with bit-math is decades old. So if you are experienced in Arduino or C++ programming, please take a look and give some advice, criticisms, other ways to do things, etc...
The data (x,y,z,t) is 12-bit. Stored in the first six registers.
[0] (x11, x10, x9, x8, x7, x6, x5, x4)
[1] (y11, y10, y9, y8, y7, y6, y5, y4)
[2] (z11, z10, z9, z8, z7, z6, z6, z4)
[3] (t11, t10, t9, t8, , , , )
[4] (x3, x2, x1, x0, y3, y2, y1, y0)
[5] ( , , , , z3, z2, z1, z0)
[6] (t7, t6, t5, t4, t3, t2, t1, t0)
I need to first combine the bits of data. Then I need to decode them.
B12 | B11 | B10 | B9 | B8 | B7 | B6 | B5 | B4 | B3 | B2 | B1
-2048|+1024|+512|+256|+128|+64|+32|+16 | +8 | +4 | +2 | +1
The trouble arises in that I'm uncomfortable publishing my conversion routines. My experience with bit-math is decades old. So if you are experienced in Arduino or C++ programming, please take a look and give some advice, criticisms, other ways to do things, etc...
The data (x,y,z,t) is 12-bit. Stored in the first six registers.
[0] (x11, x10, x9, x8, x7, x6, x5, x4)
[1] (y11, y10, y9, y8, y7, y6, y5, y4)
[2] (z11, z10, z9, z8, z7, z6, z6, z4)
[3] (t11, t10, t9, t8, , , , )
[4] (x3, x2, x1, x0, y3, y2, y1, y0)
[5] ( , , , , z3, z2, z1, z0)
[6] (t7, t6, t5, t4, t3, t2, t1, t0)
I need to first combine the bits of data. Then I need to decode them.
B12 | B11 | B10 | B9 | B8 | B7 | B6 | B5 | B4 | B3 | B2 | B1
-2048|+1024|+512|+256|+128|+64|+32|+16 | +8 | +4 | +2 | +1
Code:
// Include I²C wire interface library
#include <Wire.h>
// Variable Declaration
byte buffer[8]; // store data from sensor registers.
const byte addr = 0x5E; // address of magnetic sensor
const byte ulpm[] = {0x00,0x05}; // ultra low power mode
const byte lpm[] = {0x00,0x05,0x00,0x40}; // low power mode
const byte fm[] = {0x00,0x06,0x00,0x00}; // fast mode (unsupported)
// Setup Commands
void setup() {
Serial.begin(9600); // Begin serial connection for debug.
Wire.begin(); // Begin I²C wire communication
// Set Power Mode (ulpm, lpm, fm)
Wire.beginTransmission(addr); // transmit power mode to sensor
for(int i=0; i<sizeof(ulpm); i++){ //ulpm, lpm, fm
Wire.write(ulpm[i]);
}
Wire.endTransmission();
}
// Main Program Area
void loop() {
// Read sensor registers and store in buffer
Wire.requestFrom(addr,sizeof(buffer));
for(int i=0; i<sizeof(buffer)-1; i++){
buffer[i] = Wire.read();
}
int x = decodeX(buffer[0],buffer[4]);
int y = decodeY(buffer[1],buffer[4]);
int z = decodeZ(buffer[2],buffer[5]);
int t = decodeT(buffer[3],buffer[6]);
Serial.print(x); Serial.print("\t");Serial.print(y);Serial.print("\t");Serial.print(z);Serial.print("\t");Serial.println(t);
}
// Conversion Routines
int decodeX(int a, int b){
int ans = (a << 4) + (b >> 4);
if( ans > 2047){
ans -= 4096;
}
return ans;
}
int decodeY(int a, int b){
a <<= 4;
int ans = (a << 4) + (b &= 16);
if( ans > 2047){ ans -= 4096;}
return ans;
}
int decodeZ(int a, int b){
a <<= 4;
int ans = (a << 4) + (b &= 16);
if( ans > 2047){ ans -= 4096;}
return ans;
}
int decodeT(int a, int b){
a >>= 4;
int ans = (a << 8) + b;
if( ans > 2047){ ans -= 4096;}
return ans;
}
Attachments
-
847.6 KB Views: 2
Last edited by a moderator: