Quadrotor throttle control delay problems

Hey guys,
I'm building a quadrotor (controlled by an Arduino Mega) and I have everything working except for sloppy %@#^@# throttle control. I wrote a Java program to send throttle commands derived from input from a joystick over a serial port using a 60mw XBee antenna. The arduino receives the command with another 60 mw XBee and sends the proper signals to the speed controllers. I'm using the servo library which allows me to attach the servos to digital pins instead of the analog ones. Is this maybe the reason for sloppy throttle control?

Anyway, I am sending throttle data every 100milliseconds, and the arduino successfully receives it every time, but the motors respond generally about 1 second afterward. This is a problem. With aircraft, realtime control is necessary. Please help!!!!!!

I'll post the Java program code in a separate response. It's too long for this one.

Example of throttle data sent from computer to arduino:
$1000.1000.1000.1000.J*
'$' = start

the four "1000"s represent the signal to send to the speedcontrollers (which are controlled exactly the same way as servos)

".J" = signature showing the message was the sent by the java program

'*' = end transmission

Arduino program:

#include <Servo.h>

Servo speedController[4];

char serial2[4][4];
char Sbuffer[21]; //so strange. need to bring this one to the forums.;

int throttle[4];

int bottom = 1000;
int zero = 1292;
int top = 2000;

int mainThrottle = zero;

long refTime = micros();

int decodeThrottle(int start){
    
    int throttle = 0;
    int power = 1000;
    
    for(int i = start; i < start + 4; i ++){
        
        throttle += (int(Sbuffer[i]) - 48) * power;
        
        power /= 10;
        
    }
    
    return throttle;
    
}

void PANIC(){
    
    setAll(1000);
    
}

void ResetRefTime(){
    refTime = micros();
}

void set0(int SIGNAL){
    speedController[0].writeMicroseconds(SIGNAL);
}

void set1(int SIGNAL){
    speedController[1].writeMicroseconds(SIGNAL);
}

void set2(int SIGNAL){
    speedController[2].writeMicroseconds(SIGNAL);
}

void set3(int SIGNAL){
    speedController[3].writeMicroseconds(SIGNAL);
}

void setThrottles(int throttle[]){
    for(int i = 0; i < 4; i ++){
        speedController[i].writeMicroseconds(throttle[i]);
    }
}

void setAll(int SIGNAL){
    for(int i = 0; i < 4; i ++){
        speedController[i].writeMicroseconds(SIGNAL);
    }
}

void serial2In(){
    
    long time = millis();
    boolean flag = true;
    int i = 0;
    char in;
    
    char buffer[22]; //very very strange. if problems arise with buffer, come here first.;
    
    in = Serial2.read();
    
    //reset the flag time;
    time = millis();
    
    while(in != '*' &&
          flag){
      
      //wait for Serial2 data, but don't wait too long;
      while((!Serial2.available()) &&
          millis() - time < 300){}
      //if more than 1/3 of a second passes without receiving
      //Serial2 data, break the loop;
      if(millis() - time >=300){
        flag = false;
      }
      
      //add the character, move in and i forward in sequence;
      buffer[i] = in;
      in = Serial2.read();
      i ++;
      time = millis();
      
    }
    
    if(flag){
      
      //add signature and end character to message;
      buffer[21] = 'A';
      buffer[22] = '*';
      
      //set global variable Sbuffer equal to local variable buffer;
      for(int i = 0; i < 23; i ++){
        
        Sbuffer[i] = buffer[i];
        
      }
      
      //output global data;
      Serial2.print(Sbuffer);
      
    }if(!flag){
      
      Serial2.println("Serial2 data corrupt.");
      Serial2.flush();
      
    }
    
    time = millis();
    
}

void arm(){

    char prompt1[] = "Waiting...";
    char prompt2[] = "Ready.";

    Serial2.println(top);
    setAll(top);
    Serial2.println(prompt1);
    delay(3000);

    Serial2.println();
    Serial2.println(bottom);
    setAll(bottom);
    Serial2.println(prompt1);
    delay(3500);

    Serial2.println();
    Serial2.println(mainThrottle);
    setAll(mainThrottle);
    Serial2.println(prompt2);

}

void setup(){

    Serial2.begin(9600);

    for(int i = 0; i < 4; i ++){
        speedController[i].attach(30 + i);
    }

}

void loop(){

    if(Serial2.available()){
        
        serial2In();
        
        set0(decodeThrottle(1));
        set1(decodeThrottle(6));
        set2(decodeThrottle(11));
        set3(decodeThrottle(16));
        
        setThrottles(throttle);
        
    }

}
/*
 * QuadCopterInterfaceView.java
 */

package quadcopterinterface;

import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;

import java.io.*;
import java.util.*;
import gnu.io.*;
import java.lang.reflect.Method;
import net.java.games.input.*;
import net.java.games.util.*;

class RunThreads implements Runnable{
    
    public ArrayList<Thread> Threads = new ArrayList<Thread>();
    public long time = System.currentTimeMillis();
    
    public RunThreads(){
        
        time = System.currentTimeMillis();
        
    }
    
    public void initializeThreads(){
        
        Threads.add(new Thread(new ThrottleUpdater()));
        Threads.add(new Thread(new Updater(QuadCopterInterfaceView.xAxisLabel, Joystick.X)));
        Threads.add(new Thread(new Updater(QuadCopterInterfaceView.yAxisLabel, Joystick.Y)));
        Threads.add(new Thread(new Updater(QuadCopterInterfaceView.zAxisLabel, Joystick.Z)));
        Threads.add(new Thread(new Updater(QuadCopterInterfaceView.throttleLabel, Joystick.Throttle)));
        Threads.add(new Thread(new SerialUpdater()));
        Threads.add(new Thread(new Poller()));
        
    }
    
    public void run(){
        
        boolean flag;
        
        while(true){
            
            if(System.currentTimeMillis() - time > 200){
                
                initializeThreads();
            
                for(Thread thread : Threads){
                    
                    thread.start();

                }
                
                Threads.clear();
                time = System.currentTimeMillis();

            }
            
        }
        
    }
    
}

class ThrottleUpdater implements Runnable{
    
    public int NORTH = 0;
    public int SOUTH = 1;
    public int EAST = 2;
    public int WEST = 3;
    
    public int x;
    public int y;
    public int z;
    public int throttle;
    public int slider;
    public int bottom = 1000;
    
    public int throttleCoefficient = 700; //700 is throttleCoefficient
    public int xCoefficient = 250;
    public int yCoefficient = 250;
    public int zCoefficient = 250;
    
    public long time = System.currentTimeMillis();
    public float[] data = new float[5];
    
    public int[] throttles = new int[4];
    
    public void setThrottles(){
        
                         //(     in essence, throttle    )
        throttles[NORTH] = bottom + throttle + y + z;
        throttles[SOUTH] = bottom + throttle - y + z;
        throttles[EAST] = bottom + throttle - x - z;
        throttles[WEST] = bottom + throttle + x - z;
        
    }
    
    public void setGlobals(){
        
        for(int i = 0; i < 4; i ++){
            QuadCopterInterfaceView.throttle[i] = throttles[i];
        }
        
    }
    
    public void getData(){
        
        x = (int)(Joystick.X.getPollData() * QuadCopterInterfaceView.xScale);
        y = (int)(Joystick.Y.getPollData() * QuadCopterInterfaceView.yScale);
        z = (int)(Joystick.Z.getPollData() * QuadCopterInterfaceView.zScale);
        
        throttle = (int)((((-1) * Joystick.Throttle.getPollData() + 1)/2) * throttleCoefficient);
        
        slider = (int)((Joystick.Slider.getPollData() + 1)/2);
        
    }
    
    public void run(){
                
        getData();
        setThrottles();
        setGlobals();

        time = System.currentTimeMillis();
        
    }
    
}

class Poller implements Runnable{
    
    public long time = System.currentTimeMillis();
    
    public void run(){

        try{
            Joystick.joystick.poll();
        }catch(Exception e){
            QuadCopterInterfaceView.update(QuadCopterInterfaceView.serialDisplay, "FAILED TO POLL JOYSTICK.\n" + e.toString());
        }

    }
    
}

class SerialUpdater implements Runnable{

    public long time = System.currentTimeMillis();
    
    public void run(){
                
        QuadCopterInterfaceView.out(String.format("$%4s.%4s.%4s.%4s.J*", 
                                    String.valueOf(QuadCopterInterfaceView.throttle[0]),
                                    String.valueOf(QuadCopterInterfaceView.throttle[1]),
                                    String.valueOf(QuadCopterInterfaceView.throttle[2]),
                                    String.valueOf(QuadCopterInterfaceView.throttle[3])));

        time = System.currentTimeMillis();

    }
    
}

//class to update the text areas on the JFrame.;
class Updater implements Runnable{
    
    public javax.swing.JLabel label;
    public Component component;
    
    public long time = System.currentTimeMillis();
    
    public Updater(javax.swing.JLabel tLabel, Component tComponent){
        
        label = tLabel;
        component = tComponent;
        
    }
    
    public void run(){

                
        QuadCopterInterfaceView.update(label, String.valueOf(component.getPollData()));

        time = System.currentTimeMillis();
        
    }
    
}

class Joystick{
    
    public static Controller joystick;
    public static Component X;
    public static Component Y;
    public static Component Z;
    public static Component Throttle;
    public static Component Slider;
    public static Component buttons[];
    
    public void initialize() throws Exception{
        
        //find Saitek X52 in DefaultControllerEnvironment;
        for(Controller c : ControllerEnvironment.getDefaultEnvironment().getControllers()){
            if(c.getName().equals("Saitek X52 Flight Control System")){
                joystick = c;
                break;
            }
        }
        
        //find the joystick main components;
        for(Component c : joystick.getComponents()){
            if(c.getIdentifier().equals(Component.Identifier.Axis.X)){
                X = c; //x axis (Roll);
            }else if(c.getIdentifier().equals(Component.Identifier.Axis.Y)){
                Y = c; //y axis (Pitch);
            }else if(c.getIdentifier().equals(Component.Identifier.Axis.RZ)){
                Z = c; //z axis (Yaw);
            }else if(c.getIdentifier().equals(Component.Identifier.Axis.Z)){
                Throttle = c; //throttle (RZ axis);
            }else if(c.getIdentifier().equals(Component.Identifier.Axis.SLIDER)){
                Slider = c;
            }
        }
        
        buttons = joystick.getComponents();
        
    }
}

class QuadCopterInterfaceView extends FrameView implements SerialPortEventListener{
    
    //global variable declaration for use with Updater classes.;
    
    public static int xScale = 100;
    public static int yScale = 100;
    public static int zScale = 100;
    
    public static ArrayList<Boolean> UpdaterArrayList = new ArrayList<Boolean>();
    public static int UpdaterArrayListIndex = 0;
    Thread runThreads;
    
    public String raw;
    public static int[] throttle = {1000, 1000, 1000, 1000};
    
    public Joystick joystick;
    
    public QuadCopterInterfaceView(SingleFrameApplication app) {
        
        super(app);
        
        initComponents();
        
        xCoefficient.setText("100");
        yCoefficient.setText("100");
        zCoefficient.setText("100");
        
        try{
            initialize();
        }catch(Exception e){
            serialDisplay.append("Failed to Initialize radio communication link.\n");
            serialDisplay.append(e.toString() + "\n");
        }
        
        //start components, check and prompt for failure.;
        try{
            joystick = new Joystick();
            joystick.initialize();
            
            joystickLabel.setText(Joystick.joystick.getName());
            try{
                Joystick.joystick.poll();
            }catch(Exception e ){
                System.out.println(e.toString());
            }
            
        }catch(Exception e){
            System.out.println("Joystick failed to initialize.");
            System.out.println(e.toString());
        }
        
        runThreads = new Thread(new RunThreads());
        runThreads.start();

        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
    }
    
    public Thread[] initializeThreads(){
        
        ArrayList<Thread> threads = new ArrayList<Thread>();
        Thread[] Threads = new Thread[threads.size()];
        
        threads.add(new Thread(new ThrottleUpdater()));
        threads.add(new Thread(new Updater(xAxisLabel, Joystick.X)));
        threads.add(new Thread(new Updater(yAxisLabel, Joystick.Y)));
        threads.add(new Thread(new Updater(zAxisLabel, Joystick.Z)));
        threads.add(new Thread(new Updater(throttleLabel, Joystick.Throttle)));
        threads.add(new Thread(new SerialUpdater()));
        threads.add(new Thread(new Poller()));
        
        for(int i = 0; i < threads.size(); i ++){
            
            Threads[i] = threads.get(i);
            
        }
        
        return Threads;
        
    }
    
    public static void update(javax.swing.JTextArea area, String data){
        area.append(data + "\n");
        area.setCaretPosition(area.getDocument().getLength());
    }
    
    public static void update(javax.swing.JLabel label, String data){
        label.setText(data);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        mainPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        joystickLabel = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jScrollPane5 = new javax.swing.JScrollPane();
        jTextArea5 = new javax.swing.JTextArea();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        portLabel = new javax.swing.JLabel();
        jScrollPane6 = new javax.swing.JScrollPane();
        serialDisplay = new javax.swing.JTextArea();
        jLabel2 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        northData = new javax.swing.JLabel();
        southData = new javax.swing.JLabel();
        eastData = new javax.swing.JLabel();
        westData = new javax.swing.JLabel();
        xAxisLabel = new javax.swing.JLabel();
        yAxisLabel = new javax.swing.JLabel();
        zAxisLabel = new javax.swing.JLabel();
        throttleLabel = new javax.swing.JLabel();
        xCoefficient = new javax.swing.JTextField();
        yCoefficient = new javax.swing.JTextField();
        zCoefficient = new javax.swing.JTextField();
        coefficientsUpdateButton = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(quadcopterinterface.QuadCopterInterfaceApp.class).getContext().getResourceMap(QuadCopterInterfaceView.class);
        jLabel1.setFont(resourceMap.getFont("jLabel1.font")); // NOI18N
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        joystickLabel.setFont(resourceMap.getFont("joystickLabel.font")); // NOI18N
        joystickLabel.setText(resourceMap.getString("joystickLabel.text")); // NOI18N
        joystickLabel.setName("joystickLabel"); // NOI18N

        jLabel3.setFont(resourceMap.getFont("jLabel3.font")); // NOI18N
        jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N

        jLabel4.setFont(resourceMap.getFont("jLabel4.font")); // NOI18N
        jLabel4.setText(resourceMap.getString("jLabel4.text")); // NOI18N
        jLabel4.setName("jLabel4"); // NOI18N

        jLabel5.setFont(resourceMap.getFont("jLabel5.font")); // NOI18N
        jLabel5.setText(resourceMap.getString("jLabel5.text")); // NOI18N
        jLabel5.setName("jLabel5"); // NOI18N

        jLabel6.setFont(resourceMap.getFont("jLabel6.font")); // NOI18N
        jLabel6.setText(resourceMap.getString("jLabel6.text")); // NOI18N
        jLabel6.setName("jLabel6"); // NOI18N

        jScrollPane5.setName("jScrollPane5"); // NOI18N

        jTextArea5.setColumns(20);
        jTextArea5.setRows(5);
        jTextArea5.setName("jTextArea5"); // NOI18N
        jScrollPane5.setViewportView(jTextArea5);

        jLabel7.setFont(resourceMap.getFont("jLabel7.font")); // NOI18N
        jLabel7.setText(resourceMap.getString("jLabel7.text")); // NOI18N
        jLabel7.setName("jLabel7"); // NOI18N

        jLabel8.setFont(resourceMap.getFont("jLabel8.font")); // NOI18N
        jLabel8.setText(resourceMap.getString("jLabel8.text")); // NOI18N
        jLabel8.setName("jLabel8"); // NOI18N

        portLabel.setFont(resourceMap.getFont("portLabel.font")); // NOI18N
        portLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        portLabel.setText(resourceMap.getString("portLabel.text")); // NOI18N
        portLabel.setName("portLabel"); // NOI18N

        jScrollPane6.setName("jScrollPane6"); // NOI18N

        serialDisplay.setColumns(20);
        serialDisplay.setEditable(false);
        serialDisplay.setRows(5);
        serialDisplay.setName("serialDisplay"); // NOI18N

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, serialDisplay, org.jdesktop.beansbinding.ELProperty.create("${text}"), serialDisplay, org.jdesktop.beansbinding.BeanProperty.create("autoscrolls"));
        bindingGroup.addBinding(binding);

        jScrollPane6.setViewportView(serialDisplay);

        jLabel2.setFont(resourceMap.getFont("jLabel2.font")); // NOI18N
        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N

        jLabel9.setText(resourceMap.getString("jLabel9.text")); // NOI18N
        jLabel9.setName("jLabel9"); // NOI18N

        jLabel10.setText(resourceMap.getString("jLabel10.text")); // NOI18N
        jLabel10.setName("jLabel10"); // NOI18N

        jLabel11.setText(resourceMap.getString("jLabel11.text")); // NOI18N
        jLabel11.setName("jLabel11"); // NOI18N

        jLabel12.setText(resourceMap.getString("jLabel12.text")); // NOI18N
        jLabel12.setName("jLabel12"); // NOI18N

        northData.setText(resourceMap.getString("northData.text")); // NOI18N
        northData.setName("northData"); // NOI18N

        southData.setText(resourceMap.getString("southData.text")); // NOI18N
        southData.setName("southData"); // NOI18N

        eastData.setText(resourceMap.getString("eastData.text")); // NOI18N
        eastData.setName("eastData"); // NOI18N

        westData.setText(resourceMap.getString("westData.text")); // NOI18N
westData.setName("westData"); // NOI18N

        xAxisLabel.setText(resourceMap.getString("xAxisLabel.text")); // NOI18N
        xAxisLabel.setName("xAxisLabel"); // NOI18N

        yAxisLabel.setText(resourceMap.getString("yAxisLabel.text")); // NOI18N
        yAxisLabel.setName("yAxisLabel"); // NOI18N

        zAxisLabel.setText(resourceMap.getString("zAxisLabel.text")); // NOI18N
        zAxisLabel.setName("zAxisLabel"); // NOI18N

        throttleLabel.setText(resourceMap.getString("throttleLabel.text")); // NOI18N
        throttleLabel.setName("throttleLabel"); // NOI18N

        xCoefficient.setText(resourceMap.getString("xCoefficient.text")); // NOI18N
        xCoefficient.setName("xCoefficient"); // NOI18N

        yCoefficient.setText(resourceMap.getString("yCoefficient.text")); // NOI18N
        yCoefficient.setName("yCoefficient"); // NOI18N

        zCoefficient.setText(resourceMap.getString("zCoefficient.text")); // NOI18N
        zCoefficient.setName("zCoefficient"); // NOI18N

        coefficientsUpdateButton.setText(resourceMap.getString("coefficientsUpdateButton.text")); // NOI18N
        coefficientsUpdateButton.setName("coefficientsUpdateButton"); // NOI18N
        coefficientsUpdateButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                coefficientsUpdateButtonMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(mainPanelLayout.createSequentialGroup()
                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(mainPanelLayout.createSequentialGroup()
                                            .addContainerGap()
                                            .addComponent(jLabel1))
                                        .addGroup(mainPanelLayout.createSequentialGroup()
                                            .addContainerGap()
                                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                                .addGroup(mainPanelLayout.createSequentialGroup()
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jLabel3)
                                                        .addComponent(xAxisLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 137, javax.swing.GroupLayout.PREFERRED_SIZE))
                                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addGroup(mainPanelLayout.createSequentialGroup()
                                                            .addComponent(jLabel4)
                                                            .addGap(95, 95, 95)
                                                            .addComponent(jLabel5))
                                                        .addGroup(mainPanelLayout.createSequentialGroup()
                                                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                                .addComponent(yAxisLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 136, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                .addComponent(yCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE))
                                                            .addGap(14, 14, 14)
                                                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                                .addComponent(zCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                .addComponent(zAxisLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 167, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                                                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                                                    .addGap(15, 15, 15)
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jLabel10)
                                                        .addComponent(southData))
                                                    .addGap(48, 48, 48)
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jLabel11)
                                                        .addComponent(eastData))
                                                    .addGap(57, 57, 57)
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(westData)
                                                        .addComponent(jLabel12)))
                                                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jLabel7)
                                                        .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 339, javax.swing.GroupLayout.PREFERRED_SIZE))
                                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 37, Short.MAX_VALUE)
                                                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(throttleLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 62, Short.MAX_VALUE)
                                                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                                                            .addComponent(jLabel6)
                                                            .addGap(28, 28, 28))))))
                                        .addGroup(mainPanelLayout.createSequentialGroup()
                                            .addContainerGap()
                                            .addComponent(xCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 65, Short.MAX_VALUE))
                                .addGroup(mainPanelLayout.createSequentialGroup()
                                    .addGap(108, 108, 108)
                                    .addComponent(joystickLabel)))
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addGap(127, 127, 127)
                                .addComponent(coefficientsUpdateButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addGap(51, 51, 51)
                                .addComponent(jScrollPane6, javax.swing.GroupLayout.PREFERRED_SIZE, 369, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addGap(165, 165, 165)
                                .addComponent(jLabel8))
                            .addGroup(mainPanelLayout.createSequentialGroup()
                                .addGap(221, 221, 221)
                                .addComponent(portLabel))))
.addComponent(portLabel))))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel9))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGap(127, 127, 127)
                        .addComponent(jLabel2))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(northData)))
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(jLabel8)
                        .addGap(1, 1, 1)
                        .addComponent(portLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(joystickLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(jLabel5)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(xAxisLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(yAxisLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE)
                            .addComponent(zAxisLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(xCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(zCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(yCoefficient, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(coefficientsUpdateButton)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 303, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2))
                    .addComponent(throttleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(jLabel12)
                    .addComponent(jLabel11)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(northData)
                    .addComponent(eastData)
                    .addComponent(westData)
                    .addComponent(southData))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(quadcopterinterface.QuadCopterInterfaceApp.class).getContext().getActionMap(QuadCopterInterfaceView.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 975, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 800, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);

        bindingGroup.bind();
    }// </editor-fold>                        

    private void coefficientsUpdateButtonMouseClicked(java.awt.event.MouseEvent evt) {                                                      
        ThrottleUpdater throt = new ThrottleUpdater();
        xScale = Integer.valueOf(xCoefficient.getText());
        yScale = Integer.valueOf(yCoefficient.getText());
        zScale = Integer.valueOf(zCoefficient.getText());
    }                                                     

    // Variables declaration - do not modify                     
    private javax.swing.JButton coefficientsUpdateButton;
    private javax.swing.JLabel eastData;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JScrollPane jScrollPane6;
    private javax.swing.JTextArea jTextArea5;
    private javax.swing.JLabel joystickLabel;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JLabel northData;
    private javax.swing.JLabel portLabel;
    private javax.swing.JProgressBar progressBar;
    public static javax.swing.JTextArea serialDisplay;
    private javax.swing.JLabel southData;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    public static javax.swing.JLabel throttleLabel;
    private javax.swing.JLabel westData;
    public static javax.swing.JLabel xAxisLabel;
    public static javax.swing.JTextField xCoefficient;
    public static javax.swing.JLabel yAxisLabel;
    public static javax.swing.JTextField yCoefficient;
    public static javax.swing.JLabel zAxisLabel;
    public static javax.swing.JTextField zCoefficient;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration                   
    
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;

    private JDialog aboutBox;
    
    public String retrieveSerial;
    
    SerialPort serialPort;
    /** The port we're normally going to use. */
    private static final String PORT_NAMES[] = { 
                    "/dev/tty.usbserial-A9007UX1", // Mac OS X
                    "/dev/ttyUSB0", // Linux
                    "COM15", // Windows
                    };
    /** Buffered input stream from the port */
    private InputStream input;
    /** The output stream to the port */
    private static OutputStream output;
    /** Milliseconds to block while waiting for port open */
    private static final int TIME_OUT = 2000;
    /** Default bits per second for COM port. */
    private static final int DATA_RATE = 9600;
    
    public void updateThrottles(String data){
        
        raw = data;
        
        data = data.substring(1, data.length() - 2);
        
        String[] rep = data.split(".");
        for(int i = 0; i < 4; i ++){
            throttle[i] = Integer.valueOf(rep[i]);
        }
        
    }
    
    public void initialize() throws Exception {
        
            CommPortIdentifier portId = null;
            Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

            // iterate through, looking for the port
            while (portEnum.hasMoreElements()) {
                    CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
                    for (String portName : PORT_NAMES) {
                            if (currPortId.getName().equals(portName)) {
                                    portId = currPortId;
                                    break;
                            }
                    }
            }

            if (portId == null) {
                    System.out.println("Could not find COM port.");
                    return;
            }

            try {
                    // open serial port, and use class name for the appName.
                    serialPort = (SerialPort) portId.open(this.getClass().getName(),
                                    TIME_OUT);

                    // set port parameters
                    serialPort.setSerialPortParams(DATA_RATE,
                                    SerialPort.DATABITS_8,
                                    SerialPort.STOPBITS_1,
                                    SerialPort.PARITY_NONE);

                    // open the streams
                    input = serialPort.getInputStream();
                    output = serialPort.getOutputStream();

                    // add event listeners
                    serialPort.addEventListener(this);
                    serialPort.notifyOnDataAvailable(true);
            } catch (Exception e) {
                    System.err.println(e.toString());
            }
    }

    /**
     * This should be called when you stop using the port.
     * This will prevent port locking on platforms like Linux.
     */
    public synchronized void close() {
            if (serialPort != null) {
                    serialPort.removeEventListener();
                    serialPort.close();
            }
    }

    
    /**
     * Handle an event on the serial port. Read the data and print it.
     * ***Receives data until a '*' character is received***
     */
public synchronized void serialEvent(SerialPortEvent oEvent) {
    
    String buffer = "";
    long time = System.currentTimeMillis();
            if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                  try {   
                                
                            while(System.currentTimeMillis() - time < 100){
                                
                            }
                            
                        int available = input.available();
                        byte chunk[] = new byte[available];
                        input.read(chunk, 0, available);

                                buffer = new String(chunk);
                                
                                if(buffer.charAt(buffer.length() - 1) == '*'){
                                    update(serialDisplay, buffer + '\n');
                                }else{
                                    update(serialDisplay, "Error: " + buffer);
                                }
                                
                  } catch (Exception e) {
                        System.err.println(e.toString() + " Error here.");
                  }
            }
                retrieveSerial = buffer;
      }

    public static synchronized void out(String data){
        
        data = data.replaceAll(" ", "0");
        update(serialDisplay, data);
        
        try{
            output.write(data.getBytes());
            
        }catch(Exception e){
            System.out.println("Output to port failed. (public synchronized void out(String data)");
            System.out.println(e.toString());
        }

    }
    
}

I guess the Java program is a little long...
Anyway, PLEASE HELP ME!
I have no idea what to do from here.

Set the baud rate up to the maximum (115200), avoid using division to parse a decimal number (there is no hardware divide in a 328...), see if that helps?