Trounce Posted October 15, 2017 Share Posted October 15, 2017 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 More sharing options...
Ranma13 Posted October 16, 2017 Share Posted October 16, 2017 Which switch is this? Can you provide a picture of it? It sounds like you have a 5-position rotary switch, in which case this doc is what you need: https://github.com/dcs-bios/dcs-bios/blob/master/Scripts/DCS-BIOS/doc/userguide.adoc#switchmultipos Link to comment Share on other sites More sharing options...
Trounce Posted October 16, 2017 Author Share Posted October 16, 2017 I could not ID a part number on the switch when I looked at it and I have already enclosed it, so it would be a pain to take apart again. However, I drew a pic of it: https://i.imgur.com/7sDqMXu.png Link to comment Share on other sites More sharing options...
Baldawg Posted October 16, 2017 Share Posted October 16, 2017 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 More sharing options...
Ranma13 Posted October 16, 2017 Share Posted October 16, 2017 A rotary encoder with a push button only has 5 pins. I'm pretty sure it's a multi-position rotary switch. Link to comment Share on other sites More sharing options...
Trounce Posted October 16, 2017 Author Share Posted October 16, 2017 Yes, in fact it is a multi-position rotary switch. I wish I could rewrite and implement the DCS Bios Switchmulticlass (as an additional class for this) but I do not have the know-how for this. Link to comment Share on other sites More sharing options...
Trounce Posted October 16, 2017 Author Share Posted October 16, 2017 (edited) // 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 October 16, 2017 by Trounce Link to comment Share on other sites More sharing options...
Trounce Posted October 16, 2017 Author Share Posted October 16, 2017 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 More sharing options...
Ranma13 Posted October 17, 2017 Share Posted October 17, 2017 (edited) 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 October 17, 2017 by Ranma13 Link to comment Share on other sites More sharing options...
Trounce Posted October 17, 2017 Author Share Posted October 17, 2017 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 More sharing options...
Ranma13 Posted October 17, 2017 Share Posted October 17, 2017 (edited) 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 October 17, 2017 by Ranma13 Link to comment Share on other sites More sharing options...
Trounce Posted October 17, 2017 Author Share Posted October 17, 2017 Arghhh my brain is decomposing from this coding. I am going to shelve it till the weekend and see if a break can help out. I tried to re-upload my saved sketch and it is doing something different today. Link to comment Share on other sites More sharing options...
Boltz Posted October 18, 2017 Share Posted October 18, 2017 Real ARC-164 preset channel switch outputs Gray code I believe A-10C Cockpit Build Thread My YouTube Channel Link to comment Share on other sites More sharing options...
Trounce Posted October 19, 2017 Author Share Posted October 19, 2017 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 More sharing options...
FragBum Posted October 19, 2017 Share Posted October 19, 2017 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 More sharing options...
Trounce Posted October 19, 2017 Author Share Posted October 19, 2017 I do not know that that means. But maybe soon, I might learn. Programming is a slow concept for me. Link to comment Share on other sites More sharing options...
FragBum Posted October 19, 2017 Share Posted October 19, 2017 (edited) 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 October 19, 2017 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 More sharing options...
Ranma13 Posted October 19, 2017 Share Posted October 19, 2017 (edited) 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 October 19, 2017 by Ranma13 Link to comment Share on other sites More sharing options...
FragBum Posted October 19, 2017 Share Posted October 19, 2017 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 More sharing options...
Trounce Posted October 19, 2017 Author Share Posted October 19, 2017 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 More sharing options...
FragBum Posted October 19, 2017 Share Posted October 19, 2017 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 More sharing options...
Trounce Posted October 19, 2017 Author Share Posted October 19, 2017 (edited) 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 October 19, 2017 by Trounce Link to comment Share on other sites More sharing options...
FragBum Posted October 19, 2017 Share Posted October 19, 2017 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 More sharing options...
Trounce Posted October 20, 2017 Author Share Posted October 20, 2017 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 More sharing options...
FragBum Posted October 20, 2017 Share Posted October 20, 2017 (edited) 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 October 20, 2017 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 More sharing options...
Recommended Posts