1

i am trying to write a simple program that writes the outputs of an accelerometer (which comes down to 3 analog inputs) onto an SD-Card.

I got the hole thing working fine (sending the values as simple strings), however i wanted to increase the frequency at wich the data is taken and therefore tried to send the data to the SD card encoded in binary, and therefore i am doing some bitwise manipulation.

Unfortunately some (as i think) strange things happen. When i add a simple bitwise manipulation the data on the SD card is pretty messed up. (I was unable to detect a pattern but it seems some Bytes are missing or or are there twice without any regularity):

Here is an example of a working version:

// Get raw accelerometer data for each axis
unsigned int rawX = analogRead(A0);
unsigned int rawY = analogRead(A1);
unsigned int rawZ = analogRead(A2);

byte b1 = (byte) (rawX>>2);  
byte b2 = (byte) (rawY>>4);
b2 = b2 + (byte) (rawX<<6);
byte b3 = (byte) (rawZ>>6);
b3 = b3 + (byte) (rawY<<4);
byte b4 = (byte) (rawZ);
b4 = (byte)b4*4;
//b4 = (byte)b4<<2;

// get pressure
//temp = BMP180_getTemp();
//float a = 0;
//float a = pressure.altitude(BMP180_getPressure(), baseline);

unsigned long t = millis();

byte writeB[] ={
    b1, 
    b2, 
    (byte) (rawZ>>6), //replacing this with '(byte) ((rawZ>>6)|(0b11110000 & rawY))' will cause the error
//also replacing with b3 creates the error as well
    b4, 
    (byte) (t>>16), 
    (byte) (t>>8), 
    (byte)t, (byte)0};


dataFile.write(writeB,8);

dataFile.flush();

As mentioned as a comment in the code changing the way the byte is calculated messes up my data on the SD card. I tried several other things however it seems that the following operations are causing the error: | & << >> (However i am using some of them to calculate e.g. b2)

What i don't get is how changing how a byte is calculated affect the data output.

Maybe (probably) i overlooked some easy mistake but i cant figure out what is happening. Any help would be greatly appreciated since im working on this since quite a while.

(I am aware that the program does currently not transmit all necessary data but i startet from scratch and programmed step by step to locate/identify the error)

6
  • Please include a minimal program that compiles and demonstrates your problem. Ideally include actual and expected output. – Craig Apr 13 '18 at 18:59
  • It is unclear what you do with the code. If you try to use the whole memory by sharing the bits of a byte,you cannot use the arithmetic + operator. Instead use the | (bitwise or) operator – chrisl Apr 13 '18 at 19:23
  • i indeed try to share the bits of a byte. i tried the bitwise or operator as well. However why can i not use add (in case e.g. i know the 4 last bits are filled with 0 and the first 4 i could add this to another byte from wich i know the first 4 bits are zeros.) – Hannes Apr 13 '18 at 19:52
  • why can i not use add .... how do you know that you cannot? .... you have not shown the data, so it is impossible to guess what it happening – jsotola Apr 13 '18 at 20:12
  • Your computation of b3 seems sane to me. “the data [...] is pretty messed up” is not a useful description of the problem. Please, edit your question to add: 1. the values of rawX, rawY and rawZ, 2. the values of b1, b2, b3 and b4 you would expect, and 3. the values of b1, b2, b3 and b4 you get instead. – Edgar Bonet Apr 13 '18 at 20:56
2

Your way of sharing the bits between the three values seems a bit confusing. Your code for saving the bits is correct in the meaning of that you save all relevant information. Your bytes are shared in this way (H means high portion of value, L is the low portion of value):

     ____HX_____
b1: | 0000 0000 |
     _LX_ ___HY___
b2: | 00 | 000000 |
     __HZ__ __LY__
b3: | 0000 | 0000 |
     __LZ____
b4: | 000000 | XX |

This is a rather complex way of dividing the space. Also, since you are not using the remaining 2 bits of b4 you don't have to shift there.

When you are getting garbled values from your SD card, it wildly depends on how you are reading the bytes (you haven't shown us the code for that). As a suggestion I will explain how I would do it.


We have 3 values from analogRead(), which each have 10 bits. So in total we have 30 bits, which can be transmitted in 4 bytes (or 32 bits). When adding bits from another value, I think you can use the + operator (opposing to my comment) if the bits of the different values don't overlay (which should be anyway). For my part I like to use the bitwise or | to show more clearly, what is done there and to easier check for errors in alignment (easy to see in binary representation). Do as you like. I will use the | operator for now.

// Get raw accelerometer data for each axis
unsigned int rawX = analogRead(A0);
unsigned int rawY = analogRead(A1);
unsigned int rawZ = analogRead(A2);

byte b1 = rawX & 0xFF;
byte b2 = rawY & 0xFF;
byte b3 = rawZ & 0xFF;
byte b4 = (rawX & 0x0300) >> 2
          | (rawY & 0x0300) >> 4
          | (rawZ & 0x0300) >> 6;

The low portion of the values are saved in the bytes b1 to b3. The upper 2 bits of every value is saved left-aligned to b4 (The & 0x0300 isolates the upper portion, bit 9 and 10, in the values.).

You can read these values in this way:

rawX = b1 | (( b4 & 0b11000000) << 2);
rawY = b2 | (( b4 & 0b00110000) << 4);
rawZ = b3 | (( b4 & 0b00001100) << 6);

b1 to b3 are the start for our retrieved raw values. Then we add the other 2 bits to the raw values. For this we first isolate the bits from b4 from the positions we used in the upper code. Then we shift them to the left, until they are directly above the 8 bits of the start values.

1
  • Thanks for the detailed description! I am reading the data by opening the datafile with notepad++ using the HEX-Editor. The reason why i am sure the data is wring is simply because the 8th byte should always be 0x00. This is however not the case. I agree that using the | operator is more readable and i normally use it. Since it seemed to cause the error i tried to avoid it. I like your way of storing the data since the pattern is easier to understand. I tried your solution and it worked! Thanks a lot. I am still a little bit curious to why my code did behave so strange. – Hannes Apr 15 '18 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.