Difference between revisions of "49-Way Joystick Conversion Board"
Jump to navigation
Jump to search
| (100 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
| − | * | + | ==Custom PCB - Drop-In== |
| − | <gallery mode=" | + | |
| − | Image: | + | This board is a drop-in replacement for the original 49-way(Sinistar/ArchRivals/Pigskin 621 AD). |
| − | Image: | + | |
| + | *;What does it do? | ||
| + | **Converts 49-Way Joysticks to 8-Way (or other types if desired) | ||
| + | **Uses all other hardware from the joystick besides the board | ||
| + | **ALL components on board are new including the Optical Switches | ||
| + | **Super easy installation | ||
| + | **Provides user ability to select Joystick type with DIP switches | ||
| + | **4 outputs are provided | ||
| + | ***Up | ||
| + | ***Down | ||
| + | ***Left | ||
| + | ***Right | ||
| + | **Uses Williams Standard 7-Pin connector and Pinout (Bubbles, Spat, Inferno, Joust-with rare 2-way optical sticks) | ||
| + | **Default setting is for 8-Way that duplicates the dedicated Williams 8-Way Optical Joystick | ||
| + | |||
| + | <youtube>https://www.youtube.com/watch?v=iR32MsdxWmM</youtube> | ||
| + | <youtube>https://www.youtube.com/watch?v=pvqfKHs7_PE</youtube> | ||
| + | <gallery mode="traditional" widths=260px heights=260px class="left"> | ||
| + | Image:PCB - REV A - GerberView Front.PNG |(PCB - Front) | ||
| + | Image:PCB - REV A - GerberView Rear.PNG | (PCB - Rear) | ||
| + | Image:8-Way Board - Populated.jpg | (Populated PCB) | ||
| + | Image:8-Way Board - Populated 2.jpg | (Populated PCB) | ||
| + | Image:8-Way Board - Mounted.jpg | (Mounted) | ||
| + | Image:49-Way Matrix Locations.PNG | (Mapped Locations) | ||
| + | Image:DIP Swich On PCB.jpg | (DIP Switch on PCB) | ||
| + | Image:49-Way-Joystick-Converter-Board-V2.png | (Schematic) | ||
| + | </gallery> | ||
| + | |||
| + | ==Connection Information== | ||
| + | [[File:8-Way Optical Joystick Pinout.png|300px]] | ||
| + | |||
| + | ==Programmed Joystick Emulation Modes - 10 Unique== | ||
| + | *Thanks to Sean Riddle for the work he did building an EPROM based translator. Lots of the information I used to develop this was from him. You can visit his site [https://seanriddle.com/49way.html HERE]. (Thanks Sean!) | ||
| + | |||
| + | '''Mode 0: 8-Way | Standard''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:Standard 8-Way.PNG|(8-Way - Standard * DEFAULT) | ||
| + | Image:00 - Zero SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 1: 8-Way | No Dead Zone''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:8-Way - No Dead Zone.PNG|(8-Way - No Dead Zone) | ||
| + | Image:01 - One SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 2: 8-Way | With Dead Zone''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:8-Way - With Dead Zone.PNG|(8-Way - With Dead Zone) | ||
| + | Image:02 - Two SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 3: 4-Way | Standard''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
Image:4-Way Standard.PNG|(4-Way) | Image:4-Way Standard.PNG|(4-Way) | ||
| − | Image:4-Way - | + | Image:03 - Three SW.PNG | (DIP Switch Setting) |
| − | Image:4-Way - Corners L-R.PNG|(4-Way | + | </gallery> |
| − | Image: | + | |
| − | Image: | + | '''Mode 4: 4-Way | With Dead Zone''' |
| − | Image: | + | <gallery mode="traditional" widths=250px heights=250px class="center"> |
| − | Image: | + | Image:4-Way - Dead Zone.PNG|(4-Way - Dead Zone) |
| + | Image:04 - Four SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 5: 4-Way | Corners Left/Right''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:4-Way - Corners L-R.PNG|(4-Way - Corners L/R) | ||
| + | Image:05 - Five SW .PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 6: 4-Way | Corners Up/Down''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:4-Way - Corners U-D.PNG | 4-Way - Corners U/D | ||
| + | Image:06 - Six SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 7: 2-Way | Horizontal''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:2-Way - Horizontal.PNG|(2-Way - Horizontal) | ||
| + | Image:07 - Seven SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 8: 2-Way | Vertical''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:2-Way - Vertical.PNG|(2-Way - Vertical) | ||
| + | Image:08 - Eight SW.PNG | (DIP Switch Setting) | ||
| + | </gallery> | ||
| + | |||
| + | '''Mode 9: Diagonal''' | ||
| + | <gallery mode="traditional" widths=250px heights=250px class="center"> | ||
| + | Image:Diagonal.PNG|(Diagonal) | ||
| + | Image:09 - Nine SW.PNG | (DIP Switch Setting) | ||
</gallery> | </gallery> | ||
| − | + | ==49-Way Joystick Information== | |
| + | The Williams 49-Way Optical Joystick was advanced for the time. As the device relied on optical interrupter switches, there were no contacts to wear out or adjust. | ||
| + | |||
| + | ==Original 49-Way== | ||
| + | <div class="toccolours mw-collapsible mw-collapsed" style="width:500px; overflow:auto;"> | ||
| + | <div style="font-weight:bold;line-height:1.6;">Operation - Pinout</div> | ||
| + | <div class="mw-collapsible-content"> | ||
| + | *3 Optical Interrupter Switches are used for each direction (Up/Down-Y and Left/Right -X) .Total of 6 switches | ||
| + | **This provides a total of 7 possible positions in each X and Y axis. (3 Up/1 Center/3 Down - 3 Left/1 Center/3 Right) (7 * 7 = 49 Unique positions) | ||
| + | *There are 8 unique outputs | ||
| + | **Opto Swtich 1 (U/D - A) | ||
| + | **Opto Switch 2 (U/D - B) | ||
| + | **Opto Switch 3 (U/D - C) | ||
| + | **Up/Down Direction | ||
| + | **Opto Switch 4 (L/R - A) | ||
| + | **Opto Switch 5 (L/R - B) | ||
| + | **Opto Switch 6 (L/R - C) | ||
| + | ** Left/Right Direction | ||
| + | *12 Pin Molex Header Pin-Out | ||
| + | *#+5 Volts | ||
| + | *#Opto Switch 1 (U/D - A) | ||
| + | *#Opto Switch 2 (U/D - B) | ||
| + | *#Opto Switch 3 (U/D - C) | ||
| + | *#Up/Down Direction (Up=Low / Down = High) | ||
| + | *#Opto Switch 4 (L/R - A) | ||
| + | *#Opto Switch 5 (L/R - B) | ||
| + | *#Opto Switch 6 (L/R - C) | ||
| + | *#Left/Right Direction (Right = Low / Left = High) | ||
| + | *#Key - No Connection | ||
| + | *#Ground | ||
| + | *#Ground | ||
| + | </div></div> | ||
| + | <gallery mode="traditional" widths=160px heights=160px class="left"> | ||
| + | Image:Sinistar - 49-Way Joystick.jpg|(Sinistar 49-Way) | ||
| + | Image:Sinistar 49-Way - Disassembled.jpg | (Sinistar - Disassembled) | ||
| + | Image:49-Way - PCB.jpg|(49-Way PCB) | ||
| + | Image: Slotted Optical Switch.jpg|(Slotted Optical Switch | ||
| + | Image:Photo Interrupter - Slotted Optical Switch.gif|(Slotted Optical Switch Diagram) | ||
| + | </gallery> | ||
| + | |||
| + | <!-- [[File:Williams Flyer.jpg|right|300px]] --> | ||
| + | |||
| + | ==Atmel Microprocessor Source Code:== | ||
<nowiki> | <nowiki> | ||
//Program Written By: Brad Raedel | //Program Written By: Brad Raedel | ||
| + | //03242020 - Revision A | ||
| + | //** All 8 Profiles active | ||
| + | //** Outputs now change to inputs when not active - This allows the pull-up resistors to control the high logic | ||
//03162020 - Revision 1 - Just get it working | //03162020 - Revision 1 - Just get it working | ||
| Line 22: | Line 151: | ||
int Opto2 = 3; //Input Pin 3 | int Opto2 = 3; //Input Pin 3 | ||
int Opto3 = 4; //Input Pin 4 | int Opto3 = 4; //Input Pin 4 | ||
| − | int Up = | + | int Up = 9; //Output to Game - Pin 10 |
| − | int Dn = | + | int Dn = 10; //Output to Game - Pin 11 |
//Down | //Down | ||
int Opto4 = 5; //Input Pin 5 | int Opto4 = 5; //Input Pin 5 | ||
int Opto5 = 6; //Input Pin 6 | int Opto5 = 6; //Input Pin 6 | ||
int Opto6 = 7; //Input Pin 7 | int Opto6 = 7; //Input Pin 7 | ||
| − | int Left = | + | int Left = 11; //Output to Game - Pin 12 |
| − | int Right = | + | int Right = 12; //Output to Game - Pin 13 |
//Option Switches - These will be used to select mode/options (0 to 15) | //Option Switches - These will be used to select mode/options (0 to 15) | ||
| Line 57: | Line 186: | ||
int LtRtPos = 3; //Absolute postion of Left/Right 0 = Left, 6 = Right, 3 is Center/Neutral | int LtRtPos = 3; //Absolute postion of Left/Right 0 = Left, 6 = Right, 3 is Center/Neutral | ||
int AbsPos = 24; | int AbsPos = 24; | ||
| + | int i = 0; | ||
//Rows Then Columns - Stored Like this { {Row 0 - 0 to 48},{Row 2 - 0 to 48}...etc.. | //Rows Then Columns - Stored Like this { {Row 0 - 0 to 48},{Row 2 - 0 to 48}...etc.. | ||
| − | // | + | // 8-Way Standard |
| − | bool | + | const bool Up8WayStd[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; |
| − | bool | + | const bool Dn8WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ; |
| − | bool | + | const bool Lt8WayStd[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ; |
| − | bool | + | const bool Rt8WayStd[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ; |
| + | // 8-Way with NO Dead Zone | ||
| + | const bool Up8WayNoDZ[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn8WayNoDZ[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ; | ||
| + | const bool Lt8WayNoDZ[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ; | ||
| + | const bool Rt8WayNoDZ[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ; | ||
| + | // 8-Way with Dead Zone | ||
| + | const bool Up8WayDZ[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn8WayDZ[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ; | ||
| + | const bool Lt8WayDZ[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ; | ||
| + | const bool Rt8WayDZ[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ; | ||
| + | //4-Way Standard | ||
| + | const bool Up4WayStd[49] = {0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn4WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0} ; | ||
| + | const bool Lt4WayStd[49] = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Rt4WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0} ; | ||
| + | //4-Way Corners L/R | ||
| + | const bool Up4WayLR[49] = {0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn4WayLR[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0} ; | ||
| + | const bool Lt4WayLR[49] = {1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0} ; | ||
| + | const bool Rt4WayLR[49] = {0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1} ; | ||
| + | //4-Way Corners U/D | ||
| + | const bool Up4WayUD[49] = {1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn4WayUD[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1} ; | ||
| + | const bool Lt4WayUD[49] = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Rt4WayUD[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0} ; | ||
| + | // 2-Way Horizontal | ||
| + | const bool Up2WayH[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn2WayH[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Lt2WayH[49] = {1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0} ; | ||
| + | const bool Rt2WayH[49] = {0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1} ; | ||
| + | // 2-Way Vertical | ||
| + | const bool Up2WayV[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Dn2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ; | ||
| + | const bool Lt2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | const bool Rt2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ; | ||
| + | |||
| + | bool UpOut[49] = {}; | ||
| + | bool DnOut[49] = {}; | ||
| + | bool LtOut[49] = {}; | ||
| + | bool RtOut[49] = {}; | ||
void setup() { | void setup() { | ||
| − | Serial.begin(57600); //Disable when not debugging | + | //Serial.begin(57600); //Disable when not debugging |
pinMode(Opto1,INPUT); //Set Direction of physical inputs/outputs | pinMode(Opto1,INPUT); //Set Direction of physical inputs/outputs | ||
pinMode(Opto2,INPUT); | pinMode(Opto2,INPUT); | ||
| Line 72: | Line 242: | ||
pinMode(Opto5,INPUT); | pinMode(Opto5,INPUT); | ||
pinMode(Opto6,INPUT); | pinMode(Opto6,INPUT); | ||
| − | pinMode(Up, | + | pinMode(Up,INPUT); |
| − | pinMode(Dn, | + | pinMode(Dn,INPUT); |
| − | pinMode(Left, | + | pinMode(Left,INPUT); |
| − | pinMode(Right, | + | pinMode(Right,INPUT); |
pinMode(Op1,INPUT); | pinMode(Op1,INPUT); | ||
pinMode(Op2,INPUT); | pinMode(Op2,INPUT); | ||
| Line 92: | Line 262: | ||
if (digitalRead(Op3) == HIGH) | if (digitalRead(Op3) == HIGH) | ||
{ | { | ||
| − | OpVal = OpVal +4; | + | OpVal = OpVal + 4; |
} | } | ||
if (digitalRead(Op4) == HIGH) | if (digitalRead(Op4) == HIGH) | ||
| Line 99: | Line 269: | ||
} | } | ||
//Serial.println(OpVal); | //Serial.println(OpVal); | ||
| − | + | switch (OpVal) { | |
| + | case 0: //DIP Switch 0 - 8-Way - No Dead zone - This routine copies the array - Only on setup, not during loop/runtime | ||
| + | // 8WayStd | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up8WayStd[ i ]; | ||
| + | DnOut[ i ] = Dn8WayStd[ i ]; | ||
| + | LtOut[ i ] = Lt8WayStd[ i ]; | ||
| + | RtOut[ i ] = Rt8WayStd[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 1: //DIP Switch 1 - | ||
| + | // 8WayNoDZ | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up8WayNoDZ[ i ]; | ||
| + | DnOut[ i ] = Dn8WayNoDZ[ i ]; | ||
| + | LtOut[ i ] = Lt8WayNoDZ[ i ]; | ||
| + | RtOut[ i ] = Rt8WayNoDZ[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 2: //DIP Switch 2 - | ||
| + | // 8WayDZ | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up8WayDZ[ i ]; | ||
| + | DnOut[ i ] = Dn8WayDZ[ i ]; | ||
| + | LtOut[ i ] = Lt8WayDZ[ i ]; | ||
| + | RtOut[ i ] = Rt8WayDZ[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 3: //DIP Switch 3 - | ||
| + | // 4WayStd | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up4WayStd[ i ]; | ||
| + | DnOut[ i ] = Dn4WayStd[ i ]; | ||
| + | LtOut[ i ] = Lt4WayStd[ i ]; | ||
| + | RtOut[ i ] = Rt4WayStd[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 4: //DIP Switch 4 - | ||
| + | // 4WayLR | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up4WayLR[ i ]; | ||
| + | DnOut[ i ] = Dn4WayLR[ i ]; | ||
| + | LtOut[ i ] = Lt4WayLR[ i ]; | ||
| + | RtOut[ i ] = Rt4WayLR[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 5: //DIP Switch 5 - | ||
| + | // 4WayUD | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up4WayUD[ i ]; | ||
| + | DnOut[ i ] = Dn4WayUD[ i ]; | ||
| + | LtOut[ i ] = Lt4WayUD[ i ]; | ||
| + | RtOut[ i ] = Rt4WayUD[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 6: //DIP Switch 6 - | ||
| + | // 2WayH | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up2WayH[ i ]; | ||
| + | DnOut[ i ] = Dn2WayH[ i ]; | ||
| + | LtOut[ i ] = Lt2WayH[ i ]; | ||
| + | RtOut[ i ] = Rt2WayH[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | case 7: //DIP Switch 7 - | ||
| + | // 2WayV | ||
| + | i = 0; | ||
| + | while( i < 49 ){ | ||
| + | UpOut[ i ] = Up2WayV[ i ]; | ||
| + | DnOut[ i ] = Dn2WayV[ i ]; | ||
| + | LtOut[ i ] = Lt2WayV[ i ]; | ||
| + | RtOut[ i ] = Rt2WayV[ i ]; | ||
| + | ++i;} | ||
| + | break; | ||
| + | |||
| + | } | ||
} | } | ||
| Line 194: | Line 446: | ||
AbsPos = (UpDnPos * 7) + LtRtPos; | AbsPos = (UpDnPos * 7) + LtRtPos; | ||
//Serial.println(AbsPos); | //Serial.println(AbsPos); | ||
| − | + | //Output | |
| − | + | //UP | |
| − | + | if (UpOut[AbsPos] == true){ | |
| − | + | pinMode(Up,OUTPUT); | |
| + | digitalWrite(Up,LOW); | ||
| + | } | ||
| + | else { | ||
| + | pinMode(Up,INPUT); | ||
| + | } | ||
| + | //Down | ||
| + | if (DnOut[AbsPos] == true){ | ||
| + | pinMode(Dn,OUTPUT); | ||
| + | digitalWrite(Dn,LOW); | ||
| + | } | ||
| + | else { | ||
| + | pinMode(Dn,INPUT); | ||
| + | } | ||
| + | //Left | ||
| + | if (LtOut[AbsPos] == true){ | ||
| + | pinMode(Left,OUTPUT); | ||
| + | digitalWrite(Left,LOW); | ||
| + | } | ||
| + | else { | ||
| + | pinMode(Left,INPUT); | ||
| + | } | ||
| + | //Right | ||
| + | if (RtOut[AbsPos] == true){ | ||
| + | pinMode(Right,OUTPUT); | ||
| + | digitalWrite(Right,LOW); | ||
| + | } | ||
| + | else { | ||
| + | pinMode(Right,INPUT); | ||
| + | } | ||
} | } | ||
</nowiki> | </nowiki> | ||
Latest revision as of 11:48, 17 July 2020
Contents
Custom PCB - Drop-In
This board is a drop-in replacement for the original 49-way(Sinistar/ArchRivals/Pigskin 621 AD).
- What does it do?
- Converts 49-Way Joysticks to 8-Way (or other types if desired)
- Uses all other hardware from the joystick besides the board
- ALL components on board are new including the Optical Switches
- Super easy installation
- Provides user ability to select Joystick type with DIP switches
- 4 outputs are provided
- Up
- Down
- Left
- Right
- Uses Williams Standard 7-Pin connector and Pinout (Bubbles, Spat, Inferno, Joust-with rare 2-way optical sticks)
- Default setting is for 8-Way that duplicates the dedicated Williams 8-Way Optical Joystick
Connection Information
Programmed Joystick Emulation Modes - 10 Unique
- Thanks to Sean Riddle for the work he did building an EPROM based translator. Lots of the information I used to develop this was from him. You can visit his site HERE. (Thanks Sean!)
Mode 0: 8-Way | Standard
Mode 1: 8-Way | No Dead Zone
Mode 2: 8-Way | With Dead Zone
Mode 3: 4-Way | Standard
Mode 4: 4-Way | With Dead Zone
Mode 5: 4-Way | Corners Left/Right
Mode 6: 4-Way | Corners Up/Down
Mode 7: 2-Way | Horizontal
Mode 8: 2-Way | Vertical
Mode 9: Diagonal
49-Way Joystick Information
The Williams 49-Way Optical Joystick was advanced for the time. As the device relied on optical interrupter switches, there were no contacts to wear out or adjust.
Original 49-Way
Operation - Pinout
- 3 Optical Interrupter Switches are used for each direction (Up/Down-Y and Left/Right -X) .Total of 6 switches
- This provides a total of 7 possible positions in each X and Y axis. (3 Up/1 Center/3 Down - 3 Left/1 Center/3 Right) (7 * 7 = 49 Unique positions)
- There are 8 unique outputs
- Opto Swtich 1 (U/D - A)
- Opto Switch 2 (U/D - B)
- Opto Switch 3 (U/D - C)
- Up/Down Direction
- Opto Switch 4 (L/R - A)
- Opto Switch 5 (L/R - B)
- Opto Switch 6 (L/R - C)
- Left/Right Direction
- 12 Pin Molex Header Pin-Out
- +5 Volts
- Opto Switch 1 (U/D - A)
- Opto Switch 2 (U/D - B)
- Opto Switch 3 (U/D - C)
- Up/Down Direction (Up=Low / Down = High)
- Opto Switch 4 (L/R - A)
- Opto Switch 5 (L/R - B)
- Opto Switch 6 (L/R - C)
- Left/Right Direction (Right = Low / Left = High)
- Key - No Connection
- Ground
- Ground
Atmel Microprocessor Source Code:
//Program Written By: Brad Raedel
//03242020 - Revision A
//** All 8 Profiles active
//** Outputs now change to inputs when not active - This allows the pull-up resistors to control the high logic
//03162020 - Revision 1 - Just get it working
//Up
int Opto1 = 2; //Input Pin 2
int Opto2 = 3; //Input Pin 3
int Opto3 = 4; //Input Pin 4
int Up = 9; //Output to Game - Pin 10
int Dn = 10; //Output to Game - Pin 11
//Down
int Opto4 = 5; //Input Pin 5
int Opto5 = 6; //Input Pin 6
int Opto6 = 7; //Input Pin 7
int Left = 11; //Output to Game - Pin 12
int Right = 12; //Output to Game - Pin 13
//Option Switches - These will be used to select mode/options (0 to 15)
int Op1 = A0; //1
int Op2 = A1; //2
int Op3 = A2; //4
int Op4 = A3; //8
int OpVal = 0; //Default to zero
bool Opto1St; //Opto States
bool Opto2St;
bool Opto3St;
bool Opto4St;
bool Opto5St;
bool Opto6St;
bool UpSt; //Set HIGH when stick is UP
bool DnSt; //Set HIGH when Stick is DOWN
bool LtSt; //Set HIGH when stick is LEFT
bool RtSt; //Set HIGH when Stick is RIGHT
bool LockedStUD;//Used to Latch the UP or DOWN position
bool LockedStLR;//Used to Latch the LEFT or RIGH postion
int UpVal = 3; //Store the Up position (0-2)
int DnVal = 3; //Store the Down postion (0-2)
int UpDnPos = 3; //Absolute postion of Up/Down 0 = Top, 6 = Bottom, 3 is Center/Neutral
int LtVal = 3; //Store the Left position (0-2)
int RtVal = 3; //Store the Right position (0-2)
int LtRtPos = 3; //Absolute postion of Left/Right 0 = Left, 6 = Right, 3 is Center/Neutral
int AbsPos = 24;
int i = 0;
//Rows Then Columns - Stored Like this { {Row 0 - 0 to 48},{Row 2 - 0 to 48}...etc..
// 8-Way Standard
const bool Up8WayStd[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn8WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;
const bool Lt8WayStd[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ;
const bool Rt8WayStd[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ;
// 8-Way with NO Dead Zone
const bool Up8WayNoDZ[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn8WayNoDZ[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;
const bool Lt8WayNoDZ[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ;
const bool Rt8WayNoDZ[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ;
// 8-Way with Dead Zone
const bool Up8WayDZ[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn8WayDZ[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;
const bool Lt8WayDZ[49] = {1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0} ;
const bool Rt8WayDZ[49] = {0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,1} ;
//4-Way Standard
const bool Up4WayStd[49] = {0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn4WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,0} ;
const bool Lt4WayStd[49] = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Rt4WayStd[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0} ;
//4-Way Corners L/R
const bool Up4WayLR[49] = {0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn4WayLR[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,1,1,0} ;
const bool Lt4WayLR[49] = {1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0} ;
const bool Rt4WayLR[49] = {0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1} ;
//4-Way Corners U/D
const bool Up4WayUD[49] = {1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn4WayUD[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1} ;
const bool Lt4WayUD[49] = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Rt4WayUD[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0} ;
// 2-Way Horizontal
const bool Up2WayH[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn2WayH[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Lt2WayH[49] = {1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0} ;
const bool Rt2WayH[49] = {0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1} ;
// 2-Way Vertical
const bool Up2WayV[49] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Dn2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;
const bool Lt2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
const bool Rt2WayV[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
bool UpOut[49] = {};
bool DnOut[49] = {};
bool LtOut[49] = {};
bool RtOut[49] = {};
void setup() {
//Serial.begin(57600); //Disable when not debugging
pinMode(Opto1,INPUT); //Set Direction of physical inputs/outputs
pinMode(Opto2,INPUT);
pinMode(Opto3,INPUT);
pinMode(Opto4,INPUT);
pinMode(Opto5,INPUT);
pinMode(Opto6,INPUT);
pinMode(Up,INPUT);
pinMode(Dn,INPUT);
pinMode(Left,INPUT);
pinMode(Right,INPUT);
pinMode(Op1,INPUT);
pinMode(Op2,INPUT);
pinMode(Op3,INPUT);
pinMode(Op4,INPUT);
//Let's get our DIP Switch settings (Will = 0 to 15)
if (digitalRead(Op1) == HIGH)
{
OpVal = 1;
}
if (digitalRead(Op2) == HIGH)
{
OpVal = OpVal + 2;
}
if (digitalRead(Op3) == HIGH)
{
OpVal = OpVal + 4;
}
if (digitalRead(Op4) == HIGH)
{
OpVal = OpVal + 8;
}
//Serial.println(OpVal);
switch (OpVal) {
case 0: //DIP Switch 0 - 8-Way - No Dead zone - This routine copies the array - Only on setup, not during loop/runtime
// 8WayStd
i = 0;
while( i < 49 ){
UpOut[ i ] = Up8WayStd[ i ];
DnOut[ i ] = Dn8WayStd[ i ];
LtOut[ i ] = Lt8WayStd[ i ];
RtOut[ i ] = Rt8WayStd[ i ];
++i;}
break;
case 1: //DIP Switch 1 -
// 8WayNoDZ
i = 0;
while( i < 49 ){
UpOut[ i ] = Up8WayNoDZ[ i ];
DnOut[ i ] = Dn8WayNoDZ[ i ];
LtOut[ i ] = Lt8WayNoDZ[ i ];
RtOut[ i ] = Rt8WayNoDZ[ i ];
++i;}
break;
case 2: //DIP Switch 2 -
// 8WayDZ
i = 0;
while( i < 49 ){
UpOut[ i ] = Up8WayDZ[ i ];
DnOut[ i ] = Dn8WayDZ[ i ];
LtOut[ i ] = Lt8WayDZ[ i ];
RtOut[ i ] = Rt8WayDZ[ i ];
++i;}
break;
case 3: //DIP Switch 3 -
// 4WayStd
i = 0;
while( i < 49 ){
UpOut[ i ] = Up4WayStd[ i ];
DnOut[ i ] = Dn4WayStd[ i ];
LtOut[ i ] = Lt4WayStd[ i ];
RtOut[ i ] = Rt4WayStd[ i ];
++i;}
break;
case 4: //DIP Switch 4 -
// 4WayLR
i = 0;
while( i < 49 ){
UpOut[ i ] = Up4WayLR[ i ];
DnOut[ i ] = Dn4WayLR[ i ];
LtOut[ i ] = Lt4WayLR[ i ];
RtOut[ i ] = Rt4WayLR[ i ];
++i;}
break;
case 5: //DIP Switch 5 -
// 4WayUD
i = 0;
while( i < 49 ){
UpOut[ i ] = Up4WayUD[ i ];
DnOut[ i ] = Dn4WayUD[ i ];
LtOut[ i ] = Lt4WayUD[ i ];
RtOut[ i ] = Rt4WayUD[ i ];
++i;}
break;
case 6: //DIP Switch 6 -
// 2WayH
i = 0;
while( i < 49 ){
UpOut[ i ] = Up2WayH[ i ];
DnOut[ i ] = Dn2WayH[ i ];
LtOut[ i ] = Lt2WayH[ i ];
RtOut[ i ] = Rt2WayH[ i ];
++i;}
break;
case 7: //DIP Switch 7 -
// 2WayV
i = 0;
while( i < 49 ){
UpOut[ i ] = Up2WayV[ i ];
DnOut[ i ] = Dn2WayV[ i ];
LtOut[ i ] = Lt2WayV[ i ];
RtOut[ i ] = Rt2WayV[ i ];
++i;}
break;
}
}
//Main Program that loops
void loop() {
// Up/Down Logic
Opto1St = digitalRead(Opto1); //Read Optical Switch 1
Opto2St = digitalRead(Opto2); //Read Optical Switch 2
Opto3St = digitalRead(Opto3); //Read Optical Switch 2
if (Opto1St == true && Opto2St == true && Opto3St == true) //Determine if the joystick is in the center
{
LockedStUD = false; //Unlatch to allow Up or Down to assume control
UpSt = false; //Clear Up State
DnSt = false; //Clear Down State
UpDnPos = 3; //Set Vertical position to center
}
//Latch Direction (Determines if up or down
if (Opto1St == false && LockedStUD == false) //UP if True
{
UpSt = true; //Set UP State to TRUE
LockedStUD = true; //We lock the State so DOWN can't Steal it!
}
if (Opto3St == false && LockedStUD == false) //DOWN if True
{
DnSt = true; //Set DOWN State to TRUE
LockedStUD = true; //We lock the State so UP can't Steal it!
}
//We will figure out what row we are in (0 to 6 - 3 is center)
if (UpSt == true) //Up doesn't need any change since adding the Optical Switches is 0 to 2
{
UpVal = Opto1St + Opto2St + Opto3St;
UpDnPos = UpVal;
}
if (DnSt == true) //For Down, we determine how many Optical Switches are Low, add them up then use a look-up table to generate the position 4 to 6
{
DnVal = Opto1St + Opto2St + Opto3St;
switch (DnVal) {
case 0: //All Optos are LOW
UpDnPos = 6;
break;
case 1: //Two of the Optos are LOW
UpDnPos = 5;
break;
case 2: //One of the Optos are LOW (The others are still High)
UpDnPos = 4;
break;
}
}
// Left/Right Logic
Opto4St = digitalRead(Opto4); //Read Optical Switch 4
Opto5St = digitalRead(Opto5); //Read Optical Switch 5
Opto6St = digitalRead(Opto6); //Read Optical Switch 6
if (Opto4St == true && Opto5St == true && Opto6St == true) //Determine if the joystick is in the center
{
LockedStLR = false; //Unlatch to allow Left or Right to assume control
LtSt = false; //Clear Left State
RtSt = false; //Clear Right State
LtRtPos = 3; //Set Horizontal position to center
}
//Latch Direction (Determines if Left or Right
if (Opto4St == false && LockedStLR == false) //Right if True
{
RtSt = true; //Set Right State to TRUE
LockedStLR = true; //We lock the State so Left can't Steal it!
}
if (Opto6St == false && LockedStLR == false) //Left if True
{
LtSt = true; //Set Left State to TRUE
LockedStLR = true; //We lock the State so Right can't Steal it!
}
//We will figure out what row we are in (0 to 6 - 3 is center)
if (LtSt == true) //Up doesn't need any change since adding the Optical Switches is 0 to 2
{
LtVal = Opto4St + Opto5St + Opto6St;
LtRtPos = LtVal;
}
if (RtSt == true) //For Down, we determine how many Optical Switches are Low, add them up then use a look-up table to generate the position 4 to 6
{
RtVal = Opto4St + Opto5St + Opto6St;
switch (RtVal) {
case 0: //All Optos are LOW
LtRtPos = 6;
break;
case 1: //Two of the Optos are LOW
LtRtPos = 5;
break;
case 2: //One of the Optos are LOW (The others are still High)
LtRtPos = 4;
break;
}
}
//Calculate the absolute position
AbsPos = (UpDnPos * 7) + LtRtPos;
//Serial.println(AbsPos);
//Output
//UP
if (UpOut[AbsPos] == true){
pinMode(Up,OUTPUT);
digitalWrite(Up,LOW);
}
else {
pinMode(Up,INPUT);
}
//Down
if (DnOut[AbsPos] == true){
pinMode(Dn,OUTPUT);
digitalWrite(Dn,LOW);
}
else {
pinMode(Dn,INPUT);
}
//Left
if (LtOut[AbsPos] == true){
pinMode(Left,OUTPUT);
digitalWrite(Left,LOW);
}
else {
pinMode(Left,INPUT);
}
//Right
if (RtOut[AbsPos] == true){
pinMode(Right,OUTPUT);
digitalWrite(Right,LOW);
}
else {
pinMode(Right,INPUT);
}
}