Jump to content

DCS-BIOS Discussion Thread


FSFIan

Recommended Posts

A huge thanks to BravoYankee4 for helping me with the inverted landing gear lights. He sent me a fix that perhaps he could send to you as well Ian for implementation in a future version?

 

I do wonder still if the landing and taxi lights switch could be fixed? As is, it seems like switching between "off" and "taxi" works as normal, but switching to and from "landing" seems like it cycles to the next state in line instead of the proper one. I think it goes directly from landing to off when a 3-way switch is switched to the open position. If you could have a look and investigate I would be very thankful.

 

Thanks in advance,

Emil

Link to comment
Share on other sites

Great that you got it working, however the credits should go to McMicha that helped me with the code in the first place.

 

Just realised that I haven't connected the landing/taxi light switch on my panel, so that behavior I haven't noticed. The landing gear is working as it should though. I'll see if I can replicate that problem.

  • Like 1
Link to comment
Share on other sites

Your right its probably not wiring as I cant get a simple led master caution or ejection seat not armed to light. I'm noob to arduino I flash on my laptop and on my desktop no joy must be something simple staring me in the face but I aint gettin it.

Link to comment
Share on other sites

cBass: Try the following.

  • Flash the Master Caution example sketch to your Arduino board and connect a push button between pin 10 and ground.
  • Run connect-serial-port.cmd without having DCS open (so the output doesn't scroll away immediately)
  • press the push button
  • post a screenshot of the command line window

Link to comment
Share on other sites

Hi Ian

 

The titino board is meant for a full duplex bus, DCS-BIOS uses half duplex.

 

thank you for the response, I appreciate the time you take as some of the questions I ask must seem very basic! Still if you are ever building a house I could maybe reciprocate!

 

Neal

Desktop PC:

Intel i7 14700K, MSI Z790 MAG Tomahawk MOBO, 64Gb RAM , GPU Nvidia RTX 3080ti

Windows 11, VPC joystick, Crosswind rudder peddles, HP Reverb G2, VPC Collective, DOF Reality H2, Gametrix seat, WinWing panels.

Link to comment
Share on other sites

DCS Bios - CMSP LCD issues

 

Hi

 

I have compiled my sketch for my CMSP and it works; mostly! I have a Nano connected to a 16 x 2 lcd Shield. I have directly wired the Pot to the shield rather than through the sketch (for contrast).

 

When i run Cmd and DCS A10c the display characters extend beyond the 16 character spaces, see picture. You can see on the 2nd line the last word should be PROG and all we see is P, there is no space for ROG.

 

My sketch is below:

 

/*
 Tell DCS-BIOS to use a serial connection and use interrupt-driven
 communication. The main program will be interrupted to prioritize
 processing incoming data.
 
 This should work on any Arduino that has an ATMega328 controller
 (Uno, Pro Mini, many others).
*/
#define DCSBIOS_IRQ_SERIAL

#include "DcsBios.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void onCmsp1Change(char* newValue) {
   lcd.setCursor(0,0);
   lcd.print(newValue);
}
DcsBios::StringBuffer<19> cmsp1Buffer(0x1000, onCmsp1Change);

void onCmsp2Change(char* newValue) {
   lcd.setCursor(0,1);
   lcd.print(newValue);
}
DcsBios::StringBuffer<19> cmsp2Buffer(0x1014, onCmsp2Change);

// set up the set button 1:
DcsBios::Switch2Pos cmspArw1("CMSP_ARW1", 6);

// set up the set button 2:
DcsBios::Switch2Pos cmspArw2("CMSP_ARW2", 7);

// set up the set button 3:
DcsBios::Switch2Pos cmspArw3("CMSP_ARW3", 8);

// set up the set button 4:
DcsBios::Switch2Pos cmspArw4("CMSP_ARW4", 9);

void setup() {
 DcsBios::setup();
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 // Print a message to the LCD.
 lcd.clear();

}

void loop() {
 DcsBios::loop();
}

 

Have i missed something in the sketch? Any advise would be gratefully received.

 

Thanks

 

Neal

IMG_0282.JPG.bb808dfbde11e9d36a0997348ddcb5c3.JPG

IMG_0283.JPG.be74c57d2b3e66e5080f8ebfc1b2ec1c.JPG

IMG_0284.JPG.0118491f294f0862470fba52c40ebfd6.JPG

Desktop PC:

Intel i7 14700K, MSI Z790 MAG Tomahawk MOBO, 64Gb RAM , GPU Nvidia RTX 3080ti

Windows 11, VPC joystick, Crosswind rudder peddles, HP Reverb G2, VPC Collective, DOF Reality H2, Gametrix seat, WinWing panels.

Link to comment
Share on other sites

While we are on the topic of the CMSP I had a question also.

 

I am using 20 x 2 display. Both lines of lcd.setcursor is 0. But 19 character string starts in the 1 position.

 

[ATTACH]143093[/ATTACH]

 

(sorry... cel phone pic again)

 

Is it possible to move chaff and flare left by one thus adding a space between FLAR and OTR? It would make the alignment better in my opinion. I guess this is something inside DCS-Bios that starts 19 char string at 1.

 

Not a big deal though. Still works great but I cant move the display anymore to left without poking through the frame!

 

Thanks for help

 

ClayM

Link to comment
Share on other sites

I am using 20 x 2 display. Both lines of lcd.setcursor is 0. But 19 character string starts in the 1 position.

 

I can't open that picture, can you post another link? Also post your complete sketch. It shouldn't start in the 1 position.

 

That said, your sketch ultimately decides where each part of that 19-character string ends up, so you can rearrange it however you want no matter how DCS-BIOS presents it by default.

Link to comment
Share on other sites

Thanks Ian!

 

I re-read previous posts and figured out what I was doing wrong.

I was thinking the value after "newValue" was position when in fact it is data!

This code works and has the positions where I want them.

 

#define DCSBIOS_DEFAULT_SERIAL

 

#include "DcsBios.h"

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

 

void onCmsp1Change(char* newValue) {

lcd.setCursor(0, 0);

 

lcd.write(newValue[0]);

lcd.write(newValue[1]);

lcd.write(newValue[2]);

lcd.write(newValue[3]);

lcd.write(newValue[4]);

lcd.write(newValue[5]);

lcd.write(newValue[6]);

lcd.write(newValue[7]);

lcd.write(newValue[8]);

lcd.write(newValue[9]);

lcd.write(newValue[9]);

lcd.write(newValue[10]);

lcd.write(newValue[11]);

lcd.write(newValue[12]);

lcd.write(newValue[13]);

lcd.write(newValue[14]);

lcd.write(newValue[15]);

lcd.write(newValue[16]);

lcd.write(newValue[17]);

lcd.write(newValue[18]);

lcd.write(newValue[19]);

}

DcsBios::StringBuffer<19> cmsp1Buffer(0x1000, onCmsp1Change);

 

void onCmsp2Change(char* newValue) {

lcd.setCursor(0, 1);

 

lcd.write(newValue[0]);

lcd.write(newValue[1]);

lcd.write(newValue[2]);

lcd.write(newValue[3]);

lcd.write(newValue[4]);

lcd.write(newValue[5]);

lcd.write(newValue[6]);

lcd.write(newValue[7]);

lcd.write(newValue[8]);

lcd.write(newValue[9]);

lcd.write(newValue[9]);

lcd.write(newValue[10]);

lcd.write(newValue[11]);

lcd.write(newValue[12]);

lcd.write(newValue[13]);

lcd.write(newValue[14]);

lcd.write(newValue[15]);

lcd.write(newValue[16]);

lcd.write(newValue[17]);

lcd.write(newValue[18]);

lcd.write(newValue[19]);

}

 

DcsBios::StringBuffer<19> cmsp2Buffer(0x1014, onCmsp2Change);

 

void setup() {

DcsBios::setup();

lcd.begin(20, 2);

lcd.clear();

}

 

void loop() {

DcsBios::loop();

}

 

 

newcmsp.thumb.jpg.f7e7b56e2999f040480a408049d14214.jpg

 

 

Thanks!

 

Clay

Link to comment
Share on other sites

Actually this is better

 

#define DCSBIOS_IRQ_SERIAL

 

#include "DcsBios.h"

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

 

void onCmsp1Change(char* newValue) {

lcd.setCursor(0, 0);

 

lcd.write(newValue[9]);

lcd.write(newValue[0]);

lcd.write(newValue[1]);

lcd.write(newValue[2]);

lcd.write(newValue[3]);

lcd.write(newValue[4]);

lcd.write(newValue[5]);

lcd.write(newValue[6]);

lcd.write(newValue[7]);

lcd.write(newValue[8]);

lcd.write(newValue[9]);

lcd.write(newValue[9]);

lcd.write(newValue[10]);

lcd.write(newValue[11]);

lcd.write(newValue[12]);

lcd.write(newValue[13]);

lcd.write(newValue[14]);

lcd.write(newValue[15]);

lcd.write(newValue[16]);

lcd.write(newValue[17]);

lcd.write(newValue[18]);

lcd.write(newValue[19]);

}

DcsBios::StringBuffer<19> cmsp1Buffer(0x1000, onCmsp1Change);

 

void onCmsp2Change(char* newValue) {

lcd.setCursor(0, 1);

 

lcd.write(newValue[0]);

lcd.write(newValue[1]);

lcd.write(newValue[2]);

lcd.write(newValue[3]);

lcd.write(newValue[4]);

lcd.write(newValue[5]);

lcd.write(newValue[6]);

lcd.write(newValue[7]);

lcd.write(newValue[8]);

lcd.write(newValue[9]);

lcd.write(newValue[9]);

lcd.write(newValue[10]);

lcd.write(newValue[11]);

lcd.write(newValue[12]);

lcd.write(newValue[13]);

lcd.write(newValue[14]);

lcd.write(newValue[15]);

lcd.write(newValue[16]);

lcd.write(newValue[17]);

lcd.write(newValue[18]);

lcd.write(newValue[19]);

}

 

DcsBios::StringBuffer<19> cmsp2Buffer(0x1014, onCmsp2Change);

 

void setup() {

DcsBios::setup();

lcd.begin(20, 2);

lcd.clear();

}

 

void loop() {

DcsBios::loop();

}

 

 

 

DSC01537.thumb.jpg.b967c30fcefa0bc14c46e6288370a81a.jpg

 

Moved top CMSP line right by 1.

 

Clay

Link to comment
Share on other sites

lcd.write(newValue[19]);

That line will print the null terminator (the null byte after the string that marks the end of the string).You should remove it. (In your example, it does not make a difference, because it ends up outside of the display.)

 

Strings in C (which are just an array of characters) are indexed from counting from 0, so newValue[0] is the first character and newValue[18] is the 19th character.

Link to comment
Share on other sites

@all:

Since I was busy and got no notifications for new posts (don't know why) I've been a little stuck (offline) and missed your great progress in adapting DCS-BIOS.

Congratulations to you :thumbup:

Hope you all are also well at life and health.

 

So I'm a little ashamed about my following (hope: small) question:

 

While testing a small stack of brandnew RS485-Slaves (solder has been still warm) I had something to notice. (See the pic, please)

 

Is this just a "hickup" or should I go against it?

 

My installation consists just of a well working Master and ONE Slave. To the Slave is an Arduino NANO connected with just one button and one LED. Very simple, at a breadboard. No other gimmicks. Linked by 1 m Cat5-Cable.

No DCS was running.

 

Thank you for your kind attention.

And: Sorry for stumbling in :)

 

PS maybe @Ian: At a german Forum was suggested, to bring a pulldown R (10k) at TXenable Pin. What is your opinion?

I think every further load is bad and the Arduino has its own pulldown acitivated (turned on somewhere in your code).

294277018_SuspectDCS-BIOS.png.062c205f8c454a5a6b850331e48cd000.png


Edited by Tekkx

Manual for my version of RS485-Hardware, contact: tekkx@dresi.de

Please do not PM me with DCS-BIOS-related questions. If the answer might also be useful to someone else, it belongs in a public thread where it can be discovered by everyone using the search function. Thank You.

Link to comment
Share on other sites

Tekkx: That's just the switch bouncing. As a workaround, you can add a small delay to your loop() function until the DCS-BIOS Arduino library eventually gets some sort of debouncing support.

 

See post 365 for more information.

 

There is nothing wrong with your RS-485 setup. The same thing happens when communicating directly over a serial port. If a switch bounces and several messages are sent in quick succession, socat simply takes all of them and stuffs them into a single UDP packet. The Lua part of DCS-BIOS is aware of that, and will execute all of the commands.

 

A pulldown on the TXEnable pin would keep the MAX487 from possibly trying to drive the bus in the time between powering up the Arduino and the time that the initialization code has finished to run. It's not a bad idea, but it's also not required: the MAX487 chips are short-circuit current limited, so they won't break when several drivers are trying to drive the bus at the same time. And after a short time the initialization code has run anyway and the TXEnable pin will be in a defined state from then on because it's been configured as an output pin.

 

If there is some condition where the MAX487 will be powered up but the Arduino board will not (or will be disconnected), you should definitely include the pulldown resistor, because as long as multiple drivers are trying to drive the bus, any data that is being sent will be screwed up.


Edited by [FSF]Ian
Link to comment
Share on other sites

Thank you. I love your detailed explanations. That helps a lot :) Even at own thinking ;)

Ian;2545206']

...

If there is some condition where the MAX487 will be powered up but the Arduino board will not (or will be disconnected)...

This way I killed about 20 (or even more) Max487 and AMS1117-05: Disconnecting the Arduino from the Transmitter.

 

I'm on adding this Pulldown and also a TVS SM712 to Lines A and B.

If I have the first of those boards on hand I'll do a test and will see if there is still something smoking.

But this will have to wait until my vacations are over, also the needed items are still at the Celestial Empire ;)


Edited by Tekkx

Manual for my version of RS485-Hardware, contact: tekkx@dresi.de

Please do not PM me with DCS-BIOS-related questions. If the answer might also be useful to someone else, it belongs in a public thread where it can be discovered by everyone using the search function. Thank You.

Link to comment
Share on other sites

Ian when the flare and chaff count gets to 50 and the "LOW"signal is displayed the counts are not displayed anymore on the osram display. They continue to display in the sim but it looks like the lua code is not sending anything but "LOW" all the way down to zero(maybe fault of my glue code). I also get a N\A (null character?)when the chaff and flare counts zero out. the cmsp mode looks flaky at times displaying wrong letters. Notice the modes do not have underlines thats not part of the displays built in character set.

 

[ame]

[/ame]
Edited by cBass
Link to comment
Share on other sites

  • 1 month later...

Hallo Dears.

Yesterday I stumbled into Nextion HMI (Human Media Interface) Screens.

 

It's not my problem right now and not at high priority to me.

But: Could this become a "short" way to a new kind of CDU-Screen without messing with Monitor-Export and VGA-Converter issues?

 

I post it here cause making controller modules without DCS-BIOS doesn't make sense to me. The other way round: DCS-BIOS with RS-485 opened a countless amount of doors for pit-builders. :)


Edited by Tekkx
forgot to excuse for beeing some off-topic :)

Manual for my version of RS485-Hardware, contact: tekkx@dresi.de

Please do not PM me with DCS-BIOS-related questions. If the answer might also be useful to someone else, it belongs in a public thread where it can be discovered by everyone using the search function. Thank You.

Link to comment
Share on other sites

  • 3 weeks later...

Hi there. I know it is possible that somebody might have ask this one.

I have a X27 168 Stepper motor. Used in some car dashboards, bought on ebay for A$ 3. Works perfectly with the stepper library and there is no need for a stepper driver. (Less than 40 mA power usage). It can rotate 270 Deg. And is very smooth. Is there a way to use this in place of a servo for gauges. I know that stepper motors is difficult with DCS BIOS due to the many configurations. Any help, just a nuge in the right direction please.

 

Cheers,

Adrian

1929697366_20160818_1912521.thumb.jpg.0b6e221b6f4b1f4ce006ce83d59e0a82.jpg


Edited by a3an4e
Link to comment
Share on other sites

Warhog and I have created a Vid29Stepper class that handles most of the logic required to control the Vid29 / Switec X27.168 motors. When the sketch starts up, it will zero the stepper by driving it against its end-stop. After that, it will calculate a new stepper position and instruct the stepper to move there whenever new data comes in from DCS.

 

It takes a reference to a configuration struct for general attributes of the stepper (max. speed, acceleration and total number of steps), the address of the DCS-BIOS output, a mapping function that needs to translate the value from DCS-BIOS into the appropriate number of steps, and a reference to an AccelStepper object (provided by the AccelStepper Arduino library) that handles low-level stepper control for us.

 

IIRC we finished it to the point where it is working reliably. I don't have access to my DCS machine right now, but I'll post it when I get back there if Warhog doesn't read this earlier and beats me to it :)

 

We don't have detailed documentation yet, but the comments in the sketch should contain enough information if you are already familiar with the general operation of stepper motors.

Link to comment
Share on other sites

#define DCSBIOS_IRQ_SERIAL

#include <AccelStepper.h>
#include "DcsBios.h"

struct StepperConfig {
 unsigned int maxSteps;
 unsigned int acceleration;
 unsigned int maxSpeed;
};


class Vid29Stepper : public DcsBios::Int16Buffer {
 private:
   AccelStepper& stepper;
   StepperConfig& stepperConfig;
   unsigned int (*map_function)(unsigned int);
   unsigned char initState;
 public:
   Vid29Stepper(unsigned int address, AccelStepper& stepper, StepperConfig& stepperConfig, unsigned int (*map_function)(unsigned int))
   : Int16Buffer(address), stepper(stepper), stepperConfig(stepperConfig), map_function(map_function), initState(0) {
   }

   virtual void loop() {
     if (initState == 0) { // not initialized yet
       stepper.setMaxSpeed(stepperConfig.maxSpeed);
       stepper.setAcceleration(stepperConfig.acceleration);
       stepper.moveTo(-((long)stepperConfig.maxSteps));
       initState = 1;
     }
     if (initState == 1) { // zeroing
       stepper.run();
       if (stepper.currentPosition() <= -((long)stepperConfig.maxSteps)) {
         stepper.setCurrentPosition(0);
         initState = 2;
         stepper.moveTo(stepperConfig.maxSteps/2);
       }
     }
     if (initState == 2) { // running normally
       if (hasUpdatedData()) {
         unsigned int newPosition = map_function(getData());
         newPosition = constrain(newPosition, 0, stepperConfig.maxSteps);
         stepper.moveTo(newPosition);
       }
       stepper.run();
     }
   }
};

/* modify below this line */

/* define stepper parameters
  multiple Vid29Stepper instances can share the same StepperConfig object */
struct StepperConfig stepperConfig = {
 1360,  // maxSteps
 1200, // maxSpeed
 10000 // acceleration
 };


// define AccelStepper instance
AccelStepper stepper(AccelStepper::DRIVER, 11, 10);
// define Vid29Stepper class that uses the AccelStepper instance defined in the line above
//           +-- arbitrary name
//           |   +-- Address of stepper data (from control reference)
//           |   |       +-- name of AccelStepper instance
//           v   v       v        v-- StepperConfig struct instance
Vid29Stepper vvi(0x106e, stepper, stepperConfig, [](unsigned int newValue) -> unsigned int {
 /* this function needs to map newValue to the correct number of steps */
 return map(newValue, 0, 65535, 0, stepperConfig.maxSteps);
}); 


void setup() {
 DcsBios::setup();
}

void loop() {
 DcsBios::loop();
}

 

The interesting lines to modify (without comments) are these:

struct StepperConfig stepperConfig = {
 1360,  // maxSteps
 1200, // maxSpeed
 10000 // acceleration
 };

AccelStepper stepper(AccelStepper::DRIVER, 11, 10);
Vid29Stepper vvi(0x106e, stepper, stepperConfig, [](unsigned int newValue) -> unsigned int {
 return map(newValue, 0, 65535, 0, stepperConfig.maxSteps);
}); 

 

Here's what you'd need to add for a second stepper of the same model (i.e. same number of steps, max speed and acceleration):

AccelStepper flapPosStepper(AccelStepper::DRIVER, 13, 12);
Vid29Stepper flapPos(0x10a0, flapPosStepper, stepperConfig, [](unsigned int newValue) -> unsigned int {
 return map(newValue, 0, 65535, 0, stepperConfig.maxSteps);
}); 

  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...