added a LED matrix display

This commit is contained in:
hneemann 2017-04-08 14:34:57 +02:00
parent c1e3cead2d
commit 8e4621c2e0
8 changed files with 254 additions and 0 deletions

View File

@ -9,6 +9,7 @@ planned as v0.10
- Added a real bidirectional switch and a relay.
- Added N and P channel FETs and some CMOS examples, including a 16 bit SRAM
- Added a rotary encoder
- Added a LED matrix display
- Improved and documented the file import strategy.
- Added a tree view to insert components.
- Added support for the ATF1502 and ATF1504 CPLDs.

View File

@ -308,4 +308,16 @@ public final class Keys {
public static final Key<String> PIN
= new Key<>("pin", "");
/**
* row bits in led matrix
*/
public static final Key.KeyBits ROW_DATA_BITS
= new Key.KeyBits("rowDataBits", 8);;
/**
* column address bits in led matrix
*/
public static final Key.KeyBits COL_ADDR_BITS
= new Key.KeyBits("colAddrBits", 3);;
}

View File

@ -0,0 +1,96 @@
package de.neemann.digital.core.io;
import de.neemann.digital.core.Node;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.gui.components.graphics.LedMatrixDialog;
import javax.swing.*;
import java.awt.*;
import static de.neemann.digital.core.element.PinInfo.input;
/**
* LED-Matrix
* Created by hneemann on 08.04.17.
*/
public class LedMatrix extends Node implements Element {
/**
* the LED-Matrix description
*/
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription(LedMatrix.class, input("r-data"), input("c-addr"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.ROW_DATA_BITS)
.addAttribute(Keys.COL_ADDR_BITS)
.addAttribute(Keys.COLOR)
.addAttribute(Keys.LED_PERSISTENCE);
private final int rowDataBits;
private final int colAddrBits;
private final int dx;
private final int dy;
private final long[] data;
private final Color color;
private final boolean ledPersist;
private ObservableValue rowDataVal;
private ObservableValue colAddrVal;
private LedMatrixDialog ledMatrixDialog;
/**
* create a new instance
*
* @param attr the attributes of the element
*/
public LedMatrix(ElementAttributes attr) {
rowDataBits = attr.get(Keys.ROW_DATA_BITS);
colAddrBits = attr.get(Keys.COL_ADDR_BITS);
color=attr.get(Keys.COLOR);
ledPersist = attr.get(Keys.LED_PERSISTENCE);
dx = 1 << colAddrBits;
dy = rowDataBits;
data = new long[dx];
}
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
rowDataVal = inputs.get(0).checkBits(rowDataBits, this).addObserverToValue(this);
colAddrVal = inputs.get(1).checkBits(colAddrBits, this).addObserverToValue(this);
}
@Override
public ObservableValues getOutputs() throws PinException {
return ObservableValues.EMPTY_LIST;
}
@Override
public void readInputs() throws NodeException {
long rowData = rowDataVal.getValue();
int colAddr = (int) colAddrVal.getValue();
if (colAddr < dx && data[colAddr] != rowData) {
data[colAddr] = rowData;
dataChanged(colAddr, rowData);
}
}
@Override
public void writeOutputs() throws NodeException {
}
private void dataChanged(int colAddr, long rowData) {
SwingUtilities.invokeLater(() -> {
if (ledMatrixDialog == null || !ledMatrixDialog.isVisible())
ledMatrixDialog = new LedMatrixDialog(dy, data, color, ledPersist);
ledMatrixDialog.updateGraphic(colAddr, rowData);
});
}
}

View File

@ -88,6 +88,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
node.add(Out.SEVENDESCRIPTION);
node.add(Out.SEVENHEXDESCRIPTION);
node.add(RotEncoder.DESCRIPTION);
node.add(LedMatrix.DESCRIPTION);
node.add(DummyElement.DATADESCRIPTION);
node.add(DummyElement.TEXTDESCRIPTION);
node.add(Keyboard.DESCRIPTION);

View File

@ -0,0 +1,80 @@
package de.neemann.digital.gui.components.graphics;
import javax.swing.*;
import java.awt.*;
/**
* Component to visualize a LED matrix
* Created by hneemann on 08.04.17.
*/
public class LedMatrixComponent extends JComponent {
private final int width;
private final int height;
private final long[] data;
private final Color color;
private final boolean ledPersist;
private int lastCol;
/**
* Create a new instance
*
* @param dy height of matrix
* @param data data
* @param color the LEDs color
* @param ledPersist if true the LEDs light up indefinite
*/
public LedMatrixComponent(int dy, long[] data, Color color, boolean ledPersist) {
this.width = data.length;
this.height = dy;
this.data = data;
this.color = color;
this.ledPersist = ledPersist;
int pw = 320 / width;
if (pw < 2) pw = 2;
int ph = 200 / height;
if (ph < 2) ph = 2;
int ledSize = (pw + ph) / 2;
Dimension size = new Dimension(width * ledSize, height * ledSize);
setPreferredSize(size);
setOpaque(false);
}
/**
* Update the graphic
*
* @param colAddr col update
* @param rowData updated data
*/
public void updateGraphic(int colAddr, long rowData) {
lastCol = colAddr;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
for (int x = 0; x < width; x++) {
int xPos = x * getWidth() / width;
int dx = (x + 1) * getWidth() / width - xPos;
long word = data[x];
long mask = 1;
for (int y = 0; y < height; y++) {
boolean ledState = (word & mask) != 0;
if (ledState && (ledPersist || (x == lastCol)))
g.setColor(color);
else
g.setColor(Color.BLACK);
int ypos = y * getHeight() / height;
int dy = (y + 1) * getHeight() / height - ypos;
g.fillOval(xPos, ypos, dx, dy);
mask *= 2;
}
}
}
}

View File

@ -0,0 +1,46 @@
package de.neemann.digital.gui.components.graphics;
import de.neemann.digital.lang.Lang;
import javax.swing.*;
import java.awt.*;
/**
* The LED matrix dialog
* Created by hneemann on 08.04.17.
*/
public class LedMatrixDialog extends JDialog {
private final LedMatrixComponent ledMatrixComponent;
/**
* Create a new instance
*
* @param dy height of matrix
* @param data data
* @param color the LEDs color
* @param ledPersist if true the LEDs light up indefinite
*/
public LedMatrixDialog(int dy, long[] data, Color color, boolean ledPersist) {
super((JFrame) null, Lang.get("elem_LedMatrix"), false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
ledMatrixComponent = new LedMatrixComponent(dy, data, color, ledPersist);
getContentPane().add(ledMatrixComponent);
pack();
setAlwaysOnTop(true);
setLocationRelativeTo(null);
setVisible(true);
}
/**
* Update the graphic
*
* @param colAddr col update
* @param rowData updated data
*/
public void updateGraphic(int colAddr, long rowData) {
ledMatrixComponent.updateGraphic(colAddr, rowData);
}
}

View File

@ -376,6 +376,11 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.</string
<string name="elem_RotEncoder_tt">Drehknopf mit Drehencoder zur zustandsfreien Erfassung der Drehbewegung.</string>
<string name="elem_RotEncoder_pin_A">Encodersignal A</string>
<string name="elem_RotEncoder_pin_B">Encodersignal B</string>
<string name="elem_LedMatrix">LED-Matrix</string>
<string name="elem_LedMatrix_tt">Eine Matrix aus LEDs. Die LEDs werden in einem eigenen Fenster dargestellt.
Die LEDs können in der Simulation unendlich lange nachleuchten, um ein Flimmern der Anzeige zu verhindern.</string>
<string name="elem_LedMatrix_pin_r-data">Der Zeilen-Zustand der LEDs einer Spalte. Jedes Bit in diesem Datenwort repräsentiert den Zustand einer Zeile der aktuellen Spalte.</string>
<string name="elem_LedMatrix_pin_c-addr">Die Nummer der aktuellen Spalte, dessen Zustand gerade am anderen Eingang anliegt.</string>
<string name="error">Fehler</string>
<string name="err_DFlipflopWithoutALabel">Flipflop hat keine Bezeichnung!</string>
@ -560,6 +565,10 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_atf1502Fitter_tt">Pfad zum Fitter für den ATF1502. Geben Sie hier den vollen Pfad zur Datei fit1502.exe an. Diese Datei wird von ATMEL zu Verfügung gestellt.</string>
<string name="key_pin">Pinnummer</string>
<string name="key_pin_tt">Ist das Feld leer bedeutet das, dass dieses Signal keinem Pin zugewiesen ist.</string>
<string name="key_rowDataBits">Zeilen</string>
<string name="key_rowDataBits_tt">Gibt direkt die Zahl der Zeilen an, indem die Anzahl der Bits des Zeilenwortes festgegelgt wird.</string>
<string name="key_colAddrBits">Adressbits der Spalten</string>
<string name="key_colAddrBits_tt">Adressiert die einzelnen Spalten. Drei Bits bedeuten also acht Spalten.</string>
<string name="lib_Logic">Logisch</string>
<string name="lib_arithmetic">Arithmetik</string>

View File

@ -363,6 +363,11 @@
<string name="elem_RotEncoder_tt">Rotary knob with rotary encoder for stateless detecting rotational movements.</string>
<string name="elem_RotEncoder_pin_A">encoder signal A</string>
<string name="elem_RotEncoder_pin_B">encoder signal B</string>
<string name="elem_LedMatrix">LED-Matrix</string>
<string name="elem_LedMatrix_tt">A matrix of LEDs. The LEDs are shown in a separate window.
The LEDs are able to light up indefinitely in the simulation to prevent the display from flickering.</string>
<string name="elem_LedMatrix_pin_r-data">The row state of the LEDs of a column. Each bit in this data word represents the state of a row of the current column.</string>
<string name="elem_LedMatrix_pin_c-addr">The number of the current column whose state is currently visible at the other input.</string>
<string name="error">Error</string>
<string name="err_DFlipflopWithoutALabel">D-flip-flop has no label set</string>
@ -547,6 +552,10 @@ The names of the variables may not be unique.</string>
<string name="key_atf1502Fitter_tt">Path to the fitter for the ATF1502. Enter the full path to the file fit1502.exe provided bei ATMEL.</string>
<string name="key_pin">Pin number</string>
<string name="key_pin_tt">An empty field means this signal is not assigned to a pin.</string>
<string name="key_rowDataBits">Rows</string>
<string name="key_rowDataBits_tt">Specifies the number of rows by specifying the number of bits of the row word.</string>
<string name="key_colAddrBits">Address bits of columns</string>
<string name="key_colAddrBits_tt">Addresses the individual columns. Three bits means eight columns.</string>
<string name="lib_Logic">Logic</string>
<string name="lib_arithmetic">Arithmetic</string>