Search This Blog

Thursday, May 13, 2021

STM8 Gyrostock

 

STM8S003 + MPU6050 module

I was inspired by Cemu Gyro Joystick project which is a way to add motion data to a regular game controller. My hardware is based on cheap MPU6050 modules that was used by Gyro_Joystick from the project. 

I have ordered some USB hub chips from some dodgy supplier, but they turned out to be fake - blanks. So much for trying to squeeze it inside the controller and share the same USB connection.

Possible mounting location

It uses a firmware based USB library on a STM8S003 and communicates with the MPU6050 via I2C bus. The I2C peripheral comes with several errata with work arounds.


All would be fine except that both the firmware only USB and now I2C drivers relies on interrupts and tight timing.  I have implemented an interrupt driver based on ST's App. Note: AN3281 - STM8 8-bit MCUs I2C optimized examples It improved the reliability a bit over some other I2C drivers I was trying but it still hangs under load.

I looked at the USB traces and found that the I2C started in the middle of USB communication and cause it to hang eventually. 

Time delay

By adding a bit of time delay before the I2C transfer, I was able to fix the issue.  Now each of them gets their undivided attention from the CPU.

USB packet followed by I2C traffic

USB specs limits a Low Speed device to 8 bytes interrupt packets which is what's used for HID reports.  

6 axis at 16-bit each is 6 x 2 bytes = 12 bytes!

I have tried several things and failed.  The only way I could send out 6 axis full 16-bit data is to logically group the Accelerometers and Gyroscopes under separate Report ID and alternating between the two reports.

HID Report Descriptors
Thankfully that the host side picks up the 2 reports and treats them as one set of data (at 1/2 the data rate).Windows recognize this as a 6-axis game controller - (X/Y axis + 4 sliders).

Windows Game controller setting

The next part is to figure how to compile the Cemu Gyro Joystick project as they didn't have a pre-compiled version and I haven't got a clue on NodeJS.

Mechanicals

I have added Sketchup model for people who have fancy 3D printer(s).  I on the other hand tried to make a mount with simple hand tools. 
Sketchup 3D model

It is a home made captured M3 nut on a piece of PCB.  I drill an undersized hole and hand filed a hexagon hole. With the help of a pier and some applied force, I pressed it into the hole.  The nut bites into the slightly under sized hole and held in place. 

I cut a small piece of plexiglass with a saw blade attached to a Dremel tool.  I used a hand drill to drilled 2 holes - one  for the screw and a larger one the nut.

PCB assembly, plexiglass spacer, captured nut + M3 screw

Note the edge of the plexiglass is flush with the module and this helps to prevent the PCB assembly from spinning.


The plexiglass is then superglued to the captured nut PCB to form a mount.  I screwed in the PCB assembly to show how things fitted together. Notice the white stress points on the FR4 at the corner of the nut.  That's what holding the nut in place (along with the superglue).  FR4 can handle stress a lot better than plexiglass.  The thickness is just right for the M3 screw and clears the PCB assembly.  :)


The base can then be superglued to a controller.  My has a label area.

Homemade mount that can be glued to game controller

Here is what it looks like with everything in place.  The PCB components are protected by the back side.  The PCB assembly can be easily removed for easy access.


Github files

Conclusion

It would seem that this project is a partial failure as I have failed the objective.  It is not compatible with Cemu Gyro Joystick as it is limited by USB Low Speed to 8-byte interrupt packets size.  Node.JS is a mess to work with especially with the whole ball of wax of imported dependency.  Chances of fixing it is NIL.I have toyed with the idea of writing a program from scratch, but lost interest.

I have integrated an Interrupt driven I2C host with VUSB.  I have tested the idea of using multiple ReportID as a way to bypass the 8-byte packet limit.