简体   繁体   中英

Converting raw Accelerometer values to 12 bit number

I am coding an Accelerometer that is in built in one of the microcontroller (TZ1000 series). I am trying send the data BLE to PC application. I have to send the number in 2 bytes and receive it in application side and combine it to form a 12-bit number. I am facing problem in converting the actual raw accelerometer values to 12 bit number. I am reading it in following format.

acc->ReadAcceleration((uint16_t*)buf);  
ChannelX[M] = (buf[0].acceleration << 4) & 0xFFF0;
ChannelY[M] = (buf[1].acceleration << 4) & 0xFFF0;
ChannelZ[M] = (buf[2].acceleration << 4) & 0xFFF0;

Where the variables are of type and size as follows,

int16_t ChannelX[4] = {0,0,0,0};
int16_t ChannelY[4] = {0,0,0,0};
int16_t ChannelZ[4] = {0,0,0,0};

buf is of type static ACCEL_ACCELERATION buf[12]; and the structure of it is as follows,

  typedef struct _ACCEL_ACCELERATION {
       uint16_t updated      : 1;
      uint16_t reserved     : 3;
      int16_t  acceleration :12;
    } ACCEL_ACCELERATION;

Now when i am converting this data to two bytes and transmit over BLE, I am following below logic.

uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>12) & 0x0F) ;

uart_tx_data[i+2] = (uint8_t) (ChannelY[j] & 0xFF);
uart_tx_data[i+3] = (uint8_t) ((ChannelY[j]>>12) & 0x0F) ;

uart_tx_data[i+4] = (uint8_t) (ChannelZ[j] & 0xFF);
uart_tx_data[i+5] = (uint8_t) ((ChannelZ[j]>>12) & 0x0F) ;

where variable is of type static uint8_t uart_tx_data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

At receive side i am converting it to a 12 bit number as follows,

X[i]= (num[2] & 0xFF) | ((num[3] & 0x0F) << 12);

where int[] X= new int[2];

The values that I am getting is wrong, I checked it by doing 1g test on the accelerometer. For example when its flat it should give a number closer to zero. and at 1g it should give a number according to the sensitivity I have set ( in my case its 8G and value is 256).

Is there anything wrong in the logic I have used?? I request some one to help me on this.

Thank you in advance.

Your shifts are all off. Use a constant to see what's happening. Example: put 0x1234 into the structure (note I'm assuming 16bit variable and not caring about the bit fields in the structure which change things a bit but not the reason why it's not working)

ChannelX[M] = (buf[0].acceleration << 4) & 0xFFF0;

This will result in 0x2340. Not sure why you want the lowest four bits zero but let's go with it. Then you send it:

uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>12) & 0x0F) ;

First part will be 0x2340 & 0xff == 0x40 so you're always sending four zeroes from the lowest bits. Second part will be 0x2340 >> 12 == 0x02 so you're missing the whole 3 part there.

Why not simply take the value of acceleration and send it without making four lowest bits zero? The bit fields will make it into a 12bit value already. And when sending shift by 8, not 12.

ChannelX[M] = buf[0].acceleration;
uart_tx_data[i]   = (uint8_t) (ChannelX[j] & 0xFF);
uart_tx_data[i+1] = (uint8_t) ((ChannelX[j]>>8) & 0x0F);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM