Jump to content

DCS BIOS TACAN Left Channel


Pavespawn

Recommended Posts

Well I’m the absence of guidance, I went with the next best thing: I made things up. I prototyped a rotary encoder (fancy way of saying “I rigged this crap up”) to the output shaft of the left channel selector. It works but you have to make sure you are set to 0 at game start. Is there a way to get DCS to recognize where the encoder is positioned?

 

tN2hPXZ.jpg

 

9ZuvPUE.jpg

 

TJr5bKD.jpg

Link to comment
Share on other sites

this is the a10c tacan panel coding from the control reference.

 

right channel selector

DcsBios::RotaryEncoder tacan1("TACAN_1", "DEC", "INC", PIN_A, PIN_B);

 

left channel selector

DcsBios::RotaryEncoder tacan10("TACAN_10", "DEC", "INC", PIN_A, PIN_B);

 

the encoder should have middle pin to gnd on arduino and the 2 out side pins on encoder are pin a and b. im not sure how encoders go with arduino just hooked up i know other devices u need to wire in diodes to make them work abit better. im fairly new to dcs bios myself but so far ive been able to get most things to work in the M2000

Link to comment
Share on other sites

this is the a10c tacan panel coding from the control reference.

 

right channel selector

DcsBios::RotaryEncoder tacan1("TACAN_1", "DEC", "INC", PIN_A, PIN_B);

 

left channel selector

DcsBios::RotaryEncoder tacan10("TACAN_10", "DEC", "INC", PIN_A, PIN_B);

 

the encoder should have middle pin to gnd on arduino and the 2 out side pins on encoder are pin a and b. im not sure how encoders go with arduino just hooked up i know other devices u need to wire in diodes to make them work abit better. im fairly new to dcs bios myself but so far ive been able to get most things to work in the M2000

 

Yup. All that is coded and works. What I mean is that because the dial is a physical one, if DCS starts and the physical dial is set to anything other than 0, it doesn't sync. DCS BIOS just knows to DEC or INC. It doesn't know where my physical dial is set at start.

Link to comment
Share on other sites

Rotary incremental encoders like the one you are using will only give a sequence of pulses when it moves. This sequence will differ depending on the rotation you give it, but only send signals while you rotate;

https://en.wikipedia.org/wiki/File:Quadrature_Diagram.svg

 

This type is a very easy type to implement and I would recommend it when using LED or other type of displays for showing the channels. Then you remove the sync issue as the displays will always show what DCS is seeing anad you just tell the channels to go up or down.

But the rotary incremental encoder will never tell you the current position.

 

You can get rotary absolute encoders from which you can determine the actual position, as it has a specific set of outputs for a specific position.

https://en.wikipedia.org/wiki/File:Encoder_disc_(3-Bit_binary).svg

 

These comes in many different variants depending of use. If you are using the original switch on your TACAN then this is an absolute encoder.

 

You sent me two PM’s, oneyesterday and one today. One states that you made the original left switch into a switch with one input per positions and tried to trick DCS-BIOS into seeing the left selector as a switch.

 

The second PM was about using rotary encoder and you also tried to incorporate the right switch with my code but can’t get it to ready the port registers.

 

I am currently travelling with work and have limited time. If you need assistance then you need to do the following;

 

1. Decide which of the two switches you want to implement first

2. Make a small wiring diagram on a piece of paper so that we can see how you connect it.

3. Make a matrix which shows correlation between switch positions and which pins will be grounded in this case.

4. Imbed the code you have used to solve the switch you decided from point 1 into the post you make

 

With my limited knowledge to Arduino coding I have found that solving multiple problems at the same time ends up in a bowl hay where you will not be able to conduct sequential trying and testing to prove what works and what does not. Focus on one item at a time, code it, load it, try it. If it works then save the code with a name that you can go back to. If it doesn’t work go back to the step that worked before and rethink your strategy.

For my TACAN code I ended up with 10 different saved versions, most which worked partly.

 

An original TACAN is IMHO a very difficult panel to implement as DCS isn’t prepared for it. The ILS is a much easier panel to implement.

 

Cheers

Solo

Link to comment
Share on other sites

Hans,

 

Thanks for providing so much assistance and feedback. I did start with modding the switch so there is only a single contact for each rotation. I originally hoped that I could define the channel selector as a rotary switch and then it would work all the way to 12 ( remember you saying that you had an issue with that) but that did not work. I really needed some kind of a win so I rigged up the encoder just to prove I could make the dial move. I don’t see this as the permanent fix.

 

I am now wondering if I can stick with the individual contact idea for each switch but also use the port registers. I am going to try to code it like so (I am typing this at work so this is a guess):

  

if (PINA == B10000000) {
   valueTacan_left = 0;
 }
 if (PINA == B01000000) {
   valueTacan_left = 1;
 }
if (PINA == B00100000) {
   valueTacan_left = 2;
 }

Etc, etc
 

 

So that each individual contact works as a high reading. Since I have 13 contacts I will have to use multiple ports but it seems like it should work. What do you think?

 

I started a diagram to map this out so I’ll finish that and post my product based on my modified switch. I’ll then move onto the right switch.

 

Can you tell me what timer library you are using? I have one but it didn’t like some of your commands.

Link to comment
Share on other sites

Ok here is the matrix I created even though it seemed too simple since I modded the rotary to allow a single contact each turn of the dial. What I have depicted is:

Across the top is the rotary positions and the pin that the corresponding wire goes into the Mega.

 

The left side shows the channel that shows when in the contacted position. If I understand this correctly then the code for channel 0 would be B10000000.

The matrix runs to position 8 (channel 7) then it would have to start over on the next set of registers so I would start over (channel 8 on pin 30 would also code to B10000000.

 

1CteMgl.jpg

Link to comment
Share on other sites

Here is the code I have loaded. I do not get any indication that the left channel selector is even being recognized. Unlike the other switches, I get no flicker of a Tx light on the board and neither the serial monitor or the connect-serial-port cmd show activity (used separately)

 

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

int Tacan_left_ingame; // hold value from DCS


/* paste code snippets from the reference documentation here */
const byte tacanModePins[5] = {9, 10, 11, 12, 13};
DcsBios::SwitchMultiPos tacanMode("TACAN_MODE", tacanModePins, 5);

DcsBios::Switch2Pos tacanXy("TACAN_XY", 7);

DcsBios::Potentiometer tacanVol("TACAN_VOL", A0);

DcsBios::Switch2Pos tacanTestBtn("TACAN_TEST_BTN", 6);

//TACAN Left Channel
void onTacan10Change(unsigned int newValue_Tacan_left) {
 Tacan_left_ingame = newValue_Tacan_left;
}
DcsBios::IntegerBuffer tacan10Buffer(0x1158, 0x0f00, 8, onTacan10Change);





void setup() {
 DcsBios::setup();
 
//TACAN_10 inputs
 DDRA = B00000000; // set PINA (digital 29-22) as inputs
 PORTA = B11111111; // Sets (digital 29-22) with internal pull up

 //TACAN_10 inputs continued  
 DDRC = B00000000; // set PINA (digital 30-37) as inputs
 PORTC = B11111111; // Sets (digital 30-37) with internal pull up

}
int inputTacan_left()
{
 int valueTacan_left;
 if (PINA == B10000000) {
   valueTacan_left = 0;
 }
 if (PINA == B01000000) {
   valueTacan_left = 1;
 }
 if (PINA == B00100000) {
   valueTacan_left = 2;
 }
 if (PINA == B00010000) {
   valueTacan_left = 3;
 }
 if (PINA == B00001000) {
   valueTacan_left = 4;
 }
 if (PINA == B00000100) {
   valueTacan_left = 5;
 }
 if (PINA == B00000010) {
   valueTacan_left = 6;
 }
 if (PINA == B00000001) {
   valueTacan_left = 7;
 }
 if (PINC == B10000000) {
   valueTacan_left = 8;
 }
 if (PINC == B01000000) {
   valueTacan_left = 9;
 }
 if (PINC == B00100000) {
   valueTacan_left = 10;
 }
 if (PINC == B00010000) {
   valueTacan_left = 11;
 }
 if (PINA == B00001000) {
   valueTacan_left = 12;
 }

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

}

void setTacan() {
if (Tacan_left_ingame < inputTacan_left()) {
   sendDcsBiosMessage("TACAN_10", "INC");
 }

 if (Tacan_left_ingame > inputTacan_left()) {
   sendDcsBiosMessage("TACAN_10", "DEC");
 }


}

Link to comment
Share on other sites

Yes that wouldn't work. First thing is that the sequence of the numbers in the commentary matters. If I recall correctly then we talk about most significant and least significant numbers from left to right. Input 29 is the most significant number and input 22 is the least significant number.

 

So in your code for the first position you are looking for a HIGH value on input no. 29, where you should have been looking input 22. So the order is in reverse.

 

Now you may say that then you should still get a reaction for position number 7. Well no.

 

You remember that when you connect a toggle switch to the Arduino with DCS-BIOS then you use ground for one side of the toggle and then connect the other side of the toggle to the input.

 

So when the toggle if OFF then the Arduino reads the input as HIGH, then when switched into ON the input is grounded and goes LOW.

 

My code is set for internal pullup similar to how the DCS-BIOS code is done.

 

  PORTA = B11111111; // Sets (digital 29-22) with internal pull up

 

So if you do not connect anything to the inputs 29-22 then you will be able to measure 5VDC between each input and GND.

 

You have used this in your code;

 

  if (PINA == B10000000) {
   valueTacan_left = 0;

 

Which the Ardiuno based upon the internal pullup will interprets as "inputs 28-22 shall be LOW (connected to GND) then valueTacan_left is zero"

 

I assume that the common pin on the rotary has been connected to GND like the other toggle switches and based upon that this will be the code;

 

  if (PINA == B11111110) {
   valueTacan_left = 0;

 

Cheers

Link to comment
Share on other sites

Based on that I changed my code to the following but I still get nothing to register. I wanted to make sure that my pins were still connected so as an experiment I uploaded a test sketch that defined tacan10 as SwitchMultiPos in order to see if it would give me a return and it does. I must have something else wrong or missing that is preventing the sketch from seeing the values. :( Here is my updated sketch based on your inputs. I must be missing something.

 

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

int Tacan_left_ingame; // hold value from DCS


/* paste code snippets from the reference documentation here */
const byte tacanModePins[5] = {9, 10, 11, 12, 13};
DcsBios::SwitchMultiPos tacanMode("TACAN_MODE", tacanModePins, 5);

DcsBios::Switch2Pos tacanXy("TACAN_XY", 7);

DcsBios::Potentiometer tacanVol("TACAN_VOL", A0);

DcsBios::Switch2Pos tacanTestBtn("TACAN_TEST_BTN", 6);

//TACAN Left Channel
void onTacan10Change(unsigned int newValue_Tacan_left) {
 Tacan_left_ingame = newValue_Tacan_left;
}
DcsBios::IntegerBuffer tacan10Buffer(0x1158, 0x0f00, 8, onTacan10Change);





void setup() {
 DcsBios::setup();
 
//TACAN_10 inputs
 DDRA = B00000000; // set PINA (digital 29-22) as inputs
 PORTA = B11111111; // Sets (digital 29-22) with internal pull up

 //TACAN_10 inputs continued  
 DDRC = B00000000; // set PINA (digital 30-37) as inputs
 PORTC = B11111111; // Sets (digital 30-37) with internal pull up

}
int inputTacan_left()
{
 int valueTacan_left;
 if (PINA == B11111110) {
   valueTacan_left = 0;
 }
 if (PINA == B11111101) {
   valueTacan_left = 1;
 }
 if (PINA == B11111011) {
   valueTacan_left = 2;
 }
 if (PINA == B11110111) {
   valueTacan_left = 3;
 }
 if (PINA == B11101111) {
   valueTacan_left = 4;
 }
 if (PINA == B11011111) {
   valueTacan_left = 5;
 }
 if (PINA == B10111111) {
   valueTacan_left = 6;
 }
 if (PINA == B01111111) {
   valueTacan_left = 7;
 }
 if (PINC == B11101111) {
   valueTacan_left = 8;
 }
 if (PINC == B11110111) {
   valueTacan_left = 9;
 }
 if (PINC == B11111011) {
   valueTacan_left = 10;
 }
 if (PINC == B11111101) {
   valueTacan_left = 11;
 }
 if (PINA == B11111110) {
   valueTacan_left = 12;
 }

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

}

void setTacan() {
if (Tacan_left_ingame < inputTacan_left()) {
   sendDcsBiosMessage("TACAN_10", "INC");
 }

 if (Tacan_left_ingame > inputTacan_left()) {
   sendDcsBiosMessage("TACAN_10", "DEC");
 }


}

Link to comment
Share on other sites

Well you are not calling the function 'setTacan()' at all in the loop thus it is never executed :music_whistling:

 

Try using this loop instead;

 

void loop() {

DcsBios::loop();

setTacan();

delay(200);

 

}

 

Here you can see that the 'setTacan()' is being called, and I added a small delay of 200ms ad the end of the loop which means the Arduino will stay here for 200ms before starting all over. It's not the right way of doing it but for simplicity it will do the trick for now.

 

Can you spot the error her;

int inputTacan_left()
{
 int valueTacan_left;
 if (PINA == B11111110) {
   valueTacan_left = 0;
 }
 if (PINA == B11111101) {
   valueTacan_left = 1;
 }
 if (PINA == B11111011) {
   valueTacan_left = 2;
 }
 if (PINA == B11110111) {
   valueTacan_left = 3;
 }
 if (PINA == B11101111) {
   valueTacan_left = 4;
 }
 if (PINA == B11011111) {
   valueTacan_left = 5;
 }
 if (PINA == B10111111) {
   valueTacan_left = 6;
 }
 if (PINA == B01111111) {
   valueTacan_left = 7;
 }
 if (PINC == B11101111) {
   valueTacan_left = 8;
 }
 if (PINC == B11110111) {
   valueTacan_left = 9;
 }
 if (PINC == B11111011) {
   valueTacan_left = 10;
 }
 if (PINC == B11111101) {
   valueTacan_left = 11;
 }
 if ([b]PINA == B11111110[/b]) {
   valueTacan_left = 12;
 }

   return valueTacan_left;
}

 

Correct it and you will find that channels 0-7 works however 8-12 does not at least not if you are using the pins you listed. Try and see if you can figure out why 8-12 wont work.

 

Cheers

Hans

Link to comment
Share on other sites

:doh:Ok, you are a genius. I don't want to every hear you say you don't really know much about Arduino :lol:. I now have a working TACAN but I have the same issue that you have. I cannot go past 9. What mine does is when I flip it to 10, it jumps to 12 and sticks there until I roll all the way back down to around 4 and then flip the knob in the game itself and it will roll back down. I'll tell you that as frustrating as this can be, it is pretty fun to try and figure it out. Of course I don't speak fluent Arduino like you do.

 

Ok so looking at the code I think the reason 8-12 wouldn't work is the fact that I get into a new port and the low would start over in the first (or last) position depending on how it gets wired (and 12 is back on port A which would conflict I suppose.

 

Thanks for all the assistance. I was hoping to figure something out on the 10-12 to pay you back for all the assistance you have given me. I'll keep plugging at it as I get time. I am going out of town for a few days soon so I won't be able to work on it for a while.

 

Gary

Link to comment
Share on other sites

Sounds good.

 

(and 12 is back on port A which would conflict I suppose.

Yes firstly correct to PINC

 

 

Ok so looking at the code I think the reason 8-12 wouldn't work is the fact that I get into a new port and the low would start over in the first (or last) position depending on how it gets wired

 

Yes sir. Check your connection from post 11 and be mindful of the order in which the pins come in;

  //TACAN_10 inputs continued  
 DDRC = B00000000; // set PINA (digital 30-37) as inputs
 PORTC = B11111111; // Sets (digital 30-37) with internal pull up

 

Cheers

Link to comment
Share on other sites

  • Recently Browsing   0 members

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