Monday, August 31, 2015

Arduino Annunciator Panel


When I built my airplane, I installed switches to monitor the critical items like gear position, canopy and landing brake. I always intended to build an annunciator panel, but was unhappy with the plans design.
Building a flexible annunciator panel can be very complex. If the panel is to handle various inputs for multiple displays (IE throttle position for spoilers and gear warning) sometimes the wiring will
require diodes, and other schemes to keep the warnings coherent.

Adding a simple processor in the middle may make many complex systems easier. While in the past microprocessors were quite complex to install and program. For the hobbyist market there are many choices to make adding a processor to any system easier. One of the most basic hobbyist processor boards available is the Aurduino.  

ArduinoArtCircuit.png

In the Cozy as in most aircraft, there are certain situations the pilot must try to avoid to get the best performance out of the aircraft. The nose gear should be extended before landing, the canopy should be latched before taking off, and the landing brake (spoiler) should be retracted before adding power to the engine. There are 4 sensors that will be used in this panel, the throttle position, the gear up, the landing brake up and the canopy latched switches.

The Cozy plans suggest putting in a microswitch in for the throttle position. This is one way to do it, but using the Arduino, a potentiometer can be used to get both the throttle open and throttle
closed indications, as well as anything in between. The microswitches are used for the other sensors because they allow less exact mounting than any other switch. The plans make no provision for a landing brake sensor, because the plans have a manual landing brake and the actuator handle is an obvious indicator.









When my Cozy was built, all the switches were installed, and the wiring for the switches was run to a barrier strip near the panel. The barrier strip allows changing what is on either side without drastically affecting the opposite side. Replacing the plans circuit with a microprocessor based system is easily done.
There will be two main alarms, both a bright LED and an audio alarm will be available. Human factors research has shown a dark cockpit will allow the most use out of annunciator panel. The panel will be dark and quiet until the pilot needs to handle something. There will be individual indicators of what system is not normal, besides the master warning.
A push button is added to the annunciator panel to quiet the alarm for a period of time. I've chosen 5 seconds for the silence time. Sometimes  during testing and maneuvering, the aircraft will be in a configuration where an alarm may display, but the pilot is OK with the situation. Silencing the alarm will be OK, the master alarm light will continue to display.


When wiring sensors sometimes it seems like a good idea to run power to the switches causing them to switch 12 or 24V on to the panel, but this adds complexity. Any power run through the aircraft should be fused. When wiring switches to a microprocessor it is best to have the switches control a ground signal. The processor can have a local  voltage on board, that will be switched off when the switch closes to  ground. In a metal aircraft where the fuselage is ground, switching  grounds can simplify the wiring since the ground wires will not have to be run to the switch.





Using software to light indicators will allow the greatest flexibility. The software can monitor individual pins of input and react by changing the state on other pins. The inputs can be combined to provide the most accurate output.

The Arduino has many inputs. Looking at the schematic, all the switches are connected to digital inputs, and the potentiometer is connected to an analog input. The potentiometer is like a volume

control, not set to any particular voltage, so it will measure the voltage at the time it is read (many times a second).


There will need to be a dedicated 12V power supplied to the processor from the aircraft. It will probably be best to dedicate a 1A fuse to this circuit to protect the wires leading to the processor. Nothing on the board will require more than about 1amp of power.

The wires to the switches can be very light. Simple 22-30 gauge wire will work fine, keep the weight down and be easier to work with. Give the wires some slack near the switches in case the switches come loose, to minimize wire breakage.

The throttle position indicator can be either near the carburetor or near the throttle knob. It must be mounted and actuated in such a way as to not interfere with the throttle setting, if something comes loose. For my aircraft, I mounted it near the instrument panel connected to the throttle knob using a small piece of music wire from the hobby store.




The indicators are simple Light Emitting Diodes (LEDs). LEDs in many ways act like light bulbs, but have a couple critical differences. Lightbulbs can be connected to the power source either way, and they will light. LEDs have to be connected such that the power will flow the the proper direction, connecting them backwards won't damage them, but they won't light up. The other difference, LEDs must be current limited, without that, the LEDs will send too much current through and be very bright for a brief period of time, and never light again. The current limiter is a simple resistor, and for this project we will use a 1000ohm (brown-black-red) resistor.

The audio alert could be the same one from the plans. I chose a Soberton Inc WST-1205S buzzer available from Digi-Key. These buzzers are small, but are very loud.


I built a fixture to do the development of this system. The airplane is a short drive away, but it is cold working in the hangar, so I have this fixture with all the switches, knobs, audio alert and LEDs. The orientation is similar to the aircraft, and I have the switches and LEDs labeled.





Programming an Arduino is done on a laptop or desktop computer. The Integrated Development Environment (IDE) allows the programs to be entered in a C or Java like language, and saved on the disk. An earlier post, I did an intro to Arduino programming. The programs are loaded on the processor using a USB jack. Once loaded on the Arduino, the program will run every time power is added to the processor. Removing the power will not erase the processors memory.


Arduino programs are called sketches. The IDE supports building sketches that can be loaded from the disk, edited and compiled for loading on the processor. The microprocessor on the Arduino board doesn't read the text of the sketch. Compiling the text in the IDE converts the text of the sketch into the bytes the processor will use as instructions to do what the sketch says to do.

The program for this annunciator panel is straight forward. The setup function sets all the input and output pins as they need to be. The digital inputs are the pins where the switches are connected and the digital output are the pins where the LEDs are connected. The names

assigned to the pins are convenient for people reading the program, the computer really doesn't care what names are assigned.

void setup(){
 //configure input pins as an input and enable the internal pull-up resistor
 pinMode(GEAR_SW, INPUT_PULLUP);
 pinMode(CANOPY_SW, INPUT_PULLUP);
 pinMode(LB_SW, INPUT_PULLUP);
 
 pinMode(SILENCE_SW, INPUT_PULLUP);
 
 // configure output pins for output.
 pinMode(ALARM_OUT, OUTPUT);
 
 pinMode(GEAR_IND, OUTPUT);
 pinMode(CANOPY_IND, OUTPUT);
 pinMode(LB_IND, OUTPUT);
 pinMode(MASTER_IND, OUTPUT);
}

The loop part of the sketch will read the switches and throttle position sensor. The loop function will call the display function to compare the settings and try to set the lights to the appropriate values. The green lights will indicate the "out of normal" device. Gear down, landing brake and canopy open are out of normal for cruise flight.

/**
* Read all the switches and call the display function
*/
void loop(){
 //read the switch value into a variable
 int gearVal = digitalRead(GEAR_SW);
 int canopyVal = digitalRead(CANOPY_SW);
 int landBrakeVal = digitalRead(LB_SW);
 int silenceVal = digitalRead(SILENCE_SW);
 int throttleVal = analogRead(THROTTLE_IN);
 
  display(gearVal, canopyVal, landBrakeVal, throttleVal, silenceVal);
}

The Master Warning will happen using some more involved logic. When the gear switch is up, and the throttle position is closed, the alarm state is set.  When the Throttle position is set to takeoff power and the landing brake is down or the canopy is open the alarm state is set.

/**
* check the logic to see if there is a master warning to display
* returns 1 if the master warning should be set.
*/
int isAlertState(int gearVal, int canopyVal, int lbVal, int throttleVal)
{
 int alert = 0;
 // throttle closed, and landing gear up
 if ((throttleVal <= THROTTLE_CLOSED) && (!gearVal)) {
   alert = 1;
 }
 
 // throttle max and canopy not closed, and landing brake not up
 if ((throttleVal >= THROTTLE_MAX) && (canopyVal) && (lbVal)) {
   alert = 1;
 }
return alert;
}

The display function will set the green LEDs indicating the current "out of normal" setting. The isAlertState is called to see if the master warning should be turned on. Some logic is called to cause the buzzer to sound. The buzzer is modulated to make a more obnoxious sound. The logic for the silence uses the time library. The code will check what time the buzzer will stop
sounding when the silence button is pressed. When the silence button was released the silencedAt value will be set. When 5 seconds have elapsed beyond the silencedAt time, the buzzer will continue.

/**
* Process all the logic, to allow displaying LEDs in proper state, and
* handle master alarm state, including sound.
*/
void display(int gearVal, int canopyVal, int lbVal, int throttleVal, int silenceVal)
{
 int alert = 0;
 
 // gap is the cycle time for the tone. state is the tone state.
 static int gap=0;
 static int state=LOW;
 
 // silenced at is the time the alarm was silenced at.
 static time_t silencedAt=0;
 
  // Keep in mind the pullup means the pushbutton's
 // logic is inverted. It goes HIGH when it's open,
 // and LOW when it's pressed.:
 digitalWrite(GEAR_IND, gearVal);
 digitalWrite(CANOPY_IND, canopyVal);
 digitalWrite(LB_IND, lbVal);
 
 // The silence button is open normally. Logic is reversed.
 if (!silenceVal) {
   silencedAt = now();
 }
 
 alert = isAlertState(gearVal, canopyVal, lbVal, throttleVal);
 
 // output the master alarm status
 if (alert) {
   digitalWrite(MASTER_IND, HIGH);
   
   // generate a tone
   if (gap++ == 4) {
     state = !state;
     gap = 0;
   }
   if (now() > silencedAt + 5) {
     digitalWrite(ALARM_OUT, state);
   }
 } else {
   digitalWrite(MASTER_IND, LOW);
   digitalWrite(ALARM_OUT, LOW);
 }
}

The logic for the master warning is in its own functions. The logic can be minimized to make debugging easier. The state setting is separate from the alert indications.

Various testing schemes can be added if desired. Calling specific functions in specific order allows testing only the landing brake or the gear warning systems as needed to insure the system is working as desired.

With the system installed, the aircraft is much safer. You should continue to use your checklist, this is only designed to help if you forget. Using the Arduino, allows a more flexible system. There is plenty of expansion  in the software, and plenty of pins available to make an even more flexible system.

(This article with changes ended up in Kitplanes Magazine)

No comments:

Post a Comment