hawkt1 Posted November 23, 2015 Report Posted November 23, 2015 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
Paul Henty Posted November 24, 2015 Report Posted November 24, 2015 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
hawkt1 Posted November 24, 2015 Author Report Posted November 24, 2015 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!
Paul Henty Posted November 24, 2015 Report Posted November 24, 2015 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
hawkt1 Posted December 4, 2015 Author Report Posted December 4, 2015 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
Paul Henty Posted December 4, 2015 Report Posted December 4, 2015 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: COM14: COM22: NAV11: NAV2 e.g. to swap COM2: stbySwap.Value = 4 ' COM2 FSUIPCConnection.Process() Paul
hawkt1 Posted December 4, 2015 Author Report Posted December 4, 2015 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
Paul Henty Posted December 5, 2015 Report Posted December 5, 2015 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
hawkt1 Posted December 7, 2015 Author Report Posted December 7, 2015 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
Paul Henty Posted December 7, 2015 Report Posted December 7, 2015 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
hawkt1 Posted December 7, 2015 Author Report Posted December 7, 2015 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
hawkt1 Posted December 7, 2015 Author Report Posted December 7, 2015 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?
Paul Henty Posted December 7, 2015 Report Posted December 7, 2015 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
Paul Henty Posted December 8, 2015 Report Posted December 8, 2015 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
hawkt1 Posted December 8, 2015 Author Report Posted December 8, 2015 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")
Paul Henty Posted December 8, 2015 Report Posted December 8, 2015 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now