Jump to content

How can I use a 5 bit switch with DCS Bios?


Recommended Posts

Hello! Can you help me in using a 5 bit switch for DCS Bios? I have a switch with 6 pins. Pin one is common, and the other 5 pins change. It needs at least twenty different combinations, because it is for the UHF Channel Preset switch in the A10C. I have mapped out the truth table with a multi- meter for the switch:

//Comm_Pins_Channel

//1_6 _1

//1_3,6_ 2

//1_ 3_3

//1_3,4_ 4

//1_3,4,6_5

//1_ 4,6_6

//1_ 4 _ 7

//1_4,5- 8

//1_ 4,5,6_9

//1_ 3,4,5,6_10

//1_ 3,4,5_11

//1_ 3,5_12

//1_3,6_13

//1_5,6 _14

//1_5 _15

//1_ 2,5_16

//1_ 2,5,6_17

//1_ 2,3,5,6_18

//1-2,3,5_19

//1_ 2,3,4,5_20

 

The pins on the switch I want to label as a maybe a variable bit**

pin 2 = bit1

pin 3 = bit2

pin 4 = bit3

pin 5 = bit4

pin 6 = bit5

 

They are wired to the arduino:

bit1 to A2

bit2 to A6

bit3 to A3

bit4 to A1

bit5 to A5

Common goes to ground.

Any help/assistance would be greatly appreciated!!!

Thanks!

Link to comment
Share on other sites

Rotary Encoder

 

This appears to be a rotary encoder which would require software to implement correctly. Pin 2 and 3 are for counter clockwise 4 and 5 are clockwise and 6 is for a push button.

Win 10 Pro - Intel I7 12700k@4.9ghz water cooled - ASUS TUF Z690 -EVGA RTX 3080 12G Hybrid - EVGA 1000W PSU - 32GB 3200 G-Skill XMP- Reverb G2 -Custom mip and side panels - Leo Bodnar  BBI32x2, BBI64x4 - TM Warthog HOTAS - TM Cougar MFD's x 3 - TM TPR pedals

Link to comment
Share on other sites

// set pin numbers:

const int switchPin1 = A2; // the number of the switch’s pin

const int switchPin2 = A6; // the number of the switch’s pin

const int switchPin3 = A3; // the number of the switch’s pin

const int switchPin4 = A1; // the number of the switch’s pin

const int switchPin5 = A5;

// set variables:

int switchState1 = 0; // variable for reading the switch’s status

int switchState2 = 0; // variable for reading the switch’s status

int switchState3 = 0; // variable for reading the switch’s status

int switchState4 = 0; // variable for reading the switch’s status

int switchState5 = 0;

 

 

byte test = B0000; // Variable for printing value over serial debug

 

void setup() {

// Start serial debugging…

Serial.begin(250000);

// initialize the switch pins as an input:

pinMode(switchPin1, INPUT);

digitalWrite(A2,HIGH);

pinMode(switchPin2, INPUT);

digitalWrite(A6,HIGH);

pinMode(switchPin3, INPUT);

digitalWrite(A3,HIGH);

pinMode(switchPin4, INPUT);

digitalWrite(A1,HIGH);

pinMode(switchPin5, INPUT);

digitalWrite(A5,HIGH);

}

 

void loop(){

// read the state of the switch’s individual pins:

switchState1 = digitalRead(switchPin1);

switchState2 = digitalRead(switchPin2);

switchState3 = digitalRead(switchPin3);

switchState4 = digitalRead(switchPin4);

switchState5 = digitalRead(switchPin5);

 

// check if the pushbutton is pressed.

// if it is, the buttonState is HIGH:

if (switchState1 == HIGH) {

Serial.println("switchState1 ON");

}

else {

Serial.println("switchState1 ---");

}

if (switchState2 == HIGH) {

Serial.println("siwtchState2 ON");

}

else {

Serial.println("switchState2 ---");

}

if (switchState3 == HIGH) {

Serial.println("switchState3 ON");

}

else {

Serial.println("switchState3 ---");

}

if (switchState4 == HIGH) {

Serial.println("switchState4 ON");

}

else {

Serial.println("switchState4 ---");

}

if (switchState5 == HIGH) {

Serial.println("switchState5 ON");

}

else {

Serial.println("switchState5 ---");

}

//Channel 1

if (( (switchState1 && switchState2 && switchState3 && switchState4) == HIGH ) && (switchState5 == LOW)){

Serial.println("Channel 1 ON");

}

else {

Serial.println("Channel 1 ---");

}

//Channel 2 /*VALIDATED!!!!!! */

if (( (switchState1 && switchState3 && switchState4) == HIGH ) && ((switchState2 or switchState5 ) == LOW)) {

Serial.println("Channel 2 ON");

}

else {

Serial.println("Channel 2 ---");

}

//Channel 3 /*VALIDATED!!!!!! */

if (((switchState1 && switchState3 && switchState4 && switchState5) == HIGH) && (switchState2 == LOW)) {

Serial.println("Channel 3 ON");

}

else {

Serial.println("Channel 3 ---");//

}

//Channel 4 /*VALIDATED!!!!!! */

if (((switchState1 && switchState4 && switchState5) == HIGH) && ((switchState2 or switchState3)== LOW)) {

Serial.println("Channel 4 ON");

}

else {

Serial.println("Channel 4 ---");

}

//Channel 5 /*VALIDATED!!!!!! */

if (((switchState1 && switchState4) == HIGH) && ((switchState2 or switchState3 or switchState5)== LOW)) {

Serial.println("Channel 5 ON");

}

else {

Serial.println("Channel 5 ---");

}

//Channel 6 /*VALIDATED!!!!!! */

if (((switchState1 && switchState2 && switchState4) == HIGH) && ((switchState3 or switchState5)== LOW)) {

Serial.println("Channel 6 ON");

}

else {

Serial.println("Channel 6 ---");

}

//Channel 7 /*VALIDATED!!!!!! */

if (((switchState1 && switchState2 && switchState4 && switchState5) == HIGH) && (switchState3 == LOW)) {

Serial.println("Channel 7 ON");

}

else {

Serial.println("Channel 7 ---");

}

//Channel 8 /*VALIDATED!!!!!! */

if (((switchState1 && switchState2 && switchState5) == HIGH) && ((switchState3 or switchState4)== LOW)) {

Serial.println("Channel 8 ON");

}

else {

Serial.println("Channel 8 ---");

}

//Channel 9 /*VALIDATED!!!!!! */

if (((switchState1 && switchState2) == HIGH) && ((switchState3 or switchState4 or switchState5)== LOW)) {

Serial.println("Channel 9 ON");

}

else {

Serial.println("Channel 9 ---");

}

//Channel 10 /*VALIDATED!!!!!! */

if ((switchState1 == HIGH) && ((switchState2 or switchState3 or switchState4 or switchState5)== LOW)) {

Serial.println("Channel 10 ON");

}

else {

Serial.println("Channel 10 ---");

}

 

Serial.println("\n");

 

//Remove comment on these lines to see binary output:

//Serial.print(switchState1);

//Serial.print(switchState2);

//Serial.print(switchState3);

//Serial.println(switchState4);

 

 

delay(2000);

}


Edited by Trounce
Link to comment
Share on other sites

So I have done the above code, up to switch position 10 and now it's time to eat dinner. Super happy with what little progress I have made. Now if anyone can help me with incorporating those "IF" statements into something useful for DCS Bios UHF Preset selector, that would be super great. If not, and I find out how, I will post it!

Link to comment
Share on other sites

I'm confused. This is a multi-position rotary switch: https://www.sparkfun.com/products/13253

 

It can only activate one position at a time because it's physically shorting the common pin to whatever pin you have it turned to. However, in your code, it seems like you have a 5-position switch, but you're trying to treat it as if it has 10 positions. How many positions does your switch actually have? Can you take a picture of what the switch looks like from both sides?


Edited by Ranma13
Link to comment
Share on other sites

Okay this weekend I will take a picture because I have to dissasemble the radio. It is a real ARC-164 which is probably why the switch is weird. I am 100% sure that I will have to write a brand new switch class for this type of switch. It has 5 pins and they ouput twenty different combinations (1 combination for each preset channel) tied to the common. Since the outputs are NOT binary the nee class will have to be able to read boolean table mad for it. It is a real channel preset switch.

Link to comment
Share on other sites

You really should have mentioned that from the beginning =/. The switch has a built-in multiplexer that outputs the value as binary data. You will need to convert this data from the pins back to a byte, then use that to send the appropriate message. Something like this untested code:

 

byte value;

void loop() {
 value = 0;

 value = digitalRead(pin1) << 0 | value;
 value = digitalRead(pin2) << 1 | value;
 value = digitalRead(pin3) << 2 | value;
 value = digitalRead(pin4) << 3 | value;
 value = digitalRead(pin5) << 4 | value;

 // At this point, value should be a number 1 to 20.
 Serial.print('UHF_PRESET_SEL ' + value + '\n');
}

 

You probably can't use this code directly, as I don't know if you can directly bit shift the HIGH and LOW values, but it should give you somewhere to start from. You will also need to figure out how the bits are arranged on the pins so that you're reading the correct pin for the least significant bit up to the most significant bit.


Edited by Ranma13
Link to comment
Share on other sites

Boltz, I think you are right after looking at my truth table for the switch compared to wikipedia Gray code. The ARC-164 preset channel switch is a 5 digit Gray code. Pretty cool and I understand now why they would use it instead of normal binary.

Link to comment
Share on other sites

Could you just read the whole port to a register or byte data object and &0x1f ??

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

Ha it's been a while but if you read the whole 8bits of the port then and with 0x1f basically

 

0b00011111 == 0x1f (hex)

 

You should be left with the 5 lsb bits I'm getting back into AVR programming mind you that was in assembler but c++ will allow you to do this as well. Might be easier then reading 1 bit at a time.

 

<edit>

 

I see on Wicki there is a short for next loop to convert the 5 bit Gray to binary by exor-ing the mask value with the gray code value and subsequently shifting the mask value one place left until the mask =0x00.


Edited by FragBum
<edit>

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

Ha it's been a while but if you read the whole 8bits of the port then and with 0x1f basically

 

0b00011111 == 0x1f (hex)

 

You should be left with the 5 lsb bits I'm getting back into AVR programming mind you that was in assembler but c++ will allow you to do this as well. Might be easier then reading 1 bit at a time.

 

There's no need to AND the value with 0x1f because you already start with 0x00 on each loop, which already has the first 3 bits as 0, and the remaining bits are set by the loop. You need to read 1 bit at a time because you need to read the logic level on the pin. There's no way to treat a group of pins as the bits in a byte without reading in each wire individually and processing it.

 

I see on Wicki there is a short for next loop to convert the 5 bit Gray to binary by exor-ing the mask value with the gray code value and subsequently shifting the mask value one place left until the mask =0x00.

That's exactly what my code does, but I skip having a mask in favor of just shifting the read-in pin value directly, and it needs to use OR, not XOR. Let's say that the selected number is 13 (0b01101), and the bits from MSB to LSB are on pins 14 (LOW), 13 (HIGH), 12 (HIGH), 11 (LOW), and 10 (HIGH), then the logic broken out is:

 

  00000000 (starting value)
OR 00000001 (pin 10 is HIGH, shifted 0 places left)
         ^
-----------
  00000001

  00000001
OR 00000000 (pin 11 is LOW, shifted 1 place left)
        ^
-----------
  00000001

  00000001
OR 00000100 (pin 12 is HIGH, shifted 2 places left)
       ^
-----------
  00000101

  00000101
OR 00001000 (pin 13 is HIGH, shifted 3 places left)
      ^
-----------
  00001101

  00001101
OR 00000000 (pin 14 is LOW, shifted 4 places left)
     ^
-----------
  00001101


Edited by Ranma13
Link to comment
Share on other sites

There's no need to AND the value with 0x1f because you already start with 0x00 on each loop, which already has the first 3 bits as 0, and the remaining bits are set by the loop. You need to read 1 bit at a time because you need to read the logic level on the pin. There's no way to treat a group of pins as the bits in a byte without reading in each wire individually and processing it.

 

Thanks nice explanation. :thumbup:

 

All I was thinking is reading the whole 8 bit port into a register hence a good idea to throw away the bits your not interested in, otherwise an unexpected result may occur besides it's like a clock cycle or three. :D

 

Then doing some bit wrangling using registers as variables then pass the byte back on the stack nothing fancy like your code. :)

 

And the X-OR I just picked that up by the C example.

 

[url="https://en.wikipedia.org/wiki/Gray_code#Boolean_circuit_minimization"]from Wickipedia [/url]
/*
* This function converts a reflected binary
* Gray code number to a binary number.
* Each Gray code bit is exclusive-ored with all
* more significant bits.
*/
unsigned int grayToBinary(unsigned int num)
...

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

Below is the SwitchMultiPos code for DCS-Bios. Can you fellows help me write a new switch class that can be used with the Gray code switches?

 

 

class SwitchMultiPos : PollingInput {
	private:
		const char* msg_;
		const byte* pins_;
		char numberOfPins_;
		char lastState_;
		char readState() {
			unsigned char i;
			for (i=0; i<numberOfPins_; i++) {
				if (digitalRead(pins_[i]) == LOW) return i;
			}
			return lastState_;
		}
		void pollInput() {
			char state = readState();
			if (state != lastState_) {
				char buf[7];
				utoa(state, buf, 10);
				if (tryToSendDcsBiosMessage(msg_, buf))
					lastState_ = state;
			}
		}
	public:
		SwitchMultiPos(const char* msg, const byte* pins, char numberOfPins) : lastState_(0) {
			msg_ = msg;
			pins_ = pins;
			numberOfPins_ = numberOfPins;
			unsigned char i;
			for (i=0; i<numberOfPins; i++) {
				pinMode(pins[i], INPUT_PULLUP);
			}
			lastState_ = readState();
		}
};

Link to comment
Share on other sites

Are the 5 bits connected to the switch connected to anything else?

 

What port are the 5 bits on?

 

 

I'm just not sure why your using multiple function calls to read a port value. When you can read the entire 8 bits or defined bits of the port in one call as far as I understand it.

 

from the Arduino site

 

char readState() {
			unsigned char i;
			for (i=0; i<numberOfPins_; i++) {
				if (digitalRead(pins_[i]) == LOW) return i;

                               }
			return lastState_;
		}

.....

                       // I think this could become something like 
                       {
                       // assumes pins are bit 0 to 4 on port D
                       DRD = 0bxxx00000                     //sets port D bits 0 to 4 as read
                       return lastState_ =  0x1f & PIND;          // read and mask off unwanted bits assign to lastState_
                      }

 

Some more info here.

 

Mind you I could be wrong it's been a while. :doh:

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

I have the 6 switch ports connected as follows:

Pin 1 Common to ground

Pin 2 to A2

Pin 3 to A6

Pin 4 to A3

Pin 5 to A1

Pin 6 to A5

 

I know, I know, what is the reason behind the pins not being in any order? Well, I had a cable cluster and that's just how they ended up on the Mega after I plugged them in. No biggie, though. I only have 8 pins left open on the Mega, the ARC-164 switches use almost all of them.

 

<edit> This is all on Port F of the Arduino Mega


Edited by Trounce
Link to comment
Share on other sites

I have the 6 switch ports connected as follows:

Pin 1 Common to ground

Pin 2 to A2

Pin 3 to A6

Pin 4 to A3

Pin 5 to A1

Pin 6 to A5

 

I know, I know, what is the reason behind the pins not being in any order? Well, I had a cable cluster and that's just how they ended up on the Mega after I plugged them in. No biggie, though. I only have 8 pins left open on the Mega, the ARC-164 switches use almost all of them.

 

<edit> This is all on Port F of the Arduino Mega

 

This one ?

 

"Why" did go through my mind when I saw the pinouts.:D

 

Port F also supports analogue as well but if that is not being used it should function quite normally as a digital i/o by setting appropriate register values.

 

I'm not sure how that pin mapping translates but it would make life easier if it where logical.

As it is reading individual pins bits will allow the mapping you as the pin reads could be called in any order if required but heck.

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

As it stands, the only available input types for the UHF Preset in DCS Bios is with a rotary encoder or set pins:

DcsBios::RotaryEncoder uhfPresetSel("UHF_PRESET_SEL", "DEC", "INC", PIN_A, PIN_B);

and

const byte uhfPresetSelPins[21] = {PIN_0, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15, PIN_16, PIN_17, PIN_18, PIN_19, PIN_20};
DcsBios::SwitchMultiPos uhfPresetSel("UHF_PRESET_SEL", uhfPresetSelPins, 21);

Don't know how to incorporate the port unless a whole new read class() is made possibly in DCS-Bios

Link to comment
Share on other sites

As it stands, the only available input types for the UHF Preset in DCS Bios is with a rotary encoder or set pins:

DcsBios::RotaryEncoder uhfPresetSel("UHF_PRESET_SEL", "DEC", "INC", PIN_A, PIN_B);

and

const byte uhfPresetSelPins[21] = {PIN_0, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15, PIN_16, PIN_17, PIN_18, PIN_19, PIN_20};
DcsBios::SwitchMultiPos uhfPresetSel("UHF_PRESET_SEL", uhfPresetSelPins, 21);

Don't know how to incorporate the port unless a whole new read class() is made possibly in DCS-Bios

 

Ah I see there is no port read() that would be a problem and likely what Ranma13 meant which seemed odd that there <wouldn't> be an implementation for a port read function.

 

Where do the pins x functions come from DCS bios or Arduino libraries ??


Edited by FragBum
<edit>

Control is an illusion which usually shatters at the least expected moment.

Gazelle Mini-gun version is endorphins with rotors. See above.

 

Currently rolling with a Asus Z390 Prime, 9600K, 32GB RAM, SSD, 2080Ti and Windows 10Pro, Rift CV1. bu0836x and Scratch Built Pedals, Collective and Cyclic.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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