Jump to content

FSFIan

Members
  • Posts

    1301
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by FSFIan

  1. I don't have the Su-27, but the following works in the Huey (where the kneeboard device has id 45): local dev = GetDevice(45) dev:performClickableAction(3001,1) I have never heard of GetDevice() returning a number.
  2. This sketch is written for a serial baudrate of 250000 bps. The default in the current DCS-BIOS version is 500000. You either need to change the sketch ("Serial.begin(500000)" instead of "Serial.begin(250000)") or modify the BAUDRATE= setting in the connect-to-serial-port.cmd script. You don't need to power the LEDs separately, the MAX7219 takes care of driving them at the correct current. If you have not already, it is also a good idea to add a small capacitor (about 100 nF) across the Vcc and GND pins as close to the MAX7219 as possible.
  3. For small pieces of information, you can also use the witchcraft.log function. The output will appear in the console window of the DCS Witchcraft server process. For example, this snippet witchcraft.log("foo") witchcraft.log(42) witchcraft.log({1,2,3}) witchcraft.log({["bananas"] = 5, ["apples"] = "tasty"}) will result in the following output: *** LOG: foo *** LOG: 42 *** LOG: [ 1, 2, 3 ] *** LOG: { apples: 'tasty', bananas: 5 } Note that the value you pass to witchcraft.log() is converted to JSON to pass it to the server process (hence "[1,2,3]" instead of "{1,2,3}" in the output). It does not work with Lua tables that have both numeric and string keys in it, so the following would cause an error: witchcraft.log({ [1] = "one", ["two"] = "two" }) So if you pass an unknown value to witchcraft.log(), use mist.utils.tableShow to convert it to a string. witchcraft.log(mist.utils.tableShow({ [1] = "one", ["two"] = "two" })) Output: *** LOG: { [1] = "one", ["two"] = "two", } witchcraft.log() is not meant to log significant amounts of data, but it can be useful to quickly verify something, especially if you can watch the console window in real time on a second monitor.
  4. Your matrix wiring looks ok (some of the signal names / color coding do not match up between the pictures, e.g. the throttle base has a "D4" that is not found anywhere else, but I assume those are oversights in the schematics and that the actual wiring is correct.) What is the behavior with the current sketch? If I interpret the code correctly, the first four buttons will work, the last two won't. (Disclaimer: I am not familiar with the Teensy, I just have some experience with C++ and the Arduino platform in general.) To understand what is going on here, let's take a closer look at one of the three parts responsible for scanning the button matrix: digitalWrite(col[0], 0); digitalWrite(col[1], 1); digitalWrite(col[2], 1); delay(10); for (int y = 0; y < 4; y++) { if (digitalRead(row[y]) == 0) { buttonstate[y] = 0; if (buttonstate[y] != buttonprevstate[y]) Joystick.button(19 + y, 1); } else { buttonstate[y] = 1; if (buttonstate[y] != buttonprevstate[y]) Joystick.button(19 + y, 0); } buttonprevstate[y] = buttonstate[y]; } The first three lines make sure that only the column we want to scan (column 0 in this case, corresponding to pin 26) is logic low, the other two are set to logic high. The delay(10) is probably not necessary, but helps to avoid problems when you have very long wires, where the stray capacitance of the wire can slow down the signal transition. The for loop now scans through the rows. Because y goes from 0 to 3, it will only scan the first four rows. If it reads a logic 0, the button is pressed. If it reads a logic 1, the button is not pressed. In both cases, it stores the value in the buttonstate array, and if it has changed from the previous value, it will tell the USB joystick code to send a new button value to the PC. The other two code blocks work the same, but they scan the other two rows. They also add different values to 'y' so they don't use the same entries in the buttonstate array. The code is more verbose than it needs to be, but it should work. Note that the next two sections scan eight rows, but your rows array only has six entries. This means you are accessing memory beyond the bounds of the array, which can lead to undefined behavior, but I think this won't break anything in this specific case because (a) you never write out of bounds and (b) the value you get is only passed to digitalRead(), which will probably determine it is not a valid pin number and return 0 or something. In general though, reading (or worse, writing) to an array outside of its bounds (for example, declaring "char foo[6]" and then accessing "foo[6]" -- because with 6 entries, foo only has elements foo[0] through foo[5]!) is very dangerous, because it leads to very hard to find bugs. On a microcontroller, there is no operating system that may notice this and stop the program with a segmentation fault error -- your code will just keep running, and the effects of that memory access can be anything from no problem at all (because the memory location beyond your array happens to contain the right value) to causing arbitrary behavior (because the memory location you overwrote contained a return address, causing program execution to jump somewhere it was not supposed to). Worse, the memory layout (and thus the effects of out-of-bounds array access bugs) can change when you are working on entirely different parts of the code, so you might add a variable somewhere else which will break the program.
  5. Listening right now and just got to the commercial. Now I have tears in my eyes from laughing so hard! After I finished listening to this episode, I'll also definitely look up some of the videos, those sound really cool. Thank you for all the effort you put into the podcast. I will continue enjoying these as long as you keep making 'em.
  6. The answer is in this post. The grip just contains a bunch of shift registers which are being read by the base, so the number of buttons is fixed (of course you can build a grip with less buttons if you want to).
  7. For this application, I would use a servo instead of a stepper motor. We don't need the very precise positioning of a stepper. A servo has several advantages here: does not need a separate driver board requires only a single Arduino I/O pin no need to worry about zeroing it (although you could probably zero a stepper by driving it against the limit switch which you'll have anyway) I think servos may have more torque compared to steppers in the same size and price brackets Servos are commonly available anywhere you can buy remote controlled toys, so you could probably pick one up easily If you want to build it, I can probably knock out the code you need in an hour or two (including testing and debugging time). So that's your points one, two and four taken care of. And no matter how this turns out, everything you have done until now is not scrap! You built a real mag switch, so you have something to compare your servo experiment to. You will know the material cost, effort and difficulty of assembly, and quality of the end result in both cases, which will help you and others make an informed decision about which way to go.
  8. I don't have the Mig-21, so I cannot look into this. Please use the DCS-BIOS Discussion Thread for comments and questions. This thread is meant for DCS-BIOS related news announcements only. The idea is to have separate threads for news and discussions. Any question where the answer is useful in the future (e.g. "How do I..." instead of bug reports and general comments) should be in a new thread, with a somewhat descriptive subject line, so it is easy to find again in the future.
  9. Released v0.4.0. Thanks to airtom, we now have Ka-50 support! This release also corrects the name of the Huey's 50 KHz selector knob on the UHF radio from "VHF_50KHZ" to "UHF_50KHZ" (so you have to update any sketch that uses that control).
  10. The bus driver is smart enough to do that. Since I plan to dedicate a Mega to run the bus driver code, I have plenty of memory so allocating 128 bytes to store which addresses are present does not hurt. Every poll cycle, one of the "known absent" devices will be polled. This allows hotplugging of new devices / resetting a device independently of the rest and also ensures that we regularly run into a timeout condition, which new devices can wait for to synchronize to the data stream (i.e. don't try to parse anything until there has been no communication for 1 ms). The goal is to make all communication interrupt driven. That has two advantages: (1) people will no longer use <insert slow library of your choice here>, get garbage data, and file a bug against DCS-BIOS and (2) we can poll devices a lot faster. Think "polling 100 devices 30 times a second while still sending the export data over the same bus" (rough estimate, but my first tests show that this might actually be possible). In theory, you could run the entire cockpit off a single RS-485 bus. In practice, you still want two or three, because shorter buses leave more wiggle room for interference and faulty wiring, the above poll rate is only for the usual case where none of the devices have anything to say, and it is great to switch to a different bus to find out if an issue is with your device or the bus wiring.
  11. I am excited to see the progress that has been made over the last few days, even though I haven't done any significant work on DCS-BIOS for months now. I am looking forward to spending more time with DCS-BIOS development again now that I have finally moved into my new place. Gadroc: I took a quick look at your new library. I like the hardware abstraction layer, it's a lot easier to use than what I had in mind. If I understand the protocol correctly, the only important difference between your protocol and that of my prototype is the address space of 32 vs. 127 devices. While I don't think that more than 32 devices on a bus is a good idea, it would be convenient if devices on different buses would still have distinct addresses. That would make it easy to plug a device into a different bus temporarily for troubleshooting. I will continue working on my completely interrupt-driven implementation, but I will try to stay compatible to your developments where feasible. The second piece of exciting news is that airtom has completed Ka-50 support. I wanted to merge it today, but unfortunately I am stuck with a high-latency 10 KB/s internet connection over 2.5G (GPRS/EDGE) right now. Yesterday, a package was supposed to arrive that contains an adapter needed to connect my cable modem in the new place. Online tracking shows "2nd delivery attempt will be made", which according to DHL means that the driver cancelled his tour due to traffic/accident/health reasons. I temporarily switched to a 5 GB/month 3G plan on the SIM card in my laptop, but apparently it can take "up to 24 hours" for that to take effect. In 2015. Seriously, how hard is it to run your billing cron jobs once an hour instead of once a day? In the long term, I want to finish v0.2 of the original Arduino library (before the end of the year if I can) and call that 1.0 after the bugs are ironed out. After that, I will either focus on mission scripting again (depends on what EDGE brings) or think about designing a DCS-BIOS 2.0 where every previous design choice is up for reconsideration. I'd like to include the developers of other software (Helios, HawgTouch, iControl DCS, ...) in the planning phase. The ideal outcome would be a DCS-BIOS 2.0 where adding an aircraft to DCS-BIOS would make it available in Helios and HawgTouch with minimal extra effort, and less effort to build simpits that are suited to more than one aircraft.
  12. function parse_indication(indicator_id) local ret = {} local li = list_indication(indicator_id) if li == "" then return nil end local m = li:gmatch("-----------------------------------------\n([^\n]+)\n([^\n]*)\n") while true do local name, value = m() if not name then break end ret[name] = value end return ret end function get_uv26_display() local li = parse_indication(4) if not li then return " " end if not li.txt_digits then return " " end return li.txt_digits end The function get_uv26_display() will return the display contents as a three-character string (or three spaces if it is empty, e.g. powered off).
  13. You can't. You have to write your own modified version of the Switch2 class that knows how to read the data from your shift register. (The next version, which I hope to release this year, will make this a bit easier and allow you to override the pinMode, digitalWrite, and digitalRead functions that a class instance will use, but you'll still have to write those.) Supporting things like shift registers and I/O expanders in a generic way is not really possible, except in a very inefficient way where having five switches would result in the entire state being read five times instead of once, so it will always require custom code. See also this issue for an example LED class which works with a MCP23017 (but I think this is the inefficient way of reading the complete state over I2C every time you need a single bit of data). It would be more efficient to read the state once in loop(), save it in a variable and read it from there in the LED class.
  14. The magic words in the video are "I have already downloaded and installed DCS-BIOS and the Arduino library from the website and set everything up according to the instructions in the User Guide." Those instructions include modifying your Export.lua file so DCS-BIOS gets called. DCS-BIOS (the Lua part) has a concept of an "address space". Think of it as a 64 KiB block of memory that you can write data to. Once you are in a mission, DCS-BIOS checks what the current aircraft is and determines which export modules should run for that aircraft. Usually, that will be MetadataStart, CommonData, an aircraft-specific one (e.g. A10C.lua), and MetadataEnd. Each of those export modules (found under "Scripts/DCS-BIOS/lib") will register a bunch of hook functions on startup which are called 30 times a second. Each hook function gets a value from the sim (usually with GetDevice(0):get_argument_value), translates it to an integer number or a string (the only two datatypes DCS-BIOS knows about), and writes them to a specific location in that 64K memory block. Any scaling of the value (often from a range of 0...1 to 0...65535) happens at this point. DCS-BIOS does not export floating point values because they are inconvenient to handle on a microcontroller. After all the hook functions have run, DCS-BIOS determines which sections of that 64K memory block have changed and sends it out to the export data stream, which usually means local multicast UDP and to any connected TCP clients. You can define additional targets (e.g. IP address and UDP port) that should get a copy of the export data in BIOSConfig.lua. Each export module has an instance of a MemoryMap object (implemented in Util.lua) that manages this module's chunk of address space. It hands out MemoryAllocation objects which represent a specific sub-range of that memory. This way, we make the export data stream as memory-efficient as possible (if we only need two bits for a three-position switch state, we will only use that much). That allows us to send everything to each panel, so we don't have to tell the software to only send specific data to a panel (one of the design goals was that all configuration for a panel should be kept in that panel's microcontroller firmware). To handle input, DCS-BIOS listens for lines of plaintext on an UDP port and on all TCP connections. Each export module can register functions that will be called for a certain input command. For example, the A-10C module registers a function to handle the "AHCP_CICU" command, which will then set the CICU power switch to the desired value. The data format of the input and export data streams, the "low-level" API for how to define an export module and get a MemoryAllocation object, and how to register input hooks is described in the developer guide. Usually, export modules won't call the low-level API directly. Instead, they will call one of the convenience functions from Util.lua (e.g. defineToggleSwitch) which will get a MemoryAllocation, register the input and export hook functions, and make an entry in the documentation table which will be saved to a JSON file so the control shows up in the reference documentation. On the Arduino side, the Arduino library provides a ProtocolParser class that will take the data coming from DCS-BIOS and call a function for each 16-bit word that has changed. If you define a DcsBios::LED instance, that object will register a hook function to be called when new data comes in. That function will check if the address matches the one of this LED. If it does, it extracts the relevant bit using the mask value and calls digitalWrite() to update the pin state. A DcsBios::Switch2Pos object will register a function to be called once every loop() from DcsBios::PollingInput::pollInputs(). That function checks if the physical switch state has changed. If it detects a change, it calls sendDcsBiosMessage() to send a command to DCS-BIOS.
  15. Here's a data flow diagram: It shows DCS, the Arduino, and what happens between them, but it's not really a flowchart. Does it help if I tell you that there's "DCS-BIOS", which strictly speaking only refers to the Lua code inside DCS, and then there is the "DCS-BIOS Arduino Library", which is the part that runs on your Arduino board and handles talking to the other part? Feel free to ask more specific questions. I have the feeling that there is a lot of confusion around about how this works and which parts do what, but I find it difficult to write good documentation because I never was in the situation of learning everything at once. Maybe I should do a video where I press an NMSP button and the button's LED lights up on the Arduino, and comment about what things happen behind the scenes to make that work or something.
  16. Da stimme ich dir ja auch voll zu. Lies dir noch mal mein letztes Post durch. Die aktuelle Lösung ist nicht pareto-optimal, d.h. man kann sie verbessern, ohne dass ED auf Einnahmen verzichten muss.
  17. Das ArmA 3-System verhindert ja soweit ich weiß nicht, dass man nicht auf den Server kann, nur dass man das DLC-Zeug selbst benutzt. Bei BF4 kostet das einzelne Add-On nur $15 statt $40, und man hat auch die Möglichkeit, einmalig $50 zu zahlen, um Zugriff auf alle zukünftigen DLCs zu erhalten. (Korrigiere mich wenn ich hier was falsches behaupte, ich bin in Sachen BF4 und Arma 3 nicht up-to-date.) Für DCS schätze ich die langfristigen Kosten für "ich will auf allen Karten mitspielen wollen" eher auf $150+ (jetzt mal abgesehen von Sales) BF4 hat natürlich auch eine viel größere Community, so dass sich das Problem nicht so stark auswirkt (und sie sich leisten können, das DLC für $15 rauszuhauen). Betrachten wir mal zwei Extremfälle. Fall 1: Die aktuelle Situation. Vorteil: ED bekommt mehr Geld, um neue Karten zu machen. Nachteil: die MP-Community wird vielleicht fragmentiert. Im schlimmsten Fall senkt das sogar die Nachfrage nach den neuen Karten wegen dem Henne-Ei-Problem: wenn ich kaum Leute kenne, die die neue Karte haben, warum sollte ich sie dann kaufen? Fall 2: Die neue Karte ist kostenlos. Vorteil: Beliebige Gruppen von Leuten können zusammen spielen, egal, wer welche Teilmenge der DLCs besitzt. Nachteil: ED bekommt kein Geld und wir bekommen keine neuen Karten mehr. Ich glaube, dass es möglich ist, eine Lösung dazwischen zu finden, die folgende Bedingungen erfüllt: 1. Mehr Gruppen von Leuten können zusammen spielen, auch wenn nicht alle davon die Karte zum Vollpreis gekauft haben (z.B. in dem es reicht, wenn X% der Spieler die Karte haben, oder wenn ich mir eine Karte für $1 einen Abend lang mieten kann) 2. Niemand, der die Karte jetzt kaufen würde, rückt von seiner Kaufentscheidung ab Im besten Fall kaufen sogar mehr Leute die Karte, da sie diese selbst ausprobieren können und danach auch unabhängig von anderen Spielern nutzen können wollen. Mein Punkt ist, dass man IMO einen Mittelweg finden kann, von dem sowohl ED als auch die Spieler nur Vorteile haben.
  18. Ich bin gerne bereit, für eine gute Karte zu bezahlen. Die NTTR bietet sicher viele neue Möglichkeiten für spannende Missionen, ich freue mich auch schon sehr drauf, Las Vegas mit dem Huey zu erkunden. Problematisch sehe ich allerdings den Multiplayer: wenn ich mit ein paar Kumpels DCS zocken will, und auch nur einer davon hat die Karte nicht, können wir alle Missionen, die dafür designt wurden, vergessen. Schön gelöst finde ich es bei Payday 2, da muss nur der Host das DLC haben und jeder kann den Heist spielen. Mir ist klar, dass das bei DCS nicht gut funktionieren würde (bei Payday sind es ja max. 4 Spieler, DCS hat teilweise dedicated server mit mehreren dutzend Slots), aber ein System wie "wenn du die Karte gekauft hast, kannst du einen Freund in einen MP-Server mitbringen" wäre cool. Oder macht die Karte so günstig, dass sie sich wirklich jeder leisten kann. Richtig problematisch wird das mit der Fragmentierung der ohnehin schon kleinen DCS-Multiplayer-Community werden, sobald es mehr als eine Add-On-Karte gibt. Dann hast du eine Gruppe von fünf Leuten, keiner will auf der Black Sea-Map spielen weil die schlechtere Qualität hat, jeder hat mindestens eine gute Add-On-Karte, aber es findet sich keine Karte, die alle haben... Und genau dieses Problem könnte dann Missions-Designer abschrecken und dafür sorgen, dass Missionen für die Black Sea-Map erscheinen, obwohl sie woanders besser aufgehoben wären :( Bei Flugzeug-Modulen gibt es zwar ein ähnliches Problem, aber ich kann die Mission ggf. editieren, um ein passendes Flugzeug einzufügen.
  19. Thanks! Yes, I am the creator of DCS-BIOS. Not a god as far as I know, just someone with too much time on his hands (or way too little, considering the lack of progress on DCS-BIOS in the last months).
  20. Socat will simply open two data streams and shovel data back and forth in both directions. Think of socat as a hose that connects two pipes. A pipe can be just about anything you can read and write bytes to/from, including a file, a serial port, UDP and TCP network connections or the terminal (great for debugging). When using DCS-BIOS with an Arduino that is connected over USB, the role of socat is to connect the DCS-BIOS UDP data stream to the serial port.
  21. Welcome to the club!
  22. And if you want to have the airspeed available in the CommonData module too, you'd need to modify this Lua file. It's only a small modification, anyone who has a little experience with the Export.lua environment could do it. Unfortunately I don't have time at the moment to fire up a dev environment, make the change, test it, and release a new version (busy with exams).
  23. D'oh! I remember coming across these a year ago, setting objects_LOS_test to true and still being killed by tanks on the other side of town. That said, I dismissed those as "doesn't work, they probably never finished that feature" after one five-minute test. Looks like I should have kept experimenting with those.
  24. Look at this thread, it's the same principle. Look up the value you want to display in the control reference documentation. DCS-BIOS does not export general pitch and bank info at this time, so you'd have to rely on the ADI (or submit a pull request that adds these to CommonData.lua). To make this work for all aircraft, you'd need to add airspeed to the CommonData export module. As mentioned above, pull requests are welcome (or remind me in a few months when my exams are over and I'll have moved into a new place).
  25. With some Lua scripting, you should be able to use an event handler to detect the "weapon fired" event, check the initiator and weapon type to confirm that it is that specific unit launching that specific type of missile, and then trigger the message.
×
×
  • Create New...