Jump to content
The simFlight Network Forums
hawkt1

Write com value

Recommended Posts

Hello all

What is the increment for increasing the com frequency? I can increase the major number by adding 100 to the number but for the minor number it increments 2 then 3 then 2 then 3

Must be a simple calc? Any thoughts

Share this post


Link to post
Share on other sites

The com frequencies are divided into steps of 25khz. So if we start at 108mhz we get these frequencies:

108.000

108.025

108.050

108.075

108.100

108.125

And so on.

Radios generally only show the first two decimals so it looks like it's adding 2,3,2,3 etc. The .005's are just hidden.

You just need to keep the full value in a variable and add/subtract 0.025. Then drop the last digit when you write to FSUIPC.

Paul

Share this post


Link to post
Share on other sites

The com frequencies are divided into steps of 25khz. So if we start at 108mhz we get these frequencies:

108.000

108.025

108.050

108.075

108.100

108.125

And so on.

Radios generally only show the first two decimals so it looks like it's adding 2,3,2,3 etc. The .005's are just hidden.

You just need to keep the full value in a variable and add/subtract 0.025. Then drop the last digit when you write to FSUIPC.

Paul

 

Perfect Paul, I thought I was over complicating this!

 

I have a rotary encoder and arduino, works fine up and down but will exceed the limits ie 138 if I keep turning.  Logic in VB would suggest something like if exceeds 136 then start at 118 etc. Or would you suggest a simpler alternative?  Clearly I am overthinking it!

Share this post


Link to post
Share on other sites

Yes the easiest thing to do is just check if the value has gone out of range. If it has you have two choices: One is to wrap around as you said in your post, the other option is just to stick on the min or max so you can't go any further.

 

something like this:

' Check for over max
If newFreq > maxFreq then
   newFreq = maxFreq ' Use this line to limit to max or...
   newFreq = minFreq ' Use this line to Wrap around
end if
' Check for under min
If newFreq < minFreq then
   newFreq = minFreq ' Limit to min or...
   newFreq = maxFreq ' Wrap around
end if

Paul

Share this post


Link to post
Share on other sites

Thanks Paul, helpful as always

 

So to change the two frequencies with a button?

 

my two frequencies are

    Dim com2bcd As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H3118)
    Dim com2bcdstby As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H311C)

Logically I created a value to hold com2bcd swapped com2bcd = com2bcdstby and combcdstby = value but then I cannot update it within the app

Share this post


Link to post
Share on other sites

Look like you need offset 0x3123 to swap the operational/standby frequency in the Flight Sim. Declare this as type 'of Byte' and write only:

Dim stbySwap As Offset(Of Byte) = New FSUIPC.Offset(Of Byte)(&H3123, True)

Then you need to write the following value depending on which radio you want to swap:

 

8: COM1
4: COM2
2: NAV1
1: NAV2

 

e.g. to swap COM2:

stbySwap.Value = 4 ' COM2
FSUIPCConnection.Process()

Paul

Share this post


Link to post
Share on other sites

See too over complicating things!!!

 

Doh

 

Back to the frequency issue Paul

 

 

This is my variable:

Dim com1bcdstby As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H311A)

This is my addition

Me.com1maths.Text = com1bcdstby.Value.ToString("x") + 0.025

any my process to fsuipc

            com1bcdstby.Value = Short.Parse(com1maths.Text, Globalization.NumberStyles.AllowHexSpecifier)

            FSUIPCConnection.Process()

Now it doesnt accept it because its a decimal number, can you point me in the right direction?

 

BR

Share this post


Link to post
Share on other sites

You cannot work with the value in the offset. You need to keep your own frequency value to 3 decimal places and work with that (i.e. add and subtract 0.025).

 

The offset value is in BCD format, not a real hex number, so maths will not work on it.

 

You should declare a value for the full frequency as a decimal alongside the offset:

Dim com1bcdstby As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H311A)
Dim com1DecStby As Decimal ' This will hold the full decimal number

I would then setup 2 functions to easily convert between FSX BCD format and a real decimal number containing the whole frequency:

   Private Function encodeFreqAsBCD(freqDecimal As Decimal) As Short
        encodeFreqAsBCD = Short.Parse(((Decimal.Round(freqDecimal, 2, MidpointRounding.AwayFromZero) - 100) * 100).ToString("F0"), Globalization.NumberStyles.AllowHexSpecifier)
    End Function

    Private Function getFreqFromBCD(freqBCD As Short) As Decimal
        Dim freq As Decimal = ((Decimal.Parse(freqBCD.ToString("X")) / 100) + 100)
        ' If the freqency is not a multiple of 0.025 then it's been rounded
        ' Subtract 5Khz to get real value
        If (freq * 1000) Mod 25 <> 0 Then
            freq -= 0.005
        End If
        getFreqFromBCD = freq
    End Function

Now you can always do the maths on the full decimal number (which is easy) and then convert it to BCD when you assign the new value to the offset:

 

Here's an 'add' example (you can add the previously discussed wrap-around code)

    Private Sub Add()
        ' Add 0.025 to full decimal value
        com1DecStby+= 0.025
        ' set this new value to the offset (convert to BCD)
        com1bcdstby.Value = encodeFreqAsBCD(com1DecStby)
    End Sub

When you program first starts you need to read the current frequency from FSX and fill your decimal variable as an initial value:

        FSUIPCConnection.Process()
        Me.com1DecStby = getFreqFromBCD(com1bcdstby.Value)

Paul

Share this post


Link to post
Share on other sites

Thanks Paul,

 

Bear with me, stupid question.  By rounding say 126.025 and then encoding, were actually sending 126.03 to FSX?

Dim com1bcdstby As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H311A)
Dim com1DecStby As Decimal

Me.com1DecStby = getFreqFromBCD(com1bcdstby.Value)

com1DecStby += 0.025
com1bcdstby.Value = encodeFreqAsBCD(com1DecStby)




   Private Function encodeFreqAsBCD(freqDecimal As Decimal) As Short
        encodeFreqAsBCD = Short.Parse(((Decimal.Round(freqDecimal, 2, MidpointRounding.AwayFromZero) - 100) * 100).ToString("F0"), Globalization.NumberStyles.AllowHexSpecifier)
    End Function
    Private Function getFreqFromBCD(freqBCD As Short) As Decimal
        Dim freq As Decimal = ((Decimal.Parse(freqBCD.ToString("X")) / 100) + 100)
        TextBox1.Text = freq.ToString
        ' If the freqency is not a multiple of 0.025 then it's been rounded
        ' Subtract 5Khz to get real value
        If (freq * 1000) Mod 25 <> 0 Then
            freq -= 0.005
        End If
        getFreqFromBCD = freq
    End Function

Share this post


Link to post
Share on other sites

Yes, FSX doesn't deal with the third decimal place. That's just for our use so the frequency increment follows the correct pattern.

 

If we calculate the real frequency to be 126.025 we're actually going to send 0x2603 to FSX after encoding. The radio should show 126.03.

 

Paul

Share this post


Link to post
Share on other sites

Hmm ok, thats a pain, 126.03 wont tune 126.025 on vatsim for example, if I tune using the mouse I get 126.02 (126.025 when hovering over) - 126.05 - 126.07 (126.075 when hovering over) - 126.10

Share this post


Link to post
Share on other sites

Ah a Eureka Moment

 

I amended  this from <> to = 0 and voila I can tune 126.02 126.05 126.07 126.1  Brilliant!  

 

Thanks Paul as always so helpful

If (freq * 1000) Mod 25 = 0 Then            
freq -= 0.005
End If

For the ADF frequency (because you knew that was coming!   :cool: ) 

 

I need to be able to extract the ADF frequency and then use buttons to increase each digit individually ie like a digital ADF and then send back.

 

Any pointers for that?

Share this post


Link to post
Share on other sites

Ah sorry about that - I had it in my head that the frequencies were rounded up, not down.

 

If your mod works that's fine, but these are the corrected versions of the conversion functions:

    Private Function encodeFreqAsBCD(freqDecimal As Decimal) As Short
        encodeFreqAsBCD = Short.Parse((Int((freqDecimal - 100) * 100)).ToString(), Globalization.NumberStyles.AllowHexSpecifier)
    End Function

    Private Function getFreqFromBCD(freqBCD As Short) As Decimal
        Dim freq As Decimal = ((Decimal.Parse(freqBCD.ToString("X")) / 100) + 100)
        ' If the freqency is not a multiple of 0.025 then it's been truncated
        ' Add 5Khz to get real value
        If (freq * 1000) Mod 25 <> 0 Then
            freq += 0.005
        End If
        getFreqFromBCD = freq
    End Function

For the ADF frequencies I suggest using the same approach: keeping a decimal version for your own use and encoding to/from BCD. The ADF encodings are complicated though because they are split over two different offsets.

 

I can get you the encoding/decoding functions tomorrow.

 

Paul

Share this post


Link to post
Share on other sites

Here is the ADF code:

 

In your code you'll want to define the two offsets (Main and Extended) for the ADF (I've use ADF1 here:)

    Dim adf1BCDMain As Offset(Of Short) = New Offset(Of Short)(&H34C)
    Dim adf1BCDExtended As Offset(Of Short) = New Offset(Of Short)(&H356)

and a decimal copy of this to make changing/displaying it easier

    Dim adf1Decimal As Decimal

Here are two functions to encode and decode to/from the Decimal value to the two BCD offsets:

    Private Function getADFFromBCD(ADFMain As Offset(Of Short), ADFExtended As Offset(Of Short)) As Decimal
        Dim freq As Decimal
        freq = Decimal.Parse(ADFMain.Value.ToString("X4"))
        Dim extended As String = ADFExtended.Value.ToString("X4")
        freq += Decimal.Parse(extended.Substring(0, 2)) * 1000
        freq += Decimal.Parse(extended.Substring(2, 2)) / 10
        getADFFromBCD = freq
    End Function

    Private Sub copyADFToBCDOffsets(ADFDecimal As Decimal, ByRef ADFMainOffset As Offset(Of Short), ByRef ADFExtendedOffset As Offset(Of Short))
        Dim freq As String = ADFDecimal.ToString("0000.0")
        ADFMainOffset.Value = Short.Parse(freq.Substring(1, 3), Globalization.NumberStyles.AllowHexSpecifier)
        ADFExtendedOffset.Value = Short.Parse(freq.Substring(0, 1) & "0" & freq.Substring(5, 1), Globalization.NumberStyles.AllowHexSpecifier)
    End Sub

And here are two functions that increment and decrement individual digits in the real decimal value of the ADF. These handle wrapping around from 9 to 0 and 0 to 9. They also prevent the frequency from going outside the valid FSX range.

    Private Sub incADFDigit(ByRef ADFDecimal As Decimal, digitIndex As Short)
        Dim ADFOriginal As Decimal = ADFDecimal
        digitIndex = digitIndex - 1
        If digitIndex = 4 Then digitIndex = 5
        Dim digitValue As Short = Short.Parse(adf1Decimal.ToString("0000.0").Substring(digitIndex, 1))
        Dim amount As Decimal = 0
        Select Case digitIndex
            Case 0
                amount = 1000
                If digitValue + 1 > 1 Then
                    amount = -1000
                End If
            Case 1
                amount = 100
                If digitValue + 1 > 9 Then
                    amount = -900
                End If
            Case 2
                amount = 10
                If digitValue + 1 > 9 Then
                    amount = -90
                End If
            Case 3
                amount = 1
                If digitValue + 1 > 9 Then
                    amount = -9
                End If
            Case 5
                amount = 0.1
                If digitValue + 1 > 9 Then
                    amount = -0.9
                End If
        End Select
        ADFDecimal += amount
        If ADFDecimal > 1799.9 Then
            ADFDecimal = ADFOriginal
        End If
        If ADFDecimal < 100 Then
            ADFDecimal = ADFOriginal
        End If
    End Sub

    Private Sub decADFDigit(ByRef ADFDecimal As Decimal, digitIndex As Short)
        Dim ADFOriginal As Decimal = ADFDecimal
        digitIndex = digitIndex - 1
        If digitIndex = 4 Then digitIndex = 5
        Dim digitValue As Short = Short.Parse(adf1Decimal.ToString("0000.0").Substring(digitIndex, 1))
        Dim amount As Decimal = 0
        Select Case digitIndex
            Case 0
                amount = -1000
                If digitValue - 1 < 0 Then
                    amount = 1000
                End If
            Case 1
                amount = -100
                If digitValue - 1 < 0 Then
                    amount = 900
                End If
            Case 2
                amount = -10
                If digitValue - 1 < 0 Then
                    amount = 90
                End If
            Case 3
                amount = -1
                If digitValue - 1 < 0 Then
                    amount = 9
                End If
            Case 5
                amount = -0.1
                If digitValue - 1 < 0 Then
                    amount = 0.9
                End If
        End Select
        ADFDecimal += amount
        If ADFDecimal > 1799.9 Then
            ADFDecimal = ADFOriginal
        End If
        If ADFDecimal < 100 Then
            ADFDecimal = ADFOriginal
        End If
    End Sub

How to use these:

 

1. When your application starts you need to fill the decimal value by getting the current value from FSX:

 FSUIPCConnection.Process()
 adf1Decimal = getADFFromBCD(adf1BCDMain, adf1BCDExtended)

2. Call the inc/dec digit function when you need to change the digits. Note you need to pass in the decimal variable and the number of the digit to change. The digits are numbered from 1 to 5 from left to right. So the thousands is digit 1 and the tenths is digit 5. e.g.

        incADFDigit(adf1Decimal, 2) ' increment the hundreds digit
        decADFDigit(adf1Decimal, 3) ' decrement the tens digit

3. Write the new value back to FSX:

 copyADFToBCDOffsets(adf1Decimal, adf1BCDMain, adf1BCDExtended)
 FSUIPCConnection.Process()

Paul

Share this post


Link to post
Share on other sites

i'm just going to try that Paul, thank you.  Your tireless effort to the community should be recognised.

 

Whilst trying the above, question about the com frequencies.  When its a whole number say 132.000, my textbox shows 132

 

I hoped to format it to show 132.000, same as i'd like 132.50 to shows 132.500, I thought a simple format like below would work but no joy, any thoughts?

Me.com1DecStby = getFreqFromBCD(com1bcdstby.Value)

Me.com1DecStby.ToString("##0.000")

Share this post


Link to post
Share on other sites

Your conversion format is correct. The ToString() method just returns the formatted string however, it doesn't affect the com1DecStby variable at all. So you need to use the output of the ToString function.

 

e.g.

Me.Label1.Text = Me.com1DecStby.ToString("##0.000")

Paul

Share this post


Link to post
Share on other sites

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

×

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.