I'm making a train simulator controller (for Train Sim World 2)
The simulator accepts input from a proprietary device called a RailDriver, thankfully someone has found a workaround, with a modified .dll and a simple arduino sketch that reads potentiometer positions and sends them over the serial port in the same way a real RailDriver does.
The real RailDriver has a single lever / potentiometer for power and dynamic brake, i.e. the top half of the pot is power, bottom half is brakes,
But a lot of european trains use seperate levers for power and dynamic brakes, and the writer of the .dll said you can split the throttle and dynamic brake pot into 2 :
"SPLITTING COMBINED THROTTLE AND BRAKE
- The combined throttle and brake in the Raildriver control is sent over Byte 2 (Throttle). To split this you can use one pot connected to the Arduino as the Throttle to output 128 to 255. Then use another pot to go from 127 to 0 for braking. The braking pot should override the Throttle pot."*
This is where i stumble, how do i read from 2 seperate potentiometers and combine them so one pot's full range translates to the upper range, and the other pot's full range translates to the lower range of a single pot?
Then that bit about the brake pot should override the throttle pot (i know why, so moving the brake lever whilst the power lever is not at zero does not result in them fighting each other, but how would i do that?)
This is the sketch i am using
/*
Allows home made levers to be used with Train Sim World 2, using a custom pieHid64.dll
By Skaako (Michael Huggins 2021)
https://github.com/skaako/raildriver
*i'm running this with STMDuino on a blue pill*
RailDriver string output = Reverser, Power, TrainBrake, LocoBrake, BailOff, Wipers, Lights.
My European train style levers are in the order below, and connected to the pins indicated on the Blue Pill... not all my levers can be used at once*/
int Reverser = PA3;
int AFB = PA5;
int Power = PA4;
int DynamicBrake = PA1; // Power and Dynamic Brake are on a single pot on a real raildriver
int TrainBrake = PA0;
int LocoBrake = PA2;
int Wipers = PA6;
int Lights = PA7;
int BailOff; // American train thing not used on euro trains, so i'll give it a fixed value to pass calibration
int val[7] = {0}; // variable to store the value read
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial) { // wait for serial port to connect. Needed for native USB port only
;
}
}
void loop() {
val[0] = analogRead(Reverser); // Read value of potentiometer on Reverser Switch
val[0] = map(val[0], 0, 4095, 0, 255); // Map 12 bit STM board ADC to 8 bit outoput expected for RailDriver
delay(10);
val[1] = analogRead(Power);
val[1] = map(val[1], 0, 4095, 255, 0); //Reversed direction of lever
delay(10);
val[2] = analogRead(TrainBrake);
val[2] = map(val[2], 0, 4095, 0, 255);
delay(10);
val[3] = analogRead(LocoBrake);
val[3] = map(val[3], 0, 4095, 255, 0);
delay(10);
val[4] = (BailOff);
val[4] = (254); // Not reading a pot for this value, give it a fixed value to send
delay(10);
val[5] = analogRead(Wipers);
val[5] = map(val[5], 0, 4095, 0, 255);
delay(10);
val[6] = analogRead(Lights);
val[6] = map(val[6], 0, 4095, 0, 255);
delay(10);
// Start of string output
Serial.print("Output: "); // Write 'Output' at beginning of every line
// Padding for numbers
for(int i = 0; i < 7; i++){
if(val[i] < 10){
Serial.print(" ");
} else if(val[i] < 100){
Serial.print(" ");
}
Serial.print(val[i]);
Serial.print(" ");
}
Serial.println("");
}