Unsigned char convert to int

Dear all,

I’m new on this forum, and I have a (maybe) simple question.
I have an UDP message, what I write to an unsigned char. I want to use the last 4 byte HEX as a decimal number. How can I do this?

Here is my code:

#include <Ethernet2.h>
#include <EthernetUdp2.h>


#define UDP_TX_PACKET_MAX_SIZE 240

unsigned char UDP[40];
unsigned char UDPt[5]; // a temporary variable to the HEX numbers
int UDPc; //to the number

IPAddress kip(2, 0, 0, 188);
unsigned int kp = 8000;

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(2,0,0,90);
unsigned int localPort = 9000;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

int m=40;

EthernetUDP Udp;

void setup() {
 Ethernet.begin(mac, ip);
 Udp.begin(localPort);
 Serial.begin(9600);
}

void loop() {
 

 int packetSize = Udp.parsePacket();
 if (packetSize)
 {
   Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

   for (int s=0; s!=m; s++) {UDP[s]=packetBuffer[s];}
   for (int s=0; s!=packetSize; s++) {Serial.print(UDP[s], HEX); Serial.print(" ");} //it's good
   Serial.println();
   UDPt[0] = UDP[packetSize-4];
   UDPt[1] = UDP[packetSize-3];
   UDPt[2] = UDP[packetSize-2];
   UDPt[3] = UDP[packetSize-1];
   UDPt[4] = '\0';
   Serial.print("UDPt: "); for (int s=0; s!=4; s++) {Serial.print(UDPt[s], HEX);} //it's also good
   Serial.println();
   sscanf(UDPt, "%f", &UDPc);
   Serial.print("UDPc: "); Serial.print(UDPc);  // It's 0
   Serial.println();
   for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;
 }
}

The error message:
warning: invalid conversion from ‘unsigned char*’ to ‘const char*’ [-fpermissive]
sscanf(UDPt, “%f”, &UDPc);
^

On the serial monitor:
2F 6D 64 2F 73 65 6C 65 63 74 65 64 2F 70 6C 61 79 73 70 65 65 64 2F 64 6D 78 0 0 2C 66 0 0 42 FA 0 0
UDPt: 42FA00
UDPc: 0

The number, what I should see in this case is 125 (0x42FA0000)

And also my problem is the 0 at the end. I have to “convert” the original 0 to 00.

I hope it’s clear :slight_smile:

Many thanks,
Zoltan

Why did you strike out half of your code? You didn't? Maybe the forum software did it because you did not put the code in code tags like the "how to use the forum-please read" stickies request. Please take the time to read the stickies and fix your post.

The Arduino uses signed chars. Why is a mystery, but it is a reality. You need to copy your unsigned chars to a signed array. Or, use a cast.

fraktal:
I'm new on this forum, and I have a (maybe) simple question.
I have an UDP message, what I write to an unsigned char. I want to use the last 4 byte HEX as a decimal number. How can I do this?

Well, there's three or more possible things you might mean here.

You might mean that these last four bytes have ASCII values that should be read as if it were a four-digit decimal number.

You might mean that the last four bytes are binary coded decimal, that the value 0x12345678 sohuld be read as a decimal 12345678, not a decimal 305419896.

Or you might mean that these last four bytes are a binary integer (little endian or big endian) and you would like to print out the value of that integer in decimal.

Which is it? Or is it some weird permutation I haven't thought of?

fraktal:
The error message:
warning: invalid conversion from 'unsigned char*' to 'const char*' [-fpermissive]
sscanf(UDPt, "%f", &UDPc);

The function is defined: int sscanf(const char *str, const char *format, ...)
and you have defined: unsigned char UDPt[5];
so it gives you the warning. You could cast it to (const char *) to stop the warning

However, the contents of UDPt are not a string, it is an array of unsigned values, the last 2 of which are zero.

So your format string "%f" is not going to find a character string representing a float and (even if it did) you have UDPc which is defined as int.

The number, what I should see in this case is 125 (0x42FA0000)

So, you have the 4 8-bit values 0x42, 0xFA, 0x00, 0x00 which you want to convert into a number - how do you think you are going to get 125 from that ?

What do you think those 4 bytes represent ?

Yours,
TonyWilk

Thanks all of you guys to read my post, and answered!

TonyWilk:
So, you have the 4 8-bit values 0x42, 0xFA, 0x00, 0x00 which you want to convert into a number - how do you think you are going to get 125 from that ?

Yes, actually that's what I want: 42, FA, 00, 00 this 4 digit is my last 4 digit in the UDP message, and I saved it to my UDP variable, as a char array (I have to use the other informations to other things). If I can use this 4 digit as 1 number (like 0x42fa0000) this will be a floting point HEX value: Floating Point to Hex Converter
This is a value of a fader in another program. But now, this is 4 individual char in my UDP array...
I tried, and if I used a simple char UDP variable, the FA value stored as FFFFFFA.

PaulMurrayCbr:
Or you might mean that these last four bytes are a binary integer (little endian or big endian) and you would like to print out the value of that integer in decimal.

Actually I have some information from the other software's programmer, but for me this is not too relevant information, because I'm not a programmer... :frowning: :
"In the raw packets, the actual value is the last four bytes (32 bits) of the packet. As per the OSC spec, it’s a 32-bit big-endian floating point number."

So I can catch this 4 digit, but I can't do anything with this.

I hope it's an important information for you :confused:

fraktal:
"In the raw packets, the actual value is the last four bytes (32 bits) of the packet. As per the OSC spec, it’s a 32-bit big-endian floating point number."

Ah... so:

 UDPt[3] = UDP[packetSize-4];   // swop order, 32-bit big-endian float
 UDPt[2] = UDP[packetSize-3];
 UDPt[1] = UDP[packetSize-2];
 UDPt[0] = UDP[packetSize-1];

 float *floatPtr= (float *)UDPt;     // point to the buffer as a float
 
 float number= *floatPtr;

Note that I've changed the indexing of UDPt !!

Yours,
TonyWilk

Dear TonyWilk,

It's working well, thank you for your time, and help! :slight_smile:

Have a nice day!

Zoltan

Dear TonyWilk,

Could you help me again a little bit?
I have to send back a value on this way, so I want to convert back an int to the 32-bit big-endian floating point number.

Many thanks,
Zoltan

fraktal:
I have to send back a value on this way, so I want to convert back an int to the 32-bit big-endian floating point number.

You can use the pointer to read or write to the memory you pointed at.

 // UDPt is an array of at least 4 bytes
 //
 float *floatPtr= (float *)UDPt; // point to the buffer as a float
 
 float number= *floatPtr;        // get a 4-byte floating point number from whatever floatPtr is pointing to

 *floatPtr = number;             // save number as a 4-byte floating point to whatever floatPtr is pointing to

So, what you want to do is:

 *floatPtr = (float)myInteger;   // convert int to float and save in UDPt buffer

Yours,
TonyWilk