What are LB, HB, UB, and MB in hex data? - hex

I have a question in the code below.
I know as follows.
Hex 00FC = Decimal 252. (Note: High byte(HB) is 00. Low byte(LB) is FC.)
Hex 0565 = Decimal 1381. (Note: High byte(HB) is 05. Low Byte(LB) is 65.)
I have confirmed that there are additional UB, MB.
{
UINT32 dwData;
...
...
dwData.Val = 0x00000101;
...
...
//Write Bytes
WriteByte(dwData.byte.LB);
WriteByte(dwData.byte.HB);
WriteByte(dwData.byte.UB);
WriteByte(dwData.byte.MB);
...
...
}
What are LB, HB, UB, and MB?

Related

Error "cannot allocate memory block of size 67108864 Tb" in the R function false.nearest

The R function
tseriesChaos::false.nearest(series, m, d, t, rt=10, eps=sd(series)/10)
realizes the false nearest neighbours algorithm to help deciding the optimal embedding dimension.
I would like to apply it to the following series:
dput(x)
c(0.230960354326456, 0.229123906233121, 0.222750351085665, 0.230096143459004,
0.226315220913903, 0.228151669007238, 0.225775089121746, 0.229447985308415,
0.230096143459004, 0.232256670627633, 0.23722588311548, 0.236361672248029,
0.231716538835476, 0.229231932591552, 0.229880090742141, 0.229447985308415,
0.236901804040186, 0.234525224154694, 0.236577724964891, 0.240574700226855,
0.238090093982932, 0.233552986928811, 0.235929566814303, 0.228799827157827,
0.224694825537431, 0.225775089121746, 0.224694825537431, 0.221129955709193,
0.214540347844874, 0.213352057902128, 0.21054337258291, 0.208706924489575,
0.211083504375068, 0.212487847034676, 0.20903100356487, 0.206654423679378,
0.213027978826834, 0.211083504375068, 0.216160743221346, 0.213244031543697,
0.214324295128011, 0.216160743221346, 0.215512585070757, 0.218753375823701,
0.215836664146052, 0.225126930971157, 0.228367721724101, 0.23128443340175,
0.240574700226855, 0.244139570055093, 0.246732202657448, 0.248028518958626,
0.246300097223723, 0.245976018148428, 0.241762990169601, 0.245976018148428,
0.248892729826078, 0.258831154801772, 0.265744841741385, 0.259803392027655,
0.258831154801772, 0.261855892837852, 0.262504050988441, 0.262071945554715,
0.257102733066868, 0.270065896078643, 0.276655503942962, 0.280544452846495,
0.280004321054337, 0.276547477584531, 0.286485902560225, 0.278924057470023,
0.279140110186886, 0.272658528680998, 0.262828130063736, 0.26466457815707,
0.254726153181376, 0.264448525440207, 0.261207734687264, 0.269741817003349,
0.259587339310792, 0.256886680350005, 0.26163984012099, 0.252133520579021,
0.257858917575888, 0.255158258615102, 0.252457599654316, 0.251701415145295,
0.251161283353138, 0.251053256994707, 0.251917467862158, 0.24316733282921,
0.242195095603327, 0.249540887976666, 0.259263260235497, 0.259263260235497,
0.258399049368046, 0.252565626012747, 0.263800367289619, 0.262071945554715,
0.259695365669223, 0.256886680350005, 0.253213784163336, 0.260127471102949,
0.268769579777466, 0.271578265096684, 0.270173922437075, 0.267905368910014,
0.262071945554715, 0.262936156422167, 0.261855892837852, 0.262720103705304,
0.259047207518635, 0.263044182780598, 0.257102733066868, 0.259155233877066,
0.259155233877066, 0.250297072485687, 0.24089877930215, 0.239494436642541,
0.241546937452738, 0.24014259479313, 0.244355622771956, 0.242195095603327,
0.242303121961759, 0.241438911094307, 0.236901804040186, 0.238954304850383,
0.236793777681754, 0.239386410284109, 0.241546937452738, 0.24608404450686,
0.244139570055093, 0.237333909473912, 0.238954304850383, 0.240250621151561,
0.235281408663714, 0.234093118720968, 0.237657988549206, 0.246948255374311,
0.249432861618235, 0.246516149940585, 0.247164308091174, 0.252997731446473,
0.258399049368046, 0.258399049368046, 0.256238522199417, 0.268661553419034,
0.275143134924922, 0.273630765906881, 0.270281948795506, 0.265204709949228,
0.262071945554715, 0.258074970292751, 0.261747866479421, 0.260883655611969,
0.264124446364913, 0.267257210759425, 0.271146159662958, 0.273954844982176,
0.266933131684131, 0.269201685211192, 0.278383925677865, 0.278491952036297,
0.271146159662958, 0.272982607756293, 0.27503510856649, 0.282921032731987,
0.285297612617479, 0.285189586259047, 0.280436426488063, 0.287026034352382,
0.288538403370422, 0.286593928918656, 0.287998271578265, 0.285081559900616,
0.28464945446689, 0.279032083828454, 0.280112347412769, 0.278816031111591,
0.281624716430809, 0.278491952036297, 0.2802203737712, 0.279896294695906,
0.28097655828022, 0.276763530301394, 0.272550502322567, 0.276979583018256,
0.292643404990818, 0.28907853516258, 0.291239062331209, 0.293615642216701,
0.286918007993951, 0.287998271578265, 0.288322350653559, 0.280868531921789,
0.274386950415901, 0.271146159662958, 0.278275899319434, 0.277411688451982,
0.279140110186886, 0.28907853516258, 0.258939181160203, 0.256670627633142,
0.25278167872961, 0.255698390407259, 0.261423787404127, 0.260559576536675,
0.263692340931187, 0.260667602895106, 0.255158258615102, 0.257858917575888,
0.250081019768824, 0.245219833639408, 0.24684022901588, 0.244895754564114,
0.242195095603327, 0.246300097223723, 0.253861942313925, 0.253429836880199,
0.264988657232365, 0.260235497461381, 0.258831154801772, 0.258831154801772,
0.253213784163336, 0.249864967051961, 0.250081019768824, 0.245219833639408,
0.249756940693529, 0.245651939073134, 0.24835259803392, 0.24835259803392,
0.245867991789997, 0.248244571675489, 0.247056281732743, 0.249756940693529,
0.248676677109215, 0.251593388786864, 0.254186021389219, 0.250837204277844,
0.251593388786864, 0.248676677109215, 0.249540887976666, 0.251593388786864,
0.242627201037053, 0.242519174678622, 0.240250621151561, 0.240034568434698,
0.243059306470779, 0.244031543696662)
Hence, I used the code:
false.nearest(x, m=50, d=r, t=220, eps=1, rt=3)
Anyway, I obtained the error:
Error in false.nearest(x, m = 50, d = r, t = 220, eps = 1, rt = 3) :
cannot allocate memory block of size 67108864 Tb
I can't explain it, vector x has only 250 observations!
Looking at false.nearest source code in tseriesChaos package:
/*
False nearest neighbours algorithm.
in_series: input time series (scaled between 0 and 1)
in_length: time series length
in_m, in_d, in_t: embedding dimension, time delay, theiler window
in_eps: neighbourhood size
in_rt: escape factor
out: fraction of false nearests
out2: total number of nearests
*/
void falseNearest(double *in_series, int *in_length, int *in_m, int *in_d, int *in_t, double *in_eps, double *in_rt, double *out, int *out2) {
double eps, *series;
double dst;
double *dsts;
int *ids;
int m,d, t, length, blength;
int num, denum;
int i,j,md;
double rt;
int id;
boxSearch bs;
/*
BIND PARAMETERS
*/
m = *in_m;
d = *in_d;
t = *in_t;
rt = *in_rt;
eps=*in_eps;
series=in_series;
length=*in_length;
/**/
/*
INIT VARIABLES
*/
blength = length - m*d - t;
With your parameters set :
length. <- 250
m <- 50
d <- 3
t <- 220
(blength = length. - m*d - t)
[1] -120
blength is used as parameter to R_alloc and should be positive, otherwise sign bit will be interpreted as a huge integer, causing memory allocation error :
dsts = (double*) R_alloc(blength, sizeof(double));
In this case, max value of m to keep blength positive is m=10.
Constraints on parameters use are not documented in the package, nor does the package output an informative error message : reason for error is understood, but difficult to help further.

Why does this binary math fail when adding 00000001, but work correctly otherwise?

I've tried everything I can think of and cannot seem to get the below binary math logic to work. Not sure why this is failing but probably indicates my misunderstanding of binary math or C. The ultimate intent is to store large integers (unsigned long) directly to an 8-bit FRAM memory module as 4-byte words so that a micro-controller (Arduino) can recover the values after a power failure. Thus the unsigned long has to be assembled from its four byte words parts as it's pulled from memory, and the arithmetic of assembling these word bytes is not working correctly.
In the below snippet of code, the long value is defined as four bytes A, B, C, and D (simulating being pulled form four 8-bit memory blocks), which get translated to decimal notation to be used as an unsigned long in the arrangement DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAA. If A < 256 and B, C, D all == 0, the math works correctly. The math also works correctly for any values of B, C, and D if A == 0. But if B, C, or D > 0 and A == 1, the 1 value of A is not added during the arithmetic. A value of 2 works, but not a value of 1. Is there any reason for this? Or am I doing binary math wrong? Is this a known issue that needs a workaround?
// ---- FUNCTIONS
unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){
return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3)));
}
// ---- MAIN
void setup() {
Serial.begin(9600);
uint8_t addressAval = B00000001;
uint8_t addressBval = B00000001;
uint8_t addressCval = B00000001;
uint8_t addressDval = B00000001;
uint8_t addressValArray[4];
addressValArray[0] = addressAval;
addressValArray[1] = addressBval;
addressValArray[2] = addressCval;
addressValArray[3] = addressDval;
unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]);
// Print out resulting decimal value
Serial.println(decimalVal);
}
In the code above, the binary value should result as 00000001000000010000000100000001, AKA a decimal value of 16843009. But the code evaluates the decimal value to 16843008. Changing the value of addressAval to 00000000 also evaluates (correctly) to 16843008, and changing addressAval to 00000010 also correctly evaluates to 16843010.
I'm stumped.
The problem is that you're using pow(). This is causing everything to be calculated as a binary32, which doesn't have enough precision to hold 16843009.
>>> numpy.float32(16843009)
16843008.0
The fix is to use integers, specifically 65536 and 16777216UL.
Do not use pow() for this.
The usual way to do this is with the shift operator:
uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);

Twos complement on hex

Given:
int number = 0xFFFFFF87;
number = ~number + 1;
printf ("%x", number);
Why does 'number' become '79' instead of '87'? How can i make it '87' ?
It is 0x79 because ~0xFFFFFF87 = 0x00000078 and when 1 is added you get 0x00000079.
To get 0x87, you should use:
int number = 0xFFFFFF87 & 0xFF;
which will select only the least significant byte and mask the other bytes with zero.
~ negates every bit, not only the ones with hex group of 0xF.
To make it 0x87 just reverse the operation, i.e.:
int number = ~(0x87-1); // which is 0xFFFFFF79

ADC transfer function

I took over the project from someone who had gone a long time ago.
I am now looking at ADC modules, but I don't get what the codes mean by.
MCU: LM3S9B96
ADC: AD7609 ( 18bit/8 channel)
Instrumentation Amp : INA114
Process: Reading volts(0 ~ +10v) --> Amplifier(INA114) --> AD7609.
Here is codes for that:
After complete conversion of 8 channels which stored in data[9]
Convert data to micro volts??
//convert to microvolts and store the readings
// unsigned long temp[], data[]
temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003);
temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F);
temp[2] = ((data[2]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F);
temp[3] = ((data[3]<<8)& 0x3FF00) + ((data[4]>>8)& 0x00FF);
temp[4] = ((data[4]<<10)& 0x3FC00) + ((data[5]>>6)& 0x03FF);
temp[5] = ((data[5]<<12) & 0x3F000) + ((data[6]>>4)& 0x0FFF);
temp[6] = ((data[6]<<14)& 0x3FFF0) + ((data[7]>>2)& 0x3FFF);
temp[7] = ((data[7]<<16)& 0x3FFFC) + (data[8]& 0xFFFF);
I don't get what these codes are doing...? I know it shifts but how they become micro data format?
transfer function
//store the final value in the raw data array adstor[]
adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
131072 = 2^(18-1) but I don't know where other values come from
AD7609 datasheet says The FSR for the AD7609 is 40 V for the ±10 V range and 20 V for the ±5 V range, so I guessed he chose 20vdescribed in the above and it somehow turned to be 2000???
Does anyone have any clues??
Thanks
-------------------Updated question from here ---------------------
I don't get how 18bit concatenated value of data[0] + 16bit concatenated value of data[1] turn to be microvolt after ADC transfer function.
data[9]
+---+---+--- +---+---+---+---+---+---++---+---+---++---+---+---++
analog volts | 1.902v | 1.921v | 1.887v | 1.934v |
+-----------++-----------+------------+------------+------------+
digital value| 12,464 | 12,589 | 12,366 | 12,674 |
+---+---+---++---+---+---++---+---+---++---+---+---++---+---+---+
I just make an example from data[3:0]
1 resolution = 20v/2^17-1 = 152.59 uV/bit and 1.902v/152.59uv = 12,464
Now get thru concatenation:
temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003) = C2C0
temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F) = 312D3
temp[2] = ((data[1]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F) = 138C
Then put those into transfer function and get microvolts
adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
adstor[0]= 7,607,421 with temp[0] !=1.902*e6
adstor[1]= 30,735,321 with temp[1] != 1.921*e6
adstor[2]= 763,549 with temp[2]
As you notice, they are quite different from the analog value in table.
I don't understand why data need to bit-shifting and <<,>> and added up with two data[]??
Thanks,
Please note that the maximum 18-bit value is 2^18-1 = $3FFFF = 262143
For [2] it appears that s/he splits 18-bit word concatenated values into longs for easier manipulation by step [3].
[3]: Regarding adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
To convert from raw A/D reading to volts s/he multiplies with the expected volts and divides by the maximum possible A/D value (in this case, $3FFFF) so there seems to be an error in the code as s/he divides by 2^17-1 and not 2^18-1. Another possibility is s/he uses half the range of the A/D and compensates for that this way.
If you want 20V to become microvolts you need to multiply it by 1e6. But to avoid overflow of the long s/he splits the multiplication into two parts (*2000 and *10000). Because of the intermediate division the number gets small enough to be multiplied at the end by 10000 without overflowing at the expense of possibly losing some least significant bit(s) of the result.
P.S. (I use $ as equivalent to 0x due to many years of habit in certain assembly languages)

Convert little endian to big endian including 0 (zero)

Im trying to convert little endian to big endian and having trouble.
I have an array that has 2 bytes of unsigned char which is hex values.
and i would like to make it big endian by the zeros are gone and i cant get the values i want.
For example,
My goal is to get
array[0] = 0b
array[1] = 40
output = 0b40 so i can see this value as 2880 when %d
so i used
output = (array[1]>>4) | (array[0]<<4);
but in reality, i see
printf("output = %x04\n", output);
output = 00b4
I want that output to be 0b40 so i can get 2880 when i do
printf("output = %x\n", output);
output = 0b40
printf("output = %d\n", output);
output = 2880
thanks guys any help will be appreciated
You need to shift the bottom up by eight bits, not four, and not shift the top:
output = (array[0]<<8) | array[1];
See convert big endian to little endian in C for more discussion and code.

Resources