CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Load Int16 with hex value

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

Load Int16 with hex value
PostPosted: Fri Nov 05, 2021 6:38 pm     Reply with quote

I am here again.
I need to load an int16 with a value received from UART.
example;
The value 1358 is sent by the UART as 054E (Buf[0]=05,Buf[1]=4E), so I need to load the variable x(int16) with the value 1358(054E).
what would be the most effective means?
make16 works directly(x = make16(Buf[0],Buf[1]); ) ?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Fri Nov 05, 2021 7:16 pm     Reply with quote

make16() for sure
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Fri Nov 05, 2021 7:24 pm     Reply with quote

jeremiah wrote:
make16() for sure


Is it not necessary to convert?
Can i directly use the 05 and 4E values?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Fri Nov 05, 2021 7:31 pm     Reply with quote

vtrx wrote:
jeremiah wrote:
make16() for sure


Is it not necessary to convert?
Can i directly use the 05 and 4E values?


I may not understand: convert to what? your using integer types for your array and integer types for your resultant value. Integer types have implicit conversions. You generally only need to explicitly convert when trying to force math results because math doesn't automatically promote.
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Sat Nov 06, 2021 4:23 am     Reply with quote

I was thinking...
The PC sends 054E as ascii '0','5','4','E' because it uses serial communication and the PC routine only sends Ascii.
I don't need to manipulate this?
In fact, the application that sends data over the serial is for Android.
I'm saying this because I'm trying to port the routine I use with USB and Android has to be serial.
The USB routine is pretty easy because it works with bytes directly, I send Buf[0] with 0x05 and Buf[1] with 0x4E, only that, this way I send what I need which is the size of the data to receive.
I'm not able to send this way using serial.
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Nov 06, 2021 4:58 am     Reply with quote

this...
Quote:
The PC sends 054E as ascii '0','5','4','E' because it uses serial communication and the PC routine only sends Ascii.
is a LOT different than your original question !


It sounds like your PC program is sending data as 4 ASCII bytes even though a PC UART can send a byte of data several ways (binary, octal, hex, integer, etc.) to represent the data.

If you're really getting 2 bytes as 05, 4e then the make16() method will work and is the fastest.
If you're getting 4 ASCII bytes, then yes, you'll need to 'convert' the 4 ASCII bytes into 4 bytes and place into the correct locations in the unsigned int16 word. Pretty sure you just take the ASCII byte, subtract 30 decimal, and store the result. But, it's early here, coffee's not made and the cat wants his breakfast....
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Sat Nov 06, 2021 10:38 am     Reply with quote

vtrx wrote:
I was thinking...
The PC sends 054E as ascii '0','5','4','E' because it uses serial communication and the PC routine only sends Ascii.
I don't need to manipulate this?
In fact, the application that sends data over the serial is for Android.
I'm saying this because I'm trying to port the routine I use with USB and Android has to be serial.
The USB routine is pretty easy because it works with bytes directly, I send Buf[0] with 0x05 and Buf[1] with 0x4E, only that, this way I send what I need which is the size of the data to receive.
I'm not able to send this way using serial.


Okie dokie, in your initial post you said it sent:
Quote:

Buf[0]=05,Buf[1]=4E


which is raw integers, not ASCII. If it were ASCII, your buffer would look like:
Quote:

Buff[0] = 0x30
Buff[1] = 0x35
Buff[2] = 0x34
Buff[3] = 0x45


If it looks like that you need to convert either by appending a null character to the buffer (you need space on your buffer for this) and using the atoi() function (google can help here) or making your own function that does the conversion. You have to ensure to handle checking if the ASCII value is in range of a number, capital letter, or lowercase letter and handle each case:

Code:

unsigned int8 from_ascii(char value){
   if(value >= '0' && value <= '9'){
      return value - '0';
   }else if(value >= 'a' && value <= 'f'){
      return value - 'a'+10;
   }else if(value >= 'A' && value <= 'F'){
      return value - 'A'+10;
   }else{
      return -1;  //need some sort of error value
   }
}


Then you just can call that and make sure the value isn't -1 before using the result. NOTE that I just wrote that on the fly without checking it would compile. It's just notional for an example. I'm sure there are other examples out there on google on how to convert ASCII to hex numbers
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Sat Nov 06, 2021 7:51 pm     Reply with quote

I changed the code.

Code:

char    digit[6];
...
       digit[0]=Rs_buf[1];//0
       digit[1]=Rs_buf[2];//0
       digit[2]=Rs_buf[3];//3
       digit[3]=Rs_buf[4];//2
       digit[4]=Rs_buf[5];//3
       digit[5]=Rs_buf[6];//2
...
messagelength = atoi(digit);//messagelength int16


The Android program separates an int16(Word) into 2 bytes that are sent over the serial in decimal(ascii) format.
Ex: 1000 = 0,0,3,2,3,2
ATOI formats it right this way?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Sat Nov 06, 2021 9:01 pm     Reply with quote

you need to append a null character at the end:
Code:

char    digit[7];   //  <======== See here at size
...
       digit[0]=Rs_buf[1];//0
       digit[1]=Rs_buf[2];//0
       digit[2]=Rs_buf[3];//3
       digit[3]=Rs_buf[4];//2
       digit[4]=Rs_buf[5];//3
       digit[5]=Rs_buf[6];//2

       digit[6]= '\0';  // <============  See here
...
messagelength = atoi(digit);//messagelength int16
mdemuth



Joined: 16 Apr 2007
Posts: 71
Location: Stuttgart, Germany

View user's profile Send private message Visit poster's website

PostPosted: Tue Nov 09, 2021 9:13 am     Reply with quote

I think you are looking for something returns an int16 which is built from 4 received characters.
You can use:
Code:

int8 ASCI_TO_HEX(int8 high_nibble, int8 low_nibble)
   {
   int8 value=0;
   int8 value_ln=0;
   int8 value_hn=0;
   if ((low_nibble >= 0x30) && (low_nibble <= 0x39)) value_ln= low_nibble - 0x30; // 0..9
   if ((low_nibble >= 0x41) && (low_nibble <= 0x46)) value_ln= low_nibble - 55; // A..F
   if ((high_nibble >= 0x30) && (high_nibble <= 0x39)) value_hn= high_nibble - 0x30; // 0..9
   if ((high_nibble >= 0x41) && (high_nibble <= 0x46)) value_hn= high_nibble - 55; // A..F
   value = value_hn*16;
   value=value+value_ln;
   return(value);
   }

Then use the function above:
Code:

int16 ValueReceived = make16 (ASCI_TO_HEX(Rs_buf[1], Rs_buf[2]),  ASCI_TO_HEX(Rs_buf[3], Rs_buf[4]))

In order to have a save communication you add control characters such as: STX, ETX, CR or any other character then 0..9, A..F
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 5:12 pm     Reply with quote

The 'solution' I'm using is:
I formatted the 16-bit value into six ASCII characters to keep the same space, for example:
1000-> 001000 and i used ATOI.
Code:
 ///Android->send 1000(ASCII).
       digit[0]=Rs_buf[1];//0
       digit[1]=Rs_buf[2];//0
       digit[2]=Rs_buf[3];//1
       digit[3]=Rs_buf[4];//0
       digit[4]=Rs_buf[5];//0
       digit[5]=Rs_buf[6];//0
       digit[6]='\0';
       messagelength = atoi(digit);
mdemuth



Joined: 16 Apr 2007
Posts: 71
Location: Stuttgart, Germany

View user's profile Send private message Visit poster's website

PostPosted: Fri Nov 12, 2021 12:35 am     Reply with quote

OK, then you are printing format is decimal not hex e.g. 65536 instead of FFFF
It works (almost) just as well. The important thing is to have a clear separation between control characters and content characters.
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Sat Nov 13, 2021 5:40 pm     Reply with quote

I came back to correct a mistake.
For the value that i needed(16 bits) i need to use atoL
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group