Hans Krohn
03-08-2007, 07:00 PM
Hi guys,
I just finished programing my motorized throttle with EPIC. I had expected this to take a month, but it was suprisingly simple. I finished after just 2 hours! Must admit though that I use FS Communicator as middleware, and that superb program helped a great deal.
Now I need to catch some Z's, but tomorrow I'll post my code here!
Take care,
Hans
www.hanskrohn.com
Michael Carter
03-08-2007, 07:12 PM
That's good news! Congratulations Hans.
It took me a bit under eight hours to calibrate mine to where all of the throttles responded evenly. #2 is about .5 EPR behind the other two, but not enough to worry about. I just have to bump it a bit in cruise to keep the tanks level.
If you can post a video sometime, I'd sure like to see 'em working.
Hans Krohn
03-09-2007, 06:13 AM
a video is a good idea! I'll ask Spielberg or Lucas to come over for the weekend and shoot some scenes... :-)
Here is a link to my code:
www.hanskrohn.com/BuildingTips/Servo_Throttle/MAT_code/AT_Code.htm
Fly safely,
Hans
Hans Krohn
03-13-2007, 06:39 PM
Here is my code, as promised!
//EPL for Hans Krohn Cockpit Project
//EPICenter V1.082 - USB-EPIC
//Middleware: FS-Communicator V2.017 by Robert Fischer
//Copyright HJK 2005/2006/2007
//Created between Oct. 2005 and today
//Last Update: 8.March.2007
//***************************************************************************************
#include <modules.hpl>
#include <devices.hpl>
#include <macros.inc>
#include "Test.hpl"
//****************************************************************************************
// Definitions
//****************************************************************************************
#define via_FSC 25 // for better readability of the code
#define LED_AP_AT 0,4,0b00000010
#define LED_AP_N1 0,4,0b00000100
#define LED_AP_SPD 0,4,0b00001000
#define Rel_Throttle_Clutch 0,5,0b00001000 // Relais for Servo Auto Throttle
#define Rel_Throttle_Mot_On 0,5,0b00010000
#define Rel_Throttle_Mot_Rev 0,5,0b00100000
// ****************************************************************************************
// Flags
// ****************************************************************************************
flag f_AutoThrottle_On = false;
flag f_Thr_Lever_moving = false;
// ****************************************************************************************
// Byte variables (8 bit), range 0 - 255
// ****************************************************************************************
byte tick = 0; // see MainLoop. Used for timing purpose
// ****************************************************************************************
// word variables (16 bit) range 0 to 65535 (0xFFFF)
// ****************************************************************************************
word w_ph_ThrInput = 1; // For motorized throttle: Actual lever position
word w_ph_ThrTarget = 1; // For motorized throttle: Desired lever position
// ****************************************************************************************
// Procedures
// ****************************************************************************************
void INIT (void)
{
clearpoint (LED_AP_AT); // Reset of all LED's and Relays in the cockpit at start-up
clearpoint (LED_AP_N1);
clearpoint (LED_AP_SPD);
clearpoint (Rel_Throttle_Clutch);
clearpoint (Rel_Throttle_Mot_On);
clearpoint (Rel_Throttle_Mot_Rev);
jump (MainLoop);
}
void MainLoop (void) // this loop repeats every 40 ms. It is used for all time critical operations
{
call (CheckSpeedTimers);
tick++;
if (tick>24) {tick = 0;}
delay (2); // delay of 40 ms
jump (MainLoop);
}
void CheckSpeedTimers (void)
{
if (w_ph_ThrTarget == w_ph_ThrInput)
{
clearpoint (Rel_Throttle_Mot_On);
clearpoint (Rel_Throttle_Clutch);
clearpoint (Rel_Throttle_Mot_Rev);
f_Thr_Lever_moving = false;
}
// next timer procedure here!
}
// ****************************************************************************************
// Motorized Throttle
// ****************************************************************************************
void AT_Direction_Decider (void)
{
if (w_ph_ThrTarget > w_ph_ThrInput)
{
if (!Mecanics_1.THR_MAX_Limit)
jump AT_Move_Up;
}
if (w_ph_ThrTarget < w_ph_ThrInput)
{
if (!Mecanics_1.THR_MIN_Limit)
jump AT_Move_Dn;
}
}
void AT_Move_Dn (void)
{
f_Thr_Lever_moving = true;
setpoint (Rel_Throttle_Clutch);
setpoint (Rel_Throttle_Mot_On);
}
void AT_Move_Up (void)
{
f_Thr_Lever_moving = true;
setpoint (Rel_Throttle_Clutch);
setpoint (Rel_Throttle_Mot_Rev);
setpoint (Rel_Throttle_Mot_On);
}
void AT_Move_Stop (void)
{
clearpoint (Rel_Throttle_Mot_On);
clearpoint (Rel_Throttle_Clutch);
clearpoint (Rel_Throttle_Mot_Rev);
f_Thr_Lever_moving = false;
}
void Mecanics_1.THR_MIN_Limit.On (void)
{jump (AT_Move_Stop);}
void Mecanics_1.THR_MAX_Limit.On (void)
{jump (AT_Move_Stop);}
// ****************************************************************************************
// Autopilot Lights. Process direction: from FS to hardware
// ****************************************************************************************
// All following procedures are triggered by Qprocs (2 per LED, 1 for ON and 1 for OFF state).
// If a light goes on in PM MCP, these procedures also switch it on in the cockpit
// I use the qprocs for the MCP LEDs to determine if the autothrottle is on (not just armed).
// I admit this is a workaround, but I was too lazy to find the correct offset for AT on.
void AP_SPD_LED_Off (void)
{clearpoint (LED_AP_SPD);}
void AP_SPD_LED_On (void)
{
setpoint (LED_AP_SPD);
f_AutoThrottle_On = true;
}
void AP_THR_LED_Off (void)
{clearpoint (LED_AP_N1);}
void AP_THR_LED_On (void)
{
setpoint (LED_AP_N1);
f_AutoThrottle_On = true;
}
void AP_AT_LED_Off (void)
{
clearpoint (LED_AP_AT);
f_AutoThrottle_On = false;
}
void AP_AT_LED_On (void)
{setpoint (LED_AP_AT);}
// ****************************************************************************************
// QProc definitions (Process direction: FS to EPIC via FSUIPC and FS-Com)
// ****************************************************************************************
// QProc's are defined in FS-Communicator. Process direction is from FS via FSUICP via FS-C
// to hardware. QProcs are triggered by an offset state change in FS. Once EPIC receives a qp
// from FS-C, the corresponding procedure is executed. Mainly used to turn LEDs, lamps or
// relais on or off.
// Format: "defqp (<qp# as defined in FS-C>, <procedure name>)"
// Note: NO semicolons at the end of a line!!!
// Control of LED's in Autopilot
// --------------------------------------------------------------------------------------------
defqp(82,AP_SPD_LED_Off)
defqp(83,AP_SPD_LED_On)
defqp(84,AP_THR_LED_Off)
defqp(85,AP_THR_LED_On)
defqp(86,AP_AT_LED_Off)
defqp(87,AP_AT_LED_On)
// ****************************************************************************************
// Pigeon Hole No. 18 - Throttle Input Value. Process Direction: Throttle Pot via FSUIPC via FSC to Hardware
// ****************************************************************************************
ph ph_ThrInput (18 )
{
word word0;
word word1; // value here, scaled to 1 - 30 by FS-Commander
w_ph_ThrInput = ph_ThrInput.word1;
if (f_AutoThrottle_On)
{
if (!f_Thr_Lever_moving) // if lever is NOT moving...
jump AT_Direction_Decider;
} // if lever is moving --> do nothing
};
// ****************************************************************************************
// Pigeon Hole No. 19 - Throttle Target Value. Process Direction: PM via FSUIPC via FSC to Hardware
// ****************************************************************************************
ph ph_ThrTarget (19)
{
word word0;
word word1; // value here, scaled to 1 - 30 by FS-Commander
w_ph_ThrTarget = ph_ThrTarget.word1;
if (f_AutoThrottle_On)
{
if (!f_Thr_Lever_moving) // if lever is NOT moving...
jump AT_Direction_Decider;
}
};
// That's it, folks!