Jump to content

Stepper x27 and DCS Bios request


Johan4668

Recommended Posts

Yes Johan, I'll try to help you with the code. But I have to say that I'm not a programmer and everything I know is more or less from the internet.

First I have to re-install the 109 as I unfortunately didn't use that beauty for years, to see the DcsBios fragments.

Regards, Vinc

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

EDIT

Below are arguments and addresses of the altimeter gauge for further use.

1) Instrument needle displays the altitute from 0 to 1.000 metres at a round dial

  // Altimeter Needle in meters (0-1.000 m)
void onAltimeterFineptrChange(unsigned int newValue) {
	stepper.runToNewPosition(map(newValue, 0, 56535, 0, 1260));
}
DcsBios::IntegerBuffer altimeterFineptrBuffer(0x4248, 0xffff, 0, onAltimeterFineptrChange);

2) the lower window shows the altitude in kilometres from 0 to 13 (or better in metres to 13.000)

  // Altimeter kilometer disk (0-13.000 m)
void onAltimeterCoarseptrChange(unsigned int newValue) {
	stepper.runToNewPosition(map(newValue, 0, 56535, 0, 1260));
}
DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange);

3) the barometric pressure scale shows values from 920 to 1040 mbar

  // Altimeter barometric pressure (920 - 1040 mbar)
void onAltimeterPressureChange(unsigned int newValue) {
	stepper.runToNewPosition(map(newValue, 0, 56535, 0, 1260));
}
DcsBios::IntegerBuffer altimeterPressureBuffer(0x424c, 0xffff, 0, onAltimeterPressureChange);

4) for the pressure setting knob, the input command line can be used from DcsBios to connect rotary encoders

DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", PIN_A, PIN_B);

So the next step would be, to merge the stepper code with the lines for the km-indication window to bring the "normal" stepper to life and to connect a rotary to see the DcsWorld reaction.

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

4 hours ago, Vinc_Vega said:

EDIT

Unfortunately, DcsBios does not translate the correct arguments for the Bf-109's altimeter. So I did a deeper look into the instrument's code and read out values with an UNO by trial and error.

Below are arguments and addresses of the altimeter gauge for further use.

1) Instrument needle displays the altitute from 0 to 1.000 metres at a round dial

void onAltimeterFineptrChange(unsigned int newValue) {
    // altimeterFineptr = map(newValue, 0, 65535, 0, 1000);	// Altimeter Needle in meters (0-1.000 m)  
}
DcsBios::IntegerBuffer altimeterFineptrBuffer(0x424a, 0xffff, 0, onAltimeterFineptrChange);

2) the lower window shows the altitude in kilometres from 0 to 13 (or better in metres to 13.000)

void onAltimeterCoarseptrChange(unsigned int newValue) {
    // altimeterCoarseptr = map(newValue, 0, 65535, 0, 13000);	// Altimeter kilometre indication (0-13.000 m)
}
DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424c, 0xffff, 0, onAltimeterCoarseptrChange);

3) the barometric pressure scale shows values from 920 to 1040 mbar

void onAltimeterPressureChange(unsigned int newValue) {
    // altimeterPressure = map(newValue, 0, 65535, 920, 1040);  // Altimeter pressure scale (920 - 1040 mbar)
}
DcsBios::IntegerBuffer altimeterPressureBuffer(0x424e, 0xffff, 0, onAltimeterPressureChange);

4) for the pressure setting knob, the input command line can be used from DcsBios to connect rotary encoders

DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", PIN_A, PIN_B);

So the next step would be, to merge the stepper code with the lines for the km-indication window to bring the "normal" stepper to life and to connect a rotary to see the DcsWorld reaction.

 

Regards, Vinc

 

Ok.. I'll put the stepper code underneath the line..

Link to comment
Share on other sites

Hi Johan,

You may use te below sketch for the altimeter kilometre disk and the pressure set knob.

It still has death code for the needle and the pressure scale.

Depending on your kilometre disk layout (0 to 9 or 0 to 13), if the scale has 315 or 360 degrees and if you use further reduction gears we may have to adjust it.

Spoiler
// #define RS485  // default is USB mode, uncomment for using at the RS485 bus

#ifndef RS485
  #define DCSBIOS_IRQ_SERIAL  // use for Arduino UNO, NANO and MEGA
  // #define DCSBIOS_DEFAULT_SERIAL  // use for other boards like ESP32 or Raspberry Pi Pico
#endif

#ifdef RS485
  #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
  #define TXENABLE_PIN 2
#endif

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

// ---------- Stepper Motor Declarations ----------
#include <AccelStepper.h>

// kind of Switec X25.168 stepper motor clone, 630 steps (1260 half steps) per revolution (limited to 315°) -> 4 steps per degree
 // pin 5 @ 2h, pin 6 @ 4h, pin 7 @ 8h and pin 8 @ 10h o'clock positions (view from needle)
AccelStepper stepper0(AccelStepper::HALF4WIRE , 8, 7, 5, 6);

// ----------------------------------------------------------------------------
//     DCS Bios Stuff here
//-----------------------------------------------------------------------------

// -------------- OUTPUTS HERE ----------

  // Altimeter Needle in meters (0-1.000 m)
void onAltimeterFineptrChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer altimeterFineptrBuffer(0x4248, 0xffff, 0, onAltimeterFineptrChange);

  // Altimeter kilometer disk (0-13.000 m)
void onAltimeterCoarseptrChange(unsigned int newValue) {
	stepper0.runToNewPosition(map(newValue, 0, 56535, 0, 1260));
}
DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424a, 0xffff, 0, onAltimeterCoarseptrChange);

  // Altimeter barometric pressure (920 - 1040 mbar)
void onAltimeterPressureChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer altimeterPressureBuffer(0x424c, 0xffff, 0, onAltimeterPressureChange);

// -------------- INPUTS HERE ----------

// sea level knob
DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 3, 4);


// ----------------------------------------------------------------------------
//     SETUP loop
//-----------------------------------------------------------------------------
void setup(void)
{
  DcsBios::setup();

// ----- Stepper init
    stepper0.setMaxSpeed(16000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(1260); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(1260); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
    
}

// ----------------------------------------------------------------------------
//     LOOP loop - try to keep empty
//-----------------------------------------------------------------------------
void loop() {
  DcsBios::loop();
}

 

 

PS: I put in a compiler switch at the top if you want to try the sketch with the RS485 option.

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

1 hour ago, Vinc_Vega said:

Hi Johan,

You may use te below sketch for the altimeter kilometre disk and the pressure set knob.

It still has death code for the needle and the pressure scale.

Depending on your kilometre disk layout (0 to 9 or 0 to 13), if the scale has 315 or 360 degrees and if you use further reduction gears we may have to adjust it.

  Reveal hidden contents

// #define RS485  // default is USB mode, uncomment for using at the RS485 bus

#ifndef RS485
  #define DCSBIOS_IRQ_SERIAL  // use for Arduino UNO, NANO and MEGA
  // #define DCSBIOS_DEFAULT_SERIAL  // use for other boards like ESP32 or Raspberry Pi Pico
#endif

#ifdef RS485
  #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
  #define TXENABLE_PIN 2
#endif

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

// ---------- Stepper Motor Declarations ----------
#include <AccelStepper.h>

// kind of Switec X25.168 stepper motor clone, 630 steps (1260 half steps) per revolution (limited to 315°) -> 4 steps per degree
 // pin 5 @ 2h, pin 6 @ 4h, pin 7 @ 8h and pin 8 @ 10h o'clock positions (view from needle)
AccelStepper stepper0(AccelStepper::HALF4WIRE , 5, 6, 8, 7);

// ----------------------------------------------------------------------------
//     DCS Bios Stuff here
//-----------------------------------------------------------------------------

// -------------- OUTPUTS HERE ----------

  // Altimeter Needle in meters (0-1.000 m)
void onAltimeterFineptrChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer altimeterFineptrBuffer(0x424a, 0xffff, 0, onAltimeterFineptrChange);

 // Altimeter kilometre disk (0-13.000 m)
void onAltimeterCoarseptrChange(unsigned int newValue) {
    unsigned int stepperPosition = map(newValue, 0, 65535, 0, 1080);  // 1260 (full cycle) / 315deg * 270deg (3/4 circle) = 1080 half steps
    stepper0.runToNewPosition(stepperPosition);
}
DcsBios::IntegerBuffer altimeterCoarseptrBuffer(0x424c, 0xffff, 0, onAltimeterCoarseptrChange);

  // Altimeter barometric pressure (920 - 1040 mbar)
void onAltimeterPressureChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer altimeterPressureBuffer(0x424e, 0xffff, 0, onAltimeterPressureChange);

// -------------- INPUTS HERE ----------

// sea level knob
DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 3, 4);


// ----------------------------------------------------------------------------
//     SETUP loop
//-----------------------------------------------------------------------------
void setup(void)
{
  DcsBios::setup();

// ----- Stepper init
    stepper0.setMaxSpeed(16000);    //  maximum speed in steps per second. Must be > 0.
    stepper0.setAcceleration(8000);  //  desired acceleration in steps per second per second. Must be > 0.0
    stepper0.runToNewPosition(1260); // go to the upper end stop
    delay(250);
    stepper0.setCurrentPosition(1260); // set max steps
    stepper0.runToNewPosition(0);    // go to the lower end stop
    delay(250);
    stepper0.setCurrentPosition(0);  // set steps to zero
    
}

// ----------------------------------------------------------------------------
//     LOOP loop - try to keep empty
//-----------------------------------------------------------------------------
void loop() {
  DcsBios::loop();
}

 

 

PS: I put in a compiler switch at the top if you want to try the sketch with the RS485 option.

 

Regards, Vinc

 

 

Until i have the Mega ill try it directly.

 

so the code must be like this that i don't have the RS485 fuction.

---------------------------------

// #define RS485  // default is USB mode, uncomment for using at the RS485 bus

#ifndef RS485
  #define DCSBIOS_IRQ_SERIAL  // use for Arduino UNO, NANO and MEGA
  // #define DCSBIOS_DEFAULT_SERIAL  // use for other boards like ESP32 or Raspberry Pi Pico
#endif

//#ifdef RS485
// #define DCSBIOS_RS485_SLAVE 1 // change according your slave number (1 to 128)
//  #define TXENABLE_PIN 2
//#endif

-------------------------------------

Link to comment
Share on other sites

No, for the standard USB mode just leave it as it is.

For the RS485 option (later) delete the first two slashes.

As you may see, I connected the encoder to pins D3 and D4 and the stepper for the km-disk to pins D5 to D8.

Regards, Vinc

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

Looking at this thread, it seems to me you're coming up against the same problem as I had with the P-51 airspeed indicator - A linear output from DCS and a non-linear gauge needle position.
I found this code in the mainpanel_init.lua of the P-51, but didn't understand why it was showing linear in and out:

AirspeedNeedle				= CreateGauge()
AirspeedNeedle.arg_number	= 11
AirspeedNeedle.input		= {0,   50,   100,  150,  200, 250,  300, 350,  400, 450,  500, 550,  600, 650,  700}
AirspeedNeedle.output		= {0.0, 0.05, 0.10, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7}
AirspeedNeedle.controller	= controllers.AirspeedNeedle

I abandoned trying to fix it at the time as there was no apparent mathematical progression of the needle position, and I didn't know what was going on.  If I'd continued with the physical gauge thing, I'd have made a linear scale face.

It wasn't until I was looking into modding late last year that I found out what's going on...
The output numbers (0.0 to 0.7) refer to the needle ANIMATION position in the cockpit model (frames 0 to 70).  i.e.  DCS only deals with the linear figures, and any non-linearity in the displayed gauge is a function of the 3D model animation.
The needle is "keyframed" to point at the correct numbers on the gauge for each of the stages, and the 3D modelling software works out the frames in between.

However, even though I've realised what's going on, I've not looked at a way to fix it in code.


Edited by No1sonuk
Link to comment
Share on other sites

No, this time the mapping can be done linear for the altimeter (not like that of the Mig-21's rad alt). I have read out, mapped the values and put it temporary on a LCD display. All displayed values were perfectly in line with the respective gauge positions in the cockpit.

 

PS: have a look here for non linear solution

https://forum.dcs.world/topic/208455-dcs-bios-over-rs485/?do=findComment&comment=5168699

Regards, Vinc


Edited by Vinc_Vega
  • Thanks 1

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

C:\Users\johan\AppData\Local\Temp\.arduinoIDE-unsaved2023213-24360-9wvz4b.k76n\sketch_mar13a\sketch_mar13a.ino:17:10: fatal error: AccelStepper.h: No such file or directory
 #include <AccelStepper.h>
          ^~~~~~~~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: AccelStepper.h: No such file or directory

nullhis is how i wire it Ill post the code in a bit... 

 

I got this error?

Link to comment
Share on other sites

40 minutes ago, Johan4668 said:

C:\Users\johan\AppData\Local\Temp\.arduinoIDE-unsaved2023213-24360-9wvz4b.k76n\sketch_mar13a\sketch_mar13a.ino:17:10: fatal error: AccelStepper.h: No such file or directory
 #include <AccelStepper.h>
          ^~~~~~~~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: AccelStepper.h: No such file or directory

nullhis is how i wire it Ill post the code in a bit... 

 

I got this error?

solved.. needed the libery.

 

/*
  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"
// Altimeter Pressure Set
DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 4, 5);



 
/* paste code snippets from the reference documentation here */
 
void setup() {
  DcsBios::setup();
}
 
void loop() {
  DcsBios::loop();
}


i was trying the knob.. i see data in dcs bios.. but it is not moving.. 

null

image.png

Link to comment
Share on other sites

Maybe you have other than 4 steps per detents encoders, than the code has to be adapted. Have a look into the DcsBios "Code Snippet Reference".

Or you have to debounce the encoder. For the test code I used a standard KY-040 rotary, that already has all the resistors on board.

Alternative you may use a 10k potentiometer for the sea level knob. Shold be easier to do than an encoder and analoge input pins could be used.

Code than may need to be adjusted something like below (didn't try it yet).

DcsBios::PotentiometerEWMA<5, 128, 5> altPressSet("ALT_PRESS_SET", PIN);

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

30 minutes ago, No1sonuk said:

The data on the web site indicates it's one pulse/step per detent.

Is that good? I can do some test tomorrow. What can I do to test this encoder? Or what can I buy if this does not work... I have not an other on the shelf...

Found this..

 

// two steps per detent:

DcsBios::RotaryEncoder<2> ilsMhz("ILS_MHZ", "DEC", "INC", PIN_A, PIN_B);

Then I'll exchange the 2 for 1 because it is a 1 step..

Link to comment
Share on other sites

1 hour ago, Johan4668 said:

Is that good? I can do some test tomorrow. What can I do to test this encoder? Or what can I buy if this does not work... I have not an other on the shelf...

Found this..

 

// two steps per detent:

DcsBios::RotaryEncoder<2> ilsMhz("ILS_MHZ", "DEC", "INC", PIN_A, PIN_B);

Then I'll exchange the 2 for 1 because it is a 1 step..

1 step means it doesn't need the different code line.

Also, having looked at your image earlier, I don't think the encoder IS sending data.
Mine has "ALT_PRESS_SET -3200" and "ALT_PRESS_SET +3200" in the text.
This is after starting the connection, without DCS open:

image.png

My code:

/*
  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"

/* paste code snippets from the reference documentation here */

DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 2,3);

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

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

 

  • Thanks 1
Link to comment
Share on other sites

16 hours ago, No1sonuk said:

1 step means it doesn't need the different code line.

Also, having looked at your image earlier, I don't think the encoder IS sending data.
Mine has "ALT_PRESS_SET -3200" and "ALT_PRESS_SET +3200" in the text.
This is after starting the connection, without DCS open:

image.png

My code:

/*
  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"

/* paste code snippets from the reference documentation here */

DcsBios::RotaryEncoder altPressSet("ALT_PRESS_SET", "-3200", "+3200", 2,3);

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

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

 

now...

 

this is the nano.. and not working

null

image.png

and this the Uno.. and working

 

null

image.png

on the same sketch

Link to comment
Share on other sites

9 minutes ago, No1sonuk said:

Did you set the right board for the nano in the Arduino IDE?
Mine was also an Uno, but I just tried a Nano and got the same, working result.

Yes to arduino nano.... not an original it is a clone.. I bought a  new one to test.. will come in tomorrow.. keep you posted.. 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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