From 9e0bda088c097ac6bcc677d7b6d00683e73a68fb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 3 Feb 2014 00:24:38 -0800 Subject: micropeak: Watch serial data during download This adds a text area to monitor the incoming serial data in case some problem occurs. Signed-off-by: Keith Packard --- micropeak/Makefile.am | 1 + micropeak/MicroDownload.java | 96 ++++++++++++++++++++++++++++++++----------- micropeak/MicroSerial.java | 8 ++++ micropeak/MicroSerialLog.java | 28 +++++++++++++ 4 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 micropeak/MicroSerialLog.java (limited to 'micropeak') diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am index 33b1420a..1a614cbd 100644 --- a/micropeak/Makefile.am +++ b/micropeak/Makefile.am @@ -23,6 +23,7 @@ micropeak_JAVA= \ MicroRaw.java \ MicroSave.java \ MicroSerial.java \ + MicroSerialLog.java \ MicroStats.java \ MicroStatsTable.java \ MicroFileChooser.java \ diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java index ec76824d..cd109b79 100644 --- a/micropeak/MicroDownload.java +++ b/micropeak/MicroDownload.java @@ -26,17 +26,21 @@ import java.util.*; import org.altusmetrum.altoslib_3.*; import org.altusmetrum.altosuilib_1.*; -public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener { +public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog { MicroPeak owner; Container pane; AltosDevice device; JButton cancel; MicroData data; MicroSerial serial; + LinkedList log_queue = new LinkedList(); + Runnable log_run; + JTextArea serial_log; + JLabel status_value; private void done_internal() { - setVisible(false); if (data != null) { + status_value.setText("Received MicroPeak Data"); if (data.crc_valid) { owner = owner.SetData(data); MicroSave save = new MicroSave(owner, data); @@ -48,8 +52,43 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList "Download Failed", JOptionPane.ERROR_MESSAGE); } + setVisible(false); + dispose(); + } else { + status_value.setText("Download Failed"); + } + } + + public void drain_queue() { + for (;;) { + int c; + synchronized(this) { + if (log_queue.isEmpty()) { + log_run = null; + break; + } + c = log_queue.remove(); + } + if (c == '\r') + continue; + byte[] bytes = new byte[1]; + bytes[0] = (byte) c; + serial_log.append(new String(bytes, AltosLib.unicode_set)); + } + } + + public void log_char(int c) { + synchronized(this) { + log_queue.add(c); + if (log_run == null) { + log_run = new Runnable() { + public void run() { + drain_queue(); + } + }; + SwingUtilities.invokeLater(log_run); + } } - dispose(); } public void done() { @@ -80,6 +119,7 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList public void start() { try { serial = new MicroSerial(device); + serial.set_log(this); } catch (FileNotFoundException fe) { return; } @@ -120,7 +160,7 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList c = new GridBagConstraints(); c.gridx = 1; c.gridy = y; - c.fill = GridBagConstraints.HORIZONTAL; + c.fill = GridBagConstraints.NONE; c.weightx = 1; c.anchor = GridBagConstraints.LINE_START; c.insets = ir; @@ -135,39 +175,49 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList c.weightx = 1; c.anchor = GridBagConstraints.LINE_START; c.insets = ir; - JTextArea help_text = new JTextArea( - - "Locate the photo transistor on the MicroPeak USB adapter\n" + - "and place the LED on the MicroPeak directly in contact\n" + - "with it.\n" + - "\n" + - "The MicroPeak LED and the MicroPeak USB adapter\n" + - "photo need to be touching—even a millimeters of space\n" + - "between them will reduce the light intensity from the LED\n" + - "enough that the phototransistor will not sense it.\n" + - "\n" + - "Turn on the MicroPeak board and adjust the position until\n" + - "the blue LED on the MicroPeak USB adapter blinks in time\n" + - "with the orange LED on the MicroPeak board."); + JLabel help_text = new JLabel( + "Turn on the MicroPeak and place the LED inside the
" + + "opening in the top of the MicroPeak USB adapter.
" + + "Verify that the blue LED in the side of the USB adapter
" + + "is blinking along with the orange LED on the MicroPeak.
"); +// help_text.setEditable(false); pane.add(help_text, c); y++; c = new GridBagConstraints(); c.gridx = 0; c.gridy = y; - c.gridwidth = 1; + c.gridwidth = 2; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1; c.anchor = GridBagConstraints.LINE_START; c.insets = ir; - JLabel waiting_value = new JLabel("Waiting for MicroPeak data..."); - pane.add(waiting_value, c); + status_value = new JLabel("Waiting for MicroPeak data..."); + pane.add(status_value, c); + y++; + + serial_log = new JTextArea(10, 20); + serial_log.setEditable(false); + + JScrollPane serial_scroll = new JScrollPane(serial_log); + serial_scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + + c = new GridBagConstraints(); + c.gridx = 0; c.gridy = y; + c.gridwidth = GridBagConstraints.REMAINDER; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.anchor = GridBagConstraints.LINE_START; + c.insets = ir; + + pane.add(serial_scroll, c); + y++; cancel = new JButton("Cancel"); c = new GridBagConstraints(); c.fill = GridBagConstraints.NONE; - c.anchor = GridBagConstraints.CENTER; - c.gridx = 1; c.gridy = y; + c.anchor = GridBagConstraints.EAST; + c.gridx = 0; c.gridy = y; c.gridwidth = GridBagConstraints.REMAINDER; Insets ic = new Insets(4,4,4,4); c.insets = ic; diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java index 376223f1..39f421ec 100644 --- a/micropeak/MicroSerial.java +++ b/micropeak/MicroSerial.java @@ -24,6 +24,7 @@ import org.altusmetrum.altosuilib_1.*; public class MicroSerial extends InputStream { SWIGTYPE_p_altos_file file; + private MicroSerialLog log; public int read() { int c = libaltos.altos_getchar(file, 0); @@ -33,6 +34,8 @@ public class MicroSerial extends InputStream { return -1; if (AltosUIPreferences.serial_debug) System.out.printf("%c", c); + if (log != null) + log.log_char(c); return c; } @@ -43,8 +46,13 @@ public class MicroSerial extends InputStream { } } + public void set_log(MicroSerialLog log) { + this.log = log; + } + public MicroSerial(AltosDevice device) throws FileNotFoundException { file = device.open(); + log = null; if (file == null) { final String message = device.getErrorString(); throw new FileNotFoundException(String.format("%s (%s)", diff --git a/micropeak/MicroSerialLog.java b/micropeak/MicroSerialLog.java new file mode 100644 index 00000000..0a5a0b91 --- /dev/null +++ b/micropeak/MicroSerialLog.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2014 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.util.*; +import java.io.*; +import libaltosJNI.*; +import org.altusmetrum.altosuilib_1.*; + +public interface MicroSerialLog { + + public void log_char(int c); +} -- cgit v1.2.3 From 8d0d59c51138dc1b1bbf6933354fe9faf4d67986 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 7 Feb 2014 22:32:17 -0800 Subject: micropeak: Keep reading until we get valid data Don't stop just because we saw something invalid on the serial line; let the user try again, or cancel when they get bored. However, if the serial line disappears or some other fatal error occurs, then do stop and put up an error dialog. Signed-off-by: Keith Packard --- micropeak/MicroData.java | 22 ++++------ micropeak/MicroDownload.java | 95 +++++++++++++++++++++++++++++++++----------- 2 files changed, 79 insertions(+), 38 deletions(-) (limited to 'micropeak') diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 04e9ad32..e786ff1e 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -100,13 +100,13 @@ public class MicroData implements AltosUIDataSet { String name; MicroStats stats; - class FileEndedException extends Exception { + public class FileEndedException extends Exception { } - class NonHexcharException extends Exception { + public class NonHexcharException extends Exception { } - class InvalidCrcException extends Exception { + public class InvalidCrcException extends Exception { } private int getc(InputStream f) throws IOException, FileEndedException { @@ -167,14 +167,10 @@ public class MicroData implements AltosUIDataSet { return h; } - private boolean find_header(InputStream f) throws IOException { - try { - for (;;) { - if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P') - return true; - } - } catch (FileEndedException fe) { - return false; + private boolean find_header(InputStream f) throws IOException, FileEndedException { + for (;;) { + if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P') + return true; } } @@ -339,7 +335,7 @@ public class MicroData implements AltosUIDataSet { this.name = name; } - public MicroData (InputStream f, String name) throws IOException, InterruptedException { + public MicroData (InputStream f, String name) throws IOException, InterruptedException, NonHexcharException, FileEndedException { this.name = name; bytes = new ArrayList(); if (!find_header(f)) @@ -384,8 +380,6 @@ public class MicroData implements AltosUIDataSet { stats = new MicroStats(this); } catch (FileEndedException fe) { throw new IOException("File Ended Unexpectedly"); - } catch (NonHexcharException ne) { - throw new IOException("Non hexadecimal character found"); } } diff --git a/micropeak/MicroDownload.java b/micropeak/MicroDownload.java index cd109b79..7d2e9eb4 100644 --- a/micropeak/MicroDownload.java +++ b/micropeak/MicroDownload.java @@ -26,7 +26,7 @@ import java.util.*; import org.altusmetrum.altoslib_3.*; import org.altusmetrum.altosuilib_1.*; -public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog { +public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener { MicroPeak owner; Container pane; AltosDevice device; @@ -37,25 +37,46 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList Runnable log_run; JTextArea serial_log; JLabel status_value; + int log_column; + + public void windowActivated(WindowEvent e) { + } + + public void windowClosed(WindowEvent e) { + setVisible(false); + dispose(); + } + + public void windowClosing(WindowEvent e) { + } + + public void windowDeactivated(WindowEvent e) { + } + + public void windowDeiconified(WindowEvent e) { + } + + public void windowIconified(WindowEvent e) { + } + + public void windowOpened(WindowEvent e) { + } private void done_internal() { - if (data != null) { + setVisible(false); + dispose(); + + if (data != null && data.crc_valid) { status_value.setText("Received MicroPeak Data"); - if (data.crc_valid) { - owner = owner.SetData(data); - MicroSave save = new MicroSave(owner, data); - if (save.runDialog()) - owner.SetName(data.name); - } else { - JOptionPane.showMessageDialog(owner, - "Flight data corrupted", - "Download Failed", - JOptionPane.ERROR_MESSAGE); - } - setVisible(false); - dispose(); + owner = owner.SetData(data); + MicroSave save = new MicroSave(owner, data); + if (save.runDialog()) + owner.SetName(data.name); } else { - status_value.setText("Download Failed"); + JOptionPane.showMessageDialog(owner, + "Download Failed", + "Flight data corrupted", + JOptionPane.ERROR_MESSAGE); } } @@ -71,9 +92,26 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList } if (c == '\r') continue; - byte[] bytes = new byte[1]; - bytes[0] = (byte) c; - serial_log.append(new String(bytes, AltosLib.unicode_set)); + if (c == '\0') + continue; + String s; + if (c == '\n') { + s = "\n"; + log_column = 0; + } else if (' ' <= c && c <= '~') { + byte[] bytes = new byte[1]; + bytes[0] = (byte) c; + s = new String(bytes, AltosLib.unicode_set); + log_column += 1; + } else { + s = String.format("\\0x%02x", c & 0xff); + log_column += 5; + } + serial_log.append(s); + if (log_column > 40) { + serial_log.append("\n"); + log_column = 0; + } } } @@ -105,12 +143,20 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList public void run() { try { - data = new MicroData(serial, device.toShortString()); - serial.close(); + for (;;) { + try { + data = new MicroData(serial, device.toShortString()); + if (data != null && data.crc_valid) + break; + } catch (MicroData.NonHexcharException nhe) { + } + } } catch (FileNotFoundException fe) { } catch (IOException ioe) { } catch (InterruptedException ie) { + } catch (MicroData.FileEndedException fee) { } + serial.close(); done(); } @@ -172,12 +218,12 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList c.gridx = 0; c.gridy = y; c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; + c.weightx = 0; c.anchor = GridBagConstraints.LINE_START; c.insets = ir; JLabel help_text = new JLabel( "Turn on the MicroPeak and place the LED inside the
" + - "opening in the top of the MicroPeak USB adapter.
" + + "opening in the top of the MicroPeak USB adapter.
" + "Verify that the blue LED in the side of the USB adapter
" + "is blinking along with the orange LED on the MicroPeak.
"); // help_text.setEditable(false); @@ -205,8 +251,9 @@ public class MicroDownload extends AltosUIDialog implements Runnable, ActionList c = new GridBagConstraints(); c.gridx = 0; c.gridy = y; c.gridwidth = GridBagConstraints.REMAINDER; - c.fill = GridBagConstraints.HORIZONTAL; + c.fill = GridBagConstraints.BOTH; c.weightx = 1; + c.weighty = 1; c.anchor = GridBagConstraints.LINE_START; c.insets = ir; -- cgit v1.2.3 From 28d5239bff234cc1158a270a29c0e39067f613c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 7 Feb 2014 22:45:26 -0800 Subject: micropeak: Missing a couple of new exceptions when loading files The change to keep reading on invalid chars from the serial port exposed a couple of new exceptions from the MicroData code which the file loading code needs to cope with. Signed-off-by: Keith Packard --- micropeak/MicroPeak.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'micropeak') diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 2a8e2ca6..78bc857e 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -65,6 +65,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene try { data = new MicroData((InputStream) fis, filename.getName()); AltosUIPreferences.set_last_logdir(filename); + } catch (MicroData.NonHexcharException nhe) { + data = null; + } catch (MicroData.FileEndedException nhe) { + data = null; } catch (InterruptedException ie) { data = null; } finally { -- cgit v1.2.3