Andreas HD Andreas HD - 1 month ago 13
C++ Question

Weird behavior when shifting

When I write to my SD Card using the SDCard Library from Cypress I have some challenges. Because I have to speed everything up, using

sprintf()
and similar is not possible.

The library only lets me write to the SD card in either uchars or strings. Unfortunately my values are all
int16_t
. So here is where the problem arise:

int16_t ax = -15000;
ay = -10000;
az = -32760;
gx = 32760;
gy = 25000;
gz = 10;
mx = -10;
my = 20;
mz = 0;

// Then I put it into an array

char suma[] = {
((uint16_t) ax) & 0xff,
((uint16_t) ax) >> 8,
((uint16_t) ay) & 0xff,
((uint16_t) ay) >> 8,
((uint16_t) az) & 0xff,
((uint16_t) az) >> 8,

((uint16_t) gx) & 0xff,
((uint16_t) gx) >> 8,
((uint16_t) gy) & 0xff,
((uint16_t) gy) >> 8,
((uint16_t) gz) & 0xff,
((uint16_t) gz) >> 8,

((uint16_t) mx) & 0xff,
((uint16_t) mx) >> 8,
((uint16_t) my) & 0xff,
((uint16_t) my) >> 8,
((uint16_t) mz) & 0xff,
((uint16_t) mz) >> 8,
0
};


When I retrieve the data something is wrong. The data is fine until
gz
. It shows 10 alright but the rest is just gone.

Changing 10 to 257 eliminates the issue, and -10 is fine, meaning the error happens when I right shift a low non negative value.

What is up? I hope you have some insights :)

Answer

In converting an int16_t to a uint16 and then to a char, you're likely ending up sending a null char (\0) to the library.

The library - which only accepts char[] or string - probably casts the former to a c string, which are terminated with a null char. Meaning your most significant byte (0x00) is terminating the string early. Any uint16 under 257 will result in a null char in the most significant spot.

e.g:

0000 0000 = [0, 0] = [0x00, 0x00]   // 2 null chars, only the first will get across
0001 0000 = [1, 0] = [0x01, 0x00]   // null char
                                    // ...
1111 0000 = [256, 0] = [0xff, 0x00] // null char
1111 0001 = [256, 1] = [0xff, 0x01] // not null char

Try explicitly casting your char[] to an std::string and specifying the size of it. ex:

std::string s("ab\0c", 4);
Comments