Jump to content
The simFlight Network Forums

shorthauler

Members
  • Posts

    117
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by shorthauler

  1. Thanks a lot for your answer, John. The DC-3 is running on FSX, so it might be a bit more difficult finding the Lvar than it is in MSFS.

    There is an XML file that seems to contain Lvars, but if I send this to FSX:

    ipc.writeLvar(“L:Electrical master battery”, 0)

    I am getting an error message:

    Quote

    *** LUA Error: E:\FSX\Flight Simulator X\Modules\C-47_Test.lua:1: unexpected symbol near 'â'

    Which is what I think you get when the Lvar does not exist.

    Best regards,

    - shorthauler

    Control.xml

  2. I am trying to set up a "PilotsDeck - A StreamDeck Plugin" profile for the DIGITAL DAKOTA WORKS DC-3 / C-47. There are switches that work through Event IDs such as 66241 (TOGGLE_MASTER_BATTERY). If I send this Event through PilotsDeck, it does toggle the master battery, but the switch does not move. With other switches such as the light switches, it is different. They do move. I suspect that this is coded with the aircraft and probably cannot be changed, but I wanted to check here whether this might be a known phenomenon. I have also experienced similar issues with other aircraft (Alabeo C421). It might be something related to switches with more than one (three) position(s).

    Best regards,
    - shorthauler

  3. Thanks a lot for your advice. Yes, I am using LuaValue to call the script. Let me describe in my words what is happening:

    Turning the left encoder clockwise sends a feed value of 10 to 0x0D6C. I am monitoring this offset, so I can see that 10 is stored there. As per the script, the MHz value increases by 1 MHz. Any further clockwise turn does not increase the MHz value any further. It remains as it is. I can, however decrease the MHz value by 1 MHz (counterclockwise turn, feed value = 20). But after this, I cannot decrease any further.

    However, this is possible: Clockwise turn with left encoder increases the MHz value by 1. Then,  with a turn (clockwise resp. counterclockwise) increase resp. decrease the kHz value by 50 kHz. Only after having done so, I can increase the MHz value further as it it had been reset.

    It seems to me that once a certain feed value is set, running the script again and sending the same feed value via LuaValue does not do anything (the log file does not even produce further lines).

    Subsequent increments of decrements of MHz are only possible if there has been an increment or decrement of the kHz in between.

     

  4. Documentation for the Lua control function in MobiFlight seems to be a bit thin, I only found this: https://www.mobiflight.com/forum/message/10232.html

    It is lacking the LuaValue function.

    I have found that alternating turns of the encoders for MHz and kHz "unfreezes" the frequencies and they do advance instead of just moving one notch back or one notch forth,

    I could not assert it through the error logging (problably, because it is not an error), but the reason might be that if turning to increase the value, the feed value is set to N. And when increasing further, the same feed value is being sent.

    Event.param, if I have understood it correctly, monitors if the value changes. But this is not the case when the same value is being sent.

    By the way, I am monitoring both offsets 0x0D6C and 0x0D70, and the feed value is shown only in 0x0D6C.

    I have tried to adapt the script to "event.offset" so 0x0D6C is monitored and the script is run when it changes, but this also does not help, because if a turn in let's say the right direction always sends 10, then the offset or the param does not change.

    I have also tried to reset 0x0D6C to 0 after every input, but it does not work, yet. I will keep trying.

  5. When I wrote "undocumented," I meant undocumented for MobiFlight, sorry. I have tried the debugging facilities, but to no avail. I have also added these lines to reset the feeder value:

    ipc.sleep(500)
    ipc.writeUB(0x0D6C,0)

     

    end
    
    	newNav1_BCD = convertToBCD(tostring(newNav1))	-- convert to BCD
        ipc.control(65708, newNav1_BCD)	-- sending BCD to FSUIPC
    	ipc.sleep(500)
    	ipc.writeUB(0x0D6C,0)
    	
    end
                                          
    event.param("updateNav1")
    ipc.log("Nav1 update lua script now running")
                                          

    Unfortunately, I cannot figure out why the script only changes a value in one step up or down and then stopps changing the value.

    FSUIPC4 (2).zip

  6. Thanks a lot, John. This sort of works. I might have found a way to send values via Mobiflight to scripts via the LuaValue function (which I think is undocumented, I will write later about this). But the Value only increases 100 up and further input (I tried my encoders but also a joystick button) do not further increase the value, same with decreasing. It stops after a decrease of 100. I will try to look into this later.

  7. Unfortunately, these scripts react rather slowly and it seems to me that they also make FSX freeze after a while. Can't say whether this is because I am using MobiFlight for my hardware (not the fastest to process inputs) or because I am feeding values through MobiFlight to 0X0D6C to indicate which encoder is being turned into what direction. I will have to set up other hardware (Stream Deck buttons) for comparison.

  8. Thanks a lot, John. Yes this does work. I am pasting in an adapted script for the COM radio, reflecting the 25 kHz spacing. Trivia alert: With the 25 kHz spacing, the trailing 5 in the simulated radio dial is actually truncated, so the last digits will be 0, 2, 5 or 7. It's still found in FSX but has been replaced in real life by a 8.33 kHz spacing.

    --
    -- function to convert to BCD
    --
    function convertToBCD(freq)					
        local cleanFreq = freq:gsub("%.", "")  
        local decimalNumber = tonumber(cleanFreq) 
    		
        if not decimalNumber then return 0 end 
    
        local bcd = 0
        local shift = 0
    
        while decimalNumber > 0 do
            local digit = decimalNumber % 10
            bcd = bcd + (digit * (16 ^ shift)) 
            decimalNumber = math.floor(decimalNumber / 10)
            shift = shift + 1
        end
    
        return bcd
    end
    	
    feed_value = ipc.readUB(0x0D6C)  
    currentComBCD = ipc.readUW(0x034E) 
    currentCom = string.format("%04X", currentComBCD)  
    
    if feed_value==22 then  
        if tonumber(currentCom) >= 3600 then
          newCom = currentCom - 1800  
        else
          newCom = currentCom + 100
        end
    elseif feed_value==12 then    
    	if tonumber(currentCom) <= 1897 then 
          newCom = currentCom + 1800  
        else
          newCom = currentCom - 100
        end
    elseif feed_value==42 then    						-- the following lines reflect the 25 kHz spacing (found in FSX, but in real life nowadays superseded by a 8.33 kHz spacing)
        if string.find(currentCom, "%d%d97") then	
            newCom = currentCom - 97		
        elseif
    		string.find(currentCom, "%d%d%d7") then	
            newCom = currentCom + 3
    	elseif 
    		string.find(currentCom, "%d%d%d2") then	
    		newCom = currentCom + 3
    	elseif
    		string.find(currentCom, "%d%d%d0") then	
    		newCom = currentCom + 2
    	else
    	   newCom = currentCom + 2
        end
    else    
        if string.find(currentCom, "%d%d00") then	
            newCom = currentCom + 97		
        elseif
    		string.find(currentCom, "%d%d%d7") then	
            newCom = currentCom - 2
    	elseif 
    		string.find(currentCom, "%d%d%d2") then	
    		newCom = currentCom - 2
    	elseif
    		string.find(currentCom, "%d%d%d0") then	
    		newCom = currentCom - 3
    	else
    	   newCom = currentCom - 3
        end
    end
    
    
    newCom_BCD = convertToBCD(tostring(newCom))	-- convert to BCD
    ipc.control(65707, newCom_BCD)	-- sending BCD to FSUIPC

     

  9. Improved script. You can now turn the encoder for the kHz value completey seperately from the encoder for MHz. For example, if you reach "111.00" and continue decreasing the kHz value, you will get 111.95, not 110.95.

     

    	feed_value = ipc.readUB(0x0D6C) 		-- depending on which rotary encoder is turned and into which direction, MobiFlight sends a feed value to offset 0x0D6C
    
    	if feed_value==10 then					-- if turned right, the left encoder (MHz) sends the value 10 to offset 0x0D6C
    
    	currentNav1 = ipc.readUW(0x0350)		-- read the current NAV1 frequency
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		-- convert decimal to string
    	currentNav1_string_number = tonumber(currentNav1_string)			-- convert string to number
    
    		if currentNav1_string_number >= 11700	-- the following lines increase the MHz value by 1 MHz and wrap the frequency around, substracting 900, when 117 MHz is reached
    			then
    		newNav1 = currentNav1_string_number - 900
    			else
    		newNav1 = currentNav1_string_number + 100
    		end
    		
    	newNav1_string =tostring(newNav1)			-- converting the decimal to a string, so that the leading 1 can be cut
    	newNav1_cut = newNav1_string:sub(2,-1)		-- cutting the leading 1
    
    	elseif feed_value==20 then					-- if turned left, the left encoder (MHz) sends the value 20 to offset 0x0D6C
    	
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if currentNav1_string_number <= 10895	-- the following lines decrease the MHz value by 1 MHz and wrap the frequency around, adding 900, when 108.95 MHz is reached
    			then
    		newNav1 = currentNav1_string_number + 900
    			else
    		newNav1 = currentNav1_string_number - 100
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)		
    
    	elseif feed_value==30 then					-- if turned right, the right encoder (kHz) sends the value 30 to offset 0x0D6C
    
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if string.find(currentNav1_string, "%d%d%d95")	-- this line checks whether the frequency ends with 95 and ...
    			then
    		newNav1 = currentNav1_string_number - 95		-- ... if so, substractss 95 kHz so as to prevent the frequency from carrying (changing the MHz value) when digit wraps. So you can turn the encoder for the kHz value seperately without increasing the MHz value.
    			else
    		newNav1 = currentNav1_string_number + 5
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)		
    
    	else										-- if turned left, the right encoder (kHz) sends the value 40 to offset 0x0D6C, which for now is "else"
    	
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if string.find(currentNav1_string, "%d%d%d00")	-- this line checks whether the frequency ends with 00 and ...
    			then
    		newNav1 = currentNav1_string_number + 95		-- ... if so, adds 95 kHz so as to prevent the frequency from carrying (changing the MHz value) when digit wraps. So you can turn the encoder for the kHz value seperately without decreasing the MHz value.
    			else
    		newNav1 = currentNav1_string_number - 5
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)
    
    end
    
    	function convertToBCD(freq)					-- function to convert to BCD
    		local cleanFreq = freq:gsub("%.", "")  -- Remove decimal (e.g., "109.2" → "0920")
    		local decimalNumber = tonumber(cleanFreq) -- Convert to number
    		
    		if not decimalNumber then return 0 end -- Return 0 if conversion fails
    
    		local bcd = 0
    		local shift = 0
    
    		-- Convert each decimal digit to BCD format
    		while decimalNumber > 0 do
    			local digit = decimalNumber % 10
    			bcd = bcd + (digit * (16 ^ shift)) -- Use base 16 shift instead of bitwise left shift
    			decimalNumber = math.floor(decimalNumber / 10)
    			shift = shift + 1
    		end
    
    		return bcd
    	end
    
    	newNav1_BCD = convertToBCD(newNav1_cut)	-- calling the function
    	ipc.control(65708, newNav1_BCD)	-- sending BCD to FSUIPC
    

     

  10. For possible further reference, this is the function as it stands now. I am using it with MobiFlight's "FUSIPC - Lua Macro" function that sends values to offset 0x0D6C. Depending on which encoder is turned in what direction, different values are sent that are triggering different operations to increase/decreas MHz/kHz. 

    FSX EventIDs would only manipulate the standby frequencies that can then be swapped with the active frequency. Vintage aircraft do not have standby radios, so this script was needed for my home cockpit to manipulate the active frequency directly.

    A big thanks to John for all his help. Comments, especially corrections, are most welcome.

     

    	feed_value = ipc.readUB(0x0D6C) 		-- depending on which rotary encoder is turned and into which direction, MobiFlight sends a feed value to offset 0x0D6C
    
    	if feed_value==10 then					-- if turned right, the left encoder (MHz) sends the value 10 to offset 0x0D6C
    
    	currentNav1 = ipc.readUW(0x0350)		-- read the current NAV1 frequency
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		-- convert decimal to string
    	currentNav1_string_number = tonumber(currentNav1_string)			-- convert string to number
    
    		if currentNav1_string_number >= 11700	-- the following lines increase the MHz value by 1 MHz and wrap the frequency around, substracting 900, when 117 MHz is reached
    			then
    		newNav1 = currentNav1_string_number - 900
    			else
    		newNav1 = currentNav1_string_number + 100
    		end
    		
    	newNav1_string =tostring(newNav1)			-- converting the decimal to a string, so that the leading 1 can be cut
    	newNav1_cut = newNav1_string:sub(2,-1)		-- cutting the leading 1
    
    	elseif feed_value==20 then					-- if turned left, the left encoder (MHz) sends the value 20 to offset 0x0D6C
    	
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if currentNav1_string_number <= 10895	-- the following lines decrease the MHz value by 1 MHz and wrap the frequency around, adding 900, when 108.95 MHz is reached
    			then
    		newNav1 = currentNav1_string_number + 900
    			else
    		newNav1 = currentNav1_string_number - 100
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)		
    
    	elseif feed_value==30 then					-- if turned right, the right encoder (kHz) sends the value 30 to offset 0x0D6C
    
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if currentNav1_string_number == 11795	-- the following lines increase the kHz value by 50 kHz and wrap the frequency around, substracting 9995, when 117.95 MHz is reached
    			then
    		newNav1 = currentNav1_string_number - 9995
    			else
    		newNav1 = currentNav1_string_number + 5
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)		
    
    	else										-- if turned left, the right encoder (kHz) sends the value 40 to offset 0x0D6C, which for now is "else"
    	
    	currentNav1 = ipc.readUW(0x0350)		
    	currentNav1_string = "1" .. string.format("%04X", currentNav1)		
    	currentNav1_string_number = tonumber(currentNav1_string)
    
    		if currentNav1_string_number == 10800	-- the following lines decrease the kHz value by 50 kHz and wrap the frequency around, adding 9995, when 108.00 MHz is reached 
    			then
    		newNav1 = currentNav1_string_number + 9995
    			else
    		newNav1 = currentNav1_string_number - 5
    		end
    		
    	newNav1_string =tostring(newNav1)		
    	newNav1_cut = newNav1_string:sub(2,-1)
    
    end
    
    	function convertToBCD(freq)					-- function to convert to BCD
    		local cleanFreq = freq:gsub("%.", "")  -- Remove decimal (e.g., "109.2" → "0920")
    		local decimalNumber = tonumber(cleanFreq) -- Convert to number
    		
    		if not decimalNumber then return 0 end -- Return 0 if conversion fails
    
    		local bcd = 0
    		local shift = 0
    
    		-- Convert each decimal digit to BCD format
    		while decimalNumber > 0 do
    			local digit = decimalNumber % 10
    			bcd = bcd + (digit * (16 ^ shift)) -- Use base 16 shift instead of bitwise left shift
    			decimalNumber = math.floor(decimalNumber / 10)
    			shift = shift + 1
    		end
    
    		return bcd
    	end
    
    	newNav1_BCD = convertToBCD(newNav1_cut)	-- calling the function
    	ipc.control(65708, newNav1_BCD)	-- sending BCD to FSUIPC
    

     

    Mobiflight.JPG

  11. A quick update - I now have a working lua script. As I am still in the "lab phase" (experimenting), I am using a button to trigger. And so far I only increase the kHz. Decreasing the frequency, also Hz, using rotary encoders will follow later. Also, the kHz will increase until the limit of 117 and then do not not wrap around, this also needs to be sorted. But so far, I am quite happy. Thanks a lot, John! Will post the whole script when ready.

     

     

    currentNav1 = ipc.readUW(0x0350)		-- read the current NAV1 frequency
    currentNav1_string = "1" .. string.format("%04X", currentNav1)		-- convert decimal to string (maybe superflous as the next line will treat the string as a number)
    newNav1 = currentNav1_string + 100		-- lua has lazy types and will convert the string to a decimal and we increment by 1MHz
    newNav1_string =tostring(newNav1)		-- converting the decimal to a string, so that the leading 1 can be cut
    newNav1_cut = newNav1_string:sub(2,-1)		-- cutting the leading one
    
    function convertToBCD(freq)
        local cleanFreq = freq:gsub("%.", "")  -- Remove decimal (e.g., "109.2" → "0920")
        local decimalNumber = tonumber(cleanFreq) -- Convert to number
        
        if not decimalNumber then return 0 end -- Return 0 if conversion fails
    
        local bcd = 0
        local shift = 0
    
        -- Convert each decimal digit to BCD format
        while decimalNumber > 0 do
            local digit = decimalNumber % 10
            bcd = bcd + (digit * (16 ^ shift)) -- Use base 16 shift instead of bitwise left shift
            decimalNumber = math.floor(decimalNumber / 10)
            shift = shift + 1
        end
    
        return bcd
    end
    
    newNav1_BCD = convertToBCD(newNav1_cut)		-- calling the function suggested by John
    
    ipc.control(65708, newNav1_BCD)		-- sending the BCD to FSX

     

     

  12. Thank you very much. Does NAV1_RADIO_SET_HZ (67251) work for FSX? I am under the impression that it is only available for MSFS.

    For FSX, I have found NAV1 RADIO SET 65708, but I was not able to find an explication what it actually does.

    The script works as it sends the parameters to the values as I take from the FSUIPC log file:

      8469032 [Buttons] 4=P2,4,CL18:R,0
      8469110 FS Control Sent: Ctrl=67251, Param=118200000
      8469313 Button changed: bRef=0, Joy=2, Btn=4, Released

    But there is no change in FSX. Same for 65708.

    Best,
    shorthauler

    Files C-47 Radios.zip

  13. Hi John,
    These are the files, please let me know if something is missing. The script is triggered by a joystick button (for testing purposes) and should only increase the frequency by 1 MHz. Decreasing and kHz should follow once this works.
    Best,
    shorthauler

    This should be my script:

    oldNav1 = ipc.readUW(0350)                                                     => reading the offset
    newNav1_string = string.format(oldNav1, 0xaf)                         => converting the HEX value to a string
    newNav1_string_shortened = string.sub(newNav1_string, 3)     => starting from the 3rd digit of the string, thereby cutting the first two digits from the string
    newNav1 = tonumber (newNav1_string_shortened)                  => converting the string to a (decimal) integer
    newNav1_Hz = newNav1*10000                                                 => multiplying with 10^4 to obtain herz,
    newNav1_value = newNav1_Hz+1000000                                  => adding 1^6 Hz = 1 MHz
    ipc.writeLvar("L:NAV1_RADIO_SET_HZ", newNav1_value)           => sending the result to FSX

    Files C-47 Radios.zip

  14. Thank you very much, I tried this, but no luck:

    oldNav1 = ipc.readUW(0350)

    newNav1 = oldNav1 +100

    function Nav1plus(param)
            ipc.writeLvar("L:NAV1_RADIO_SET", newNav1)
    end

    event.param ("Nav1plus")

    This is what I get in the log:

    ********* LUA: "C-47 Radios" Log [from FSUIPC version 4.977] *********
      7576015 System time = 15/02/2025 20:28:31, Simulator time = 13:45:33 (19:45Z)
      7576015 LUA: beginning "E:\FSX\Flight Simulator X\Modules\C-47 Radios.lua"
      7576031 >>> Thread forced exit (ipc.exit or os.exit) <<<
      7576031 System time = 15/02/2025 20:28:31, Simulator time = 13:45:33 (19:45Z)
    ********* LUA execution terminated: Log Closed *********

    Any idea what I could try that might work?

  15. Hm, these are the onese that I am using:

    65640   NAV1_RADIO_WHOLE_DEC
    65641   NAV1_RADIO_WHOLE_INC
    65642   NAV1_RADIO_FRACT_DEC
    65643   NAV1_RADIO_FRACT_INC

    But they only change the standby frequency in the background (invisible, because just one Nav radio in the DC 3, no standby display). How do I know this? I have a frequency ("frequency 1") in the active (only) frequency display, I toggle via FSUIPC, I then have another frequency ("frequency 2") in the display. I dial my rotary encoders, "frequency 2" remains unchanged. I toggle again and "frequency 1" is back in the display, but this time modified according to how I have turned the dials.

  16. Thank you, problem solved. The out-of-the-box controls in FSX were *not* disabled (options/settings/controls/enable controllers) so they were interfering. My CMOS battery was empty and I had to start the PC without it a few times before the new battery came in. I don't know if it was this or something else, but something must have erased my FSX.cfg (I take this from the fact that all of a sudden the startup music was back on). And so the controllers were enabled and interfered. Apologies for taking your time with something that I could have figured myself. My punishment are a lot of nights without flight simming.

  17. Thank you, problem solved. The out-of-the-box controls in FSX were *not* disabled (options/settings/controls/enable controllers) so they were interfering. My CMOS battery was empty and I had to start the PC without it a few times before the new battery came in. I don't know if it was this or something else, but something must have erased my FSX.cfg (I take this from the fact that all of a sudden the startup music was back on). And so the controllers were enabled and interfered. Apologies for taking your time with something that I could have figured myself. My punishment are a lot of nights without flight simming.

×
×
  • 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.