Jump to content
The simFlight Network Forums

HELP! VB6 and BCD format numbers for freq.


Recommended Posts

Guest mike UK
Posted

HELP!

Im trying to set COM freq using VB6(I dont do C or C++ unfortunatly)& I dont have time, at present, to get up to speed with dotNET.

Reading these values is not a problem, as long as you remeber that VB dosnt do Binary or BCD.

But right them back to the offset, well...

Ive tried using all sorts of dirty tricks, rewriting the FSUIPC SDK vb samples. Banging the values over as string, variant, long, short, tall and fat, thin etc ............... Ive tried FSUIPC_write, FSUIPC_writes and re-hacked versions of these two with no joy at all.

I get a TRUE response from the calling boolean and a 0 from dwResult.

but nothing happens at the other end. COM stays tunned to existing freq value and the offset remains unchange even though boolean = true & dwresult = 0. Am I being thick, is there and easy way here or shall I just bye another packet of pain killers and keep banging away at it..

As in my experience C++ programers are the best people on the planet!Anyone fancy building a C++ ActiveX COM DLL to do just the BCD stuff to FSUIPC. Take a VB long(int)1345 and covert to

BCD 0001 0011 0100 0101 then bang over to FSUIPC.

Grovel grovel.........

Cheers all from the sunny SW UK

Mike

Posted

My experience in VB is limited but a conversion routine shouldn't be so hard:

number=float (numberOri)

bcd=0

for i=0 to 5

number=number/10

number1=decimal (number)

number=number-number1

REM I think there isn't rotations in VB

bcd=number1*2^(3*i)+bcd;

end

Just an Idea. Of course I don't know how to do float() and decimal () it's just pseudo code.

José

Posted
VB dosnt do Binary or BCD

Hardly anything "does" BCD, it is just a convention, but all languages "do" binary -- it's the only thing computers understand when you get down to it. 0s and 1s.

Take a VB long(int)1345 and covert to

BCD 0001 0011 0100 0101

I don't know VB, but doesn't it handle binary ANDs, ORs and shifts of some sort? Surely. These are essential programming operations in any language. (If not, you *can* use muliplication instead of shifts).

Notice that 1345 / 1000 = 1 (ignoring remainder).

Shift that 1 up 12 bits (<<12 in C, I don't know VB. Else multiply it by 2^12). That gives you 0x1000 (the first digit in your desired BCD).

Take the remainder of 1345/1000 -- this is 1345%1000 in C, I don't know VB. If there's no remainder function you'd do it by

1345 - 1000*(1345/1000).

So you have 345. Divide by 100 and you have 3. Shift it up 8 bits (or multiply by 2^8) and you have 0x0300.

Add that to your first result (0x1000) and you have 0x1300.

You are half way there. I'm sure you can figure out the rest. It really is simple arithmentic, not complex programming nor mathematics.

Pete

Posted

Thanks José

But I think you missed my point.

Converting from one number format to another is not the problem.

The value has to be sent as a string or variant, as a long or int will convert it to decimal straight away(VB thing) No binary or BCD in VB whatso ever.

The problem is, whatever format the number is in, int, decimal, binary, string whatever.

When I do succ = FSUIPC_write or writes(offset, 2, mynumber, dwResult)

I get a succ = TRUE and dwResult = 0. which is a total success message from FSUIPC

The COM freq in fs2002 dosnt change and if I read back the offset value straight away it hasnt changed at all, even though FSUIPC says the write was successfull.

Thanks anyway

Mike

Posted
The value has to be sent as a string or variant, as a long or int will convert it to decimal straight away(VB thing) No binary or BCD in VB whatso ever.

No. the value is sent as a number, a 16-bit short number in fact.

You say "no binary in VB whatsoever", but this really is nonsense. Honest. There's actually no decimal -- all your integers or longs or shorts or whatever you want to call them are BINARY. Your example 1345 is represented in the computer as hex 0541 (0000 0101 0100 0001 in binary), NOT as 1345 at all.

After you've converted one integer (1345) into another (hex 1345 = 4933 in decimal) that's what you have, just another number. Send that as 16 bits (2 bytes) to FSUIPC and it will work.

Please play with FSInterrogate and look at the different representations it can show you, ALL from binary numbers.

When I do succ = FSUIPC_write or writes(offset, 2, mynumber, dwResult) I get a succ = TRUE and dwResult = 0. which is a total success message from FSUIPC.

All that means is that the write was done. What FS makes of what you are writing is another matter. FS2000 and before wouldn't even check -- if you sent rubbish as a frequency, it would set it. And mighty odd it looked too. FS2002 checks things and won't use an invalid frequency.

The COM freq in fs2002 dosnt change and if I read back the offset value straight away it hasnt changed at all, even though FSUIPC says the write was successfull.

Reading and writing are different things. Writing is an instruction to FSUIPC to do something. Reading is reading an FS setting. They are often not the same. The image presented by FSUIPC, of an area of memory with values you can change and read, is just that, an image. It is presented for compatibility across all versions of Fs, starting with FS98 (where, in fact, the image was the reality).

Pete

Posted
I don't know if VB as bit rotate or even bit masks. That's why I putted things like above.

Understood, but it has to have AND and OR (not that you need them for this, as I showed), or it is too limited to be called a programming language , and bit shifting doesn't need shifts if you can multiply, it is just likely to be more efficient -- though a decent optimising compiler would replace multiplication by powers of 2 with shifts in any case.

I seem to rember Bill Gates' original Basic on the first personal computers had a full complement of logical operations, so I can't see that they'd all be removed.

Regards,

Pete

Posted
Im trying to set COM freq using VB6(I dont do C or C++ unfortunatly)& I dont have time, at present, to get up to speed with dotNET.

Reading these values is not a problem, as long as you remeber that VB dosnt do Binary or BCD.

But right them back to the offset, well...Mike

Mike,

I struggled with this a bit myself recently and with some help from Pete solved it in VB.net. The algorithms are still clumsy as I was just trying to make it work and though in .net should easily translate to vb6. You'll have to change SHORTs to INTEGERs but otherwise should run.

Here are the algorithms:

****************************************************

Public Class CHelper

'This class serves to separate out conversion functions, etc

Public Function DECtoBCD(ByVal intDEC As Integer) As Integer

'This function takes the decimal equivalent of a BCD and returns the BCD

Dim mThous As Short

Dim mHund As Short

Dim mTen As Short

Dim mOne As Short

mThous = (intDEC And 61440) / 4096 * 1000

mHund = (intDEC And 3840) / 256 * 100

mTen = (intDEC And 240) / 16 * 10

mOne = (intDEC And 15)

DECtoBCD += mThous + mHund + mTen + mOne

Return DECtoBCD

End Function

Public Function BCDtoDEC(ByVal intBCD As Integer) As Integer

'This function takes a BCD and returns decimal equivalent

Dim mThous, MHund, MTen, MOne As Short

mThous = Int(intBCD / 1000) * 1000

MHund = Int((intBCD - mThous) / 100) * 100

MTen = Int((intBCD - mThous - MHund) / 10) * 10

MOne = Int((intBCD - mThous - MHund - MTen))

BCDtoDEC = mThous / 1000 * 4096 + MHund / 100 * 256 + MTen / 10 * 16 + MOne

End Function

End Class

***********************************************

And here is the code that uses it:

If ReadCOM1(FSCOM1, intError) Then

'Able to read com1

'Let's try to write incremented value

Dim temp_FSCOM1 As Integer = myCHelper.DECtoBCD(FSCOM1) 'temp var to increment FSCOM1's value

Dim case_FSCOM1 As Integer

case_FSCOM1 = temp_FSCOM1 - (Int(temp_FSCOM1 / 1000) * 1000)

case_FSCOM1 = case_FSCOM1 - Int(case_FSCOM1 / 100) * 100

case_FSCOM1 = case_FSCOM1 - Int(case_FSCOM1 / 10) * 10

Select Case case_FSCOM1 'selects last digit of BCD

Case 0

'BCD ends in 0 so add 2

temp_FSCOM1 += 2

Case 2

'BCD ends in 2 so add 3

temp_FSCOM1 += 3

Case 5

'BCD ends in 5 so add 2

temp_FSCOM1 += 2

Case 7

'BCD ends in 7 so add 3

temp_FSCOM1 += 3

Case Else

MessageBox.Show("Error - shouldnt get here")

End Select

If temp_FSCOM1 > 3597 Then

'exceeds highest freq - return to low

temp_FSCOM1 = 1800

End If

temp_FSCOM1 = myCHelper.BCDtoDEC(temp_FSCOM1)

If WriteCOM1(temp_FSCOM1, intError) Then

'Write Successful

Else

MessageBox.Show("Error writing to COM1", "Error!")

Exit Sub

End If

Else

'Problem reading - therefore cannot change

Exit Sub

End If

Readcom and writecom are simply functions that pass the info to the generic read/write/process/get functions - intError is the same as dwResult, etc.

Hope this helps! I've tested it with a rotary and it works. Of course there's a lot of tweaking to do e.g. if you want separate whole and fractional frequency controls and obviously a complementary decrement function but this should give you the picture.

Scott

Posted

Im humbled in your presence......Scott & Pete :D

A help forum is one thing but, just like FSUIPC, you take it to a new level...

I really didnt expect you to do this sort of thing, although its much appreciated of course.

Thank you very much guys and I really do mean that.

If I can ask a question. why is only 1 COM freq exposed in FSUIPC SDK doc. Is this a bill gates thing!

Anything I can do for you in the future just let me know

Posted
If I can ask a question. why is only 1 COM freq exposed in FSUIPC SDK doc.

This is only true in versions of FS which only had one COM frequency -- i.e. all those before FS2002. Since FS2002 I provide access to COM2 and both Standby frequencies as well -- please refer to the Programmer's Guide, offsets 3118 following.

Pete

Posted
I don't know if VB as bit rotate or even bit masks. That's why I putted things like above.

Understood, but it has to have AND and OR (not that you need them for this, as I showed), or it is too limited to be called a programming language

I really don't know if you can do bit masks with AND or OR or XOR. I began with Assembly and the migrate to C (it saved me a lot of time), I see C++ classes as struts and functions I know it's wrong but what can I do? I'm a dinosaur whit no possible salvation :)

Cheers,

José

Posted
I began with Assembly and the migrate to C (it saved me a lot of time), I see C++ classes as struts and functions I know it's wrong but what can I do? I'm a dinosaur whit no possible salvation :)

I am the same, though I started with a unipunch making holes individually in paper tape in order to bootstrap code into prototype mainframes -- back in 1963, when I started as an engineering test programmer!

Since then I mostly used whatever assembly code was appropriate for each mainframe I needed to write stuff for. I did have a brief encounter with Fortran, but it didn't last long. When personal computing started in the late 70's my first non-homebuilt one was a Commodore Pet and that came with MS Basic built into the firmware. That's how I came to experience a bit of Basic, but I soon got into 6502 assembler. On the Apple I used Pascal a bit, but mostly 6800 assember. I used BCPL for quite some time (a precursor to C) before changing to C, but even then still used 68000 assembler on computers like the Sinclair QL and Commodore Amiga.

C is really as far removed from the real computer as I like to get. The convoluted machine level code which C++ produces frankly horrifies me! Like you, I have to boil it down to structs and functions or procedures anyway.

Best,

Pete

Posted
I began with Assembly and the migrate to C (it saved me a lot of time), I see C++ classes as struts and functions I know it's wrong but what can I do? I'm a dinosaur whit no possible salvation :)

I am the same, though I started with a unipunch making holes individually in paper tape in order to bootstrap code into prototype mainframes -- back in 1963, when I started as an engineering test programmer!

Well its a case of each to there own then. I started in the game late in life(31) after being a sheet metal eng. Then did a degree in Geology(Just because I love the subject) and then the PC boom took off in the UK.

I have no formal qualifications in ICT and am completely self tought in ASP, VB 4 5 6 and now looks like dotNET as well as ASP VBS, Win2k Sys admin etc. Suits me as I dont do assembly or C and I can visualise functions, classes etc like a flowel diagram. I regret no having any C or C++ training as there is so much I cant do. Like win systems stuff. But never mind Im happy so thats that...

I havnt had time to deal with the dotNET code, as off yet, but when its finished and working I'll post it back to the forum....

Thanks alot

Mike

  • 3 years later...
Posted

Thank you petdocvmd for the VB.Net Code. :D I converted and used it in a C# application to read and write the Radio Frequencies.

As a token of my appreciation here is the C# version of the code:

public static class MyConvert
    {
        // This class serves to separate out conversion functions, etc 
        public static short DECtoBCD(int intDEC)
        {
            short rval;

            // This function takes the decimal equivalent of a BCD and returns the BCD 
            short mThous;
            short mHund;
            short mTen;
            short mOne;

            mThous = Convert.ToInt16((intDEC &amp; 61440) / 4096 * 1000);
            mHund = Convert.ToInt16((intDEC &amp; 3840) / 256 * 100);
            mTen = Convert.ToInt16((intDEC &amp; 240) / 16 * 10);
            mOne = Convert.ToInt16((intDEC &amp; 15));

            rval = Convert.ToInt16(mThous + mHund + mTen + mOne);

            return rval;
        }

        public static short BCDtoDEC(int intBCD)
        {
            short rval;

            // This function takes a BCD and returns decimal equivalent 
            short mThous;
            short mHund;
            short mTen;
            short mOne;

            mThous = Convert.ToInt16((intBCD / 1000) * 1000);
            mHund = Convert.ToInt16(((intBCD - mThous) / 100) * 100);
            mTen = Convert.ToInt16(((intBCD - mThous - mHund) / 10) * 10);
            mOne = Convert.ToInt16((intBCD - mThous - mHund - mTen));

            rval = Convert.ToInt16(mThous / 1000 * 4096 + mHund / 100 * 256 + mTen / 10 * 16 + mOne);

            return rval;
        }
    }

The Class is declared Static so one does not need to create an instance of the class.

fritzw

  • 7 months later...
Posted
To convert BCD to decimal with VB6 try following:

FsFreq = Val(Str(Hex(ReadFSValue)))

9349 will convert to 2485 which is correct for a COM1 Standby set at 124.85

That line of code works fine in VB.net, thanks!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.