Cockpit

* User Profile

Welcome, Guest. Please login or register.

Login with username, password and session length

Who's Online

  • *Users: 1
  • *Guests: 57
  • *Total: 58

Our Discord

WORLDFLIGHT 2019 - TEAM USA SUPPORTERS (HERO'S)

 
Worldflight 2019
Donations Starting Early
With 50 Days Left, it's time to start Counting Down to Worldflight 2019.  Beginning in August, we had 2 kind gentleman lead the way on our quest for donations to this amazing Charity Event.  Over the Past 6 Years, we (This community) Has helped to raise over $25,000.00USD to help the kids and their families of the All Children's Hospital in St. Petersburgh, Florida.  Kicking off the donations this year these Two Hero's are leading the way to another Successful Year.  I personally want to thank these two Gentleman and use this opportunity to have all of you donate to our wonderful cause. 
Thank you in advance for your help and please wish us much success for our 2019 event.
       
  ---Worldflight 2019 HEROS---

 James Williams, Warren Soeldner,  Sam Llorca, Doug Snow, Ryan O'Keefe, Edwin Burton        





Thanks to all of you, You are all helping to make Worldflight 2019 a success..
Because of all you wonderful people so far we have raised a total of:

$1245.00 USD


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

Offline kurt-olsson

  • I am chained to this website!
  • *
  • Posts: 1,233
  • 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: 765
  • 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: 824
  • 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,233
  • 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

WORLDFLIGHT 2019 - Scenery Check Volunteers Needed
by Vincent T.
[September 14, 2019, 03:08:00 PM]
WORLDFLIGHT 2019 - FLIGHT BIDS
by Vincent T.
[September 14, 2019, 03:00:40 PM]
WORLDFLIGHT 2019 - AVAILABILITY
by Trevor Hale
[September 14, 2019, 07:25:32 AM]
WORLDFLIGHT 2019 - Employer matching for Donations...
by RayS
[September 14, 2019, 12:03:45 AM]
SimFest-West 2019 Videos
by RayS
[September 13, 2019, 07:27:16 PM]
737 MAX Build
by helloo
[September 13, 2019, 04:41:17 PM]
A little pucker factor here, I'm sure... nerves of steel
by RayS
[September 12, 2019, 06:30:45 PM]
727/737 yokes
by Caflyt
[September 12, 2019, 10:26:12 AM]
Which size fuses to use in fuse block supplying FDS boards?
by blueskydriver
[September 11, 2019, 05:56:37 PM]
I finally got the shell pulled off the ATC-810...
by geneb
[September 11, 2019, 07:29:51 AM]
Wanted: Optoma GT1080Darbee Short Throw Projector
by Flightdeck57
[September 11, 2019, 12:24:08 AM]
F16 Simulator For Sale
by blueskydriver
[September 06, 2019, 03:52:34 PM]
Ebay Assistance
by iwik
[September 06, 2019, 02:00:00 PM]
Matrox 3
by jackpilot
[September 05, 2019, 10:45:00 AM]
So I got a big crate the other day...
by geneb
[September 05, 2019, 09:20:22 AM]
Official WF 2019 Route
by fsaviator
[September 05, 2019, 08:20:10 AM]
Are some sellers off their trolly
by kurt-olsson
[September 02, 2019, 12:39:54 PM]
Display Glare FDS w/Pic
by Joe Lavery
[September 01, 2019, 02:33:47 AM]
MCP
by Caflyt
[August 27, 2019, 06:57:41 PM]
Dispatch and Career Add-on
by fsaviator
[August 26, 2019, 10:42:45 AM]
What have you done for your simulator today?
by B763
[August 25, 2019, 04:58:46 PM]
Free Jet Ranger.
by geneb
[August 23, 2019, 06:16:52 PM]
items/oem from overhead
by gufau
[August 23, 2019, 12:49:15 PM]
Hi everyone!
by jskibo
[August 23, 2019, 08:05:33 AM]
737-800 Front window post size
by kurt-olsson
[August 23, 2019, 03:35:11 AM]
Shipping Woes
by Caflyt
[August 22, 2019, 10:47:49 AM]
Worldflight 2019 Open for Business
by Trevor Hale
[August 21, 2019, 08:28:13 AM]
More ?'s - annunciators?
by kattz
[August 21, 2019, 05:44:21 AM]
Looking for annunciators
by kattz
[August 19, 2019, 10:36:39 PM]
OK, So here we go!
by Caflyt
[August 19, 2019, 02:32:28 PM]