FT232RL module as GPIO for softphone
This kind of USB to UART converter based on FT232RL (or more likely its clone) might be cheapest way of adding general purpose inputs and outputs to PC:
- costs $2 if shipped directly from China
- no programming and no assembly required - off the shelf module
- 3.3V or 5V compatible (jumper on the board)
- tested (there might be other useful lines): 2 output lines, 4 input lines
CommState.zip - source + binary
- unzip CommState.dll to /phone subdirectory of tSIP
- activate plugin in tSIP settings
- close tSIP - configuration file (CommState.cfg) would be created
- change COM port number in config file to match port that is assigned to FT232 by OS
DLL is using EscapeCommFunction to control state of DTR and/or RTS line.
-- Lua script lines to control outputs: PluginSendMessageText("CommState.dll", "SET DTR 1") PluginSendMessageText("CommState.dll", "SET DTR 0") PluginSendMessageText("CommState.dll", "SET RTS 1") PluginSendMessageText("CommState.dll", "SET RTS 0")
Note: settings DTR or RTS to 1 sets physical line to 0V, setting state to 0 sets 3.3V or 5V depending on jumper. I think that initial output state should be assumed to be unknown, thus be careful when using it in critical application or when controlling power hungry devices.
For controlling lines from multiple serial interfaces make multiple copies of the DLL (named e.g. Comm1.dll, Comm2.dll, ... CommX.dll) and set different COM number for each of them.
DLL is using GetCommModemStatus to read current state of COM lines. State is then available to Lua scripts as variable with name that consist of lowercase dll name (without extension) and "State" string, e.g. commstateState with default DLL name.
To test inputs you may use resistor (4.7k works) - connecting input to GND through resistor sets its state to 1.
local function bitand(a, b) local result = 0 local bitval = 1 while a > 0 and b > 0 do if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits result = result + bitval -- set the current bit end bitval = bitval * 2 -- shift left a = math.floor(a/2) -- shift right b = math.floor(b/2) end return result end local state, isSet = GetVariable("commstateState") if isSet == 0 then print("commstateState variable is not set (port not opened? DLL not activated?)\n") else print(string.format("commstateState = %s\n", state)) state = tonumber(state) if bitand(state, 128) ~= 0 then print("DCD line is set\n") end if bitand(state, 64) ~= 0 then print("RI line is set\n") end if bitand(state, 32) ~= 0 then print("RSD line is set\n") end if bitand(state, 16) ~= 0 then print("CTS line is set\n") end end
Note: state variable is refreshed once per second. Rebuild DLL from source code if faster refreshing is needed, optionally SetCommMask function can be used to react on event, not read state. If COM port would be detached state variable would be cleared.
As variable name depends on DLL name multiple DLLs can be used simultaneously to monitor multiple ports.
Back to tSIP softphone