Welcome to Cockpitbuilders.com. Please login or sign up.

April 27, 2024, 03:00:20 AM

Login with username, password and session length

PROUDLY ENDORSING


Fly Elise-ng
492 Guests, 0 Users
Members
  • Total Members: 4,154
  • Latest: xyligo
Stats
  • Total Posts: 59,641
  • Total Topics: 7,853
  • Online today: 506
  • Online ever: 582
  • (January 22, 2020, 08:44:01 AM)
Users Online
Users: 0
Guests: 492
Total: 492

COUNTDOWN TO WF2022


WORLDFLIGHT TEAM USA

Will Depart in...

Recent

Welcome

flap indicator interface with Fs9

Started by Mach7, August 03, 2023, 04:23:14 PM

Previous topic - Next topic

0 Members and 8 Guests are viewing this topic.

ame

Just out of curiosity, if you have flaps at zero, and you drive them to 33 degrees (either with your flaps lever or keyboard or on-screen control) how long does it take for the on-screen simulated flaps gauge to travel from 0 to 33 degrees? An approximation is fine, are we talking one second, 10 seconds, a minute? This will help to make the make the real gauge movement look less fake.

Mach7

I will boot it up and time it right now...give me 5 mins

Mach7

#102
It takes 35 seconds from zero to 33 degrees.

ame

Ok. So approximately one second per flap degree.

My guess is that the simulator is simulating a slow movement, and will send intermediate needle positions (i.e. <G000<G000<G000<G001<G001<G002<G002<G003 etc.) but the resolution is only one flap degree, no decimals, so the gauge movement will be a little lumpy.

So currently when the sim goes from 001 to 002 the gauge will jump. We need to feed out some small increments to the needle over one second. It means that the real gauge will lag from the sim gauge, but only slightly.

There are a couple of techniques for this.

Mach7


ame

Ok. Here's an attempt. It's not very elegant, but it does two things:
1 Allow the gauge to move only one PWM unit per 0.1 second (or 10 PWM units per second). There are 255 PWM units across the whole gauge range.
2 Jump to whatever the first value is after the Arduino gets turned on.

Hopefully you can see how it works. There's basically two separate parts, and every time around the loop the code decides which part needs to do anything. Either read in from serial and update the value, or trigger every 10th of a second and move the needle closer to the target if necessary.

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;

int flaps_PWM_out_pin = 3; // Must be one of 3, 5, 6, 9, 10, or 11 for Arduino Uno

// 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
const int flaps_max_PWM_per_slot=1; // 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_PWM_value; // Flag to see if we should go directly to target



void setup()
{
 Serial.begin(115200);
 // Set up PWM pin to drive flaps gauge
 pinMode(flaps_PWM_out_pin, OUTPUT);
 // Set PWM value to zero.
 analogWrite(flaps_PWM_out_pin, 0); 
 flaps_PWM_target=0;
 flaps_PWM_current=0;
 first_flaps_PWM_value=true;

}

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
  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
   if (flaps_PWM_target > flaps_PWM_current) {
     flaps_PWM_current += flaps_max_PWM_per_slot;
      if (flaps_PWM_current > flaps_PWM_target) flaps_PWM_current=flaps_PWM_target;
   }
   else if (flaps_PWM_target < flaps_PWM_current) {
     flaps_PWM_current -= flaps_max_PWM_per_slot;
      if (flaps_PWM_current < flaps_PWM_target) flaps_PWM_current=flaps_PWM_target;
   }
   else {
    // target and current are equal. Nothing to do.
   }
   analogWrite(flaps_PWM_out_pin, flaps_PWM_current); 
 }

}

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
      float flaps_degrees = flaps.toFloat();
      // Convert degrees to PWM 0-255.
      // 33 degrees is full scale, so multiplier is 255/33=7.727
      int PWM_out = flaps_degrees*7.727;
      // Clip output to maximum if (for some reason) it's >255
      if(PWM_out > 255) PWM_out=255;
      // New flaps PWM is calculated. Copy to other variables to
      // be handled by main loop on next 100ms boundary
      flaps_PWM_target=PWM_out;
      // If this is the first value we have received, go directly there.
      if (first_flaps_PWM_value) {
        flaps_PWM_current=flaps_PWM_target;
        first_flaps_PWM_value=false;
      }
     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
}


Mach7

Thanks ame!

Ill give it a go and report back!!


Jim

Mach7

Hello ame

Much much better!! thank you!

It runs much smoother, still a tiny bit of stutter, but I think if we made it smoother it would slow the gauge down "too" much.

I am very happy with it!!!

I will post a video here shortly.

Jim

Mach7


ame

Excellent! I can see what's up, but I lack the motivation to get deep into the problem. Basically the gauge is allowed to move one pwm unit per 1/10th second, but it should be about 0.8 units. But integer maths is easier than floating point.

If you're happy with it then that's all that matters. I'm glad the code actually works. I did test it, but I didn't know how it would look in reality.

Next, the fuel gauges?

Mach7

Yes!!! fuel gauges next!!.

I will start the prelim testing with the results on the gauges when I get home on Saturday...leaving today for work again:(

Thank you again for the code ame...i appreciate it!!

Jim

Mach7

Hey guys...back again after 4 days of work to tackle the fuel gauge project using arduino.

So...i am still in the prelim stages...but it appears these fuel gauges are a lot less than 5 volts...i gently touched the positive probe with a 1.5 battery and it shot off the scale...so I am going to use resistors to get a more accurate value.

I am looking at the 'fade' program..is there anyway to reduce the arduino output voltage through the sketch program...or just attach a resistor to the output pin?

Mach7

Here are some pics of the gauges...looks like they run from 2 to 7.04 milliamps. Unsure of the resistance to calculate the voltage...so looks like trial and error. Hopefully the former.

ame

Hello again. Glad to see you had some time to work on this.

You can't really reduce the PWM voltage out of the Arduino. The PWM module basically turns the pin on and off very rapidly, from 5V to 0V. The ratio of on time to off time sets the percentage of power transferred to the load. In the case of a moving coil meter, the needle is quite sluggish, so it doesn't flick between zero and fsd. Instead it shows the average power transferred, which is what you want it to do.

For the new gauge let's assume it's a moving coil meter again. And let's assume that 7.04mA represents the fsd. You can use shunts and multipliers to tailor the meter to the desired behaviour. I did this in high school, so I'm a bit hazy on the details, but no doubt there is an online calculator these days...

Mach7

Thanks ame,

So having understood that Arduino sends out this pulse voltage...could I not do the same with a resistor off the arduino ouput pin?

ame

Ok. You need a multiplier. To calculate the multiplier resistance you need to know the meter's coil resistance. But you could do it by trial and error as you suggested. You could use a pot and the fade program. When the pot is set correctly you could measure the set position and install the equivalent resistor.

ame

Quote from: Mach7 on August 20, 2023, 01:49:35 PMThanks ame,

So having understood that Arduino sends out this pulse voltage...could I not do the same with a resistor off the arduino ouput pin?
Yes. You could calculate it, if you know the meter's resistance, or derive it empirically.

Mach7

I'll do some testing with the fade circuit and some resistors...I will post when finished.

Mach7

Update, using 660 ohms of resistance I can connect the 'fade' program up and the gauge will travel to "just about" full travel and back again. It only needs to register 8200 on the dial for full fuel (one tank) and with 660 ohms it travels to the 9k mark.

ame

Quote from: Mach7 on August 20, 2023, 04:15:12 PMUpdate, using 660 ohms of resistance I can connect the 'fade' program up and the gauge will travel to "just about" full travel and back again. It only needs to register 8200 on the dial for full fuel (one tank) and with 660 ohms it travels to the 9k mark.
Excellent. The resistor of the Beast (within tolerance).

So, again stating assumptions, assume that the gauge is linear, and responds to 0-255 values of PWM as 0-100% of full scale, it should be possible to receive the fuel value from the sim and convert it to a PWM value to drive the gauge.

Conveniently, the fuel gauge is marked from 0 to 100, but it seems to me that 0 on the gauge is not at the zero position of the meter. Also, you implied that the needle goes past the topmost marking on the gauge. So, there's a small offset in the maths, and the scale factor is not going to be precisely 2.55.

Incidentally, you stated that the gauge shows 8200 for full scale, and the needle goes to 9000, but the photo shows a gauge with 0 to 100 markings. Are your two gauges different?

Anyway, if you are familiar with the Arduino programming environment you can find the terminal program (icon in top right of the main window). What you can do is modify the fade program so that it prints the current PWM value to the terminal. Then you can make some notes of what PWM value indicates what value on the gauge. This means you can confirm linearity, and derive the maths easily.

I can give you the code for this if you like.

Mach7

Hello ame,

I mention the 8200 mark due to the fact that the main fuel tanks hold 8120 max (left and right) and the center tank holds a max of 4400 lbs.

Having said that, the gauges go from 0 to 100, but with a full tank of gas they should only read the max capacity of approx 8000 lbs, with the center tank registering something a lot lower at 4400 max, (which is max capacity for the center tank).

In the real aircraft, the center tank gauge is graduated from 0 to 5000k, but will only go to 4400 as that is the max capacity.


Since I don't have a spec gauge for the center tank, I am using a (normal) main tank gauge, and hopefully when the programming is complete will indicate only 4400 lbs when the tank is full of fuel.

I am thinking that, once the code is written to drive the fuel gauges, than the link2fs should be able to do the rest to feed the information directly to Arduino(?). I am assuming we just have to make sure that the gauge can be driven to the 8200 mark, (which it can with the resister intact).



Mach7

Here are a couple of pics, first the real gauge environment, and the second is the setup I have now, using a main fuel gauge in place of the (real) center tank unit.

ame

Ok, so the gauge is a percentage of full capacity?

i.e. when there is 8120 lbs of fuel present the gauge will show 100?

It should be easy to make the needle point however you like, if you know the relationship between PWM value and needle position, and you know the range of values sent out by the simulator.

Anyway, do you know how to use the terminal in the Arduino programming environment?

Mach7

The gauge is graduated from 0 lbs to 10,000 lbs (1 to 100)

The gauge is not a percentage of, but rather an actual indication of the amount of fuel, (in pounds) that is currently in the respective tank. (Its a bit hard to read on the gauge itself, but at the bottom in blue letters it says x100).

For example, the gauge could read 3000 lbs, or 6000lbs, but the maximum capacity of said tank (mains) is 8120.

3000 lbs of fuel in the tank would have the gauge indicate at the "30" mark, 6000 bls would indicate the "60" mark, so on and so forth.

With respect to reading the terminal on the Arduino script, I see the serial monitor icon on the top right of the screen. I have never done it before, but I am assuming it will give me a bunch of values as the fade program works with which I will copy and paste for reference?
.

ame

Ok. I understand. I did not see the x100 indicator.

So, the fade program sends PWM values from 0 to 255. What you are saying is that the maximum you see with the chosen resistor is 9000, and the maximum your plane can hold is 8120 therefore it is not necessary to calibrate the resistor to allow the needle to get to 100?

If that is the case, I understand now.

Back to serial. The Arduino can be a standalone device, but the USB port appears as a serial port. This means that as well as programming the Arduino over the serial port you can also send and receive data. If the Arduino is standalone it doesn't matter. But if the Arduino is connected to something then data can go back and forth between the Arduino and what it's connected to.

In the case of the flight simulator the Arduino communicates serially with link2fs, which itself is connected to the simulator. But you can also send and receive data manually through the terminal, which is great for interacting with something on your Arduino, or for debugging.

In the setup() part of the fade program you can start the serial port:
Serial.begin(115200);

In the main loop of the fade program you can print out the current value of the PWM, which you will see on the terminal:
Serial.println(fadeValue);

You probably want to increase the loop delay to slow everything down so you can see the correlation between PWM value and needle position.

So your code will look something like this:
Quote/*


  Fading


  This example shows how to fade an LED using the analogWrite() function.


  The circuit:


  - LED attached from digital pin 9 to ground.


  created 1 Nov 2008


  by David A. Mellis


  modified 30 Aug 2011


  by Tom Igoe


  This example code is in the public domain.


  https://www.arduino.cc/en/Tutorial/Fading


*/


int ledPin = 9;    // LED connected to digital pin 9


void setup() {

  Serial.begin(115200);


}


void loop() {


  // fade in from min to max in increments of 5 points:


  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {


    // sets the value (range from 0 to 255):


    analogWrite(ledPin, fadeValue);
    Serial.println(fadeValue);

    // wait for 500 milliseconds to slow down the printing rate


    delay(500);


  }


  // fade out from max to min in increments of 5 points:


  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {


    // sets the value (range from 0 to 255):


    analogWrite(ledPin, fadeValue);

    Serial.println(fadeValue);

    // wait for 500 milliseconds


    delay(500);


  }

}

Now, download this program to the Arduino. When it's done, click on the terminal button. Something should happen.

Take a note of the reported PWM value at key points on the gauge. There should be a linear relationship between PWM and gauge position. And the "zero" position might not be at PWM 0.

Like the Website ?
Support Cockpitbuilders.com and Click Below to Donate