uint128_t to 4*32 bits or 2*64 bits

Hi everybody !

I came here because I need some help.
My objectiv is the following: I want to put a uint128_t variable into four uint32_t variables (or in two uint64_t variables). I need to do that because I can't use "print" to display the value of my 128 bits variable...
If anyone has an idea, I'm here to read every solutions.

PS: I'm using a Arduino board and the 1.8.7 IDE version.

Regards,

Alexis

If you have wanted to mean 128-bit data (16-byte) by this (your keyword) uint128_t, then this kind of data type is not supported by Arduino UNO. You may use array of 4-element of type uint32_t which will allow you to print your data/result in the Serial Monitor.

void setup()
{
  Serial.begin(9600);
  uint32_t myData[4] = {0x12345678, 0x87654321, 0xABCDEF12, 0x12ABCDEF};
  for(int i=0; i<4; i++)
  {
    Serial.print(myData[i], HEX);
    Serial.print(' ');
  }
}

void loop() 
{
  
}

Hi GolamMostafa,

Thanks for your answer !
That what I want to say :slight_smile:
I've read that uint128_t type isn't supported by Arduino UNO and that's why I'm looking for help.
Your solution looks great, I'm going to test it and give you a feedback. BUT, my data is in the uint128_t variable and I don't want to fix uint32_t values. Because they are part of uint128_t. So, I think your solution has a part of what I'm looking for but not completely. Do you have any other idea ?
However, thanks for your fast answer !

Alexis

There are no better ideas. The uint128_t does not exist, that's it, period.
The uint64_t does exist for the compiler, but not the Arduino functions.
You can use an array of four uint32_t, or sixteen uint8_t, or write them in a text array, either as binary or readable text.
To print them, you can write your own function that scans through all the nibbles.

Where do those 128 bits come from ? in what format ?
You don't have a uint128_t variable to start with :smiley_cat:

Hi Koepel,

Thanks for your answer !
This uint128_t value is an application Key (in LoRaWAN), so that's a 128-bits value.
However, the value comes from a function describe as below:

armError_t LwIds(uint32_t* devAddr,
									uint64_t* devEui,
									uint64_t* appEui,
									uint128_t* appKey,
									uint128_t* nwkSKey,
									uint128_t* appSKey);

That's in the .h file and the code of the function is:

armError_t Arm::LwIds(uint32_t* devAddr,
									uint64_t* devEui,
									uint64_t* appEui,
									uint128_t* appKey,
									uint128_t* nwkSKey,
									uint128_t* appSKey)
{
	#ifdef ARM_WITH_N8_LW
	_ARM_IMP1(N8_LW)
	{
		armError_t err = ARM_ERR_NONE;
		int i;
		
		//Go to AT commend
		err = this->_GoAt();
		if(err != ARM_ERR_NONE)
			return err;
			
		if(devAddr)
		{
			
			for(i=0; i<_ARM_N8LW_SIZE_DEVADDR; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_DEVADDR, ((uint8_t*)devAddr)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}
		
		if(devEui)
		{
           	
			for(i=0; i<_ARM_N8LW_SIZE_DEVEUI; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_DEVEUI, ((uint8_t*)devEui)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}
		
		if(appEui)
		{
           	
			for(i=0; i<_ARM_N8LW_SIZE_APPEUI; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_APPEUI, ((uint8_t*)appEui)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}
		
		if(appKey)
		{
           	
			for(i=0; i<_ARM_N8LW_SIZE_APPKEY; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_APPKEY, ((uint8_t*)appKey)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}
			
		if(nwkSKey)
		{
           	
			for(i=0; i<_ARM_N8LW_SIZE_NWKSKEY; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_NWKSKEY, ((uint8_t*)nwkSKey)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}

		if(appSKey)
		{
           	
			for(i=0; i<_ARM_N8LW_SIZE_APPSKEY; i++)
			{
				err = this->_GetReg('O', i+_ARM_N8LW_REGO_APPSKEY, ((uint8_t*)appSKey)+i);
				if(err != ARM_ERR_NONE)
					return err;
			}
		}
		
		//Quit AT commend
		return this->_BackAt();
	}
	#endif
	
	return ARM_ERR_NO_SUPPORTED;
}

There is many variables which are created by the creator of the file...
The shield I'm using is a ACW_DUINO from ATIM and is compatible with an Arduino.
I want the value because it's important in LoRa communication.
Maybe my problem hasn't solution x)
But I tried to get some help by the way :stuck_out_tongue:

It's a pointer - just cast it to something more sensible.

It is a pointer to 16 bytes, so all you need is to find or make a function that prints 16 bytes. Do you want to print them as hexadecimal or decimal or binary ?

Hi,

Thanks Koepel and AWOL for your answers.

Koepel:
It is a pointer to 16 bytes, so all you need is to find or make a function that prints 16 bytes. Do you want to print them as hexadecimal or decimal or binary ?

Hexadecimal should be better, but decimal is good too.

I read that some versions of the gcc compiler have a __uint128_t type, but Arduino 1.8.9 for the Arduino Uno does not support that.

Is it about this function: armapi/arm.c at master · atim-radiocommunications/armapi · GitHub ?

They have defined their own uint128_t with this: armapi/arm.h at master · atim-radiocommunications/armapi · GitHub

typedef struct uint128_s
{
	uint64_t lsb;
	uint64_t msb;
}uint128_t;

To print them as 16 bytes, we need some luck that the Arduino Uno will have the same byte order with the uint64_t and the struct definition. It seems that we are lucky, because the next example works for a Arduino Uno:

typedef struct uint128_s
{
  uint64_t lsb;
  uint64_t msb;
}uint128_t;

uint128_t x = { 0x0123456780123456, 0xAA55CC6600FF11EE };  // lsb, msb

void setup()
{
  Serial.begin(9600);
  printAs16Bytes( &x);  // use a pointer to the uint128_t
}

void loop()
{
}

void printAs16Bytes( uint128_t *p)
{
  byte * pByte = (byte *) p;

  for( int i=15; i>=0; i--)
  {
    byte b = pByte[i];
    if( b < 0x10)
      Serial.print( "0");
    Serial.print( b, HEX);
  }
}

It prints: "AA55CC6600FF11EE0123456780123456".