Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by FSFIan

  1. Does it work if you change the timeout in the new script to three seconds as well?
  2. Try the following: #define DCSBIOS_IRQ_SERIAL #include "DcsBios.h" namespace DcsBios { class SwitchMultiPosBCD : PollingInput { private: const char* msg_; const byte* pins_; char numberOfPins_; char lastState_; char readState() { unsigned char i; unsigned char state = 0; for (i=0; i<numberOfPins_; i++) { unsigned char j = numberOfPins_ - i - 1; state |= (digitalRead(pins_[i]) << j); } return state; } void pollInput() { char state = readState(); if (state != lastState_) { char buf[7]; utoa(state, buf, 10); if (tryToSendDcsBiosMessage(msg_, buf)) lastState_ = state; } } public: SwitchMultiPosBCD(const char* msg, const byte* pins, char numberOfPins) : lastState_(0) { msg_ = msg; pins_ = pins; numberOfPins_ = numberOfPins; unsigned char i; for (i=0; i<numberOfPins; i++) { pinMode(pins[i], INPUT_PULLUP); } lastState_ = readState(); } }; } const byte iffMode1Wheel1Pins[4] = {5, 6, 7, 8}; DcsBios::SwitchMultiPosBCD iffMode1Wheel1("IFF_MODE1_WHEEL1", iffMode1Wheel1Pins, 4); void setup() { DcsBios::setup(); } void loop() { DcsBios::loop(); } Using the SwitchMultiPos class as a starting point, I wrote a SwitchMultiPosBCD class. All I had to change was the readState() method so it treats the pin numbers it is given as a BCD type input instead of "one pin per position". The code I posted assumes that a BCD input is connected to pins 5, 6, 7 and 8, with 5 being the most significant bit and pin 8 being the least significant bit. If a "1" bit means LOW in your setup instead of HIGH (in case your BCD output is not a digital output but a switch that pulls the Arduino pin to ground), you can change the readState() method so it inverts the input values it reads: // before: state |= (digitalRead(pins_[i]) << j); // after: state |= ((digitalRead(pins_[i]) ^ 1) << j); You can use the SwitchMultiPosBCD class just like SwitchMultiPos. If you copy from the control reference, make sure to get the length of the pin number array right in both locations (the definition of the array and the instantiation of SwitchMultiPosBCD in the line after that).
  3. What aircraft type is your client aircraft? I just tried it with an A-10C and could not get it to work. I added an A-10C (group name "a10c") to a mission, skill set to "Client", runway start. I started the mission, jumped into the A-10C, and then executed the following code: local cpos = Group.getByName("a10c"):getUnit(1):getPosition().p local wp = {} wp.speed = 100 wp.x = cpos.x wp.y = cpos.y wp.type = 'Turning Point' wp.ETA_locked = false wp.ETA = 100 wp.alt = 500 wp.alt_type = "BARO" wp.speed_locked = true wp.action = "Fly Over Point" wp.airdromeId = nil wp.helipadId = nil local wp1 = {} wp1.speed = 500 wp1.x = cpos.x + 1000 wp1.y = cpos.y + 10000 wp1.type = 'Turning Point' wp1.ETA_locked = false wp1.ETA = 100 wp1.alt = 500 wp1.alt_type = "BARO" wp1.speed_locked = true wp1.action = "Fly Over Point" wp1.airdromeId = nil wp1.helipadId = nil wp1.name = "BAR" local newRoute = {} newRoute[1]=wp newRoute[#newRoute+1]=wp1 local newTask = { id = 'Mission', params = { route = { points = newRoute, }, }, } local group = Group.getByName("a10c") local ctrl = group:getController() ctrl:pushTask(newTask) My waypoints did not change at all.
  4. The emergency trim hat uses different commands for each direction, which I missed when I added the A-10C module. Fixed in v0.5.4. (I then remembered the new connect-serial-port.cmd script I wanted to add, so the latest release is v0.5.5 now.) Thanks for the comprehensive bug report!
  5. Released DCS-BIOS v0.5.5. Changes from 0.5.3: A-10C: fix Emergency Trim Hat on the Emergency Flight Control Panel Add improved connect-serial-port.cmd script (ask for COM port, fix an issue with Arduino Mega boards getting stuck in the bootloader by adding a small delay) For comments and general feedback use the DCS-BIOS Discussion Thread. If you need help or have found a bug, please open a new thread in the Home Cockpits forum.
  6. Try editing your connect-serial-port.cmd script and insert the following line after the line with the "mode" command: timeout 3 See also: this post by GSS Rain, who had the same issue. When using a Mega, it sometimes gets stuck in the bootloader when it receives data too soon after being reset. I'll release an updated version of DCS-BIOS with the new script in a few days when I get back to my apartment.
  7. Thanks for testing! I'll release a new version of DCS-BIOS with the modified script in a few days when I get back to my apartment.
  8. Hallo McMicha, hier hat jemand das Problem, dass euer ExportScript und Simshaker nicht gleichzeitig funktionieren. Das liegt daran, dass ihr im ExportScript die Callback-Funktionen (LuaExportStart, etc.) einfach neu definiert, ohne Rücksicht auf Callbacks, die möglicherweise von Skripten definiert wurden, die vor euch geladen wurden. Die Lösung des Problems ist relativ einfach: bevor Ihr eure eigenen Callbacks definiert, einfach Referenzen auf die existierenden irgendwo hin speichern und dann von euren neuen Callbacks aus aufrufen. Im DCS Export Core benutze ich dazu einfach eine file-local variable. Auf die Verwendung von LuaExportActivityNextEvent(t) würde ich komplett verzichten (die kann nämlich nicht von zwei Skripten benutzt werden, ohne dass die sich gegenseitig auf die Füße treten). Statt dessen könnt ihr z.B. in LuaExportBeforeNextFrame() über LoGetModelTime() die aktuelle Zeit abfragen.
  9. It looks like the current DCS ExportScript for DAC and Ikarus does not preserve existing callback functions, it simply overwrites them. This means it will remove any callbacks from things that were loaded before it. If you load the ExportScript first and Simshaker second, it should work (because Simshaker checks for existing callback functions and makes sure they get called). I'll ask McMicha to add handling of existing callbacks in their thread on the German boards.
  10. You can get special cable designed for RS-485. It was designed for the same conditions as RS-485: industrial automation. It's shielded, flame- and smoke-protected, and expensive. It's also overkill for our purposes. We are not running cable over hundreds of meters and we are not running huge motors or welding robots right next to it. If you are not using termination resistors, any twisted pair (shielded or unshielded) should do. If you want to use termination resistors (to handle long bus lengths or other transceiver chips), you need to know the characteristic impedance of your cable to choose a matching termination resistor. I'd recommend Cat5 cable. It's easy to source, cheap, and has a known characteristic impedance of 100 ohm. Another alternative (haven't looked into it in detail, but saw it mentioned in a Hackaday article) would be XLR cable, which might be a bit easier to solder to or use with screw terminals. For testing, any two conductors will do. If they are not right next to each other in a twisted pair, you lose the advantages of differential signalling (the idea being that any interference has the same effect on both conductors and will be cancelled out in the receiver when it calculates the difference between the two signals), but there will still be some margin of error. Regarding the ground wire: I don't think we need a dedicated ground wire for the RS-485 bus in a home cockpit. Just make sure that all your boards are connected to the same ground via their power supply. Most people will power all boards from a single supply (e.g. a computer PSU), so that's a given. Even with separate supplies and no additional ground connection, they will probably be plugged into the same mains circuit, and the RS-485 bus would still be within spec. (Unless one of the supplies is not mains earth referenced, in which case you'd need to connect its ground to one of the others). As far as I understand, the separate RS-485 ground wire becomes important in setups where the different nodes are far apart and/or may be plugged into different mains circuits (possibly even in different buildings), in which case the local ground potentials can differ by a significant amount.
  11. I am working on two DCS-BIOS-related projects right now. The first is what I call "DCS-BIOS 1.0". This will be DCS-BIOS as it is right now, but with a new documentation that is a) complete and b) aimed at beginners instead of programmers. This is mostly documentation work, but also requires some work on the RS-485 bus master firmware so I can give a definite answer to the question of how many RS-485 buses (2 or 3?) can be connected to a single Arduino Mega board. The new documentation will have schematics for wiring up an RS-485 bus with MAX487 transceivers. The second project is "DCS-BIOS 2.0", which involves replacing the current Export.lua with the "DCS Export Core" (which only focuses on exporting data and does not know anything about the meaning of argument numbers, etc.) and replacing socat with a program written in C# that translates between DCS and the serial port. I aim to design DCS-BIOS 2.0 in such a way that features such as multi-function panels (one physical panel to control several radios, for example) or control remapping (using your A-10C pit to fly a Mig-21) can be added later on. I also want to replace the text-based command protocol (for the data that the Arduinos send to the PC) with a more efficient, binary protocol.
  12. The multiple-port version runs the following line for each COM port: start /b cmd /c connect-serial-port.cmd /Q %%i That will start the connection script in the background (so they all run in parallel) and without creating a new window. The output from all of the connect-serial-port.cmd instances will land in that one window. If one of the USB ports was not available, you should at least see a "no such device or address" error. It's certainly not a good solution for 30+ devices, since all the "cannot compute FAST_CWD" warnings will make the actual error messages difficult to spot, but I thought about including this in DCS-BIOS 1.0 as a convenient way to run a handful of panels -- one or two connections to a Mega acting as RS-485 bus master plus maybe one or two panels that cannot be an RS-485 slave (for example because they use an Arduino-compatible board with a different, faster processor to control a large display or something, so they will only work in DEFAULT_SERIAL mode). That should work as a stopgap measure until DCS-BIOS 2.0 is ready.
  13. Sorry, I forgot to mention that it needs to be saved in the same directory as the original script because it references socat by a relative path. Is the Mega now working reliably for you? (If it is not, you can try to increase the timeout in the script a bit, for example from "timeout 2" to "timeout 5".)
  14. You have to save it as a text file with a ".cmd" extension, then run it.
  15. There is an issue where the Mega hangs in the bootloader because it receives DCS-BIOS data right after it has been reset so it never times out waiting for a program upload, even though the data is no valid program. Warhog and I first encountered this issue while developing the RS-485 Master sketch. A while ago I found a fix for that. I just wanted to look up which release of DCS-BIOS I fixed that in. Apparently I never did. Oops... Can you try the following connect-serial-port.cmd script with a Mega? @echo off REM Specify the COM port number to connect to in the following line. REM If set to the default value of ASK, the script will ask you to type it in each time. set COMPORT=ASK REM Set PROTOCOL to "TCP" if UDP does not work for you. When using TCP, REM you have to start the script after you have started the mission and the simulation REM has been unpaused, otherwise the connection will fail ("Connection refused"). set PROTOCOL=UDP set VERBOSE=-v set MODE_OUTPUT_REDIR=CON if "%1" == "/Q" ( set VERBOSE= set MODE_OUTPUT_REDIR=NUL shift ) if not "%1" == "" set COMPORT=%1 if "%COMPORT%" == "ASK" set /p COMPORT=Enter a COM Port Number: set /A TTYNUM=%COMPORT%-1 if "%MODE_OUTPUT_REDIR%" == "NUL" echo Connecting to COM port %COMPORT% mode COM%COMPORT% BAUD=250000 PARITY=N DATA=8 STOP=1 TO=off DTR=off > %MODE_OUTPUT_REDIR% timeout 2 if "%PROTOCOL%" == "UDP" socat\socat %VERBOSE% UDP4-RECV:5010,ip-add-membership=,reuseaddr!!udp-sendto:localhost:7778 /dev/ttyS%TTYNUM% if "%PROTOCOL%" == "TCP" socat\socat %VERBOSE% TCP4-CONNECT: /dev/ttyS%TTYNUM% pause The script will ask you for a COM port number to connect to. It will also wait two seconds between setting the baud rate and running socat (this should fix the issue mentioned above). The script also accepts a COM port number as a parameter and supports the "/Q" option to suppress some of the output. This means you should be able to run the following script to connect to several ports in parallel: @echo off REM The COMPORTS variable should be set to a space-separated list of COM port numbers: set COMPORTS=4 3 for %%i in (%COMPORTS%) do start /b cmd /c connect-serial-port.cmd /Q %%i
  16. Um die primären Steuerachsen kümmert sich DCS-BIOS nicht. Im Prinzip könnte ich das zwar einbauen, dann würde ich aber eine Grundannahme hinter dem Design von DCS-BIOS verletzen. Diese Annahme lautet: Der Pilot hat nur zwei Hände, und eine davon ist immer am HOTAS. Das bedeutet, dass es nie (bzw. äußerst selten) vorkommt, dass zwei Schalter, Potis etc. gleichzeitig Eingaben zum PC senden wollen. Dadurch können wir dann im Prinzip ein komplettes Cockpit über eine einzige serielle Schnittstelle ansteuern, die "nur" 25.000 Bytes pro Sekunde schafft. Wenn man jetzt die Steuerachsen für die Fluglage über DCS-BIOS laufen lassen würde, dann müssten die immer aufeinander warten, was die Latenz erhöhen würde, und das würde natürlich ausgerechnet bei diesen Achsen auch noch am meisten stören. Mit anderen Worten: DCS-BIOS funktioniert gut für Schalter und Regler, die nur ab und zu bewegt werden. Pitch, Roll und Yaw werden von über USB angebundenen Joysticks und Ruderpedalen besser bedient. Wenn du sowas selbst bauen willst, guck dir mal MMJoy an. Damit kann man sich soweit ich weiß Firmware für den Arduino Pro Micro (ca. $5) zusammenklicken, die ein paar Analog- und Digitaleingänge als Joystickachsen und -Buttons anbindet. IIRC können die auch Hall-Sensoren ansteuern, wenn man keine Potentiometer verbauen will.
  17. I don't know. If you have that many panels going, you should grab some MAX487 chips, an Arduino Mega and build an RS-485 bus instead. Even if there is a way to overcome this particular limitation, you don't want to mess around with dozens of COM ports when Windows randomly decides to renumber them... This problem will probably also be solved by DCS-BIOS 2.0 if I get there eventually (because that will ditch socat entirely). My problem is that I keep redesigning the thing because this is my chance to add features that require backwards-incompatible changes and I want to get the fundamentals right so I don't have to do that again in the future. Unfortunately, RS-485 is pretty much an undocumented feature right now. It works, but I don't understand it enough to come up with a series of steps to follow that will definitely work. I don't know whether one Mega can support three or just two RS-485 buses yet, and until recently did not understand why some people had problems with MAX485 (instead of MAX487) chips. Here's a quote that's buried on page 20 of the DCS-BIOS discussion thread: If you have a sketch that works in IRQ_SERIAL mode, you can change it to an RS-485 slave by commenting out the "#define DCSBIOS_IRQ_SERIAL" line and adding the #defines for RS485_SLAVE <address> and TXENABLE_PIN from the RS485Slave example sketch. If you use the MAX487 chip, do not add any resistors to the bus, and keep the total wiring length below 12 meters, you can add 126 devices to one bus in theory. I don't know where the practical limitations are.
  18. The radio menu is part of the GUI, not the cockpit. It is not accessible from Export.lua and from what I can tell there is no reference to it in the *GameGUI.lua environment either. It looks like parts of it are implemented in Lua (Scripts/UI/RadioCommandsDialog) but some of the glue code is implemented in C++. I could not find a way to get a reference to the text widgets that it creates.
  19. It is tied to the switch position. There is no way to get the coil state through Export.lua. If you move an electrically held switch to the ON position, DCS-BIOS will hold the mouse button down on that switch (so it gets pushed to the ON position) and then immediately release the mouse button (so it stays if the coil is on and flips back if the coil is off). This happens in a single frame so you don't see any movement at all if it snaps back.
  20. It sounds like your rotary encoder is one that advances one step per detent instead of four. The DCS-BIOS Arduino Library defaults to four steps per detent, as that is what the cheap chinese ones use. Try this code: DcsBios::RotaryEncoder hsiCrsKnob("HSI_CRS_KNOB", "-3200", "+3200", PIN_A, PIN_B, DcsBios::ONE_STEP_PER_DETENT);
  21. If you want to use an RS-485 bus to connect multiple DCS-BIOS panels through a single USB port, you will have to choose a transceiver chip. My recommendation is the MAX487: it is cheap (about $0.20 a piece) and theoretically allows up to 126 devices on a single bus without the need for bias or termination resistors (as long as the total bus length is shorter than about 12 meters). However, several people have tried to use these breakout boards that are based on the MAX485 and have run into problems (unreliable transmission, resulting in garbled data or long reaction times). I had a guess about why that happened. Now I have two of those modules on my desk and have verified my assumptions. First, these are the steps you will need to take to make those modules work: Make the same connections that you would for the MAX487 chip (Arduino TXO to MAX485 DI, Arduino RXI to MAX485 RO, Arduino TX_ENABLE to MAX485 DE and RE, Arduino +5V to MAX485 VCC, Arduino GND to MAX485 GND, daisy-chain the A and B pins) Connect two 470 ohm resistors to one of the modules on the bus: one between A and VCC and the other between B and GND On any module except the first and last ones on the bus: remove the 120-ohm resistor (marked "121" on the SMD resistor, R7 on my boards) You can use up to six MAX485 transceiver modules (so up to five slave devices) per RS-485 bus. To understand why you need to add the two 470-ohm resistors to the bus and remove the 120-ohm resistors on the devices in the middle, you need to know about termination and fail-safe biasing. When an electric signal is sent over a wire, the wire behaves like a transmission line. When the signal hits the end of a transmission line, a slightly less powerful version of it is reflected back into the line and travels in the opposite direction. This reflected signal can cause the receiver to read a wrong value. It then hits the other end of the line, gets reflected again, etc. until after a few times the magnitude of the reflected signal becomes insignificantly small. If the transmission line (i.e. your RS-485 bus) is short enough, this effect can be ignored (the signal finishes bouncing back and forth and the reflections die off so fast that no one notices). What is "short enough"? According to TI App Note slla070d: RS-422 and RS-485 Standards Overview and System Configurations we can use this rule of thumb: Electromagnetic waves in copper travel at about two thirds of the speed of light. The minimum driver rise/fall time of the MAX485 chip is 3 nanoseconds; the MAX487 has a minimum rise/fall time of 250 nanoseconds. With that information, we can calculate how long we are allowed to make the bus without using termination resistors. For the MAX485: 3 ns * 2/3 * c / 4 = 0.15 m For the MAX487: 250 ns * 2/3 * c / 12 = 12.5 m This means that with the MAX487, we don't need to worry about termination as long as we keep the length of the bus below 12 meters, which should be the case for most home cockpits. On the other hand, with the MAX485, we will need to terminate the bus, as we probably need the signal to travel more than 15 centimeters. So what is bus termination? In short: we can eliminate the reflections by adding a resistor at the end of the line. Because any device on the bus can transmit, we need a termination resistor at both ends of the bus. The value of the termination resistor should be close to the characteristic impedance of the cable. The standard value for RS-485 is 120 ohm. The characteristic impedance of Cat5 cable is 100 ohm, which should still work fine with 120 ohm termination resistors. Now that we have added termination resistors, we got rid of the reflections, but we have another problem. To determine whether a logic 0 or a logic 1 is being transmitted, an RS-485 transceiver looks at the difference between the voltages on the "A" and "B" lines. If it is at least +200 mV, it reads a logic 0. If it is less than -200 mV, it reads a logic 1. Anything in between -200 mV and +200 mV is undefined. When one device stops transmitting on the bus and another device starts transmitting, there is a short time in between when no device is actively driving the bus into a valid value. Without termination resistors, the bus is "open circuit", i.e. the "A" and "B" lines are not connected to anything. The MAX485 and MAX487 chips guarantee that an "open circuit" bus will always read as a logic 1. When we add termination resistors, a bus that is not being driven is not "open circuit" anymore: the "A" and "B" lines are connected together through the termination resistors at either end. The voltage between them will be (close to) zero volts, so the logic level is undefined and the receiver can output whatever it wants to, which will confuse the software that is trying to make sense of the received data and can cause the errors described above. There is another issue: adding bias resistors influences the bus termination. If we add the bias resistors at the start of the bus, we would have to replace the 120 ohm resistor at the start with about 138 ohms for ideal results. In practice, 120 is close enough to 138 that I wouldn't bother with that. The biasing resistors also present an additional load to the bus driver. Because of that additional load, we can only use 6 MAX485 chips on the bus instead of the theoretical 32. In other words, the failsafe resistors are equivalent to about 26 MAX485 receivers on the bus. I got all of the information in this post from the following sources: RS-485: Passive failsafe for an idle bus (TI app note slyt324) RS-422 and RS-485 Standards Overview and System Configuration (TI app note slla070d) The MAX485 / MAX487 datasheet The first app note explains failsafe biasing and bus termination in detail, including schematics and equations. I have extracted the equations from that app note into a handy calculator that allows you to play with different values for termination and biasing resistors. At the end, it will tell you how many devices you can connect to the bus. A MAX485 takes up one unit load, while the MAX487 is a 1/4 unit load device.
  22. Those might be double-pole switches. Either for redundancy (so it still works if one connection breaks) or it might switch both a higher voltage signal to do the work and a lower voltage signal to notify some flight computer about the switch state. Either way, you can take a multimeter, find two wires that are disconnected when the switch is off and become connected when the switch is on, and ignore the other wires :) Disclaimer: I have no knowledge at all about real-world avionics. I am just a computer scientist who tinkers with electronics in his free time.
  23. The variable names for your DcsBios::SwitchMultiPos and DcsBios::LED instances are both "saspYawSasL", and the compiler complains because you can't have two variables with the same name. Just rename one of those variables and it will compile. The name of those variables does not matter, as they are not referenced anywhere else in your code anyway.
  24. It sounds like the Arduino library is not correctly installed. ...and that sentence does not make any sense at all to me. You can install the library like this: Open the Arduino IDE Select Sketch > Include Library > Add .ZIP Library Select dcs-bios-arduino-library-0.2.11.zip Upgrading to a later version works the same, except you have to delete the previous library directory from "Documents/Arduino/libraries" first.
  25. I don't think your breakout boards are broken. It's probably got something to do with bias resistors, but I cannot verify that until I have some of those boards on my own desk to tinker with. This will probably happen some time next week. The MAX487 won't need any additional resistors, so the circuit is a lot simpler than what you see on those MAX485 breakout boards. Some prototyping board (stripboard) should be all you need to integrate a MAX487 chip into your circuit.
  • Create New...