serielle Schhnittstelle

Status
Nicht offen für weitere Antworten.
Hallo

Ich bin dabei, ein Programm zu schreiben welches Daten von einem Rechner (nicht PC, sondern Fremdsystem) herunterlädt. Diese lege ich danach in einem File ab.

Code:
import java.io.*;
import javax.comm.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import javax.swing.*; //Swing-Komponenten
/**
 *

 */
//public class Transfer extends JFrame implements SerialPortEventListener{
public class Transfer extends JFrame{
    static CommPortIdentifier portID;   //muss static sein
    static SerialPort serss;            //muss static sein
    static InputStream serialIn;
    static OutputStream serialOut;
    FileOutputStream fileOut;
    String sDownload;
    byte[] readBuffer;
    byte[] compReadBf;
    boolean readBufferFull;
    boolean datenTransfer;
    boolean noMoreDDS =false;
    boolean firstLoop;
    boolean downloadNext;
    boolean dataAv;
    int numBytes;
    //String locNr;
    String fileName;

    //Befehlssatz des Download
    final String givePuttOffDDS =       "damo090000000000";     //"64616D6F303930303030303030303030"; //damo09
    final String downloadDDS =          "damo0C0000000000";     //"64616D6F304330303030303030303030"; //damo0C
    final String actualDDSPtr =         "damo0E0000000000";     //"64616D6F304530303030303030303030"; //damo0E
    final String resetDownloadBits =    "damo0D0000000000";     //64616D6F304430303030303030303030"; //damo0D
    final String damoclesIdentity =     "DamoclesIdentity";     //"44616D6F636C65734964656E74697479"; 
    final int ctrlChar = 0x03;
    final int lfChar = 0x0A;
  
    //Befehlssatz des NFS-Access
    final String readTime =             "64616D6F30";
    final String readDate =             "64616D6F30";
    final String readOpHour =           "64616D6F30";
    final String readRelOpHour =        "64616D6F30";
    final String writeTime =            "64616D6F30";
    final String writeDate =            "64616D6F30";
    final String writeOpHour =          "64616D6F30";
    final String writeRelOpHour =       "64616D6F30";
    
    String decStr = "";
    
    byte lbStoerbild;   //low Byte Störbild
    byte hbStoerbild;   //high Byte Störbild
    
    
    //Main Methode wird gebraucht, wenn Klasse alleine ausgeführt werden soll
   /* public static void main(String[] args){
        try{
            
        Transfer transfer = new Transfer();
            
            transfer.download(true);
        }
        catch(Exception e){
        }
       
  }*/
        
    
     public Transfer() {
        try{portID = CommPortIdentifier.getPortIdentifier("COM1");
            serss = (SerialPort) portID.open("DamoclesXP",2000);            
        }
        catch(Exception e){System.out.println("Fehler :"+e);
        }        
        
            serss.notifyOnDataAvailable(true);
        
        try {serss.setSerialPortParams(4800,
                                   SerialPort.DATABITS_8,
                                   SerialPort.STOPBITS_1 ,
                                   SerialPort.PARITY_NONE);}
        catch (UnsupportedCommOperationException e) {}        
    }
    

    
        
    public void download(boolean firstL){
       String locNr;
       String date;
       StringBuffer strBfDate;
       String tmpStr;
       String tStr;
       
       
          
           send(ctrlChar); //Hexwert 03 senden
           send(lfChar); //Hexwert 0A senden    
           
           send(damoclesIdentity);//Befehl für Rückgabe Loknr
           
           locNr = getLocNr();             
           send(givePuttOffDDS);
           
           
           
           if(readBuffer[0]==0x03 && readBuffer[1]==0x05){
               strBfDate = new StringBuffer();
               
               for (int i=13; i<=15; i++){
                   tmpStr = Integer.toHexString(readBuffer[i]);
                   if (tmpStr.length()==1){
                       tStr = "0" + tmpStr;
                       strBfDate.append(tStr);
                   }
                   else{
                       strBfDate.append(tmpStr);
                   }
                   
                   fileName = strBfDate.toString();
                    }
               
               fileName = fileName + "." + locNr;
               save(fileName, compReadBf);
           }
               send(actualDDSPtr);
           
           if(readBuffer[0] == 0x03 && readBuffer[1] == 0x05){
               loopDownload();
               }
          
           else if(readBuffer[0] == 0x04){               
               //showMessage("Der DDS-Pointer konnte nicht korrekt gesetzt werden.");
           }
              
       }
    
    //Download läuft bis keine DDS mehr vorhanden sind
    public void loopDownload(){
        boolean noMoreDDS = false;
        do{ send(downloadDDS);
            
        
        if(readBuffer[2]==0x06){
            noMoreDDS = true;
        }
        
        if(readBuffer[0] == 0x03 && readBuffer[1] == 0x05){                
                    save(fileName, compReadBf);
                    send(actualDDSPtr);
            }
        
        else if (readBuffer[2]==0x06){
                    //Message Download beendet
                }              
        }
        while(noMoreDDS == false);
    }
    
    //waitForCode() kann später in send() übernommen werden
    public void waitForCode(){
       // datenTransfer = true;
        try{
            //serialIn = serss.getInputStream();
            serialIn = serss.getInputStream();
            readBuffer = new byte[100];
                    
              if(serialIn.available() > 0) {  
                            numBytes = serialIn.read(readBuffer);    //numBytes = Anzahl Bytes im readBuffer
                            
                        compReadBf = new byte[numBytes];
                            for(int i = 0; i<numBytes; i++){ //readBuffer in einen komprimierten Array der nötigen Länge umladen
                               compReadBf[i] = readBuffer[i];
                            }                        
              }
        }
        catch(Exception e){
            System.out.println("Fehler " + e);
        }
            }            
    
    public String getLocNr(){
        int i;
        int strLg;
        String locNr ="";
        char tmpChar;
        String tmpStr;
        StringBuffer strBfLoc;
        
        if(readBuffer[0] == 0x05){ //05H = ready to send            
            strLg = readBuffer[5];
            
            if(readBuffer[5] == 0x07){ // 3-stellige Loknr vom Format 450 000 ablegen
                strBfLoc = new StringBuffer(2);
                
                for(i=10; i<=12; i++){
                    tmpStr = Integer.toHexString(readBuffer[i]);
                    //tmpChar = Character.forDigit(readBuffer[i],57);
                    
                    strBfLoc.append(tmpStr);
                    locNr = strBfLoc.toString();
                    System.out.println(locNr);                                    
                }
            }
            else if(readBuffer[5] == 0x06){ // 3-stellige Loknr vom Format 450000 ablegen
                strBfLoc = new StringBuffer(2);
                for(i=9; i<=11; i++){
                    tmpStr = Integer.toHexString(readBuffer[i]);
                    //tmpChar = Character.forDigit(readBuffer[i],57);
                    strBfLoc.append(tmpStr);
                    locNr = strBfLoc.toString();
                    System.out.println(locNr);
                }
            }
        } 
        return locNr;
    }
    
    public void send(int value){
           
        try{
                serialOut = serss.getOutputStream();
                serialOut.write(value);
                serialOut.close();
                serialOut.flush();
                
               
                for(int i=1; i<=10000000; i++){
                    i = i+1;
                }
                waitForCode();      
        }          
        
            catch(Exception e){
                System.out.println("Fehler" + e);
            }
    }
    
    
    public void send(String sendStr){
       
        byte[] sendBytes = sendStr.getBytes(); //String in Byte umwandeln
        
            try{serialOut = serss.getOutputStream();
               
                serialOut.write(sendBytes);
                serialOut.close();
                serialOut.flush();
                
                for(int i=1; i<=10000000; i++){
                    i = i+1;
                }
                 waitForCode();
                
        }            
            catch(Exception e){
                System.out.println("Fehler" + e);
            }
    }
   
    
    public void save(String fileName, byte[] compReadBf){
      
        try{
            File ddsFile = new File(fileName);
            fileOut = new FileOutputStream(ddsFile, true); //Erzeugt File mit Zeiger auf das Ende der Datei
            fileOut.write(compReadBf);
            fileOut.close();
            fileOut.flush();
                             
        }
        catch(Exception e){
        }
        
    }

    
}
Einen Teil davan habe ich aus einem bereits vorhandenen Tool übernommen, deshalb ist mir nicht alles klar:

Was macht serss.notifyOnDataAvailable(true) ???

In den send() - Methoden musste ich nach einem gesendeten Befehl jeweils eine for - Schleife einbauen, die "sinnlos" zählt um Zeit zu gewinnen, denn wenn ich anschliessend gleich in dei waitForCode - Methode gehe, sind noch keine oder nicht alle Daten an der Schnittstelle vorhanden, die ich mit getInputStream abholen kann. Wie kann ich das ganze eleganter lösen? Kann man das ev. mit einem Listener lösen... damit habe ich aber nicht wirklich Erfahrung, deswegen bin ich offen für jegliche Anregungen.

Danke
 

jPat

Bekanntes Mitglied
Falls du dem serss einen EventListener hinzufügst, wird dieser aufgerufen, falls daten "aviable" sind. (so wie ich es verstanden hab.):wink:

evtl hilft dir das weiter ....
klick
 
Mein Probelm ist, dass noch nicht alle Daten im Array readBuffer gelandet sind, wenn ich sie wieder da raus hole. Ich suche also einen Weg, wie ich abwarten kann, bis die Daten komplett im readBuffer sind. Dabei ist aber jeweils nicht klar, wie viele Daten kommen werden.
 

HoaX

Top Contributor
dann schreib dir doch einen eigenen "buffered reader", der bei read so lange liest bis ein inhaltlich vollständiger datensatz da ist und dann erst zurück gibt
 
Tönt ja ziemlich einfach, aber habe leider keine Ahnung wie du das meinst... kannst du vielleicht ein Beispiel machen? Ich denke eben, das Problem liegt am delay, den der Rechner hat, den ich ansprechen möchte, bis er auf den Befehl reagiert hat und dann die Daten liefert.
Ich müsste es also irgendwie schaffen, dass mein Programm wartet, bis Daten anstehen, denn der Rechner liefert eigentlich auf jedes Kommando irgend etwas, müsste das Resultat dann nur noch prüfen...
 

jPat

Bekanntes Mitglied
schau dir mal den link an, den ich hir gepostet hab.
da gibt es ein eventlistener der aufgerufen wird, wenn daten ankommen ...

Code:
InputStream ins;

Initialisieren des Inputstream:
 try { ins = serss.getInputStream();  //Dein InputStream
         serss.addEventListener(new commListener());
    }
   catch (Exception e) { System.out.println("Fehler: "+e);}
    serss.notifyOnDataAvailable(true);

dein Listener, der die Daten empfängt:
Code:
 public class commListener implements SerialPortEventListener{
    public void serialEvent(SerialPortEvent event) {
      if(event.getEventType()==SerialPortEvent.DATA_AVAILABLE){
        byte[] readBuffer = new byte[20];
        try {
          while (ins.available() > 0) {int numBytes = ins.read(readBuffer);}
          String nachricht = new String(readBuffer);
          ausgabe.append(nachricht);
        }
        catch (IOException e) {System.out.println("Fehler: "+e);}
      }
    }
  }
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben