16 bit to 8 bit uint value conversion

hi,
i need to convert by u_16 bit value which is between 200-2000 mS into u_8 in order to store it in my 8-bit eeprom.

((u_8)val&0xff)|((u_8)val&0xff)>>8;

this is the formula that i am using but if the val = 2000 i am getting an output of 208 where, 0x07D0 (D0 = 208) similarly if i am changing val to 300 the output becomes 44 which is 0x012c (2c = 44). why is that so and how do i rectify it, is my formula correct????

i have tried several methods to do so such as:
//storing

EEPROM_write_eeprom_data = (((u_8)val&0xff));
EEPROM_write_eeprom_data = (((u_8)val&0xff)>>8);

note: i can write the values but when i read it, it resets to some diff value such as 300 = 44, however, as long as the value is between 0-255 (8-bit val) i can read exact same values. is it issue with the pointer or formula, the rest the code works perfectly fine i just have issues with saving my 16bit val onto an 8-bit eeprom.

it is from low to high 200-2000, where 200 is the default val

is val the 16 bit value ?

you want to shift before you mask... otherwise you loose the MSB

You are shifting after masking for the high order byte.

Shift first, then mask. You can lose the casts.

EEPROM_write_eeprom_data = val & 0xff;
EEPROM_write_eeprom_data = (val >> 8) & 0xff;

I can't test that, but it's def closer to right than

EEPROM_write_eeprom_data = ((            (u_8) val & 0xff                ));
EEPROM_write_eeprom_data = (             ((u_8) val & 0xff) >> 8      );

Also, parentheses can help, but too many is too many. There is no need to ((( ))) entire expressions on the right hand side.

HTH

a7

ok so, do you mean

((u_8)val>>8)|((u_8)val&0xff)

or could you please share the formula.

yes it is a 16bit register value

hi,
i tried using the tip as well but unfortunately,it did not help
could you please share the formula of shift first, then mask data

do you mean something like

((u_8)val >>8)&0xff) //shift first
((u_8)val)&0xff) //then mask

the masking etc is automatically done when you assign to a byte

uint16_t val16 = 0xBEEF;
uint8_t lsb = val16; // Least significant byte
uint8_t msb = val16 >> 8; // most significant byte

and if you want to recompose you can just do (bytes are promoted to int in formulas but it does not hurt to cast)

uint16_t val16 = (uint16_t (msb) << 8) | uint16_t (lsb);

you can try this

void setup() {
  Serial.begin(115200);
  uint16_t val16 = 0xBEEF;
  uint8_t lsb = val16; // Least significant byte
  uint8_t msb = val16 >> 8; // most significant byte
  Serial.print("16 bit value = 0x"); Serial.println(val16, HEX);
  Serial.print("Least Significant byte= 0x"); Serial.println(lsb, HEX);
  Serial.print("Most Significant byte= 0x"); Serial.println(msb, HEX);
  uint16_t val = (uint16_t (msb) << 8) | uint16_t (lsb);
  Serial.print("Recomposed 16 bit value = 0x"); Serial.println(val, HEX);
}

void loop() {}

2 Likes

I did!

EEPROM_write_eeprom_data = val & 0xff;
EEPROM_write_eeprom_data = (val >> 8) & 0xff;

As long as I am typing again, start using some spaces in your exprsssions. The compiler doesn't care butitisveryhsrdtoreadstuffwithoutslaces. Or see typos.

Putting it back together

    unsigned int whatever = high_order_byte;
    whatever = (whatever << 8) | low_order_byte;

a7

2000 is bigger as 1 byte can physically store, so you need to store whole value of 2 byte.
with

#include "EEPROM.h";

void setup(){
  uint16_t yourValue = 2000;
  EEPROM.put(0, yourValue );
  Serial.begin(115200);
}
void loop(){
  uint16_t getInt;
  EEPROM.get(0, getInt);
  Serial.println(getInt);
}
1 Like