Go Down

Topic: INT/DOUBLE value to HEX unsigned char array (Read 2506 times) previous topic - next topic

_beamster

Hi,

I'm sorry for my bad english.

For a project im using a Arduino UNO and a Seeduino CAN-BUS shield. Im using the Arduino Library of the shield to send CAN messages.
I want to create a function where I want to convert INT value (from sensorvalue) to a array of HEX values. A CAN message is 8 bytes long and is send like this with the library of the shield :

 unsigned char st[8] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    CAN.sendMsgBuf(0x301, 0, 8, st);

As example I used int cantxValue = 4112.

And then I tried some stuff like transforming cantxValue to a HEX string ("1010") and then filled it up with zeros until it had length of 16 (1 byte is 2 digits in HEX --> 16 digits for 8 bytes).

But now I want to find how cut this string and put them in an unsigned char array (canMsg) of length 8 with a prefix of "0x" for each part of that string.


Maybe I am overthinking the problem and there is a faster/easier way. Can someone help me? I getting crazy about this problem. Im not really a good programmer but I am willing to learn.

septillion

#1
Jan 25, 2017, 09:19 pm Last Edit: Jan 25, 2017, 09:20 pm by septillion
Uhm, do you want to transfer it as ASCII aka '4', '1', '1', '2' or, what sounds more logical to me like 0x10, 0x10.

If the later, bitshift :)

Code: [Select]

unsigned int value = 4113;
byte blocks[] {value >> 8, value};

Probably even no need to put it into an array/variable first (depending on the library method).
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

_beamster

Thank you for your reply! Yes, I want to sent the message with CAN in the 0x format.

And i just have to put the variable ''blocks'' in the send function of the CAN? Or do i have to transform it futher? I really dont have any insight of transforming and combining messages. I dont really understand it all the time.


Because I really want a standard CAN frame of 8 bytes. So when I have 0x10 and 0x10, the rest of my array has to be 0x00. Just want to have a function that transform any INT variable (small or large) into a CAN message of 8 bytes.

With kind regards,

_beamster

holmes4

First - you are NOT repeat NOT using string. The first clue is the "" is not being used and second the char array is 8 long and has 8 values. If it where a string it would need to be 9 in length.

Second 0x0a is just the same as writing 10 (ten) it is just a different notation.

int a =10; and
int a = 0x0a;
both give a the same value.

byte and char are often used to mean the same thing.

ASCII has nothing to do with this.

Mark



_beamster

Is there anayone who can help me with designing a function when you have an integer (max 65536) and convert in to HEX values and put them in a unsigned char array of 8 long like this :  unsigned char st[8] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

It driving me crazy for a couple of days now. Solution of septillion (see above) is in the right direction but i dont know how to proceed with this. My coding skills are not that great.

septillion

#5
Jan 26, 2017, 11:21 am Last Edit: Jan 26, 2017, 11:26 am by septillion
I damn showed you in reply #1! And holmes4 added to that that you have to stop thinking of hex as something different. It's just a notation, what's saved is always a binairy number but you can use all sorts of representations for it. Same like language, you can write down a 1 but you can all it one, eins, uno, un, één. All the same, just different representation.

Solution of septillion (see above) is in the right direction but i dont know how to proceed with this.
Then show us what you tried :) Because in this case, the answer is as good as the question. You only ask a question in a direction so the answer is in a direction as well.

an integer (max 65536)
That's a unsigned int (aka 2 bytes on a Arduino Uno-ish) which is part of the integer family.

But okay, but how should that number be broken up? Where in the 8 bytes should it end up? And MSB of LSB first. Aka, which one of you want to send 12345:
a) {0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
b) {0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
c} {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39}
d) {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30}
or maybe even something as weird as
e) {0x00, 0x00, 0x00, x030, 0x39, 0x00, 0x00, 0x00}

But it might be my lack of knowledge about the protocols on the CAN-bus, but why do you want to send 8 bytes anyway?

Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

_beamster

#6
Jan 30, 2017, 11:30 am Last Edit: Jan 30, 2017, 11:56 am by _beamster
@septillion, Im using now your bitshift code you posted. So when I send 12345, It wil send 0x30, 0x39 to my other device(display). But there I get 14640 so in HEX that is 0x39, 0x30. So I need to send the hex values like you said in option B. But I didnt found how to switch these values. I really appreciate the help I get from you. This is my example code :



//send data:  id = 0x00, standard frame, data len = 8, stmp: data buf
    value = 12345;
    Serial.println(value);
   
    thisString = String(value, HEX);     //INT = 4112 --> HEX = 1010
    Serial.println(thisString);
    Serial.println("");

   
     byte blocks[] {value >> 8, value};    //max INT 65535!
    //Serial.println(blocks, HEX);
    CAN.sendMsgBuf(0x401, 0, 2, blocks); //0 = STANDARD FRAME (11 bit ID) , 1 = EXTENDED FRAME (29 bit ID)
    delay(1000);                       // send data each 2000ms
   
    Serial.println("Data send");


For your question about CAN, you dont need to send the whole 8 bytes ( I thought it make my code standard for messages for 8 bytes). But now im just testing with 2 bytes, like I said in my example of an integer of 4112 (HEX = 1010)

septillion

quote tags != code tags. Can you please edit you post? Will make it a lot more readable for the rest.

But what about just switching the order of the two variables?
Code: [Select]

 byte blocks[] {value, value >> 8};    //max INT 65535!
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

sterretje

Maybe something simple like copying a variable with memcpy.

Code: [Select]

void loop()
{
  // buffer
  char canBuffer[8];
  // fill buffer with zeroes
  memset(canBuffer, 0, sizeof(canBuffer));

  // two variables to copy into buffer
  int i = 345;
  int j = 512;

  // store i in locations 0 and 1 in buffer 
  memcpy(&canBuffer[0], &i, sizeof(i));
  // store j in locations 2 and 3 in buffer 
  memcpy(&canBuffer[2], &j, sizeof(j));
}
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

septillion

But keep in mind memcopy relies om the fact that AVR is little endian. If you don't find that a problem you can even skip that all together.

Code: [Select]

CAN.sendMsgBuf(0x401, 0, 2, (byte*)&value);
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Go Up