Jump to content
The simFlight Network Forums

Recommended Posts

Posted (edited)

*** Moved from FSUIPC7 / MSFS sub-forum to main support forum ***

Hi everyone,

I’m currently working on a small Arduino project that allows me to input a radio frequency using a keypad. The frequency is displayed on an LCD screen. For example, if I type 120.800 and press the "#" key, the following appears in the serial monitor:

COM1SB 120.800

What I want to achieve is setting the COM1 standby frequency in the simulator. I believe I’ll need to write a Lua script to detect the string "COM1SB", extract the frequency, and send it to the simulator using ipc.control.

Am I correct that 66371 (COM_STBY_RADIO_SET) is the right ipc.control command to use? Could someone share an example of a Lua script that would accomplish this?

Best regards,
Isak

 

Edited by John Dowson
Moved to main support forum, key file removed
  • Isak changed the title to Lua script to set the COM1 standby frequency (FSUIPC6 and P3Dv5)
Posted

First, you posted in the sub-forum for FSUIPC7 / MSFS - please use the main forum for all other versions of FSUIPC, not the specific sub-forum for FSUIPC7.
You also attached the trial license/key file for FSUIPC7 for some reason...I have removed that.

16 hours ago, Isak said:

Am I correct that 66371 (COM_STBY_RADIO_SET) is the right ipc.control command to use? Could someone share an example of a Lua script that would accomplish this?

Yes, that is the correct control/event, but be aware that the parameter for that control is in BCD16 format (Binary-encoded decimal), so to set to 120.80 you would use:
     ipc.control(66371, 0x2080)
(the leading 1 is assumed).

17 hours ago, Isak said:

I believe I’ll need to write a Lua script to detect the string "COM1SB", extract the frequency,

That is the difficult bit. You would need to register a function to receive key presses (using the event.key function) for the keys 'C'. 'O', 'M'. '1', ' ', 'S', 'B', ',' , and all the digits, then keep track of everything entered and in the correct order....I really can't recommend doing it this way....

Maybe take a look at this user' contribution, which is a lua script to allow keyboard entry for radios (as well as obs and AP). Its for FSUIPC4, but should work with FSUIPC5, although some small modifications may be needed: 

 

 

John

Posted

Hi John,

Thank you for your detailed response and for pointing out my mistake with the forum and the license file. Apologies for that!

I appreciate the clarification on the BCD16 format. That example definitely helps.

Regarding the Lua script for detecting "COM1SB," I can see how handling all those key presses might get complicated. I'll check out the Lua script you mentioned for keyboard entry of radios and see if I can adapt it to my needs.

Thanks again for your help!

Best regards,
Isak

Posted

I am not sure how you are getting the input to set your LCD display, but It may be easier to use the ipc.ask lua function to get this user input / com frequency in one go (rather than monitoring keyboard input via event.key), and then use the value received to set your LCD display (however that is done!) and send the control to set in the sim. You would need to run such a script on a specific key combination or button press.
Cheers,

John

Posted

...and if you have written your own program to drive the LED connected to the arduino, you could use the FSUIPC SDK to just write the com1 standby frequency to offset 0x05CC (or 0x311A).

Note that you can also use the following control to set the frequency using Hz rather than in BCD format:

67363   COM1_STBY_RADIO_HZ_SET

Posted

Thank you for the insights, John! I'm currently traveling, but as soon as I'm back, I'll share my Arduino code and my current Lua script attempt. Looking forward to any additional feedback you might have once I post those details.

Cheers,

Isak

Posted

Here is the working Arduino code that allows me to type in a frequency, which then shows up on the LCD screen. When I press the "#" key, the frequency is sent over the serial port as shown below (output from the serial monitor):

17:12:34.711 -> COM1SB 120.800
 

#include <Keypad.h>
#include <LiquidCrystal.h>

// Initialize the LCD connected to pins 9, 8, 7, 6, 5, 4 on Arduino
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

// Keypad settings
const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {A0, A1, A2, A3}; 
byte colPins[COLS] = {A4, A5, A6, A7}; 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

String frequency = "1";  // Pre-define the first digit as '1'

void setup() {
  lcd.begin(20, 4); 

  // Turn off the display:
  lcd.noDisplay(); delay(500);
  // Turn on the display:
  lcd.display();
  
  // Initial LCD message:
  lcd.setCursor(0, 0);
  lcd.print("Keypad Radio");
  delay(4000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Frequency to send:");
  
  Serial.begin(115200); //start checking serial connection
}

void loop() {
  char key = keypad.getKey();
  if (key) {
    if (key == '#') {
      sendFrequencyToSim();
      frequency = "1";  // Reset to '1' after sending
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Frequency to send:");
    } else if (key == '*') {
      if (frequency.length() > 1) {  // Ensure '1' stays as the first digit
        frequency.remove(frequency.length() - 1); // Remove last digit
        
        // Clear the previous frequency display and update it
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Frequency to send:");
        lcd.setCursor(0, 2);
        lcd.print(formatFrequency(frequency));
      }
    } else if (isDigit(key)) {
      if (frequency.length() < 6) {  // limit to 6 digits (including '1')
        frequency += key;
        
        // Update the LCD with the new frequency
        lcd.setCursor(0, 2);
        lcd.print(formatFrequency(frequency));
      }
    }
  }
}

String formatFrequency(String freq) {
  // Automatically add the decimal point at the right place
  if (freq.length() >= 4) {  // Adjusted to account for the pre-defined '1'
    return freq.substring(0, 3) + "." + freq.substring(3);
  }
  return freq;  // If less than 3 digits, no decimal
}

void sendFrequencyToSim() {
  String formattedFrequency = formatFrequency(frequency);  // Add the decimal point
  Serial.print("COM1SB ");  // Add COM1SB tag
  Serial.println(formattedFrequency);  // Send formatted frequency (with decimal)
}

Now, I am struggling with the Lua script. I’m not very experienced with coding and would really appreciate any guidance. My current attempt connects to the serial port, but the frequency is not being set:

----------------------------------------------------------------
----------------------------------------------------------------
dev = com.open("COM6", 115200, 0)  -- Open COM port with baud rate 115200
----------------------------------------------------------------
----------------------------------------------------------------

-- Display a message to indicate that the script is running
ipc.display("Lua script is running...", 3)  -- Message stays for 3 seconds

function processInput()
    local datastring = com.read(dev, 256, 100)  -- Read up to 256 bytes from the serial port, 100ms timeout
    if datastring ~= "" then
        ipc.display("Data received: " .. datastring, 2)  -- Display the received data for debugging

        -- Example of parsing the received string to set COM1 standby frequency
        if datastring:match("^COM1SB") then
            local frequency = tonumber(datastring:sub(8)) * 1000  -- Extract frequency and convert to Hz
            ipc.control(67363, frequency)  -- COM1_STBY_RADIO_HZ_SET
            ipc.display("COM1 standby frequency set to: " .. frequency, 3)
        end
    end
end

-- Main loop to continuously check for serial input
while true do
    processInput()  -- Call the function to process any incoming serial data
    ipc.sleep(100)  -- Small delay to avoid high CPU usage
end

Cheers,

Isak

Posted
16 minutes ago, Isak said:

Now, I am struggling with the Lua script. I’m not very experienced with coding and would really appreciate any guidance. My current attempt connects to the serial port, but the frequency is not being set:

Is the script receiving any data? Try debugging the script, by either starting it with LuaDebug or by setting Debug / Trace Lua plugins in the FSUIPC logging tab.

 But it would be better to update your C code and use the FSUIPC SDK to update the offset with the COM! stndby frequency. Take a look in the SDK subfolder, at the UIPC64_SDK_C_version2 toolkit. You can use this to update FSUIPC offsets, which will trigger the controls to set the values in the FS,

John

Posted

So, if I change the C code and use the FSUIPC SDK to update the offset with the COM! stndby frequency, there is no need for a lua script?

Posted

Here is the FSUIPC6.log that shows what happens when I start the script and try to send/set a frequency. The script is called RadioTest.lua.

FSUIPC6.log

Posted
1 hour ago, Isak said:

So, if I change the C code and use the FSUIPC SDK to update the offset with the COM! stndby frequency, there is no need for a lua script?

Yes.

49 minutes ago, Isak said:

Here is the FSUIPC6.log that shows what happens when I start the script and try to send/set a frequency. The script is called RadioTest.lua.

You are using Linda so that log is very difficult to interpret...set Log Lua plugins separately and show me the log file for the script only, and also attach the script.

John

Posted
Quote

    local datastring = com.read(dev, 256, 100)  -- Read up to 256 bytes from the serial port, 100ms timeout

This is not correct - the documentation states:

str, n = com.read(handle,max,min)

so your call will always return a null string until at least 100 characters are read, Please see the documentation on com.read (see below)  - you need something like (with no minimum):

function processInput()
    local datastring, length = com.read(dev, 256)  -- Read up to 256 bytes from the serial port
    if length then
        ipc.display("Data received: " .. datastring, 2)  -- Display the received data for debugging
        ipc.log("Data received: '" .. datastring .. "' [" .. length .. "]") -- log to file
        -- Example of parsing the received string to set COM1 standby frequency
        if datastring:match("^COM1SB") then
            local frequency = tonumber(datastring:sub(8)) * 1000  -- Extract frequency and convert to Hz
            ipc.control(67363, frequency)  -- COM1_STBY_RADIO_HZ_SET
            ipc.display("COM1 standby frequency set to: " .. frequency, 3)
            ipc.log("COM1 standby frequency set to: " .. frequency)  -- log to file
        end
    end
end

John

str, n = com.read(handle,max)

str, n = com.read(handle,max,min)

str, n = com.read(handle,max,min, term)

Reads up to 'max' bytes from the port, returning them as a string in 'str' with the number actually read returned in 'n'.

If the 'min' parameter is also given, this returns a null string and n=0 until at least that minimum number of bytes are available. It does not block waiting for them. If you specify -1 as the minimum then the terminating character ('term') must be seen before the function returns a non-zero result, unless of course the 'max' size is reached first.

The 'term' parameter specifies an ASCII value (0 to 255) which is to be treated as a terminator for each block. This character is included in the returned count and string.

Note that you can use the event library function, event.com to perform reads and call your Lua back when there is data to process. This can be more efficient and tidier than a program which uses continuous loops to scan the input.

 

Posted

With the code you suggested (with no minimum), I now receive a SimConnect message when I try to send a frequency.

For example, when I type in 120.800 and send it, the following message appears:

SimConnect Message Window
COM1 standby frequency set to: 120800

Or if I send 118.100, I get:

SimConnect Message Window
COM1 standby frequency set to: 118100

However, the COM1 standby frequency in the aircraft does not actually update. I am using the standard Lockheed Martin AC-130H aircraft for testing. Any insights on what might be missing?

I attached the script and log file again.

Isak

RadioTest.log RadioTest.lua

Posted

I just got back from work and tried multiplying by 1000000, and it worked! Thank you so much for helping me out. Now, I’m planning to optimize the Lua script further by using the event.com function to handle reads and call back when there’s data to process. I’ll also look into modifying the C code to send the frequency directly to the simulator.

Again, thank you so much for your help!

Cheers,
Isak

Posted

Glad its now working. Yes, using event.com is much more efficient.

10 hours ago, Isak said:

I’ll also look into modifying the C code to send the frequency directly to the simulator.

That is probably a better long-term solution, as you are already writing your own code to drive the LCD. Via the SDK, you can either write the COM1 standby frequency (in Hz) to offset 0x05CC (as a 4-byte int), or you can use offset 0x3110 which operates a facility to send any control to the FS.

Cheers,

John

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.