10$ Trim Wheel

I built 10$ trim wheel for myself and my brother. Both are working perfectly.




Arduino-LEONARDO-ATmega32U4-miniUSB

If anybody is interested here are some details:

  1. Arduino Pro Micro ATmega32U4 (compatible clone) - 6$
    -very easy to buy
  2. rotary encoder 30 impulses per rotation (higher is better) - 1$
    -most encoders are 24 impulses or less, 30 or more are much better
  3. star knob M10 (diameter 50-65 mm) - 1$
    -prefered 8 sided or more (hard to buy), 5 sided or less will look and feel bad (easy to buy)
    -star knob is mounted on encoder via plastic nail expansion anchor cuted in half and reamed a little. This is most problematic part because is very hard to mount it streight, maybe gluing might be easier.
  4. three jumper wires female to female - 1$
    -very easy to buy
  5. micro USB cable - 1$
    -very easy to buy

I wrote custom firmware for Arduino and rotary encoder because all code which I found on internet worked bad and were loosing precision. I also added communication via virtual COM port (thru USB), so I am able to set encoder to proper position when for example autopilot changed a trim (my software is communicating with Flight Simulator to read the trim from the sim and then is sending this value via COM port to Arduino).

Where to buy parts:
AliExpress (cheap), local stores, eBay, Amazon (expensive), Allegro (Poland)

How to connect:
Rotary encoder with button has 3+2 pins (without button 3 pins). Connect yellow to left, green to middle, blue to right.
At the board connect yellow to pin 7, green to pin GND (on the same side as 7 & 8), blue to pin 8.
If you want revert rotation direction then switch yellow with blue at the board or at the encoder (better to switch wires than use reverse option in FS settings).

How to flash the board:

  1. Install Arduino IDE 2.x and start it.
  2. Connect the board, select “Tools > Port > Arduino Leonardo” and COM port.
  3. Paste source code (sketch) to the editor.
/*
 * Trim Wheel 1.0 for Arduino Pro Micro/Leonardo (ATmega32U4)
 * with incremental rotary encoder
 * (c) 2021 Szymon SZZYY Zielinski
 * szy.ziel@gmail.com
 */

#include <Joystick.h>

#define ROTPIN_A 8
#define ROTPIN_B 7
#define ROT_RESOLUTION 255 /* 1 impulse = 100%/255 = 0.4% of max trim */
static int PrevStateAB;
static int RotDir, RotVal = 0;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
  0, 0,                  // Button Count, Hat Switch Count
  false, true, false,    // only Y Axis
  false, false, false,   // No Rx, Ry, or Rz
  false, false,          // No rudder or throttle
  false, false, false);  // No accelerator, brake, or steering 


void setup() {
  pinMode(ROTPIN_A, INPUT_PULLUP);
  pinMode(ROTPIN_B, INPUT_PULLUP);
  Serial.begin(9600);
  Joystick.begin();
  Joystick.setYAxisRange(-ROT_RESOLUTION, ROT_RESOLUTION);
  PrevStateAB = (digitalRead(ROTPIN_A) << 1) | digitalRead(ROTPIN_B);
}


void loop()
{
  int CurrStateAB;

  /*
   * Encoder can be set by external program via COM port.
   * This functionality is required by autopilot or flaps auto trim.
   */
  if (Serial.available() > 1)
  {
    RotVal = (Serial.read() << 8) | Serial.read();
  }

  /*
   * rot1  11->01 01->00
   * rot2  00->10 10->11
   * -rot1 11->10 10->00
   * -rot2 00->01 01->11
   */
  CurrStateAB = (digitalRead(ROTPIN_A) << 1) | digitalRead(ROTPIN_B);

  if (PrevStateAB != CurrStateAB)
  {
    int PrevCurrStateAB = (PrevStateAB << 2) | CurrStateAB;
    if ((PrevCurrStateAB == 0b1101) || (PrevCurrStateAB == 0b0010))
    {
      RotDir = 1;
    }
    else if ((PrevCurrStateAB == 0b1110) || (PrevCurrStateAB == 0b0001))
    {
      RotDir = -1;
    }
    else if ((PrevCurrStateAB == 0b0100) || (PrevCurrStateAB == 0b1011))
    {
      if ((RotDir == 1) && (RotVal < ROT_RESOLUTION))
      {
        RotVal++;
        Joystick.setYAxis(RotVal);
        /* Serial.println(RotVal); */
      }
    }
    else if ((PrevCurrStateAB == 0b1000) || (PrevCurrStateAB == 0b0111))
    {
      if ((RotDir == -1) && (RotVal > -ROT_RESOLUTION))
      {
        RotVal--;
        Joystick.setYAxis(RotVal);
        /* Serial.println(RotVal); */
      }
    }
    PrevStateAB = CurrStateAB;
  }
}
  1. Add below joystick library. Click the on the “library icon” and select install.
    https://github.com/MHeironimus/ArduinoJoystickLibrary/archive/version-2.0.zip
  2. Select “Upload” from main editor. It should compile the code and upload it to the board.

How to test the trim:

  1. In Windows click Start button, type joy.cpl in the Start Search box, and then press ENTER.
  2. Select Arduino Leonardo, and then click Properties.
  3. On the Test tab cross should go up or down if you rotate the wheel.
    To check real resolution of encoder just enable println (remove /* and */) in the code. You should see in Arduino IDE Serial Monitor (enable it in Tools) rotation values.

Problems:
When autopilot or flaps auto trim change trim value then this value must be send to trim wheel to avoid inconsistency (for example if you rotate wheel to 10, then autopilot change trim to 20, then you rotate wheel again, trim will skip to 11 which is wrong).
I made a special program which is connected to MSFS and is sending new trim values to Arduino when required. This program is only required if you are using autopilot or plane has flaps auto trim. You need start it before or after MSFS start. Can be downloaded from here:

Can I connect second wheel or other stuff to one board?
Yes, but changes to source code are required.

17 Likes

I am using this trim and it became absolutely essential for my flying. I would say after joystick this is the second most important controller, more so than my yoke (honeycomb alpha) and rudder pedals. It seems that for MSFS this solution using trim axis is better than a trim wheel that uses trim up/down functions and has issues with precision and definitely better than trim buttons that I used for a long time.

1 Like

Interesting. While I already have a good trim wheel for the elevator, this smaller version would be perfect for a rudder trim.

Could you by any chance make a short tutorial on how to solder the stuff together and how to program the board? I’m kind of hopeless with stuff like that.

How many different switches and dials can you put on one of these cards?

Is there a software that works for those less skilled at programming our own code?

Have you tried MobiFlight? it really is super easy to assign an encoder to any function including trim - upload and everything is automatic so even inexperienced users can get everything configured

2 Likes

I can post source code for this after 4th of January (right now I don’t have access to my PC). You need install Arduino IDE (I am using version 2), connect board, select board type and COM port, paste source code and button upload should compile the code and upload it. I don’t remember any struggles with it except writing and testing my code.
Regarding soldering there are many tutorials on Youtube, also how to install Arduino IDE and how to use it.

How many different switches and dials can you put on one of these cards?

A lot. There are many different boards. Smallest have few pins, huge boards have a lot of them.

4 Likes

before i buy…can you tell me if these parts I found on amazon will work? are they correct?

I couldn’t find any 30 pulse encoders on amazon. infact, even on a site like rs, it’s either 24 pulse, 40 pulse (with a tiny 4mm shaft), or 128+ pulse (but those look to need more than 5v?).

This one says 100 pulse and actually comes as a pretty decent looking dial already?

Board looks exactly like mine, so should be good. Regarding encoder it looks strange. I don’t have electronics background, so I can’t say if it will work or not, but looks like might not.

In Poland you can buy 30 imp encoder which I used:
https://electropark.pl/pl/p/Enkoder-mechaniczny%2C-impulsator-30-impobr-20mm-z-

But on Aliexpress you can find a lot of different 30 impuls encoders. Have very different shafts but with some changes can be mounted to wheel.
https://www.aliexpress.com/wholesale?trafficChannel=main&d=y&CatId=0&SearchText=rotary+encoder+30+position

Also found them on Amazon:
https://www.amazon.co.uk/s?k=rotary+encoder+30&crid=27DMIFYCOGH7M&sprefix=rotary+encoder+30

BTW I just figure out that encoder from picture which I attached is not what I used. Shop has different picture than what they exactly sell. After 4th of January, when I will be in home, I will post a proper picture, so people maybe will be able to find it somewhere.

1 Like

Cheers. I’ll hang on until the January update then. Really cool project by the way.

I’m also thinking maybe of mounting a larger wheel instead of the star knob. Maybe something like the small wheels you find on push chairs and buggys. Or find something else that’s more like the c152 trim wheel.

Thanks for all this, really cool diy.

The only problem I see with this trim wheel is an encoder with a large wheel will be too loose and could be turned too easily by inadvertance.
I prefer to feel a “resistance” when turning the wheel. It’s why I’ve an encoder with a 14cm wheel with an adjustable friction system.
But it’s typically a personal preference.
And you can’t get all you want for a so cheap price.

I have 5 cm wheel and my brother has 6.5 cm. Both are really nice to use. Bigger wheel might be too heavy and rotation angle would be too big. If encoder has only 30 steps then you can easily calculate this. I don’t think that big step would feel right under hand.
1step

Analog encoder would be better but analog can’t change position without changing physical rotation, so when autopilot will trim then you can’t update analog wheel without motor. With digital I can send new trim value via COM to Arduino and next time when you trim with wheel it will use a value from autopilot.

BTW Amazon is pricy. I would find this stuff in local stores or in China.

for anyone interested, iv’e just seen this on ebay

looks like the correct board, and it’s already got pins soldered in place, so in theory, you could just connect the rotary encoder using breadboard cables?

Yes, this would require just connect the wires. And jumper wires female to female also doesn’t need soldering.
But soldering is easy and soldering iron is cheap (5$). Soldering of Arduino was my first soldering ever. Only 3 pins needs to be soldered.

No doubt. Soldering would be the best option, but I’m just thinking for anyone who is really not confident doing that, this seems like a pretty cheap and foolproof way of doing this project :slight_smile:

I added to first post more details and source code with pictures of encoder which I am using. This encoder is working very nice.

1 Like

Isn’t that just a Pro Micro board that are about £3 from AliExpress. What makes this a solution for MSFS particularly? Just wondering…

ÂŁ7.99 from Amazon UK. Half that from AliExpress.

Yes, It is Pro Micro but it is ÂŁ4 from Ali :slight_smile:

regarding mine solution:
Board can be used with any sim but external SW is only for FS. This is explained in “Problems:” on first post.

regarding this soldered from eBay:
Looks like this guy is selling his own solution. Arduino with his own software and BOX with switches etc for FS. I am guessing that he also has external SW to communicate with FS->Arduino->BOX and BOX->Arduino->FS.

Anyone have links to buy this stuff in the uk? I’ve searched Amazon, Ali, Ebay and I still can’t find any rotary encoders that say they’re 30 pulse or more (except those large cnc encoders, or ones which need 12v). Also, any links for the cheapest board with pins already soldered (just more convenient and easy to add to).

This looks like mine. Select B-20MM and AliExpress Saver Shipping. It will cost you 2,75ÂŁ with shipping for 2 pieces :smiley: Should be delivered to UK before 10th of February.

1 Like