Cockpit

* User Profile

Welcome, Guest. Please login or register.

Login with username, password and session length

Who's Online

  • *Users: 1
  • *Guests: 53
  • *Total: 54

Our Discord

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

Offline kurt-olsson

  • I am chained to this website!
  • *
  • Posts: 1,209
  • 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: 756
  • 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: 817
  • 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

Offline kurt-olsson

  • I am chained to this website!
  • *
  • Posts: 1,209
  • 737 -mixed year OEM panel builder.
  • First Name: Peter
  • Home Location: Gothenburg
Re: Teensy LC Throttle Quadrant
« Reply #4 on: July 08, 2019, 08:09:41 AM »
Thanks for the nice comments.
More sketches is coming. :)

 

Recent Posts

X-Plane 11 multi-monitor & Fly Elise-ng - tuto
by blueskydriver
[Today at 05:33:45 AM]
FOR SALE: CA & FO Cockpit Seats with J Rails
by Philip
[July 19, 2019, 04:23:24 PM]
For sale
by TNT
[July 18, 2019, 07:57:29 PM]
For Sale: Dual Linked Rudder Pedals RSP
by Philip
[July 17, 2019, 06:47:22 PM]
737-800 Arduino X-Plane Build
by kurt-olsson
[July 17, 2019, 02:55:53 PM]
Boeing 737 Dual Linked Yokes
by tennyson
[July 16, 2019, 08:59:28 PM]
Flyengravity desktop MIP (SOLD)
by patiju
[July 16, 2019, 02:01:48 PM]
Flight deck solutions FDS-B737NG-PRO-MX- rudder pedal
by Mach7
[July 16, 2019, 04:52:26 AM]
Korry 318 gets hot.
by Joe Lavery
[July 16, 2019, 03:49:14 AM]
What have you done for your simulator today?
by blueskydriver
[July 14, 2019, 10:25:43 AM]
Where to find or how to make this switch guard?
by blueskydriver
[July 13, 2019, 03:46:30 AM]
NIB 747-400 ThrottleTek + FDS CDUs x2 [SOLD]
by blueskydriver
[July 12, 2019, 10:53:12 PM]
FDS 5V IBL Dimmer and Expansion Board / Pokeys 57E (SOLD)
by fsaviator
[July 10, 2019, 08:35:14 PM]
PM MCP.ini Question...
by ScottThePilot
[July 10, 2019, 12:56:38 PM]
Stab Trim Indicator...
by ScottThePilot
[July 09, 2019, 12:56:42 PM]
Teensy LC Throttle Quadrant
by kurt-olsson
[July 08, 2019, 08:09:41 AM]
Multiple Teensys, sketch upload question
by kurt-olsson
[July 08, 2019, 08:05:27 AM]
Anders Simparts - Summer info
by archen
[July 07, 2019, 03:30:31 AM]
Group buy - Oshino OL-2405BP lamps - interested?
by kattz
[July 03, 2019, 09:26:22 PM]
Prosim737 Ver 2 license for sale
by ifeliciano
[July 02, 2019, 09:58:37 AM]
Anyone have this connector and possibly a clamp as well for the yoke?
by mickc
[July 01, 2019, 08:01:04 PM]
Happy Canada Day
by jackpilot
[July 01, 2019, 10:09:40 AM]
MH 370 Article
by FredK
[June 30, 2019, 07:28:41 PM]
Calling any B747 mechs... please help
by kattz
[June 30, 2019, 06:08:50 PM]
International shipping?
by jackpilot
[June 27, 2019, 08:29:07 AM]
Flooring Installed!
by jackpilot
[June 25, 2019, 05:49:57 PM]
How much room between center pedestal and seat?
by jackpilot
[June 25, 2019, 08:19:42 AM]
2020 Microsoft Flight Simulator - new at E3 2019
by blueskydriver
[June 24, 2019, 02:29:16 PM]
How to install DZUS fasteners?
by Buster99
[June 22, 2019, 04:12:34 PM]
Desert Air Spares - Trustworthy?
by kattz
[June 22, 2019, 12:40:51 PM]