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
float fuel_L_lbs;
float fuel_C_lbs;
float fuel_R_lbs;
// Record last needle position for damping
float filtered_fuel_L_lbs;
float filtered_fuel_C_lbs;
float filtered_fuel_R_lbs;
// Can be reused for each gauge as we do one at a time.
float fuel_percent;
int fuel_PWM_out;
// Variables for flaps
float flaps_degrees;
float filtered_flaps_degrees;
int flaps_PWM_out;
// Variables to support incremental update of gauges
unsigned long currentMillis;
unsigned long previousMillis;
unsigned long period = 100; // 100millis = 0.1s, 10 updates per second
// Variables for damping gauges
// The gauge on the simulator travels from 0 to 33 degrees in about 35 seconds
// But the simulator only reports integer degrees.
// Introduce fractional degrees for the physical gauge so that it
// moves smoothly between integer degree positions.
// Similarly, the simulator reports integer percentage of tank full.
// We convert to lbs, and allow the lbsx100 gauge to move at limited speed.
const float flaps_max_degrees_per_period = 0.0943; // Maximum amount we can move in 0.1s
const float fuel_max_lbs_per_period = 3000; // Maximum amount we can move in 0.1s
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);
// Start all filtered values at zero.
// If the simulator is already running, or the initial value
// reported is not zero then it will take a while for the
// gauges to match reality.
filtered_flaps_degrees = 0;
filtered_fuel_L_lbs = 0;
filtered_fuel_C_lbs = 0;
filtered_fuel_R_lbs = 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.
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
flaps_PWM_out = filtered_flaps_degrees*7.727;
analogWrite(flaps_PWM_out_pin, flaps_PWM_out);
// Now update the fuel gauges.
// Yes, this should be done as an array...
// Left
if (fuel_L_lbs > filtered_fuel_L_lbs) {
filtered_fuel_L_lbs += fuel_max_lbs_per_period;
if (filtered_fuel_L_lbs > fuel_L_lbs) filtered_fuel_L_lbs = fuel_L_lbs;
}
else if (fuel_L_lbs < filtered_fuel_L_lbs) {
filtered_fuel_L_lbs -= fuel_max_lbs_per_period;
if (filtered_fuel_L_lbs < fuel_L_lbs) filtered_fuel_L_lbs = fuel_L_lbs;
}
else {
// target and current are equal. Nothing to do.
}
// Centre
if (fuel_C_lbs > filtered_fuel_C_lbs) {
filtered_fuel_C_lbs += fuel_max_lbs_per_period;
if (filtered_fuel_C_lbs > fuel_L_lbs) filtered_fuel_C_lbs = fuel_C_lbs;
}
else if (fuel_C_lbs < filtered_fuel_C_lbs) {
filtered_fuel_C_lbs -= fuel_max_lbs_per_period;
if (filtered_fuel_C_lbs < fuel_C_lbs) filtered_fuel_C_lbs = fuel_C_lbs;
}
else {
// target and current are equal. Nothing to do.
}
// Right
if (fuel_R_lbs > filtered_fuel_R_lbs) {
filtered_fuel_R_lbs += fuel_max_lbs_per_period;
if (filtered_fuel_R_lbs > fuel_R_lbs) filtered_fuel_R_lbs = fuel_R_lbs;
}
else if (fuel_R_lbs < filtered_fuel_R_lbs) {
filtered_fuel_R_lbs -= fuel_max_lbs_per_period;
if (filtered_fuel_R_lbs < fuel_R_lbs) filtered_fuel_R_lbs = fuel_R_lbs;
}
else {
// target and current are equal. Nothing to do.
}
fuel_PWM_out = ((filtered_fuel_L_lbs * 1. / 10000.0) + 75.0;
if(fuel_PWM_out > 255) fuel_PWM_out = 255;
analogWrite(fuel_L_PWM_out_pin, fuel_PWM_out);
fuel_PWM_out = ((filtered_fuel_C_lbs * 1. / 10000.0) + 75.0;
if(fuel_PWM_out > 255) fuel_PWM_out = 255;
analogWrite(fuel_C_PWM_out_pin, fuel_PWM_out);
fuel_PWM_out = ((filtered_fuel_R_lbs * 1. / 10000.0) + 75.0;
if(fuel_PWM_out > 255) fuel_PWM_out = 255;
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_L_lbs = fuel_percent * 9200;
// 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_C_lbs = fuel_percent * 4400;
// 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_R_lbs = fuel_percent * 9200;
// 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.170 seconds with 24 queries.