Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
dancili
Published © GPL3+

FlightGear Analog Trim Tab Wheel

I wanted an additional analog control in FlightGear - nice, cheap and compact.

IntermediateFull instructions provided6,828
FlightGear Analog Trim Tab Wheel

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
or compatible board
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
Capacitor 100 µF
Capacitor 100 µF
×1
Adafruit SSD1306 0.96 inches OLED
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE
Anaconda
FlightGear

Story

Read more

Schematics

Breadboard view

In Fritzing it is not possible to pass wires below components. The ground wire of the display may go under the Arduino Nano.

Code

arduinoElevatorTrimOLED.ino

Arduino
Code to load on the Arduino Nano. Adjust line 2 (type of display) as needed.
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI
 
int xmax = 128;                                  
int ymax = 64;                                   
int xcenter = xmax/2;                            
int ycenter = ymax/2+10;                        
int arc = ymax/2;                             
int angle = 0;                                   
char* label = "TRIM";  
int labelXpos = 53;                               
int p, w, m;
u8g_uint_t xx = 0;
int const potPin = A6;
float potVal;

// Customized function
void gauge(uint8_t angle) {
  
  // draw border of the gauge
  u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT);
  u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT);
  u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT);
  u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT);
  
  // draw the needle
  float x1 = sin(2*angle*2*3.14/360);           
  float y1 = cos(2*angle*2*3.14/360); 
  u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);
  u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT);
  u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT);
  u8g.setFont(u8g_font_chikita);
   
  // show scale labels
//  u8g.drawStr( 10, 42, "-1.0");                   
//  u8g.drawStr( 19, 14, "-0.5");
//  u8g.drawStr( 63, 14, "0");
//  u8g.drawStr( 92, 14, "0.5");
//  u8g.drawStr( 105, 42, "1.0");
  u8g.drawStr( 1, 42, "DOWN");
  u8g.drawStr( 52, 17 , "NEUT");
  u8g.drawStr( 105, 42, "UP");
  
  // show gauge label
  u8g.setPrintPos(labelXpos,32);            
  u8g.print(label); 
  // show digital value and align its position
  u8g.setFont(u8g_font_profont22);             

  if (w >= 99) {                                  
    u8g.setPrintPos(47,60);
  }
  if (w >= 10 && w < 99) {
    u8g.setPrintPos(54,60);
  }
  if (w >= 0 && w < 9) {                                  
    u8g.setPrintPos(60,60);
  }
  if (w >= -9 && w < 0) {                                  
    u8g.setPrintPos(48,60);
  }
  if (w >= -99 && w < -9) {                                  
    u8g.setPrintPos(42,60);
  }
  if (w < -99) {                                  
    u8g.setPrintPos(35,60);
  }
  u8g.print(w);
}

void setup() {
  Serial.begin(9600);

  u8g.setFont(u8g_font_chikita);
  u8g.setColorIndex(1);                        
  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);                    
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);                      
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);                      
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
}

void loop() {
  potVal = analogRead(potPin);
  potVal = (potVal - 512.0)/512.0;
  Serial.print(potVal);
  Serial.print("\n");

  // p is the same as potVal, but it is an integer
  p = analogRead(potPin);                  
  w = map(p,0,1023,100,-100);                    
  m = map(p,0,1023,90,0);                   
  // show needle and dial
  xx = m;                                    
  if (xx < 45){                                
    xx = xx + 135;
  }
  else {
    xx = xx - 45;
  } 
  // picture loop
  {
    u8g.firstPage(); 
    do {             
      gauge(xx);
    }
    while( u8g.nextPage() );
  }
  
  delay(10);
}

arduinoElevatorTrim.py

Python
Script to be executed along with FlightGear to "translate" serial communication into UDP packets. You need Python installed in order to execute this script. Modify line 14 (USB port where the Arduino is connected) as needed.
#!/usr/bin/python
import sys
import serial
from socket import *


host = "localhost"
port = 21567
#buf = 1024
addr = (host,port)
UDPSock = socket(AF_INET,SOCK_DGRAM)


tty="COM4"
print("tty is ", tty)


try:
   ser = serial.Serial(tty,9600)
except:
   print("Error connecting to " , tty)
   
prevline=""
while 1:
  outline=''
  line=ser.readline()
  if line != prevline:  #some value changed
    print(line)
    outline=line
    UDPSock.sendto(outline,addr)
    prevline=line

arduinoElevatorTrim.xml

XML
Script to be added in the folder <FlightGearRoot>/data/Protocol. Do this once for all.
<?xml version="1.0"?>

<PropertyList>

<generic>
    <input>   
        <line_separator>\n</line_separator>
        <var_separator>,</var_separator>
   
        <chunk>
            <name>Elevator trim</name>
            <node>/controls/flight/elevator-trim</node>
            <type>float</type>
        </chunk>
 
    </input>
</generic>

</PropertyList>

Github

Online repository on Github

Credits

dancili
0 projects • 11 followers
Contact

Comments

Please log in or sign up to comment.