Selbständig ActionEvent auslösen zum Daten senden über serielle Schnittstelle

Quax

Mitglied
Hallo ich arbeite an einem ständigen Datenaustausch zwischen Java und Arduino UNO R3. Als Schnittstellenbibliothek verwende ich die JSSC. Es soll also z.B. mit dem Arduino ein Poti oder ein LDR (Light dependet resistor) ausgelesen werden. Der Wert wird dann an ein Java-Programm auf dem PC geschickt, dort wird entschieden welche LED am Arduino leuchten soll. Das Ganze nicht nur einmal sondern ständig Arduino -> Java -> Arduino -> Java -> usw. hin und her…
Mir ist bewußt, dass solche Aufgaben der Arduino ganz einfach alleine bewältigen kann. Aber das ist nur das reduzierte Problem.
Ich habe ein Java Programm geschrieben (wie angefügt) bei dem diese Sache mittels eines Windows-Buttons schon funktioniert. Also der Sendevorgang an den Arduino durch einen MouseEvent ausgelöst wird. D.h. Java empfängt ständig Daten vom Arduino und wenn ich auf den Button drücke wird die Information „LL“ an den Arduino gesendet und dort ein LED geschaltet. Das klappt gut!

Jetzt verfolge ich die Idee, dass ein Event durch eine Bedingung ausgelöst wird. Also z.B. wenn der vom Arduino empfangene Wert eine bestimmten Betrag hat, soll Java selbständig die Information z.B. „L1“ an den Arduino gesendet werden. Anstatt des Buttons-Click sollte dies jetzt durch eine bestimmten Wert selbständig ausgelöst werden. Kann man also einen Listener/Event definieren der eine in der Funktion gleiche Aktion auslöst wie z.B. der MouseEvent?

Es müsst doch dann der serialEvent, welcher die Daten vom Arduino empfängt vorübergehend unterbrochen werden um Daten zu senden. Wahrscheinlich so lange bis der sendende Event (also von Java zum Arduino) wiederrum unterbrochen wird und der serialEvent wieder Daten empfangen kann. Soweit meine Vorstellung.

Leider hab ich noch keine Idee wie ich solch einen „selbstauslösenden“ Event implementieren, auslösen, behandeln, definieren usw. muss. Ich habe von der Listener- und Eventthematik sehr wenig Ahnung.

Kann mir da jemand bitte helfen?

Danke - Quax


Java:
// Programme entstanden in Anlehnung an einfache Beispielcodes
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

@SuppressWarnings("serial")
public class SD3_mod1 extends JFrame implements SerialPortEventListener,
                                               MouseListener {
   // Deklarationen
   private SerialPort sp = new SerialPort("COM3");
   private JButton button1;
   private JPanel mainPanel;
   private JPanel buttonsPanel;
   // Sammelen des ankommenden
   private String sammler = "";
   
// Konstruktur ---------------------------------------------------------
   public SD3_mod1(){
       // Öffnen und deklarieren des COM3-Ports
       try{
           sp.openPort();
           sp.setParams(19200, 8, 1, 0);
           sp.addEventListener(this);
       }catch(SerialPortException ex){
           System.out.println(ex);
       }
       // Definition eines Panels mit Button --------------------------
       mainPanel = new JPanel(new BorderLayout());
       buttonsPanel = new JPanel(new GridLayout(1,2,0,0));
       button1 = new JButton("LED A");
       
       buttonsPanel.add(button1);
       mainPanel.add(buttonsPanel, BorderLayout.PAGE_END);
       
       button1.addMouseListener(this);
       this.addMouseListener(this);
       this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
       this.setContentPane(mainPanel);
       this.pack();
       this.setVisible(true);
   }
// Einlesen und Verarbeiten des Datenstreams vom Arduino ------------------------
   @Override
   public void serialEvent(SerialPortEvent e) {
       try{
           byte[] buffer = sp.readBytes(10);
           InputStream sBAIS = new ByteArrayInputStream(buffer);
           BufferedReader serRed = new BufferedReader(new InputStreamReader(sBAIS));
           try {
               String line = serRed.readLine();
               if(line.indexOf("S")>-1 && line.indexOf("E")>line.indexOf("S")){
                   line=line.substring(1, line.indexOf("E"));
                   System.out.println("Ausgabe: " + line);
                   parsing(line);
               }
           } catch (IOException e1) {
               e1.printStackTrace();
           }
       }catch(SerialPortException ex){
           System.out.println(ex);
       }
   }
// ------------------------------------------------------------------
   @Override public void mouseClicked(MouseEvent e){}
   @Override public void mouseEntered(MouseEvent e){}
   @Override public void mouseExited(MouseEvent e){}
   @Override public void mousePressed(MouseEvent e){}
   @Override public void mouseReleased(MouseEvent e){
// MouseEvent mit Aktion belegen -> Daten an Arduino senden ---------
// Hier sollte dann die automatische Auswertung des vom Arduino -----
// gesendeten Wertes stattfinden und automatisch gesendet werden ----
       if(e.getComponent()==button1){
           try {
               sp.writeBytes("LL".getBytes());
               System.out.println("Maus released");
           } catch (SerialPortException e1) {
               e1.printStackTrace();
           }
       }
   }
   
   private void parsing(String line){
       System.out.println("Annahme: " + line);
   }
   
   public static void main(String[] args) {
       new SD3_mod1();

   }
}
 

mrBrown

Super-Moderator
Mitarbeiter
Du solltest dich mal mit Mustern wie zB MVC auseinandersetzen, damit würde es vermutlich etwas leichter überblickbar für dich werden.
 

Manuel.R

Bekanntes Mitglied
Ich muss mal dumm fragen:
Wie sind der MikroController und der PC (Java-Programm) verbunden, RS232?

Der UNO kann doch auch bestimmte andere Kommunikationsformen oder muss es seriell sein?

Ich würde an dieser Stelle das Client-Server-Prinzip empfehlen.
 

Quax

Mitglied
Erstmal Danke für Eure Antworten.
@ mrBrown: sind das Model View Controller? Aber wie bringt mich das denn weiter?
@ Manuel: Der UNO ist via USB mit dem PC verbunden.
Ich denke mir es muss doch möglich sein, einen ActionEvent, wie er eben auch von einem MouseListener ausgelöst wird eben durch eine beliebige Bedingung auszulösen. Z.B. Variable hat bestimmten Wert. Ich habe so etwas auch schon gelesen schaffe es aber noch nicht dies entsprechend zu implementierten.
Hier ist ein Link der diese Thema behandelt:
www.tutorials.de/threads/eigener-java-listener-zum-aktualisieren-von-werten-in-einer-gui.354564/
der dieses Thema behandelt.
Aber wie verheirate ich das eben mit meiner Geschichte? Das gelingt mir im MOment nicht.
Vielleicht weiß von Euch da jemand weiter bitte.
Danke Quax
 

mrBrown

Super-Moderator
Mitarbeiter
@ mrBrown: sind das Model View Controller? Aber wie bringt mich das denn weiter?
Ja.
Du hast dann View und Logik getrennt, was dich dem Verständnis vllt einen Schritt weiter bringt ;)

Ich denke mir es muss doch möglich sein, einen ActionEvent, wie er eben auch von einem MouseListener ausgelöst wird eben durch eine beliebige Bedingung auszulösen. Z.B. Variable hat bestimmten Wert. Ich habe so etwas auch schon gelesen schaffe es aber noch nicht dies entsprechend zu implementierten.
Naja, du musst die Methode einfach selbst aufrufen, wenn die Bedingung stimmt...irgendwelche Magie steckt da nicht hinter
 

Manuel.R

Bekanntes Mitglied
Ja.
Du hast dann View und Logik getrennt, was dich dem Verständnis vllt einen Schritt weiter bringt ;)


Naja, du musst die Methode einfach selbst aufrufen, wenn die Bedingung stimmt...irgendwelche Magie steckt da nicht hinter

war das verständlich?
Ich bin mir nicht sicher ob man das unbedingt Event nennen muss. Aber was du bereits kannst, ist das lesen der Daten vom UNO. Sollten die Daten eine bestimte Bedingung erfüllen, ruftst du eine bestimmte Methode auf
Code:
// Einlesen und Verarbeiten des Datenstreams vom Arduino ------------------------
   @Override
   public void serialEvent(SerialPortEvent e) {
       try{
           byte[] buffer = sp.readBytes(10);
           InputStream sBAIS = new ByteArrayInputStream(buffer);
           BufferedReader serRed = new BufferedReader(new InputStreamReader(sBAIS));
           try {
               String line = serRed.readLine();
               if(line.indexOf("S")>-1 && line.indexOf("E")>line.indexOf("S")){
                   line=line.substring(1, line.indexOf("E"));
                   System.out.println("Ausgabe: " + line);
if(line == irdenwas){
methodeX();
}
                   parsing(line);
               }
           } catch (IOException e1) {
               e1.printStackTrace();
           }
       }catch(SerialPortException ex){
           System.out.println(ex);
       }
   }

wenn ich das alles richtig verstehe mit dem Event.......
 

Quax

Mitglied
@ mrBrown: Danke für den Lösungsansatz ich muss das jetzt mal versuchen in die Praxis umzusetzen.
@ Manuel: Sieht recht simpel aus ich werds gleich mal probieren. Danke auch dir vorerstmal.
Ich werde Euch berichten wenn ich neues weiß.
Quax
 

Quax

Mitglied
HEUREKA --> Es hat funktioniert.
Manuels Tip schien mir zu einfach aber es hat damit wirklich geklappt. VIELEN DANK Manuel!!!
@ mrBrown: Dir auch VIELEN DANK ich werde mich doch nochmals mit der von dir vorgeschlagenen Thematik Model View Controler beschäftigen.
Zwar läuft die Übertragung noch etwas langsam aber vielleicht liegt das auch an der JSSC-Schnittstelle. Ich werde das auch mal mit der RXTX-Bibliothek probieren. Aber ihr habt mir schonmal einen großen Schritt weitergeholfen.
Hier also der Code mit der entsprechenden Ergänzung von Manuel. Damit kann man also fortlaufend Daten unabhängig von Einflüssen des Anwenders vom Arduino zu Java und wieder zurück austauschen. Basierend auf JSSC Schnittstelle.
Großartig!!!
Java:
// Programme entstanden in Anlehnung an einfache Beispielcodes
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;

@SuppressWarnings("serial")
public class SD3_mod1 extends [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jframe']JFrame[/URL] implements SerialPortEventListener,
                                               [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouselistener']MouseListener[/URL] {
   // Deklarationen
   private SerialPort sp = new SerialPort("COM3");
   private [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jbutton']JButton[/URL] button1;
   private [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jpanel']JPanel[/URL] mainPanel;
   private [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jpanel']JPanel[/URL] buttonsPanel;
   // Sammelen des ankommenden
   private [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] sammler = "";
   
// Konstruktur ---------------------------------------------------------
   public SD3_mod1(){
       // Öffnen und deklarieren des COM3-Ports
       try{
           sp.openPort();
           sp.setParams(19200, 8, 1, 0);
           sp.addEventListener(this);
       }catch(SerialPortException ex){
           [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system']System[/URL].out.println(ex);
       }
       // Definition eines Panels mit Button --------------------------
       mainPanel = new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jpanel']JPanel[/URL](new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+borderlayout']BorderLayout[/URL]());
       buttonsPanel = new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jpanel']JPanel[/URL](new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+gridlayout']GridLayout[/URL](1,2,0,0));
       button1 = new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jbutton']JButton[/URL]("LED A");
       
       buttonsPanel.add(button1);
       mainPanel.add(buttonsPanel, [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+borderlayout']BorderLayout[/URL].PAGE_END);
       
       button1.addMouseListener(this);
       this.addMouseListener(this);
       this.setDefaultCloseOperation([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+jframe']JFrame[/URL].DO_NOTHING_ON_CLOSE);
       this.setContentPane(mainPanel);
       this.pack();
       this.setVisible(true);
   }
// Einlesen und Verarbeiten des Datenstreams vom Arduino ------------------------
   @Override
   public void serialEvent(SerialPortEvent e) {
       try{
           byte[] buffer = sp.readBytes(10);
           [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+inputstream']InputStream[/URL] sBAIS = new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+bytearrayinputstream']ByteArrayInputStream[/URL](buffer);
           [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader']BufferedReader[/URL] serRed = new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+bufferedreader']BufferedReader[/URL](new [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+inputstreamreader']InputStreamReader[/URL](sBAIS));
           try {
               [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] line = serRed.readLine();
               if(line.indexOf("S")>-1 && line.indexOf("E")>line.indexOf("S")){
                   line=line.substring(1, line.indexOf("E"));
                   [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system']System[/URL].out.println("Ausgabe: " + line);
                   int y = Integer.parseInt(line);
                   if(y < 500){
                       System.out.println("LDR kleiner 500");
                       try {
                           sp.writeBytes("LL".getBytes());
                       } catch (SerialPortException e1) {
                           e1.printStackTrace();
                       }
                   }
                   parsing(line);
               }
           } catch ([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+ioexception']IOException[/URL] e1) {
               e1.printStackTrace();
           }
       }catch(SerialPortException ex){
           [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system']System[/URL].out.println(ex);
       }
   }
// ------------------------------------------------------------------
   @Override public void mouseClicked([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouseevent']MouseEvent[/URL] e){}
   @Override public void mouseEntered([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouseevent']MouseEvent[/URL] e){}
   @Override public void mouseExited([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouseevent']MouseEvent[/URL] e){}
   @Override public void mousePressed([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouseevent']MouseEvent[/URL] e){}
   @Override public void mouseReleased([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+mouseevent']MouseEvent[/URL] e){
// MouseEvent mit Aktion belegen -> Daten an Arduino senden ---------
// Hier sollte dann die automatische Auswertung des vom Arduino -----
// gesendeten Wertes stattfinden und automatisch gesendet werden ----
       if(e.getComponent()==button1){
           try {
               sp.writeBytes("LL".getBytes());
               [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system']System[/URL].out.println("Maus released");
           } catch (SerialPortException e1) {
               e1.printStackTrace();
           }
       }
   }
   
   private void parsing([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL] line){
       [URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system']System[/URL].out.println("Annahme: " + line);
   }
   
   public static void main([URL='http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string']String[/URL][] args) {
       new SD3_mod1();

   }
}

Wenn also nun der LDR einen Wert < 500 sendet entscheidet das Java-Programm, dass eine LED geschaltet werden soll. Dementsprechend springt es in eine if-Abfrage und sendet die entsprechende Information in Bytes an den Arduino. Weiterhin kann, wie vorher eben auch die LED auch über einen Button geschaltet werden.

Verbesserungen und Anregungen nehme ich dankend an. Bin für jeden Austausch froh.

Schönen Advent noch
Quax
 

Ähnliche Java Themen

Neue Themen


Oben