How use a hexa as a mask

Dear All,

I am trying to increment a hexa

// THIS WILL INCREMENT THE MASK
#define EPROM_INC 0x0100

#define EPROM_LAR 0x0008
byte result;

// THIS IS A MASK
byte mask = 0x0000;

mask = mask+EPROM_INC; // MASK SHOULD BE 0x0100

result = mask+EPROM_LAR; // RESULT SHOULD 0x0108 but apparently the operation does not works as I expected

Following my example, maks should be egal to 0x0100?

and "result" should be 0x0108

How can I use a mask to change the value of a hexa? How could you correct me?

many thnak

Cheers

Each hexadecimal digit represents four binary bits.

A byte (8 bits) can contain two hexadecimal digits.

You appear to be trying to store four hexadecimal digits in a byte. That will not work.

You should make both ‘mask’ and ‘result’ at least 16 bits. I recommend ‘unsigned int’.

Hello

Thank for your answer. It's look really better and it helps I changed like this

// THIS WILL INCREMENT THE MASK
#define EPROM_INC 0x0100

#define EPROM_LAT 0x0008

unsigned int result;

// THIS IS A MASK
unsigned int mask = 0x0000;

mask = mask+EPROM_INC;

result = mask+EPROM_LAT;

We are agree, that now result will be 0x0108?

I will do better test tomorrow that I can not do right now.

0x0008 represente a position in the EEPROM to record a value. This value change and it's important that the new value is recorded at 0x0108. And the next is recorded at 0x0208, and the next is recorded at 0x0308 etc....

(there will have a loop for the that)

Thank a lot

pierrot10:

mask = mask+EPROM_INC;

result = mask+EPROM_LAT;

Typically, you want to use binary logical operations when using masks. Using addition will surprise you if the result is already set. The logical operations are:

// Set mask EPROM_INC in state
state |= EPROM_INC;

// clear EPROM_INC in state
state &= ~EPROM_INC;

// do action if mask is set
if ((state & EPROM_INC) != 0)  { ... }

// do action if mask is not set
if ((state & EPROM_INC) == 0) { ... }

// Note, you can do multiple tests
if ((state & EPROM_LAT) == 0 && (state & EPROM_INC) == 0) { ... }

// could also be written (and it is more efficient at the instruction level)
if ((state & (EPROM_LAT & EPROM_INC)) == 0) { ... }

// Similarly
if ((state & EPROM_LAT) != 0 || (state & EPROM_INC) != 0) { ... }

// could be written
if ((state & (EPROM_LAT | EPROM_INC)) != 0) { ... }

// set each bit in state to 1 if either mask1 or mask2 bit is set
state = mask1 | mask2;

// set each bit in state to 1 only if both mask1 and mask2 bits are set
state = mask1 & mask2;

// set each bit in state to 1 if the bit in mask1 is different than mask2
state = mask1 ^ mask2;

// invert the sense of each bit
state = ~mask1;

// Set a variable bit mask (if value == 0, then 0x0001 is set, if value == 1, then 0x0002 is set, if value == 2 then 0x0004 is set)
state |= (1U << value);

But... you are not trying to use it as a mask. You are using it as an increment. you can get the same result by using something like...

eepromaddr = 0x0108;

then later

result = eepromaddr + 0x100;

Hello, thank for your answer and example.

May be I used a bad word with mask. I called "mask" because is going to be "applay" to a value, increment the 2nd digit. But it true, it's more an incrementation.

Dear Michael,

Your example is interresting but I do not understand a part.

// Set mask EPROM_INC in state
state |= EPROM_INC;

I miss skills, if EPROM_INC is 0x0100, state will be 1 or 0x0100 as well? |= is lake to copy a value to another variable? I0ve never see |

// clear EPROM_INC in state
state &= ~EPROM_INC;

I also never see this &= ~. And what do you mean by clearing. EPROM_INC must keep its value as it was a const

// do action if mask is set
if ((state & EPROM_INC) != 0)  { ... }

In Above condition, EPROM_INC will never be egal to 0, it will always be 0x0100, or may 0x0200...

// do action if mask is not set
if ((state & EPROM_INC) == 0) { ... }

idem

my goal is record some set

at 0x00ii at the first loop. at 0x01ii at the 2nd loop at 0x02ii at the third loop at 0x03ii at the 4th loop

etc

"ii" being 08,18,28,38,48 depending of the subjetc (LAT, LON, ALT etc

http://arduino.cc/en/Reference/HomePage

Check out the bit that says bitwise operators. Second from the bottom on the left hand column.

[quote author=pierrot10 link=topic=188968.msg1399181#msg1399181 date=1379707315]
Dear Michael,

Your example is interresting but I do not understand a part.
[code]
// Set mask EPROM_INC in state
state |= EPROM_INC;

I miss skills, if EPROM_INC is 0x0100, state will be 1 or 0x0100 as well? |= is lake to copy a value to another variable? I0ve never see | [/quote]

In C/C++, most of the operators can be written with an equal sign immediately after the operator. What this means is the value of the target is used as the left side of the arithmetic operation. So for example:

// You can write:
a += 4;

// The compiler treats this as:
a = a + 4;

Note that any side effects on the value on the left (called lvalue) only happen once, so for example:

a[i++] += b;

// Is equivalent to:
tmp_i = i;
i++;
a[tmp_i] = a[tmp_i] + b;

I.e. i in this example, the variable i is only incremented once, though logically the left side is referenced twice (to read the existing value, and replace it with a new value),

So, getting back to the OR operation. Any bits in the value in the right side are set in the left, but if the right side bit is 0, it does not change the left side. The result table for OR is:

0 == 0 | 0 1 == 0 | 1 1 == 1 | 0 1 == 1 | 1

pierrot10: // clear EPROM_INC in state state &= ~EPROM_INC;

I also never see this &= ~. And what do you mean by clearing. EPROM_INC must keep its value as it was a const [

Again, a &= b is the same as a = (a & b). In this case, the values of the and are:

0 == 0 & 0
0 == 0 & 1
0 == 1 & 0
1 == 1 & 1

The ~ operator inverts each bit:

1 == ~ 0
0 == ~ 1

Finally, ^ is exclusive or. It sets the bit only if the two bits differ:

0 == 0 ^ 0
1 == 0 ^ 1
1 == 1 ^ 0
0 == 1 ^ 1

So what do people use these for? As I said, you typically use these for flags. Lets say, you want to keep track of an object. The object has 3 different attributes. It can be big or small. It can be black or white. Finally it can be odd or even.

So, you could have a structure to describe the object:

struct {
    unsigned int big : 1;
    unsigned int black : 1;
    unsigned int odd : 1;
} obj;

// ...

if (object_is_big) {
    obj.big = 1;
}

if (object_is_white) {
    obj.white = 0;
}

if (object_is_seen) {
    if (obj.odd) {
        obj.odd = 0;
    } else {
        obj.odd = 1;
    }
}

So, in this silly code, you could rewrite it using integers and masks.

unsigned int obj;

#define OBJ_BIG       0x1
#define OBJ_BLACK 0x2
#define OBJ_ODD     0x4

// ...

if (object_is_big) {
    obj |= OBJ_BIG;          // mark that the object is big
}

if (object_is_white) {
    obj &= ~OBJ_BLACK;   // clear the black mask
}

if (object_is_seen) {
    obj ^= OBJ_ODD; 
}

If the machine does not have instructions to extract and set bitfields, the compiler will use the logical and shift operations to isolate the value for the bit field.[/code]

Dear Michael,

I am going to read carefully to your post, but before all, I would like to thank you for time you took for explication and example

It very nice to "meet" people who take this time

Cheers

pierrot10: Dear Michael,

I am going to read carefully to your post, but before all, I would like to thank you for time you took for explication and example

It very nice to "meet" people who take this time

Cheers

You are welcome.

Dear Michael

You structure example was very clear and it's hihlight me for a different question I has previously.

Thank

However, even if I understood you, regarding

bool a=0;
bool b=1
a|=b
a = a|b // Equivalent
a will dsiplay 1

But I am still confused about. I am going to ask my question and comment in CAPITAL

unsigned int obj;

#define OBJ_BIG       0x1 // THIS EGAL TO 1
#define OBJ_BLACK 0x2 // THIS EGAL TO 2
#define OBJ_ODD     0x4 // THIS IS EGAL TO 4

// ...

if (object_is_big) {
    obj |= OBJ_BIG;          // mark that the object is big
  // THIS IS THE EQUIVALENT OF obj = obj | OBJ_BIG, OR obj = 0|1 (0 because it's not defined yet, and 1 because 0x1)
  // SO AT THE END, OBJ WILL HAVE THE VALUE OF 1
  // CAN WE NOT SIMPLY WRITE obj = true;?
}

if (object_is_white) {
    obj &= ~OBJ_BLACK;   // clear the black mask
   // HERE OBJ_BLACK HAVE THE VALUE OF 2, BUT IT'S CLEARED TO 0 BECAUSE OF ~
  // THEN obj IS EQUAL TO 0 BECAUSE WE CAN WRITE THE EQUIVALENCE OF obj = obj&OBJ_BLACK OR obj = 0&0
  // BUT CAN WE NOT WRITE SIMPLY obj = false
}

if (object_is_seen) {
    obj ^= OBJ_ODD; 
}

But after all of you nice explication, does it really ask to my need? Or may be I have to be sorry, if I have not undertood a part!

At each loop (loop()), the function GetGPS is call and I wish to store the position in a postion of my EEPROM.

So at position

0x0008 => course 0x0018 => longitude 0x0028 => latitude 0x0038 => altitude 0x0048 => time 0x0058 => speed 0x0068 => stat

and the 2nd position of hexa digit must be incremented, each time GetGPS() is called. It's the reason why I am trying to use a "mask" of 0x0100

0x0108 => course 0x0118 => longitude 0x0128 => latitude 0x0138 => altitude 0x0148 => time 0x0158 => speed 0x0168 => stat

0x0208 => course 0x0218 => longitude 0x0228 => latitude 0x0238 => altitude 0x0248 => time 0x0258 => speed 0x0268 => stat

For example

#define EPROM_COU 0x0008
#define EPROM_INC 0x0100 // Incrementation
const int mask = 0x0000;
void GetGPS(){
[...]
writeEEPROM(rom,mask+EPROM_COU,course_id); // here, the second parameter should be equal to 0x00ii, then 0x01ii, then 0x03ii, then 0x04ii, etc
mask = mask+EPROM_INC; // Here mask should 0x0100, then 0x0200, then 0x0300, etc
[...]
}

But in the same time, I will think how to use structure, but I think, at the end, I have to answer to the same problem, how to increment the 2nd digit of the hexa for the second loop... :)