Hi All,
I have an arcade project designed by someone else that uses an Arduino mega as a joystick controller but the sketch uploaded to it also controls some lamp outputs using a ULN2003A.
As the Arduino is flashed to use Unojoy the main usb port is used for tx only to send joystick commands back to the pc.
The lamp data is sent via a PL2303HX serial adaptor to ports 14tx & 15rx on the mega.
The lamp data from the game emulator is captured by a pre-compiled program (with no access to the source) and sent to the Arduino via the serial cable.
I have captured the serial data -
[14/12/2019 15:42:51] Written data (COM5)
82 20 ‚
[14/12/2019 15:42:51] Written data (COM5)
82 40 ‚@
[14/12/2019 15:42:51] Written data (COM5)
82 80 ‚€
[14/12/2019 15:42:52] Written data (COM5)
82 04 ‚.
[14/12/2019 15:42:52] Written data (COM5)
82 08 ‚.
[14/12/2019 15:42:52] Written data (COM5)
82 10 ‚.
04 - start
08 - vr1
10 - vr2
20 - vr3
40 - vr4
80 - leader
Each single command triggers a lamp.
Here is the sketch -
/*
BigPanik Model2Pac v1.2 Final
Interface Model 2 hardware (wheel, pedals, buttons, gear, FFB and lamps) to USB
*/
#include "UnoJoy.h"
int incomingByte = 0; // for incoming serial data
char FFByte = 0;
byte LampValue = 0;
byte Datatrame = 0;
void setup(){
setupPins();
setupUnoJoy();
Serial3.begin(38400);
}
void loop(){
// Always be getting fresh Input data
dataForController_t controllerData = getControllerData();
setControllerData(controllerData);
}
void setupPins(void){
// UnoJoy
// Set all the digital pins as inputs
// with the pull-up enabled, except for the
// two serial line pins
for (int i = 2; i <= 12; i++){
pinMode(i, INPUT);
digitalWrite(i, HIGH);
}
pinMode(A4, INPUT);
digitalWrite(A4, HIGH);
pinMode(A5, INPUT);
digitalWrite(A5, HIGH);
//FFB
// SEGA DRIVE board connected on port A (22-29)
DDRA = 0xFF;
PORTA = 0;
// Lamps
// ULN2003 connected between A8 and A14
// A: VR Green
pinMode(A14, OUTPUT);
digitalWrite(A14, LOW);
// B: VR Green
pinMode(A13, OUTPUT);
digitalWrite(A13, LOW);
// C: VR Green
pinMode(A12, OUTPUT);
digitalWrite(A12, LOW);
// D: VR Green
pinMode(A11, OUTPUT);
digitalWrite(A11, LOW);
// E: VR Green
pinMode(A10, OUTPUT);
digitalWrite(A10, LOW);
// E: Not Connected
pinMode(A9, OUTPUT);
digitalWrite(A9, LOW);
// G: Race Leader
pinMode(A8, OUTPUT);
digitalWrite(A8, LOW);
}
dataForController_t getControllerData(void){
// Set up a place for our controller data
// Use the getBlankDataForController() function, since
// just declaring a fresh dataForController_t tends
// to get you one filled with junk from other, random
// values that were in those memory locations before
dataForController_t controllerData = getBlankDataForController();
// Since our buttons are all held high and
// pulled low when pressed, we use the "!"
// operator to invert the readings from the pins
//Start
controllerData.startOn = !digitalRead(9); //Start = button 10
//VR
controllerData.squareOn = !digitalRead(8); //Red = button 1
controllerData.crossOn = !digitalRead(7); //Blue = button 2
controllerData.circleOn = !digitalRead(6); //Yellow = button 3
controllerData.triangleOn = !digitalRead(5); // Green = button 4
//Gear
// 4=1+2/!3+4 = 4
// 3=2/4 = 2
// 2=1/3 = 1
switch(!digitalRead(4) + !digitalRead(3) * 2 + !digitalRead(2) * 4)
{
case 5: //gear 1
controllerData.l2On = 1;
controllerData.l3On = 0;
controllerData.r1On = 0;
controllerData.r2On = 0;
controllerData.l1On = 0; //Button 5
break;
case 6: //gear 2
controllerData.l2On = 0;
controllerData.r1On = 0;
controllerData.l3On = 1;
controllerData.r2On = 0;
controllerData.l1On = 0; //Button 5
break;
case 1: //gear 3
controllerData.l2On = 0;
controllerData.r1On = 1;
controllerData.l3On = 0;
controllerData.r2On = 0;
controllerData.l1On = 0; //Button 5
break;
case 2: //gear 4
controllerData.l2On = 0;
controllerData.l3On = 0;
controllerData.r1On = 0;
controllerData.r2On = 1;
controllerData.l1On = 0; //Button 5
break;
default: //Neutral
controllerData.l2On = 0;
controllerData.l3On = 0;
controllerData.r1On = 0;
controllerData.r2On = 0;
controllerData.l1On = 0; //Button 5 OFF version speciale Sans Neutre
}
//Coin
controllerData.selectOn = !digitalRead(12);
//Test SW
controllerData.r3On = !digitalRead(11);
//Service SW
controllerData.homeOn = !digitalRead(10);
// Set the analog sticks
// Since analogRead(pin) returns a 10 bit value,
// we need to perform a bit shift operation to
// lose the 2 least significant bits and get an
// 8 bit number that we can use
controllerData.leftStickX = analogRead(A0) >> 2;
controllerData.leftStickY = analogRead(A1) >> 2;
controllerData.rightStickX = 0;
controllerData.rightStickY = analogRead(A2) >> 2;
// And return the data!
return controllerData;
}
// Always be setting fresh Output (FFB + Lamps) data
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial3.available() > 0) {
if (Datatrame == 0) //FFB
{
FFByte = (char) Serial3.read();
PORTA = FFByte;
Datatrame++;
}
else //Lamps
{
LampValue = Serial3.read();
// if (LampValue & 128 )digitalWrite(A8,HIGH); else digitalWrite(A8,LOW); // Leader
digitalWrite(A8, !!(LampValue & (1u << 7))); // Leader
// if (LampValue & 4)digitalWrite(A10,HIGH); else digitalWrite(A10,LOW); // Start
digitalWrite(A10, !!(LampValue & (1u << 2))); // Start
// if (LampValue & 8)digitalWrite(A11,HIGH); else digitalWrite(A11,LOW); // Rouge
digitalWrite(A11, !!(LampValue & (1u << 3))); //Red
// if (LampValue & 16)digitalWrite(A12,HIGH); else digitalWrite(A12,LOW); // bleu
digitalWrite(A12, !!(LampValue & (1u << 4))); // Blue
// if (LampValue & 32)digitalWrite(A13,HIGH); else digitalWrite(A13,LOW); // Jaune
digitalWrite(A13, !!(LampValue & (1u << 5))); // Yellow
// if (LampValue & 64)digitalWrite(A14,HIGH); else digitalWrite(A14,LOW); // vert
digitalWrite(A14, !!(LampValue & (1u << 6))); // Green
Datatrame=0;
}
}
}
I can see the section of code that triggers the lamps but due to my lack of knowledge I cant see how the Arduino knows to trigger the lamps as I see no reference to the serial commands sent. If anyone could explain that would be great.
I'm also after some recommendations on how to send the same serial commands to the Arduino.
Thanks
Gareth
