Isak Posted October 22 Report Posted October 22 (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 October 23 by John Dowson Moved to main support forum, key file removed
John Dowson Posted October 23 Report Posted October 23 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
Isak Posted October 23 Author Report Posted October 23 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
John Dowson Posted October 24 Report Posted October 24 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
John Dowson Posted October 24 Report Posted October 24 ...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
Isak Posted October 25 Author Report Posted October 25 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
Isak Posted October 28 Author Report Posted October 28 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
John Dowson Posted October 28 Report Posted October 28 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
Isak Posted October 28 Author Report Posted October 28 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?
Isak Posted October 28 Author Report Posted October 28 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
John Dowson Posted October 28 Report Posted October 28 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
Isak Posted October 29 Author Report Posted October 29 Here I have attached the separate log-file and the lua script. Isak RadioTest.lua RadioTest.log
John Dowson Posted October 29 Report Posted October 29 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.
Isak Posted October 29 Author Report Posted October 29 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
John Dowson Posted October 29 Report Posted October 29 120.800 is in MHz, not KHz, so multiply by 1000000 not 1000 here: local frequency = tonumber(datastring:sub(8)) * 1000000 -- Extract frequency and convert to Hz
Isak Posted October 30 Author Report Posted October 30 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
John Dowson Posted October 31 Report Posted October 31 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
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