Avionic System Test Stand

Team Members: Yanbaihui Liu, Yatong Bai, Ning Zhu

Description

Many aviation systems could not be tested on the aircraft in the early stage of construction, so we built a test stand to verify the performance of avionic systems and help estimate the heading and the angular velocity of the aircraft.

The test stand incorporates a brushed DC motor with a built-in encoder, a MOSFET, an LED, an mbed, and a Windows PC. This test stand also provides a heading ground truth that can be used to help design and test the DSP software to reflect the needed DSP software module of avionics due to noise issues

https://os.mbed.com/media/uploads/tommyzhu19951204/quwymnir_zrlpozfniigklvulqb6_mm5r0hehzqr4zhao9g_t7benbx46gpqdl7dgp9nr_qqlf02tzxlndhn6l4lx2wonm90i-gf6uzgfmtytgdrmg1v2zjc8qpda6hwv.png

A GUI will be created to run on a Windows PC, which allows users to enter the desired rotational speed through it. The PC will then control the Mbed by sending the target speed via the serial port. The mbed will then run a PID algorithm to maintain a constant motor speed. An I/O interrupt function triggered by the rising edges of the encoder will calculate the angular velocity and perform PID control. Using an interrupt ensures real-time. The PWM module shall be utilized to drive a MOSFET, which in turn drives the motor. The current heading and the angular velocity of the test stand will be displayed on the GUI real-time. When the test stand rotates to the predefined “0 degrees” position, the LED should light up. Additionally, the encoder can be a little erratic sometimes so “false” rising edges that occur too frequently should be discarded by the interrupt function. Our encoder only has 11 ticks per rev, so the software also needs to estimate the heading between two ticks based on angular velocity information.

Parts List

  • Test Stand Base
  • 1 Brushed DC Motor (with built-in encoder)
  • 1 MOSFET
  • 1 LED
  • 1 mbed NXP LPC1768 Development Board

Wiring

mbedMOSFET PCBMotorExternal Power (12V)
gndJP2-2 gndgnd (black)Negative
JP2-1 RAWPositive
p21JP2-3 Control
JP1-1M2 (white)
JP1-2M1 (red)
p22C1/C2 (yellow/green)
3.3v3.3 V (blue)

Codes

1. Mbed
This code demonstrates the operation of a rotary encoder and displays results on a serial monitor. It implements PID control in an effort to optimize the speed control. The builtin LED1 will turn on between -10 and 10 degrees, and LED2 will blink during encoder rising edge.

/*
  Rotary Encoder Test
  Demonstrates operation of Rotary Encoder
  Displays results on Serial Monitor
*/

#include "mbed.h"

#define tick 32.727272727272727
#define pi 3.14159265358979323846264338

InterruptIn encoder (p22);
PwmOut motor (p21);
Serial pc (USBTX, USBRX);
DigitalOut led(LED1);
DigitalOut blinker(LED2);
Timer t;
Timer t2;

volatile double rev = 0, old_rev = 0, raw_rev = 0, print_rev = 0;
volatile double elapsed_time = 99999999999, cur_elapsed_time = 0;
volatile double angle = 0, raw_angle = 0, target = 0, target_diff = 0;
volatile double cur_angle = 0, print_angle = 0, num = 0, err = 0;

volatile int p = 0, i = 0, d = 0, spd = 0, up_lim = 255;
volatile int low_lim = 20, cntr = 0, print_spd = 0;
char buf[5];
volatile bool bypass = false, bypass2 = false;

void PID(){
    // PID
    err = target-rev;
    p = err*(110*target+500);
    double temp = err*elapsed_time*(target*330+110);
    if (temp < 20 && temp > -20)
        i += temp;
    else if (temp >= 20)
        i += 20;
    else
        i -= 20;
    if (i < -5)
        i = -5;
    else if (i > 120+target*80)
        i = 300;
    d = (old_rev-rev)/elapsed_time*7;
    spd = p + i + d;
  
    if (target == 0)
        spd = 0;
    
    else{
        up_lim = target * 25 + 160;
    
        if (spd < low_lim)
            spd = low_lim;
        else{
            if (spd > up_lim)
                spd = up_lim;
            if (spd > 255)
                spd = 255;
        }
    }
    
    motor = spd / 255.0;
}

void control() {
    t.stop();
    elapsed_time = t.read();
    t.reset();
    t.start();
    
    blinker = !blinker;
  
    if (elapsed_time == 0)
        raw_rev = 7;
    else
        raw_rev = tick/360.0/elapsed_time;
    rev = raw_rev;
  
    // Discard unrealistic revs
    if (rev - 1.3*print_rev > 1 || rev > 6){
        rev = print_rev;
        cntr++;
    }
    else{
        old_rev = rev;
        raw_angle += tick;
        angle = (raw_angle + 2*cur_angle) / 3.;
    }
    if (rev<6.5)
        print_rev = (print_rev * 39. + rev) / 40.;
  
    PID();
}

int main() {
    encoder.rise(&control);
    pc.baud(38400);
    pc.printf("Hello\n");
    motor.period_us(800);
  
    while (true){
  
        if (pc.readable()){
            pc.scanf("%s", &buf);
            num = atof(buf);
            if (num > 6){
                angle -= cur_angle;
                raw_angle -= cur_angle;
                cur_angle = 0;
                elapsed_time = 99999999999;
                rev = 0;
            }
            else{
                target_diff = abs(target-num);
                target = num * 1.005;
                motor = (target*40.0+50.0) / 255.0;
                bypass = true;
                i = 0;
                low_lim = 0;
            }
        }

        cur_elapsed_time = t.read();
        if (target<2 && cur_elapsed_time>elapsed_time){
            rev = tick/360.0/cur_elapsed_time;
            if (rev - 1.2*print_rev > 0.2 || rev > 5)
                rev = print_rev;
            PID();
        }
       
        cur_angle = angle + print_rev*360*cur_elapsed_time;
        if (cur_angle > angle + tick)
            cur_angle = angle + tick;
        if (cur_angle > 360.){
            raw_angle -= 360.;
            angle -= 360.;
            cur_angle -= 360.;
        }
        
    
        if (rev < 6.5){
            print_rev = (print_rev * 39. + rev) / 40.;
            print_angle = cur_angle;
            if (print_angle < 10 || print_angle > 350)
                led = 1;
            else
                led = 0;
            pc.printf("%5.1f,%4.2f,%d,%3.1f\n", print_angle, print_rev, i, target);
        }
    }
}

Import programtest_stand

This code controls the real rotation of the test stand.

2. C#
The GUI was built with Visual Studio 2019 using C# and used for showing the target speed, real-time speed and angle position of the test stand. Target speed can be input in one text box, while other parameters are shown on the other two text boxes. A click button is added to start the serial connection between the PC and the test

main.cpp

#include "mbed.h"

int main() {
    printf("Hello World!\n");
}

Demo Video

(video%20link)


Please log in to post comments.