Cockpit

* User Profile

Welcome, Guest. Please login or register.

Login with username, password and session length

Who's Online

  • *Users: 0
  • *Guests: 57
  • *Total: 57

Our Discord

Author Topic: Teensy LC Throttle Quadrant  (Read 187 times)

Offline kurt-olsson

  • I am chained to this website!
  • *
  • Posts: 1,172
  • 737 -mixed year OEM panel builder.
  • First Name: Peter
  • Home Location: Gothenburg
Teensy LC Throttle Quadrant
« on: April 17, 2019, 04:39:04 AM »
Almost final code, there are some tips and tricks here for rounding / NUllzones and not writing to X-plane if not needed to.


const int PIN_FLAPS = 21;
const int PIN_ENGINE_LEVER_1 = 18;
const int PIN_ENGINE_LEVER_2 = 19;

const int PIN_MOTOR_CONTROLLER_SPEED_LEVER_1 = 3; // PWM, do analogWrite
const int PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_1 = 4;  //Motor 1 direction
const int PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_1 = 6;  //Motor 2 direction

const int PIN_MOTOR_CONTROLLER_SPEED_LEVER_2 = 9; // PWM, do analogWrite
const int PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_2 = 10;  //Motor 1 direction
const int PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_2 = 20;  //Motor 2 direction

const int PIN_PARKING_BRAKE_PUSH_TO_TEST = 23;
const int PIN_PARKING_BRAKE_ON_OFF = 22;

const int PIN_PARKING_BRAKE_SWITCH = 15;

const int PIN_STAB_TRIM_MAIN_SELECT = -1;
const int PIN_STAB_TRIM_AUTO_PILOT = -1;

float throttle1 = 0;
float throttle2 = 0;

float flaps = 0;

const int NrOfDigitsInConversion = 2;
const int AverageIterations = 80;
const float ThrottleLeverNullZone = 0.02;
FlightSimFloat throttle1Position;
FlightSimFloat throttle2Position;
FlightSimFloat flapsRequestSettings;
FlightSimFloat autothrottleArmPosition;
FlightSimFloat parkingBrakeStatus;
FlightSimFloat parkingBrake;

void setup() {
  flapsRequestSettings = XPlaneRef("laminar/B738/flt_ctrls/flap_lever");
  throttle1Position = XPlaneRef("sim/cockpit2/engine/actuators/throttle_ratio[0]");
  throttle2Position = XPlaneRef("sim/cockpit2/engine/actuators/throttle_ratio[1]");
  autothrottleArmPosition = XPlaneRef("laminar/B738/autopilot/autothrottle_arm_pos");
  parkingBrakeStatus = XPlaneRef("laminar/B738/annunciator/parking_brake");
  parkingBrake = XPlaneRef("laminar/B738/parking_brake_pos");
 
  //Serial.begin(9600);
  analogReadResolution(16);

  pinMode(PIN_FLAPS,INPUT_PULLUP);
  pinMode(PIN_ENGINE_LEVER_2,INPUT_PULLUP);
  pinMode(PIN_ENGINE_LEVER_1,INPUT_PULLUP);
 
  pinMode(PIN_STAB_TRIM_MAIN_SELECT, INPUT_PULLUP);
  pinMode(PIN_STAB_TRIM_AUTO_PILOT, INPUT_PULLUP);

  pinMode(PIN_PARKING_BRAKE_PUSH_TO_TEST, OUTPUT);
  pinMode(PIN_PARKING_BRAKE_ON_OFF, OUTPUT);

  pinMode(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1, OUTPUT);
  pinMode(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_1, OUTPUT);
  pinMode(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_1, OUTPUT);

  pinMode(PIN_MOTOR_CONTROLLER_SPEED_LEVER_2, OUTPUT);
  pinMode(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_2, OUTPUT);
  pinMode(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_2, OUTPUT);

  pinMode(PIN_PARKING_BRAKE_SWITCH, INPUT_PULLUP);
}

void loop() {

  //Test code autothrottle movement
  //-------------------------------------------------------
  /*analogWrite(PIN_MOTOR_CONTROLLER_SPEED,0);
  //Decrease power
  digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1,HIGH); 
  digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2,LOW);
  //Increase power
  digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1,HIGH); 
  digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2,LOW);*/
  //-------------------------------------------------------
 
 
  FlightSim.update();

  int parkingBrakeValue = digitalRead(PIN_PARKING_BRAKE_SWITCH) == 0 ? 1 : 0;
  if (parkingBrake != parkingBrakeValue)
     parkingBrake = parkingBrakeValue;
     
  digitalWrite(PIN_PARKING_BRAKE_ON_OFF,parkingBrakeStatus);  //ON OFF
  digitalWrite(PIN_PARKING_BRAKE_PUSH_TO_TEST,HIGH); //PUSH TO TEST
 
  // THROTTLES -------------------------------------
  //Throttle logic
  //--------------------------------------------------------------
  //Get average values for stable analog reading / this is min repeated 80 times for stable values (teeny is fast Hurray!)
  int throttleValue1Avg = 0;  //todo break out function.
  for(int i = 0; i < AverageIterations;i++) {
    throttleValue1Avg += analogRead(PIN_ENGINE_LEVER_1);
  }
  throttleValue1Avg = throttleValue1Avg / AverageIterations;

  int throttleValue2Avg = 0;
  for(int i = 0; i < AverageIterations;i++) {
    throttleValue2Avg += analogRead(PIN_ENGINE_LEVER_2);
  }
  throttleValue2Avg = throttleValue2Avg / AverageIterations;

  throttle1 = abs(mapfloat(throttleValue1Avg,2250,40,0.0,1.0));
  throttle2 = abs(mapfloat(throttleValue2Avg,2250,40,0.0,1.0));

  //Now round to only two digits so that we dont update the throttle position too much,
  //this causes the Teensy to stop working when sending too much info in the buffer.
  //this is also fixed with a total of 120ms delay.
 
  float throttle1Rounded = String(throttle1,NrOfDigitsInConversion).toFloat();
  float throttle2Rounded = String(throttle2,NrOfDigitsInConversion).toFloat();
   
  //Manual mode, no Autothrottle engaged in X-Plane
  if (autothrottleArmPosition == 0) {
    analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1,0);
    analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1,0);
    //dont write values if they are the same, keep data minimum!
    if (throttle1Position != throttle1Rounded)
      throttle1Position = throttle1Rounded;
 
    if (throttle2Position != throttle2Rounded)
      throttle2Position = throttle2Rounded;
   
  }  //Autothrottle engaged, follow the set throttle position.
  else if (autothrottleArmPosition == 1) {
    //Lever 1 logic   TODO: Break out to function.
    float delta_throttle_1 = throttle1Position - throttle1;
    //only move if the difference is bigger than Nullzone in lever position
    if (abs(delta_throttle_1) > ThrottleLeverNullZone) {  //0.02
        //manual throttle needs to catch up
        if (delta_throttle_1 > 0) {
           analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1,255);
           digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_1,LOW); 
           digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_1,HIGH);
        } //manual throttle needs to chill down
        else if (delta_throttle_1 < 0) {
          analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1,255);
          digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_1,HIGH); 
          digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_1,LOW);
        }
      //only move is there is a bigger seperation between lever and set position
    }
    else
    {
      //Make sure to stop the engine if movement is not needed, otherwise it will loop.
      analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_1,0);
    }

    //Lever 2 logic   TODO: Break out to function.
    float delta_throttle_2 = throttle2Position - throttle2;
    //only move if the difference is bigger than Nullzone in lever position
    if (abs(delta_throttle_2) > ThrottleLeverNullZone) {
        //manual throttle needs to catch up
        if (delta_throttle_2 > 0) {
           analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_2,255);
           digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_2,HIGH); 
           digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_2,LOW);
        } //manual throttle needs to chill down
        else if (delta_throttle_2 < 0) {
          analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_2,255);
          digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_1_LEVER_2,LOW); 
          digitalWrite(PIN_MOTOR_CONTROLLER_DIRECTION_2_LEVER_2,HIGH);
        }
      //only move is there is a bigger seperation between lever and set position
    }
    else
    {
      //Make sure to stop the engine if movement is not needed, otherwise it will loop.
      analogWrite(PIN_MOTOR_CONTROLLER_SPEED_LEVER_2,0);
    }

   
   
  }
 
  //FLAPS -----------------------------------------

  flaps = getFlapsPositionValue(analogRead(PIN_FLAPS));
 
  if (flapsRequestSettings != flaps)
      flapsRequestSettings = flaps;
 
  //FLAPS 40 DONT WORK, THIS IS DUE TO POTENTIOMETER THAT HAS TO LITTLE SPAN, 30 AND 40 GIVES THE SAME VALUES
 
  delay(50);
}

float getFlapsPositionValue(int flaps_analog_value) {
  if (flaps_analog_value > 0 && flaps_analog_value < 500) { return 0.00; }      //4 flaps 0
  if (flaps_analog_value > 500 && flaps_analog_value < 3000) { return 0.125; }   //700 flaps 1
  if (flaps_analog_value > 3000 && flaps_analog_value < 5200) { return 0.25; }    //4500 flaps 2
  if (flaps_analog_value > 5200 && flaps_analog_value < 7000) { return 0.375; }   //6000 flaps 5
  if (flaps_analog_value > 7000 && flaps_analog_value < 9200) { return 0.50; }    //8500 flaps 10
  if (flaps_analog_value > 9200 && flaps_analog_value < 10500) { return 0.625; }   //10000 flaps 15
  if (flaps_analog_value > 10500 && flaps_analog_value < 12000) { return 0.75; }    //11400 flaps 25
  if (flaps_analog_value > 12000 && flaps_analog_value < 14000) { return 0.875; }   //13100 flaps 30
  if (flaps_analog_value > 14000 && flaps_analog_value < 15000) { return 1.00; }    //15000 flaps 40 ?? DONT WORK DUE TO POT NOT REACHING VALUE
 
  return 0.00;
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Offline Joe Lavery

  • I spend way too much on this forum!
  • *
  • Posts: 745
  • 737 Builder
  • First Name: Joseph
  • Home Location: Newport, UK
Re: Teensy LC Throttle Quadrant
« Reply #1 on: April 17, 2019, 04:57:55 PM »
You can't see me Kurt but I'm bowing my head while tipping my hat to the master.... 8)
« Last Edit: April 17, 2019, 04:58:17 PM by Joe Lavery »
'Life isn't about waiting for the storm to pass, it's about learning to dance in the rain!'

www.pcpilot.net


Offline ElStino737

  • Forum GURU
  • *
  • Posts: 28
  • Aviation Enthusiast
  • First Name: Stijn
  • Home Location: Ninove
Re: Teensy LC Throttle Quadrant
« Reply #2 on: April 18, 2019, 06:56:37 AM »
Definitely appreciate these teensy code posts.
I will really start building my own project in a year or so and these code examples really will help me a lot  and probably anyone trying to do the same.

Offline RayS

  • I spend way too much on this forum!
  • *
  • Posts: 814
  • Private Pilot, Sim Enthusiast
    • Anthony Scott Photography
  • First Name: Ray Sotkiewicz
  • Home Location: Seattle, WA
Re: Teensy LC Throttle Quadrant
« Reply #3 on: April 18, 2019, 03:38:14 PM »
Awesome work!

Regarding the Flaps40 issue: You should be able to re-map the pot output of flaps_analog_value to something within range?
Ray Sotkiewicz

 

FlightSimExpo 2019

FsExpo

Recent Posts

Wanted: FDS 737 CDU, EFIS, MCP
by jskibo
[Today at 05:27:20 AM]
Change the Forum Theme to suit your own Needs.
by 757Simulator
[Today at 04:35:43 AM]
Overhead: Where to mount interface cards?
by helloo
[April 25, 2019, 11:46:07 PM]
Where to buy/what size is this connector?
by helloo
[April 25, 2019, 11:44:19 PM]
737-800 Arduino X-Plane Build
by kurt-olsson
[April 25, 2019, 04:43:15 PM]
Complete 737-800 cockpit - moving sale
by jskibo
[April 25, 2019, 02:25:50 PM]
What have you done for your simulator today?
by blueskydriver
[April 24, 2019, 03:30:03 PM]
unfinished project 737
by LORENZO
[April 23, 2019, 06:29:47 PM]
747-400 Yoke Color
by bernard S
[April 23, 2019, 04:39:55 PM]
737 MAX Sismo soluciones (SPAIN)
by kkoutoulas
[April 23, 2019, 02:53:50 PM]
TV Screen Position
by iwik
[April 22, 2019, 07:53:38 PM]
Question on B737NG center pedestal instrument availability
by navymustang
[April 22, 2019, 05:05:09 PM]
Wanted - Jetmax B737 TQ
by kattz
[April 22, 2019, 12:57:09 AM]
Multi-Projector color calibration
by jmlohrenz
[April 21, 2019, 05:33:40 PM]
Bernard...info
by FredK
[April 20, 2019, 06:29:17 PM]
Complete 200 degree curved visual system with projectors
by fsaviator
[April 20, 2019, 04:25:12 PM]
For Sale GoFlight Jet Console, 2 Private Pilot Racks all with GoFlight Modules.
by blueskydriver
[April 20, 2019, 11:26:43 AM]
Old Projector(s)
by fsaviator
[April 20, 2019, 10:53:59 AM]
OEM 737NG project - Long overdue update
by Karl737
[April 19, 2019, 09:56:23 PM]
CPFlight 737 NG MCP Pro and Efis Pro
by patiju
[April 19, 2019, 06:14:33 PM]
Goflight Airliners collection stuff for sale
by Steenos
[April 19, 2019, 03:22:12 PM]
German B738NG Homecockpit-Projekt
by Joe Lavery
[April 19, 2019, 04:59:21 AM]
Teensy LC Throttle Quadrant
by RayS
[April 18, 2019, 03:38:14 PM]
FSDream Team Couatl crashes when shutting down computers - any ideas
by navymustang
[April 18, 2019, 08:25:11 AM]
FLIGHTSIMEXPO RELEASES 2019 SPEAKER SCHEDULE, ANNOUNCES NEW PARTNERSHIP WITH EAA
by 757Simulator
[April 18, 2019, 04:20:53 AM]
Teensy as Joystick
by kurt-olsson
[April 16, 2019, 01:54:29 PM]
Which Processor i7 - 8700K or i7 - 9700K
by Joe Lavery
[April 15, 2019, 04:00:33 PM]
Computer / Projector Combo
by blueskydriver
[April 15, 2019, 02:50:24 PM]
Flyengravity desktop MIP
by Steenos
[April 15, 2019, 02:22:39 PM]
Join me on Vatsim Tonight
by Trevor Hale
[April 14, 2019, 05:07:50 PM]