Combining 2 sketches... one USB keyboard, other serial output

Post here first, or if you can't find a relevant section!
Post Reply
Gazz292
Posts: 7
Joined: Sat Apr 23, 2022 9:02 pm

Combining 2 sketches... one USB keyboard, other serial output

Post by Gazz292 »

i'm pretty useless at programming, able to just about modify examples or other peoples shared codes a little to suit what i am doing.

i'm using a STM32f blue pill, running an arduino sketch to read lever positions in a train driving simulator controller i am building.

The train simulator (TSW2) does not accept standard joystick inputs, but will work with a proprietary device called a 'RailDriver'
Which someone has written a '.dll' which replaces the standard one that allows a real RailDriver to be used in the sim,
so you can make your own levers, and connect the potentiometers to an arduino board.

The arduino sketch simply reads the potentiometers positions and sends it to the simulator over serial in the format a RailDriver would send.

However it only reads the 7 potentiometer positions, and none of the buttons / switches.

So i thought i'd just add in abit of USB keyboard code to read the buttons i have on my controller, and send the keyboard strokes that operate the function in the sim.


Only it dosent work as simple as that it seems, as soon as i put any USB HID keyboard code in the serial sketch, the blue pill is seen as a HID Keyboard in windows, and the serial output doesn't work.

Is there a way to get both USB HID keyboard and serial output working together?

This is the RailDriver serial code:

Code: Select all

/*
Custom Hardware for use with Train Sim World 2 using my custom pieHid64.dll
By Skaako (Michael Huggins 2021)
*/

int Reverser = PA3;
int Power = PA4;
int TrainBrake = PA0;
int LocoBrake = PA2;
int BailOff = PA5; // Sets pins Potentiometers are connected to
int Wipers = PA6;
int Lights = PA7;

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 output expected for RailDriver
  if (val[0] == 256){val[0] = 254;}  // i assume this is to prevent errors if a potentiometer read is over 8 bits?

  delay(10);
  
  val[1] = analogRead(Power);  // Read value of pot on power lever
  val[1] = map(val[1], 0, 4095, 255, 0); // 12 to 8 bit mapping, and reverse the lever direction.
  if (val[1] == 256){val[1] = 254;}

  delay(10);
  
  val[2] = analogRead(TrainBrake);
  val[2] = map(val[2], 0, 4095, 0, 255);
  if (val[2] == 256){val[2] = 254;}

  delay(10);
  
  val[3] = analogRead(LocoBrake);
  val[3] = map(val[3], 0, 4095, 0, 255);
  if (val[3] == 256){val[3] = 254;}

  delay(10);
  
  val[4] = analogRead(BailOff);
  val[4] = map(val[4], 0, 4095, 0, 255);
  if (val[4] == 256){val[4] = 254;}
  
  delay(10);
  
  val[5] = analogRead(Wipers);
  val[5] = map(val[5], 0, 4095, 0, 255);
  if (val[5] == 256){val[5] = 254;}

    delay(10);

  val[6] = analogRead(Lights);
  val[6] = map(val[6], 0, 4095, 0, 255);
  if (val[6] == 256){val[6] = 254;}

  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(""); // Write potentiometer values one after the other
  
  
}

And this is the USB keyboard code i am playing with:

Code: Select all

#include <USBComposite.h>

USBHID HID;
HIDKeyboard Keyboard(HID); // Stuff needed to get USB keyboard started


int sifa = PB1; // Sifa button connected to this pin
int previousButtonState = HIGH; // Ensure button is off to start with


void setup() {
  HID.begin(HID_KEYBOARD);
  Keyboard.begin(); // Starts the HID Keyboard stuff
  
 // pinMode(sifa, INPUT);  // works without this, is it needed ?



}

void loop() {
        

  
  int buttonState = digitalRead(sifa);  //check the state of the button
  

  if (buttonState == LOW && previousButtonState == HIGH) { // If button is pressed
    Keyboard.press('q'); // Send letter 'q'
    delay(50); // Debouncing?
  }

  if (buttonState == HIGH && previousButtonState == LOW) { // When button released
    Keyboard.release('q'); // Stop sending letter 'q'
    delay(50);
  }
 
  previousButtonState = buttonState; // Go back to waiting for button press

}
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Combining 2 sketches... one USB keyboard, other serial output

Post by ag123 »

i'm not sure what is being done, but it is probably easier to do it as 2 separate devices / sketches. one is just HID the other Serial. 2 blue pills are required.

if you are trying to mimic the custom protocol, you may need to go beyond 'simple' HID. it may involve things like using a usb sniffer / analyzer and reverse engineer the protocol. then you'd need to make stm32 do that custom thing, that may not be as simple as the 'HID' implementation currently available.
Gazz292
Posts: 7
Joined: Sat Apr 23, 2022 9:02 pm

Re: Combining 2 sketches... one USB keyboard, other serial output

Post by Gazz292 »

thankyou, i think from what i've read, it's hid OR serial, not both with STMduino / STM blue pill boards,

i already have 2 blue pill boards stacked (with some pins between them disconnected) ... one runs FreeJoy, the other runs the RailDriver serial output arduino sketch,

So i'm thinking i may have to use something like 'joytokey' to read the FreeJoy button inputs, and convert them to keyboard presses.
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Combining 2 sketches... one USB keyboard, other serial output

Post by ag123 »

HID talks to the host, i.e. your PC, it doesn't talk to the other blue pill
if Freejoy is a hid implementation, then it probably can cater for the buttons as part of its hid implementation
Gazz292
Posts: 7
Joined: Sat Apr 23, 2022 9:02 pm

Re: Combining 2 sketches... one USB keyboard, other serial output

Post by Gazz292 »

oh yes, sorry for the confusion,

Blue Pill 1 is flashed with FreeJoy using the STM Link dongle, and appears to windows as a HID joystick (8 axis, 128 buttons etc) this board is used when i play with another simulator that does accept joystick input, everything is programmed from then on with a GUI.

Blue Pill 2 is flashed with the STMDuino bootloader thing, shows up as a Maple mini, and has the 'FakeRailDriver' arduino serial output sketch on it, this one is used when i play on the simulator that does not accept joystick input.


I have one set of levers and buttons, so i stacked the 2 Blue Pill's together, so they share all pins except reset, 5V, V.bus and the 2 usb data pins on PA11 and 12)
This is so they both can read the potentiometers and switches but not interfere with each other (neither board will boot if plugged into eachotehr with all pins intact)

I was simply swapping the usb lead between the boards when i changed simulators.

So now i will put a usb hub in the controller's box, and have one usb lead out to the computer,
and use JoyToKey or similar to read the button output from the FreeJoy board and send them as keystrokes to the simulator that is reading from the STMDuino board.

A bit clunky, and a waste of all that power the blue pill has, but better than nothing as there's no way i can write USB HID stuff.
ag123
Posts: 1653
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: Combining 2 sketches... one USB keyboard, other serial output

Post by ag123 »

what you have done is probably as 'simple' as it gets.
i.e. use software / app on the host to bridge HID to Serial, converting between them.
it is probably the way most apps work.

for anything more, you would need custom control on the firmware (i.e. your blue pills stm32f103) and the host s/w (i.e. that you can change the program).
then you can possibly design it any way you prefer, i.e. totally custom and maybe only a single blue pill is needed)
Post Reply

Return to “General discussion”