Nybbles
Nybbles
Hi,
MikroBasic have a beautiful built-in routines: Lo, Hi, Higher and Highest, which make it easy to divide words into bytes in order to transfer them via UART. But there are communication protocols in which the transfer takes place by sending ASCII characters. For example, a byte 00111011 ("3B") is transmitted as two bytes: 00010011 ("3") and 1000010 ( "B").
For this operation, I need to divide byte into two nybbles (4 bis each), but I not founded such routines here.
Please message me where such routines, and if is not exist, then how to properly make nybbles by other manner in MikroBasic?
MikroBasic have a beautiful built-in routines: Lo, Hi, Higher and Highest, which make it easy to divide words into bytes in order to transfer them via UART. But there are communication protocols in which the transfer takes place by sending ASCII characters. For example, a byte 00111011 ("3B") is transmitted as two bytes: 00010011 ("3") and 1000010 ( "B").
For this operation, I need to divide byte into two nybbles (4 bis each), but I not founded such routines here.
Please message me where such routines, and if is not exist, then how to properly make nybbles by other manner in MikroBasic?
Re: Nybbles
Hello,
You have in the Conversions Library some routines for converting to ASCII characters.
Try ByteToHex routine, it will take a byte as input and at output it will take a string of 2 in which it will put the ASCII characters.
Extract from the help file:
Converts input number to a string containing the number's hexadecimal representation. The output string is right justified and remaining positions on the left (if any) are filled with zeros.
Best regards.
You have in the Conversions Library some routines for converting to ASCII characters.
Try ByteToHex routine, it will take a byte as input and at output it will take a string of 2 in which it will put the ASCII characters.
Extract from the help file:
Code: Select all
dim procedure ByteToHex(dim input as byte, dim byref output as string[2])
Best regards.
Just tell me....
Re: Nybbles
serge87,
Thank you very much!
Can I do reverse conversion by StrToInt?
PS. MicroE, when will we see MANUAL.PDF?
Thank you very much!
Can I do reverse conversion by StrToInt?
PS. MicroE, when will we see MANUAL.PDF?
Re: Nybbles
No.ART_ME wrote:Can I do reverse conversion by StrToInt?
The ByteToHex routine transforms (in your case) the value 3B in to characters "3" and "B".
The StrToInt routine expects the decimal representation of the number (in your case "59", characters "5" and "9").
Just tell me....
Re: Nybbles
Oh...
If I have to send via UART byte 0011 1011, I use ByteToHex, and send two bytes - 00110011 ("3") and 01000010 ( "B").
But when I take two bytes - 00110011 ("3") and 01000010 ( "B"), how can I converte them in byte 0011 1011?
If I have to send via UART byte 0011 1011, I use ByteToHex, and send two bytes - 00110011 ("3") and 01000010 ( "B").
But when I take two bytes - 00110011 ("3") and 01000010 ( "B"), how can I converte them in byte 0011 1011?
Last edited by ART_ME on 16 Feb 2017 10:20, edited 2 times in total.
Re: Nybbles
Code: Select all
dim value as byte 'this is the final variable
dim receive as char[2] ' this is the variable in which you load the ASCII from UART
value = 0
if ((receive[0] < 0x39) AND (receive[0] > 0x47)) then
value = receive[0] - 48
else
if ((receive[0] < 71) AND (receive[0] > 64)) then
value = receive[0] - 65
value = value << 4
end if
end if
if ((receive[1] < 0x39) AND (receive[1] > 0x47)) then
value = value OR (receive[1] - 48)
else
if ((receive[1] < 71) AND (receive[1] > 64)) then
value = value OR (receive[1] - 65)
end if
end if
Regards.
Just tell me....
Re: Nybbles
I'm sorry,
I not understand receive[0] < 0x39 AND (receive[0] > 0x47
May be receive[0] < 0x39 OR (receive[0] > 0x47 ?
Or receive[0] > 0x39 AND (receive[0] < 0x47 ?
I not understand receive[0] < 0x39 AND (receive[0] > 0x47
May be receive[0] < 0x39 OR (receive[0] > 0x47 ?
Or receive[0] > 0x39 AND (receive[0] < 0x47 ?
Last edited by ART_ME on 16 Feb 2017 11:32, edited 1 time in total.
Re: Nybbles
Yeah, my mistake, sorry.
I haven't tested it
Here's the fixed piece of code:
I haven't tested it
Here's the fixed piece of code:
Code: Select all
dim value as byte 'this is the final variable
dim receive as char[2] ' this is the variable in which you load the ASCII from UART
value = 0
if ((receive[0] < 58) AND (receive[0] > 47)) then
value = receive[0] - 48
else
if ((receive[0] < 71) AND (receive[0] > 64)) then
value = receive[0] - 65
value = value << 4
end if
end if
if ((receive[1] < 58) AND (receive[1] > 47)) then
value = value OR (receive[1] - 48)
else
if ((receive[1] < 71) AND (receive[1] > 64)) then
value = value OR (receive[1] - 65)
end if
end if
Just tell me....
Re: Nybbles
serge87,
May be instead
?
Besides, 66 ("B") - 65 ("A") = 0000 0001 while we need 0000 1011
There other way:
But all this does not matter to convert to ASCII and back have special operators:
Chr and Ord.
I had a problem with access to nybbles, and you decided it accidentally:
<< and >>
Thank you!!!
May be instead
Code: Select all
value = value OR (receive[1] - 65)
Code: Select all
value = value + (receive[1] - 65)
Besides, 66 ("B") - 65 ("A") = 0000 0001 while we need 0000 1011
There other way:
Code: Select all
if receive[0] = 48 then value = %0
if receive[0] = 49 then value = %1
if receive[0] = 50 then value = %2
.....
if receive[0] = 70 then value = %F
But all this does not matter to convert to ASCII and back have special operators:
Chr and Ord.
I had a problem with access to nybbles, and you decided it accidentally:
<< and >>
Thank you!!!
Re: Nybbles
As I understood the problem, you need to transmit ASCII characters to the UART port.
A value to ASCII conversion is done based on the ASCII table.
If we take the example you given (3B) and convert it to ASCII with the StrToHex function we produce a string of 2 characters which contains the following values:
00110011 - character "3"
01000010 - character "B".
In order to convert the ASCII representation back to a value we need to take in 2 characters and spit out 1 byte.
Now let's see what the code posted by me does:
First we work on the first character in the string, in our case "3".
This piece verifies if the character is between "0" and "9" and if it is then it will do the following"
If the character is not in that interval it check to see if the character is between "A" and "F", because there are other characters between "9" and "A" in the ASCII table we need to do this in 2 steps.
If it is in this region then we will do the following:
After all of this we have in the variable "value" a value between 0 and 15.
Now we need to put it in the upper nibble of the variable, so we do this.
(I found another mistake, damn, I'm hurrying to much)
The above code shifts the variable left by 4 locations.
The mistake is that this shift must be done after the if structure.
Back to our example. in the case of character "3" coming in we have the following:
00110011 - which in decimal is 51, so 51 - 48 = 3 = 00000011, then we shift the bits 4 locations to the left and we have: 00110000.
After the first IF block the value = 00110000.
Now in the second IF block we do the same comparisons and divisions as in first but we have to take in to account that variable "value" has something in it.
If we take the example again in this case with character "B" we have the following:
(Damn another mistake, have to stop writing in a hurry)
00110000 - which in decimal is 66, so 66 - 55 = 11 = 00001011.
In order to put it in the variable without deleting the value in it we have to do the following:
which does the following:
00110000 OR
00001011
------------
00111011 , which is 3B.
Chr(67) will return the letter "C"
Ord("C") will return the value 67 not 13.
P.S. Sorry for the mistakes, I have a tendency to do things in a hurry.
A value to ASCII conversion is done based on the ASCII table.
If we take the example you given (3B) and convert it to ASCII with the StrToHex function we produce a string of 2 characters which contains the following values:
00110011 - character "3"
01000010 - character "B".
In order to convert the ASCII representation back to a value we need to take in 2 characters and spit out 1 byte.
Now let's see what the code posted by me does:
First we work on the first character in the string, in our case "3".
Code: Select all
if ((receive[0] < 58) AND (receive[0] > 47)) then
Code: Select all
value = receive[0] - 48
Code: Select all
if ((receive[0] < 71) AND (receive[0] > 64)) then
Code: Select all
value = receive[0] - 55
Now we need to put it in the upper nibble of the variable, so we do this.
Code: Select all
value = value << 4
The above code shifts the variable left by 4 locations.
The mistake is that this shift must be done after the if structure.
Back to our example. in the case of character "3" coming in we have the following:
00110011 - which in decimal is 51, so 51 - 48 = 3 = 00000011, then we shift the bits 4 locations to the left and we have: 00110000.
After the first IF block the value = 00110000.
Now in the second IF block we do the same comparisons and divisions as in first but we have to take in to account that variable "value" has something in it.
If we take the example again in this case with character "B" we have the following:
(Damn another mistake, have to stop writing in a hurry)
00110000 - which in decimal is 66, so 66 - 55 = 11 = 00001011.
In order to put it in the variable without deleting the value in it we have to do the following:
Code: Select all
value = value OR (receive[1] - 55)
00110000 OR
00001011
------------
00111011 , which is 3B.
Code: Select all
dim value as byte 'this is the final variable
dim receive as char[2] ' this is the variable in which you load the ASCII from UART
value = 0
if ((receive[0] < 58) AND (receive[0] > 47)) then
value = receive[0] - 48
else
if ((receive[0] < 71) AND (receive[0] > 64)) then
value = receive[0] - 55
end if
end if
value = value << 4
if ((receive[1] < 58) AND (receive[1] > 47)) then
value = value OR (receive[1] - 48)
else
if ((receive[1] < 71) AND (receive[1] > 64)) then
value = value OR (receive[1] - 55)
end if
end if
The above routines do not convert to ASCII and back, they just return the ASCII value of the character:ART_ME wrote:But all this does not matter to convert to ASCII and back have special operators:
Chr and Ord.
Chr(67) will return the letter "C"
Ord("C") will return the value 67 not 13.
P.S. Sorry for the mistakes, I have a tendency to do things in a hurry.
Just tell me....
Re: Nybbles
00110000 = %30serge87 wrote: 00110000
OR
00001011
------------
00111011 , which is 3B.
00001011 = %0B
-------------------
%30 + %0B = %3B, which is 00111011
Also:
00110000 = 48
00001011 = 11
-----------------
48 + 11 = 59, which is 00111011
Where mistake?
Last edited by ART_ME on 16 Feb 2017 19:14, edited 1 time in total.
Re: Nybbles
OK, your listing is good.serge87 wrote:Code: Select all
value = receive[0] - 55
Why MikroE not use it to create HexToByte routine?
- lana.arsic
- mikroElektronika team
- Posts: 1715
- Joined: 15 Jan 2016 12:50
Re: Nybbles
Hi,
I have forwarded your request to our developers to take in consideration.
Kind regards,
Lana
I have forwarded your request to our developers to take in consideration.
Kind regards,
Lana
Re: Nybbles
Yes!lana.arsic wrote:Hi,
I have forwarded your request to our developers to take in consideration.
Kind regards,
Lana
One good turn deserves another.