The simFlight Network Forums

# 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 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 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 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 on other sites

• 2 weeks later...

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 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 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)
```

```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 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 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 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 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 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 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 on other sites

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
Dim extended As String = ADFExtended.Value.ToString("X4")
freq += Decimal.Parse(extended.Substring(0, 2)) * 1000
freq += Decimal.Parse(extended.Substring(2, 2)) / 10
End Function

Dim freq As String = ADFDecimal.ToString("0000.0")
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)
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
End If
End If
End Sub

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
End If
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()

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

3. Write the new value back to FSX:

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

Paul

##### 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 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

## Create an account

Register a new account