generate 16 bit data from two 8 bits data

 DevX Home Today's Headlines   Articles Archive   Tip Bank   Forums

# Thread: generate 16 bit data from two 8 bits data

1. Registered User
Join Date
Apr 2009
Location
United Kingdom
Posts
84

## generate 16 bit data from two 8 bits data

Hi

I have hardware which is handling 16 bit binary data. I used to send the data through UART. UART normally handles 8 bit data. In order to transfer the 16 bit data , I used to split the 16 bit into two 8 bits and then transmit.

In the PC side I am using vb.net to capture the data. For e.g

Data I send from the hardware is like ( I have included two examples)

0000000000000001(decimel 1) = In Computer looks like 00000000 00000001
0000000100000000(decimel 256)= In Computer looks like 00000001 00000000
.

I am trying to read the binary file by combining two 8 bits and then convert back to decimel. Here is the code I have used

For i = 0 To bytes.Length - 1 Step 2
str = Convert.ToString(bytes(i), 2) & Convert.ToString(bytes(i + 1), 2)
'Dim decimel As Integer = Convert.ToUInt32(str, 2)

next

Above code works fine up-to 255. Once the cursor reaches 256 ,it will treat as 10. Since it ignores zeroes towards the least significant bit

Any help would be appreciated

Regards

Faisal
Last edited by pfaisalbe; 11-23-2010 at 09:48 AM.

2. Registered User
Join Date
Feb 2004
Location
Longueuil, Québec
Posts
577
Hi.

First of all, the code you send is not very evident, because we do not see what bytes is. It looks as a collection of Byte, but it is not clear, and it requires a lot of work to try to understand what you are doing.

If it is an array of Byte as I am lead to think, why loop to bytes.Length, since the length is fixes. Without the declaration it is difficult for me if you are looping through 8 bytes or 16 bytes. I do not know what the length is.

And in any case, I cannot see what your Step 2 is about. I know what Step 2 does, but why skip one bit out of 2 in your loop ????

Maybe bytes is an array of Char, then it might make sense to remove the the extra byte in the 2 bytes Unicode Char, but since you are putting the stuff back into a String that is itself a collection of Unicode Char, nothing really make sense to me.

Then, why to try to convert to a 32 bit decimal (ToUInt32) while you are working with a 16 bit value. By the way, the UInt types are special things that needs to be handled in a special way and are used only in very special situations.

Without the declaration for bytes, anything one would try to understand is pure conjecture.

When you send a piece of code, you should always send the declarations and assignations of everything that is used in the code, otherwise we are left to try to understand what you are trying to do.

-----

If, as I think, bytes is an array of Byte, here is how I would do your work:

Code:
```    Dim bytes() As Byte = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}  'Recreates you array of byte
Dim str As String
Dim decimel As Integer

'Build a string out of your array
For Each value As Byte In bytes
str = str & value.ToString
Next

'Convert the string ("0000000100000000") to a decimal value on base 2
decimel = Convert.ToInt16(str, 2)```
-----

And if somebody from Microsoft reads this, when will you finally give us something more than the bit operators to work with bits? Why not have a Convert method in the BitArray collection?

3. Registered User
Join Date
Apr 2009
Location
United Kingdom
Posts
84
Many Thanks for your reply. I feel sorry that my post was not clear. I have attached picture of the binary file i am using.

Here is my code in detail

Dim fInfo As New FileInfo(FileDialog.FileName) ' Filedialog is a common dialogue
Dim numBytes As Long = fInfo.Length
Dim fs As New FileStream(FileDialog.FileName, FileMode.Open, FileAccess.Read)
Dim bytes As Byte() = br.ReadBytes(CInt(numBytes))

For i = 0 To bytes.Length - 1 Step 2
str = Convert.ToString(bytes(i), 2) & Convert.ToString(bytes(i + 1), 2)
Dim decimel As Integer = Convert.ToUInt32(str, 2)
next

Also Reason I use the step2 in for loop is every two byte gives one 16 bit.

Any help would be appreciated

Best Regards

Faisal
Last edited by pfaisalbe; 11-24-2010 at 04:22 AM.

4. Registered User
Join Date
Apr 2009
Location
United Kingdom
Posts
84
Dear JBourgeois ,

Many Thanks. Finally I have managed to get it done. So far the code is working. I am not a software guy . This problem stops me to concentrate on other work for two days.

I am not sure why such small things are not straight forward in VB.net. Would it make the life easier with C ?.

Looking forward to hear your comments. Here is the code I used

Dim str1 As String
Dim str2 As String
Dim str As String
Dim i As Integer
Dim decimel As Integer
Dim ofile As System.IO.FileInfo
ofile = New System.IO.FileInfo(Environment.CurrentDirectory & "\mybin128m.bin")
Dim ofilestream As System.IO.FileStream = ofile.OpenRead()
Dim lbytes As Long = ofilestream.Length
Dim zeroes As String = ""
Dim diff As Integer

If (lbytes > 0) Then

Dim filedata(lbytes - 1) As Byte
ofilestream.Close()

For i = 0 To lbytes - 3 Step 2
str1 = Convert.ToString(filedata(i), 2)
str2 = Convert.ToString(filedata(i + 1), 2)

If (str1.Length < 8) Then
diff = 8 - str1.Length
str1 = zeroes.PadLeft(diff, "0") & str1
End If

If (str2.Length < 8) Then
diff = 8 - str2.Length
str2 = zeroes.PadLeft(diff, "0") & str2

End If

str = str1 & str2
decimel = Convert.ToInt16(str, 2)
SENDDATA(decimel & vbNewLine)
Next

End If

Regards

Faisal

5. Registered User
Join Date
Feb 2004
Location
Longueuil, Québec
Posts
577
Hi.

Sorry for not coming back to you sooner and for my short reply right now, but I have a crazy 2-3 weeks where I am on the road and in the air all the time in small towns where WiFi is and SciFi (Science Fiction) are the same thing.

I keep note of your post and will be back to you as soon as I get a few minutes in a location that enables Internet connection.

6. Registered User
Join Date
Apr 2009
Location
United Kingdom
Posts
84
No problem , Thanks

Faisal

7. Registered User
Join Date
Feb 2004
Location
Longueuil, Québec
Posts
577
Hey! Finally got those "few minutes".

You got it working, that is the important thing.

Code:
`I am not sure why such small things are not straight forward in VB.net. Would it make the life easier with C ?.`
Well, this one is many questions wrapped into one.

-----

First, the small things

"Such small things" does not exist anymore? With many different versions of Windows (XP, Vista and 7, with a lot of Windows 98 still running) that tries to speak to each other; with those trying to speak to Linux, UNIX, the Mac and a few others; with XML that added to the soup of binary vs text files; with the security requirements that were forced upon Microsoft that always tried hard to keep backward compatibility (those 2 are contradictory when you think of backward compatibility between MS-DOS and Windows 7); with the move from 16-bits to 32-bits to 64-bits that might be one element into your specific problem (you are reading 16-bits values into a 32-bits environment); with a lot of other reasons, nothing is simple anymore.

As a "I am not a software guy", sometimes, you do not see the wide implication of things that seem simple at first view. They do not make those things complex just to piss you off, they usually have good reasons to do so.

----

Second, "Would it make the life easier with C".

Some nuances. C, C++ and C# are 3 different languages, no matter the common letter and the fact that each one, in the order stated, is based on the previous one. C evolved into C++. C# is a new approach to C++, but is in fact closer to Java than it is to C++.

Nobody programs in C anymore. Except for a few dinosaurs that refuse to die or still live in their MS-DOS forest, everybody has moved to something else. Here is mainly why.

C does not make the life easier, on the contrary. It might have changed, because I have not programmed in C since 1992 or so, but at the time, to build a Form with no buttons and no anything, the type of form you get when you add a new Form to a .NET project, it took 150 lines of code. C++ brought it down to 30. VB to 0.

Nobody would think that doing something with 150 lines of code would be simpler than doing it in 0. I think you will agree with this one.

C# is probably what you meant in you sentence that I would rephrase as "Would it make the life easier with C#".

C# is the C / C++ / Java variation that has taken hold in .NET.

VB and C# are the 2 main languages used for .NET deployment. From my experienced, and for many reasons I have not time to elaborate on here, the popularity of each against the other has fluctuated a lot since the official appearance of .NET in 2002.

They are different languages, they have different syntaxes, different compilers and different editors. But in .NET, that fundamentally means very little. In .NET, the language is simply an interface on something called the framework. There is basically no difference between what those language do, because the framework is doing the work. What takes 8 lines of code in VB also usually requires 8 lines of code in C#, and vice-versa.

One can argue about the quirks of the language (I personnally dislike the case sensitivity of C# and the need for a ; at the end of each line of code), on can argue about the editor (I personnally adore the automatic construction of structures such as If...End If and For...Next in VB while then C# editor is not able to automatically able to automatically generate the all present { }). On those type of considerations, I personnally think that life is actually easier in VB than it is in C#, and I have programmed extensively in both.

But a programmer who is used to the C or the Java syntax would say that C# is easier.

This is a question of perspective, personal affinities and experience. Not a question to argue about. For those of you who know a little French, I have an article on that subject at http://www.technologia.com/vbnet-aff...gnant-est.html.

-----

Your code works, that is the main thing.

-----

Code:
`New System.IO.FileInfo(Environment.CurrentDirectory & "\mybin128m.bin")`
This is a dangerous one. I do not see the whole, maybe it has been set differently somewhere else in the program, but Environment.CurrentDirectory is usually the folder in which the application is installed. This usually something under Program Files. And for a user that is not administrator of its station, Program Files in read-only under the .NET security.

This is probably not a problem in your case because you seem to use the thing only to read the data, but that is something that you need to be aware of.

-----

The way you access your file to read it is complex without any reason. That is exactly the type of information I was complaining was missing in your first post. If you had given me a hint of the way you are accessing the file, I would have been in better situation to help you.

Now, don't start changing everything after reading me. There is a saying among programmers: "If it ain't broke, don't fix it!". As I understand, you code works as it is. If you try to adapt it to what I will say, which I feel (personal opinion) would be a better way to do things, you might end up with another 2 days of trying to make things work, and might not feel the difference after all.

It works, leave it as it is. But in future work...

Not your fault, most books do it the way you do it. Most books are bad. I won't elaborate here, but if somebody wants to argue, I could tell you in another thread how the edition world and \$\$\$ considerations forces book writers to do a cheap job and end up with such crap as going through a FileInfo object to open a FileStream. You can open a FileStream directly:

Code:
`Dim ofilestream As System.IO.FileStream = New System.IO.FileStream(Environment.CurrentDirectory & "\mybin128m.bin", System.IO.FileMode.Open)`
And if somebody could tell me why all the books on the market insists on using a FileStream, I would kiss him or her with real love (in my case, I would hope that it is a her, but I would go for a him anyway, because I might learn about a very important truth that is out of my reach as of now).

Almost every book on the market works with a FileStream. Almost no programmer who knows about the stuff uses a FileStream.

FileStream is a very direct class to a file, but it is a very generic one that makes your life a pain to use. I know understand why you needed to loop with Step 2.

There are many other streams in .NET, each specialized for a specific way to work with files.

The most often used are optimized to work with text files: StreamReader and StreamWriter that have methods such as ReadLine and WriteLine that are lot easier to used than dealing with the basic Read and Write methods of the FileStream that mainly work at the byte level.

In your case, you might have been interested to work with a BinaryReader, which has been designed to work with binary data. It has a ReadInt16 that I think you might have liked, because it deals directly with 16 bits values.

To be honest, I did not look at your data file, I unfortunately do not have time, and any way, the environment I carry with me in the hotel life I am living actually does not provide me with a tool to easily analyze the structure of a binary file, something that is hard to do anyway unless someone is provided with a layout of the structure of the file.

But my intuition by looking at what you do in your code is that a BinaryReady.ReadInt16 would have made things a lot easier for you from the start.

Once again, what is that infatuation with the FileStream? The name of that class is very attractive when one wants to deal with a File, but that class is usually just something that the other stream classes use in order to communicate with the file system. As a programmer, I am interested in words, lines, dates, strings, long and integer, not in bytes which is the way the FileStream deals with things.

Well, a lot of programmers think that it looks more professional to do somethings in 25 lines of code when it can be done in 3. Ah, those crazy customers that pay you \$2 for each line of code. \$75 should be a lot better than 6\$, isn't it?

-----

Code:
```str1 = Convert.ToString(filedata(i), 2)
decimel = Convert.ToInt16(str, 2)```
These work. And they are not bad. In fact, because you are working with that FileStream and have to think about 2 bytes values instead of dealing with 16 bits values, they might be your only solution.

But most of the time, using VB internal conversion commands instead of Convert is faster. You would not feel the difference if you have very little data to work on, but if you hundreds or even thousands of lines of data, you could see the performance jump a lot by using the CShort VB instruction instead of Convert.ToInt16. If you type CShort in the environment, you will see that it appears in blue, as a reserved word. The compiler is optimized to work with those and usually does a better job with blue words than in does with black words. When you have 2 different ways to do something and one is in Blue, the Blue one is usually faster.

It would not work in your case because you use Convert to combine 2 bytes into one 16 bits value (if I understand correctly, because these are not forms of Convert I have worked with before). But most of the time, CInt, CLng, CDate are faster than Convert.

-----

On my size limit... again... this continues in the next post.

8. Registered User
Join Date
Feb 2004
Location
Longueuil, Québec
Posts
577
... This is the next post, continuation of the preceding one.

-----

Code:
```Dim decimel As Integer
decimel = Convert.ToInt16(str, 2)```
I will be a little finicky here, but programming is about little details. Sometimes for performance, sometimes to prevent bugs, oftentimes to make code easier to understand when you have to come back to it to change things, 2 weeks, 2 months or 2 years after you have written it, things need to be very neat.

This is not the case with those 2 lines, but there are so many things to learn in this field (the previous comment about why as "I am not a software guy", sometimes, you do not see the wide implication of things that seem simple at first view holds very hard here) that you are excused if you did not catch those little details before. A lot of those who proclaims themselves as "I am a software guy" are not even aware of what is coming.

decimel is an Integer. An Integer is 32 bits long. I see a lot of hands raising and mouths yelling: "This JBourgeois is a fraud, we finally got him, an Integer is 16 bit!". Sorry raised hands, and the guys (maybe a few girls) under those hands, but please, get out of Visual Basic 6. Integer has been promoted. Integer is now 32 bits. Short has replaced it as the 16 bits integer type in VB.NET.

In your code, you are first converting to 16 bits, but then the system needs to convert again to 32 bits because you are trying to put the 16 bits result into a 32 bits variable. Your code should be either

Code:
`Dim decimel As Shortdecimel = Convert.ToInt16(str, 2)`
or

Code:
`Dim decimel As Integerdecimel = Convert.ToInt32(str, 2)`
Not that it does not work, and remember, "If it ain't broke, don't fix it!". But by converting to 16-bits and then storing to 32-bits (naturally, to know that, you need to know that an Integer is 32-bits), you force the system into converting twice, which would reduce the performance of the application if you are dealing with a lot of data.

-----

Maybe too bad for you, you were Looking forward to hear your comments. I am a professional programmer, and that is the way we are thinking. For professionals, these little details can make a big difference. For amateur, they might be a little on the edge.

But I know that many amateurs like to learn a bit about those little nuances.