Quote from: Jason L on August 25, 2023, 05:49:10 AMWill try not to read too much into your comment but the assumption that if you use MobiFlight you aren't building a cockpit seems a bit of a stretch.Ah, sorry, that was not my intention at all. I meant "where are all the cockpit builders?". We've been helping Mach7 here, but there are no other similar threads (building something) on this site. So, where else are people doing it and writing about it?
Quote from: ame on August 24, 2023, 01:26:08 PMQuote from: Jason L on August 24, 2023, 01:15:52 PMAny thoughts of using mobiflight as your interface instead of link2fs? Actively supported with multiple flavors of arduinos and works really well.Does it support FS9?
Since it's all working now there's probably not much sense in reimplementing it.
Quote from: ame on August 24, 2023, 08:09:54 PMQuote from: Jason L on August 24, 2023, 01:15:52 PMAny thoughts of using mobiflight as your interface instead of link2fs? Actively supported with multiple flavors of arduinos and works really well.On a related note, how can we encourage more people to build things? This is "cockpitbuilders.com" after all. Or is everyone on the mobiflight site these days?
I have enjoyed this little foray into link2fs, and in some ways I'm disappointed that it's gone. MSFS now has "Simconnect", which can be utilised in a number of ways, but that's no good for FS9.
Quote from: ame on August 24, 2023, 08:09:54 PMQuote from: Jason L on August 24, 2023, 01:15:52 PMAny thoughts of using mobiflight as your interface instead of link2fs? Actively supported with multiple flavors of arduinos and works really well.On a related note, how can we encourage more people to build things? This is "cockpitbuilders.com" after all. Or is everyone on the mobiflight site these days?
I have enjoyed this little foray into link2fs, and in some ways I'm disappointed that it's gone. MSFS now has "Simconnect", which can be utilised in a number of ways, but that's no good for FS9.
Quote from: Jason L on August 24, 2023, 01:15:52 PMAny thoughts of using mobiflight as your interface instead of link2fs? Actively supported with multiple flavors of arduinos and works really well.On a related note, how can we encourage more people to build things? This is "cockpitbuilders.com" after all. Or is everyone on the mobiflight site these days?
Quote/*
This code is in the public domain
For use with "Link2fs_Multi"
Jimspage.co.nz (via archive.org)
*/
int CodeIn;// used on all serial reads
String flaps;
String fuel; // Re-use this variable for all fuel gauges as we only do one at a time
// PWM pins for gauges. Must be one of 3, 5, 6, 9, 10, or 11 for Arduino Uno
// Flaps
int flaps_PWM_out_pin = 3;
// Fuel
int fuel_L_PWM_out_pin = 5; // Left fuel gauge
int fuel_C_PWM_out_pin = 6; // Centre fuel gauge
int fuel_R_PWM_out_pin = 9; // Right fuel gauge
// Variables for fuel gauges
int fuel_L_PWM_out;
int fuel_C_PWM_out;
int fuel_R_PWM_out;
int fuel_PWM_out;
// Record last needle position for damping
int last_fuel_L_PWM_out;
int last_fuel_C_PWM_out;
int last_fuel_R_PWM_out;
// Can be reused for each gauge as we do one at a time.
float fuel_percent;
float fuel_lbs;
// Variables for flaps
float flaps_degrees;
float filtered_flaps_degrees;
int flaps_PWM_out;
// Variables to support incremental update of gauges
unsigned long currentMillis; // store the current time
unsigned long previousMillis;
unsigned long period = 100; // 100millis = 0.1s, 10 updates per second
// Variables for flaps gauge
// The gauge on the simulator travels from 0 to 33 degrees in about 35 seconds
// We should introduce fractional degrees for the physical gauge so that it
// moves smoothly between integer degree positions.
const float flaps_max_degrees_per_period=0.0943; // Maximum amount we can move in 0.1s
int flaps_PWM_target; // Target PWM value, based on last flaps degrees
int flaps_PWM_current; // Current PWM value, can only move slowly
bool first_flaps_value; // Flag to see if we should go directly to target
void setup()
{
Serial.begin(115200);
// Set up PWM pins.
pinMode(flaps_PWM_out_pin, OUTPUT);
pinMode(fuel_L_PWM_out_pin, OUTPUT);
pinMode(fuel_C_PWM_out_pin, OUTPUT);
pinMode(fuel_R_PWM_out_pin, OUTPUT);
// Set PWM values to zero.
analogWrite(flaps_PWM_out_pin, 0);
analogWrite(fuel_L_PWM_out_pin, 0);
analogWrite(fuel_C_PWM_out_pin, 0);
analogWrite(fuel_R_PWM_out_pin, 0);
first_flaps_value=true;
last_fuel_L_PWM_out=0;
last_fuel_C_PWM_out=0;
last_fuel_R_PWM_out=0;
}
void loop() {
// Deal with incoming data from link2fs
if (Serial.available()) {
CodeIn = getChar();
if (CodeIn == '=') {EQUALS();} // The first identifier is "="
if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
}
// Other tasks
// Smooth the needle output.
// For flaps, we calculate intermediate flaps positions and then move the needle.
// For fuel, we calculate the PWM output, and apply a running average filter.
currentMillis = millis(); // store the current time
if (currentMillis - previousMillis >= period) { // check if 100ms passed
// We're on a 100ms boundary
previousMillis = currentMillis; // update the time we were here
// flaps_degrees is updated elsewhere when new data arrives.
// Filter the gauge needle position slowly over time.
if (flaps_degrees > filtered_flaps_degrees) {
filtered_flaps_degrees += flaps_max_degrees_per_period;
if (filtered_flaps_degrees > flaps_degrees) filtered_flaps_degrees=flaps_degrees;
}
else if (flaps_degrees < filtered_flaps_degrees) {
filtered_flaps_degrees -= flaps_max_degrees_per_period;
if (filtered_flaps_degrees < flaps_degrees) filtered_flaps_degrees=flaps_degrees;
}
else {
// target and current are equal. Nothing to do.
}
// Convert degrees to PWM 0-255.
// 33 degrees is full scale, so multiplier is 255/33=7.727
// If this is the first value we have received, go directly there.
if (first_flaps_value) {
filtered_flaps_degrees=flaps_degrees;
first_flaps_value=false;
}
flaps_PWM_out = filtered_flaps_degrees*7.727;
analogWrite(flaps_PWM_out_pin, flaps_PWM_out);
// Now update the fuel gauges. Just a simple digital filter.
// Yes, this should be done as an array...
fuel_PWM_out = ((3.0*last_fuel_L_PWM_out) + fuel_L_PWM_out)/4.0;
last_fuel_L_PWM_out = fuel_PWM_out;
analogWrite(fuel_L_PWM_out_pin, fuel_PWM_out);
// Lighter filter on centre gauge
fuel_PWM_out = ((2.0*last_fuel_C_PWM_out) + fuel_C_PWM_out)/3.0;
last_fuel_C_PWM_out = fuel_PWM_out;
analogWrite(fuel_C_PWM_out_pin, fuel_PWM_out);
fuel_PWM_out = ((3.0*last_fuel_R_PWM_out) + fuel_R_PWM_out)/4.0;
last_fuel_R_PWM_out = fuel_PWM_out;
analogWrite(fuel_R_PWM_out_pin, fuel_PWM_out);
}
}
char getChar()// Get a character from the serial buffer
{
while(Serial.available() == 0);// wait for data
return((char)Serial.read());// Thanks Doug
}
void EQUALS(){ // The first identifier was "="
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'A'://Found the second identifier
//Do something
break;
case 'B':
//Do something
break;
case 'C':
//Do something
break;
}
}
void LESSTHAN(){ // The first identifier was "<"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'A'://Found the second identifier
//Do something
break;
case 'B':
//Do something
break;
case 'G': //Found the second identifier ("G" Flaps position)
// Next three characters should be numeric
flaps = "";
flaps += getChar();
flaps += getChar();
flaps += getChar();
// convert 3-character numeric string to a float
// Expected range is 000 to 033
flaps_degrees = flaps.toFloat();
// Moving the needle will be done in the main loop.
break;
case 'X': // "X" left fuel gauge
// Next three characters should be numeric
fuel = "";
fuel += getChar();
fuel += getChar();
fuel += getChar();
// convert 3-character numeric string to a float
// It's a percentage of full, where full is 9200 lbs (left)
// Expected range is 000 to 100
fuel_percent = fuel.toFloat();
fuel_lbs = fuel_percent * 9200;
// Convert lbs to PWM 0-255.
// 0 lbs on gauge is PWM 75
// 10,000 lbs on gauge is 255
// So PWM is (1.8 x (lbs/100)) + 75
fuel_L_PWM_out = ((fuel_lbs * 1./10000.0)+75.0;
// Clip output to maximum if (for some reason) it's >255
if(fuel_L_PWM_out > 255) fuel_L_PWM_out=255;
// Moving the needle will be done in the main loop.
break;
case 'Y': // "Y" centre fuel gauge
// Next three characters should be numeric
fuel = "";
fuel += getChar();
fuel += getChar();
fuel += getChar();
// convert 3-character numeric string to a float
// It's a percentage of full, where full is 4400 lbs (centre)
// Expected range is 000 to 100
fuel_percent = fuel.toFloat();
fuel_lbs = fuel_percent * 4400;
// Convert lbs to PWM 0-255.
// 0 lbs on gauge is PWM 75
// 10,000 lbs on gauge is 255
// So PWM is (1.8 x (lbs/100)) + 75
fuel_C_PWM_out = ((fuel_lbs * 1./10000.0)+75.0;
// Clip output to maximum if (for some reason) it's >255
if(fuel_C_PWM_out > 255) fuel_C_PWM_out=255;
// Moving the needle will be done in the main loop.
break;
case 'Z': // "Z" right fuel gauge
// Next three characters should be numeric
fuel = "";
fuel += getChar();
fuel += getChar();
fuel += getChar();
// convert 3-character numeric string to a float
// It's a percentage of full, where full is 9200 lbs (left)
// Expected range is 000 to 100
fuel_percent = fuel.toFloat();
fuel_lbs = fuel_percent * 9200;
// Convert lbs to PWM 0-255.
// 0 lbs on gauge is PWM 75
// 10,000 lbs on gauge is 255
// So PWM is (1.8 x (lbs/100)) + 75
fuel_R_PWM_out = ((fuel_lbs * 1./10000.0)+75.0;
// Clip output to maximum if (for some reason) it's >255
if(fuel_R_PWM_out > 255) fuel_R_PWM_out=255;
// Moving the needle will be done in the main loop.
break;
}
}
void QUESTION(){ // The first identifier was "?"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'A'://Found the second identifier
//Do something
break;
case 'B':
//Do something
break;
case 'C':
//Do something
break;
}
}
void SLASH(){ // The first identifier was "/" (Annunciator)
//Do something
}
Page created in 0.148 seconds with 24 queries.