Start of the viggen panels, tips, tricks and alot of help is welcome

Hello there.

I started this project to try and do a viggen cockpit :smiley: gonna be interresting. Biggest peoblem will probably be the space needed haha. And after that will be learning to code.

I have started with the nav/datapanel, it felt like a good start. There were already a topic created by Stingersharp over on (ED forum, Navpanel that had the dimensions. So thanks Stingersharp.
There are buttons, switches and knob and a display (which i am very very scared of xD).


Picture taken from Novelair, which is also where i bought the buttons for this project.
prototyp1
My prototype.

What kind of screws whould you guys use for the DZUS screws?

The switch was easy enough just on-off. That is one pin.
code was easy too.

#define DCSBIOS_DEFAULT_SERIAL

#include “DcsBios.h”

/* paste code snippets from the reference documentation here */
DcsBios::Switch2Pos dataInOut(“DATA_IN_OUT”, 12);

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

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

Then i did the buttons and was not so intrigued of using 11 pins on my micro so I made a matrix for that so only 7 pins were used for that :slight_smile:
The code for that I got from Hansolo who hade done a matrix for the cdu on the a10, so thanks for that :slight_smile: just altered it alittle bit.

#define DCSBIOS_DEFAULT_SERIAL

#include <Keypad.h>
#include “DcsBios.h”
/* paste code snippets from the reference documentation here */
const byte ROWS = 3; //three rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
{‘1’,‘4’,‘7’,‘A’},
{‘2’,‘5’,‘8’,‘0’},
{‘3’,‘6’,‘9’},

};
byte rowPins[ROWS] = {0, 1, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 5, 4, 3}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
DcsBios::setup();
keypad.addEventListener(keypadEvent); // Add an event listener.
keypad.setHoldTime(100); // Default is 1000mS
keypad.setDebounceTime(50); // Default is 50mS
}

void loop() {
DcsBios::loop();
char key = keypad.getKey();
}

void keypadEvent(KeypadEvent KEY){
switch (keypad.getState()) { // gives PRESSED, HOLD or RELEASED
case PRESSED: // If someone finds a better solution as switch - case: Let me know, please :slight_smile:
switch(KEY) { // following commands are fired unique if PRESSED
//CDU
case ‘1’: sendDcsBiosMessage(“DATAPANEL_KEY_1”, “1”); break;
case ‘2’: sendDcsBiosMessage(“DATAPANEL_KEY_2”, “1”); break;
case ‘3’: sendDcsBiosMessage(“DATAPANEL_KEY_3”, “1”); break;
case ‘4’: sendDcsBiosMessage(“DATAPANEL_KEY_4”, “1”); break;
case ‘5’: sendDcsBiosMessage(“DATAPANEL_KEY_5”, “1”); break;
case ‘6’: sendDcsBiosMessage(“DATAPANEL_KEY_6”, “1”); break;
case ‘7’: sendDcsBiosMessage(“DATAPANEL_KEY_7”, “1”); break;
case ‘8’: sendDcsBiosMessage(“DATAPANEL_KEY_8”, “1”); break;
case ‘9’: sendDcsBiosMessage(“DATAPANEL_KEY_9”, “1”); break;
case ‘0’: sendDcsBiosMessage(“DATAPANEL_KEY_0”, “1”); break;
case ‘A’: sendDcsBiosMessage(“CK37_RENSA_CLEAR”, “1”); break;

}}

switch (keypad.getState()){ // gives PRESSED, HOLD or RELEASED
case RELEASED:
switch(KEY) { // Released KEYs or Neutral Rockers signal is sent
//CDU
case ‘1’: sendDcsBiosMessage(“DATAPANEL_KEY_1”, “0”); break;
case ‘2’: sendDcsBiosMessage(“DATAPANEL_KEY_2”, “0”); break;
case ‘3’: sendDcsBiosMessage(“DATAPANEL_KEY_3”, “0”); break;
case ‘4’: sendDcsBiosMessage(“DATAPANEL_KEY_4”, “0”); break;
case ‘5’: sendDcsBiosMessage(“DATAPANEL_KEY_5”, “0”); break;
case ‘6’: sendDcsBiosMessage(“DATAPANEL_KEY_6”, “0”); break;
case ‘7’: sendDcsBiosMessage(“DATAPANEL_KEY_7”, “0”); break;
case ‘8’: sendDcsBiosMessage(“DATAPANEL_KEY_8”, “0”); break;
case ‘9’: sendDcsBiosMessage(“DATAPANEL_KEY_9”, “0”); break;
case ‘0’: sendDcsBiosMessage(“DATAPANEL_KEY_0”, “0”); break;
case ‘A’: sendDcsBiosMessage(“CK37_RENSA_CLEAR”, “0”); break;

}}
}

It works very well.

Now i am working on the knob for the “datapanel_selector”. And again i am trying to save pins so i was gonna try and do a analog read value type of code. I got the code working outside dcs bios.
I first tried doing it with a switch code with 7 steps.
But if i understand it correctly, if i give them a value of 0-600 it divides it equally over 7 steps, so I might have put the wrong resistors because step 3 and 4 are to close each other so it goes like 0-1-2-4-4-5-6. Any idea how I should pick the resistors, i know there should be a way to calculate it.

const int sensorMin = 0; // sensor minimum, discovered through experiment
const int sensorMax = 577; // sensor maximum, discovered through experiment

void setup() {
Serial.begin(9600); // initialize serial communications at 9600 bps
}

void loop() {

int sensorReading = analogRead(A0);
int range = map(sensorReading, sensorMin, sensorMax, 0, 5);

switch (range) {
case 0: // your hand is on the sensor
Serial.println(sensorReading);
break;
case 1: // your hand is close to the sensor
Serial.println(sensorReading);
break;
case 2: // your hand is a few inches from the sensor
Serial.println(sensorReading);
break;
case 3: // your hand is nowhere near the sensor
Serial.println(sensorReading);
break;
case 4: // your hand is close to the sensor
Serial.println(sensorReading);
break;
case 5: // your hand is a few inches from the sensor
Serial.println(sensorReading);
break;
case 6: // your hand is nowhere near the sensor
Serial.println(sensorReading);
break;

}
delay(1); // delay in between reads for stability
}

Anyway i decided to go forward with a few if statements with the values read from the serial monitor.
But even after that I can not get the datapanel_selector to read the states 0-6.
The code was borrowed and altered from Eman2000 on youtube

#define DCSBIOS_DEFAULT_SERIAL

#include “DcsBios.h”

/* paste code snippets from the reference documentation here */
const int analogInPin = A0;

int sensorValue = 0; // value read from the buttons
int state = 0; // used for storing what button was pressed

void setup() {
DcsBios::setup();
Serial.begin(9600); // initialize serial communications at 9600 bps
}

void loop() {

DcsBios::loop();
Serial.print("Value = ");
Serial.println(sensorValue);
Serial.print("State = ");
Serial.println(state);
}
void readSwitch () { //creates the function to read the switch states
sensorValue = analogRead(analogInPin); //read the analog pin the switches are connected to

if (sensorValue < 600 && sensorValue > 550) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 0;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “0”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}

if (sensorValue < 550 && sensorValue > 520) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 1;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “1”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}

if (sensorValue < 520 && sensorValue > 480) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 2;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “2”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}

if (sensorValue < 480 && sensorValue > 370) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 3;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “3”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}
if (sensorValue < 370 && sensorValue > 280 ) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 4;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “4”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}
if (sensorValue < 280 && sensorValue > 130 ) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 5;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “5”); //have tried with and without citation marks
delay(100); //delay for debounce purposes
}
if (sensorValue < 130 && sensorValue >= 0 ) { //if the analog reading is within a certain range we know which button was pressed and set the state accordingly
state = 6;
sendDcsBiosMessage(“DATAPANEL_SELECTOR”, “6”); //have tried with and without citation marks
delay(100);
}
delay(1); //delay for timeing purposes
}

Now I am not so good at the coding part. I have borrowed all code and experimented with them and edited them to my liking. But this last part doesn’t work the rest does. If anyone sees something wrong I’d love to try and understand why it is wrong :slight_smile: I dont know if it just is something with the sendDcsBiosMessage, that the msg is not correct or the arg. because i can not find any relatable topics that have any info, the closes is this one which say there are x amount of possible values to put out but on the viggen there should be 0-6 but maybe it is not the value which is should send?

After the knob I will start on the display which I am afraid will be a nightmare xD I first bought a display that if I understand it correctly has an built in serial chip… but I can not get them to work. I read that all 7segment have either common cathode or anode. But these displays has neither.

Let me know if there is something else you want me to clarify xD

I will continue to do other panels on the viggen cockpit on this thread too.

11 Likes

Awesome project there, @Creedarn!
Subscribing!!

2 Likes

Nice! I’ve started on a Viggen project as well.

For easy fake DZUS fasteners, M4 cheese head screws in a 3d printed plastic bezel is a pretty simple solution.

Or you could attempt printing the actual mechanism:

https://www.thingiverse.com/thing:1064398/files

4 Likes

Nice. Is it al 3dprinted? :slight_smile: Did you paint it afterwards?

I will check the m4 cheese head :smiley:

I did a video today of when i have assembled the whole design, now only painting and some kinks left and then it is finished. Video is of me testing the physical functions. I am using some cherry mx buttons but with the “0” button there is a thicker button in the bottom so i had to 3dprint some extensions that fit on the cherrys buttons. which are the grey collums underneath the buttons.

I have decided to go forward with using the regular dcsbios programming line, and connect each pin on the rotary switch to a pin on the arduino. As dcs bios reads the pin that is being connected as LOW. and all other pins as “NOT LOW”. So the middle pin is just ground.

Any one good with arduino coding that can check the code up there with the if statements and see if ive done something wrong. Or may it just be because DCS bios is trying to read the “datapanel_selector” as a low statement so that i need to write: “datapanel_selector”, “6”, FALSE?

That way i will need to buy another board for the displays if i can not get the otherones i bought that seem to have a shift register built in working.
I can not understand the datasheet that you get with it:

PRoduct: https://www.mouser.se/ProductDetail/Lite-On/LTM-8522E?qs=WxFF5lh7QM1GSTjPDyEoBQ%3D%3D
Datasheet: https://www.mouser.se/datasheet/2/239/lite-on_lites01085-1-1737017.pdf
If anyone can help me out that would be gold worth :smiley:

Otherwise i bought some regular display i will try and play with alittle bit later.

3 Likes

Yeah, three layers of 3d printed PETG with the top one roughly sanded, primed in black acrylic gesso, sanded some more and sloppily painted in miniature game acrylics.

Won’t win any beauty contests up close but should suffice until I get setup to cut and engrave acrylic.

Funny, i recently started a similar project, but decided to go for a bit less realistic approach and use this engraved metal front plate


I just need to wait for my chinese LCDs to check if their size is accurate… Has one of you figured out how to pull the display readings out of DCS?

1 Like

I was gonna try and finish my panel tomorrow but got a almost done design now.
https://youtu.be/o4IMO0R6ip4

Regarding the LCD I have not read into it yet. Think I will need to swap my micro for a mega board. With the rotary switch eating up 7 pins on the arduino. 7 more pins for the button matrix, 1 pin for on-off switch and x amount of pins for the LEDs.
But lcds can output a picture so maybe something like the program helios? I got led screens so will start with those and se how it looks.
What type and from where did you order lcds? What are the “specifications” to look for in choosing a LCD?

Will update with code and finished panel soon :slight_smile:

The LCD is just one of these 16x64 (I think) dot matrix displays, so pictures aren’t really a option :confused: my idea was that it would be also possible to display the text of the nav point display, but if the contrast is too bad I will switch it for a led display

@outbaxx did a CK37 panel with a display…

1 Like

Checked his channel. Cool stuff :smiley: really wondering if i should do, when i get to doing it, to do a throttle like him, or like the real where it was direct connected with a long rod, to the… fuelthingy xD

Yes, DCS-BIOS can directly interface with your hardware, it has arduino commands. Or if you are running it on a standalone machine you can send packets back and forth.

1 Like

I’ve put 100ohm resistors between the pins on the rotary switch and read the resistance on one pin on the Nano.
I have one Nano for the button and switches and one Nano for the display.

2 Likes

@outbaxx how did you code the part where it reads the, i guess voltageread.
I tried it but dont know enough about dcs bios to troubleshoot it.

Think i dont have the part where it knows which value it is but cant send the correct value to dcs bios.

Thanks, thats exactly what i needed! You can access the value of the data panel, and i bet i can get it to output the value of the destination display too

2 Likes
    //#define DCSBIOS_IRQ_SERIAL
//#define DCSBIOS_DEFAULT_SERIAL
#define DCSBIOS_RS485_SLAVE 21
#define TXENABLE_PIN 2

#include "DcsBios.h"

DcsBios::Switch2Pos datapanelKey1("DATAPANEL_KEY_1", 12);

DcsBios::Switch2Pos datapanelKey2("DATAPANEL_KEY_2", 11);

DcsBios::Switch2Pos datapanelKey3("DATAPANEL_KEY_3", 10);

DcsBios::Switch2Pos datapanelKey4("DATAPANEL_KEY_4", 9);

DcsBios::Switch2Pos datapanelKey5("DATAPANEL_KEY_5", 8);

DcsBios::Switch2Pos datapanelKey6("DATAPANEL_KEY_6", 7);

DcsBios::Switch2Pos datapanelKey7("DATAPANEL_KEY_7", 6);

// PIN 5 for PWM LED
int PanelLight_pin = 5;
int PanelLed_Value;

DcsBios::Switch2Pos datapanelKey8("DATAPANEL_KEY_8", 4);

DcsBios::Switch2Pos datapanelKey9("DATAPANEL_KEY_9", 3);

DcsBios::Switch2Pos ck37RensaClear("CK37_RENSA_CLEAR", A0);

DcsBios::Switch2Pos datapanelKey0("DATAPANEL_KEY_0", A1);

DcsBios::Switch2Pos dataInOut("DATA_IN_OUT", A2);

//DcsBios::Switch2Pos rensaButtonCover("RENSA_BUTTON_COVER", A3);

DcsBios::AnalogMultiPos datapanelSelector("DATAPANEL_SELECTOR", A7, 6, (1023/6));


void setup() {
  
  DcsBios::setup();
 //  pinMode(PanelLight_pin, OUTPUT);
}

void onMainElectricPowerChange(unsigned int newValue) {
    if (newValue==0){
      PanelLed_Value = 0; }
}
DcsBios::IntegerBuffer mainElectricPowerBuffer(0x460e, 0x4000, 14, onMainElectricPowerChange);
  
void onPanelLightsChange(unsigned int newValue) {
      PanelLed_Value = map(newValue, 0, 65535, 0, 200);
     analogWrite(PanelLight_pin, PanelLed_Value);
}
DcsBios::IntegerBuffer panelLightsBuffer(0x460a, 0xffff, 0, onPanelLightsChange);



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

So this row:

DcsBios::AnalogMultiPos datapanelSelector(“DATAPANEL_SELECTOR”, A7, 6, (1023/6));

Reads the value and divide it into the six positions.
Edit: 7 positions

2 Likes

Wow thanks @outbaxx. Could hug you but it is corona. So a elbowbump has to suffice.

Even got to se how you did the led code you talked about on youtube :smiley: gonna read up on what a uln2003 is :smiley: for now my leds are on or off ^^

1 Like


I made these,(red & blue) they make the rotary switches into voltage dividers and i only use one pin in the Nano for each. I think I use 100Ohm resistors and a capacitor, the capacitor is there so it won’t read zero between switches.
Here is another picture of my project, left side start to actually look like a cockpit :wink:

5 Likes

Very nice, very nice indeed!

A small progress update:
https://imgur.com/a/cfGjehs

2 Likes

Aaaah! starburst LED segments! I love those things ridiculously much!

2 Likes