# Problem mit Com-Port-Komunikation



## Kaladial (14. Dez 2007)

moin

also ich muss mein programm irgendwie umstricken und vielleicht könnt ihr mir helfen...

also ich hab nen programm geschrieben welches sich zu z.b. Com1 verbindet an dem ein Scanner angeschlossen ist...

Wenn ich an den Scanner z.b.den befehl: BZ schicke liefert er mir <ACK>BZ=0001<LF><CR> zurück
soweit sogut...

wenn ich jetzt aber 
BZ
BZ
BZ
schicke, geht das n bissel durcheinander bzw nicht durcheinander aber meine antwort wird nicht in 3 antworten geteilt sondern alles in eine antwort rein gefriemelt... 
<ACK>BZ=0001<LF><CR><ACK>BZ=0001<LF><CR><ACK>BZ=0001<LF><CR> bekomm ich dann als antwort... 

das ist für den fall wie oben beschrieben noch nicht so das problem weil ich ja weis was zurück kommt und es entsprechend auseinander nehmen kann...

nun ist es aber so das der scanner eigentlich ne kamera ist und ich nun auch das bild abholen will 


```
for(int be=7; be>=0; be--){
			for(int zb=0; zb<(480/20); zb++){
				int zb_aktuell=zb*20;
				setzteWerte("IG1",0);
				
				String zb_str="";
				if(Integer.toHexString(zb_aktuell).length()==4){
					zb_str=Integer.toHexString(zb_aktuell);
				}else{
					for(int i=0; i<(4-Integer.toHexString(zb_aktuell).length()); i++){
						zb_str=zb_str+"0";	
					}
					zb_str=zb_str+Integer.toHexString(zb_aktuell);
				}
				String comand="IG2:0000"+zb_str+"0001000100500014";
				setzteWerte(comand,0);
				String comand2="IG3:0"+be+"00000000";
				setzteWerte(comand2,0);
			}			
		}
```

das kann ich über diesen code machen,
aber wie ihr set muss ich 3 komandos hintereinander abschicken und 
dann auch nur die antwort vom 3. komando in eine datei umleiten.... 

hier hab ich aber das problem das mein code nicht wirklich wartet, zumindestens sieht das so aus wenn ich mir die COM-Komunikation angucke:

Request: 14.12.2007 14:10:35.46564 (+0.0938 seconds)

 49 47 33 3A 30 30 30 30 30 30 30 30 30 30 0A 0D   IG3:0000000000..
 49 47 31 0A 0D 49 47 32 3A 30 30 30 30 30 30 35   IG1..IG2:0000005
 30 30 30 30 31 30 30 30 31 30 30 35 30 30 30 31   0000100010050001
 34 0A 0D 49 47 33 3A 30 30 30 30 30 30 30 30 30   4..IG3:000000000
 30 0A 0D 49 47 31 0A 0D                           0..IG1..

also wie kann ich meinen code so umbauen das er jedes komando einzeln ausführt und auch einzeln zurück gibt und erst dann das nächste komando anfängt?

hier drunter poste ich mal den kompletten code zur komunikation (ist etwas länger)

vielen dank für die hilfe 

mfg Kala


```
ScannerControl sc = new ScannerControl(comport, baudrate, datenbits, paritaet, stopbits, geraet, threadCounter);
		sc.scannerRead();
```


```
package ScanControl;

import java.net.InetAddress;
import java.util.Vector;

public class ScannerControl {
	
	private Vector<ScannerThread> threads = new Vector<ScannerThread>(); 
	private String comport[]; 
	private int baudrate[]; 
	private int datenbits[]; 
	private String paritaet[]; 
	private int stopbits[]; 
	private String geraet[]; 
	private int threadCount=0;
	
	public ScannerControl(String comport[], int baudrate[], int datenbits[], String paritaet[], int stopbits[], String geraet[] , int threadCount) {
		this.comport=comport;
		this.baudrate=baudrate;
		this.datenbits=datenbits;
		this.paritaet=paritaet;
		this.stopbits=stopbits;
		this.geraet=geraet;
		this.threadCount = threadCount; 
	} 

	synchronized public void scannerRead() { 
		for (int i = 0; i < threadCount; i++) { 
			ScannerThread thread = new ScannerThread(this, comport[i], baudrate[i], datenbits[i], paritaet[i], stopbits[i], geraet[i], i); 
			thread.running = true;
			threads.add(thread); 
			thread.start(); 
		} 
/*		try { 
			this.wait(); // Stoppt bis notify aufgerufen wird 
		} catch (InterruptedException e) { 
			e.printStackTrace(); 
		}*/ 
	} 
    
	public void sendeTest(){
		for(int be=7; be>=0; be--){
			for(int zb=0; zb<(480/20); zb++){
				int zb_aktuell=zb*20;
				setzteWerte("IG1",0);
				
				String zb_str="";
				if(Integer.toHexString(zb_aktuell).length()==4){
					zb_str=Integer.toHexString(zb_aktuell);
				}else{
					for(int i=0; i<(4-Integer.toHexString(zb_aktuell).length()); i++){
						zb_str=zb_str+"0";	
					}
					zb_str=zb_str+Integer.toHexString(zb_aktuell);
				}
				//System.out.println("zb_str:"+zb_str);
				String comand="IG2:0000"+zb_str+"0001000100500014";
				setzteWerte(comand,0);
				String comand2="IG3:0"+be+"00000000";
				setzteWerte(comand2,0);
			}			
		}
		
		/*setzteWerte("BZ",0);
		setzteWerte("BZ",1);
		setzteWerte("VE",0);
		setzteWerte("VE",1);*/
	}
	
	private String setzteWerte(String command, int PortID){
		StringBuffer    rxMsgBuf  = new StringBuffer(5000);  //Empfangspuffer 
		String          rxMsg     = ""; 
		command = command + "\n\r";  
		threads.get(PortID).get(command, rxMsgBuf); 
		rxMsg = rxMsgBuf.toString();
		return rxMsg;
	}	
	
	public boolean initDone(){
		boolean returnwert=true;
		for(int i=0; i<threadCount; i++){
			if(threads.get(i).running==false){
				returnwert=false;
			}
		}
		return returnwert;
	}

	
	public void stopThread(){
		for(int i=0; i<threadCount; i++){
			threads.get(i).running=false;
		}
	}
	
	public synchronized void removeThread(ScannerThread thread) { 
		threads.remove(thread); 
		if (threads.size() == 0) { 
			this.notify(); 
		} 
	} 

}
```


```
package ScanControl;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;

public class ScannerThread extends Thread implements SerialPortEventListener{
	int ii = 0;
	ScannerControl scanner;
	private String comport; 
	private int baudrate; 
	private int datenbits; 
	private String paritaet; 
	private int stopbits; 
	private String geraet; 
	int threadid; 
	private CommPortIdentifier portId;
	private SerialPort serialPort;
	private InputStream inputStream;
	private OutputStream outputStream;
	public boolean verbindung = false;
	public boolean running = false;

	String in;

	private StringBuffer inputBuffer = new StringBuffer(1);
	
    public StringBuffer rxMsgBuf;
    public String txMsg;

	public ScannerThread(ScannerControl scanner,String comport, int baudrate, int datenbits, String paritaet, int stopbits, String geraet , int threadid) {
		this.scanner=scanner;
		this.comport=comport;
		this.baudrate=baudrate;
		this.datenbits=datenbits;
		this.paritaet=paritaet;
		this.stopbits=stopbits;
		this.geraet=geraet;
		this.threadid = threadid; 
		
		
    	int parity_int=0;
    	if(paritaet.compareToIgnoreCase("keine")==0){
    		parity_int=SerialPort.PARITY_NONE;
    	}
    	if(paritaet.compareToIgnoreCase("gerade")==0){
    		parity_int=SerialPort.PARITY_EVEN;
    	}
    	if(paritaet.compareToIgnoreCase("ungerade")==0){
    		parity_int=SerialPort.PARITY_ODD;
    	}
		try {
			portId = CommPortIdentifier.getPortIdentifier(comport);
			try {
				serialPort = (SerialPort)portId.open(comport + "_IO", 2000);
				try {
					serialPort.enableReceiveTimeout(25);
					serialPort.setSerialPortParams(baudrate, datenbits, stopbits, parity_int);
					try {
						serialPort.addEventListener(this);
						try {
							inputStream = serialPort.getInputStream();
							try {
								outputStream = serialPort.getOutputStream();
								System.out.println("Start Reader Thread for " + portId.getName());
								serialPort.notifyOnDataAvailable(true);
								verbindung = true;
							} catch (IOException e) {
								System.err.println("SerialIO(6): " + e.toString());
								inputStream.close();
								serialPort.close();
								verbindung = false;
							}
						} catch (IOException e) {
							System.err.println("SerialIO(5): " + e.toString());
							serialPort.close();
							verbindung = false;
						}
					} catch (TooManyListenersException e) {
						System.err.println("SerialIO(4): " + e.toString());
						serialPort.close();
						verbindung = false;
					}
				} catch (UnsupportedCommOperationException e) {
					System.err.println("SerialIO(3): " + e.toString());
					serialPort.close();
					verbindung = false;
				}
			} catch (PortInUseException e) {
				System.err.println("SerialIO(2): " + e.toString());
				verbindung = false;
			}
		} catch (NoSuchPortException e) {
			System.err.println("SerialIO(1): " + e.toString());
			verbindung = false;
		}	
	}

	public String get(String txMsg, StringBuffer rxMsgBuf) {
    	this.txMsg = txMsg;
    	this.rxMsgBuf = rxMsgBuf;
        //System.out.println("Jetzt sende ich");
        send(txMsg);

        doGet();
        return in;
    }

	public synchronized void send(String given){
		int length = given.length();
		byte[] retvalue = new byte[length];
		char[] c = new char[length];
		given.getChars(0, length, c, 0);
		for (int i = 0; i < length; i++) {
			retvalue[i] = (byte)c[i];
 		}
		try {
			send(retvalue);
		}
		catch(Exception e) {
		    System.out.println("SerialIO(send 2): " + e.toString());
		}
	}
	
	private synchronized void send(byte[] temp){
		//System.out.println("send byte");
		try {
			outputStream.write(temp, 0, temp.length);
			outputStream.flush();
		}
		catch(Exception e) {
		    System.out.println("SerialIO(send 1) " + portId.getName() + ": " + e.toString()); //$NON-NLS-1$
		}
	}

    public void doGet(){
		new Thread(){
			public void run(){
			//	System.out.println("Jetzt bin ich in der Runmethode");
				while ( available()==0 ){
/*					try {
						//Thread.sleep(100);
					}
					catch (InterruptedException e) {}*/
				}
				
				try {
					Thread.sleep(75);
				}catch (InterruptedException e) {}
				if ( (ii = available())>0 ){
					if(inputBuffer.toString().startsWith("\u0006"+"IG3")){
						in = receive();
						
						int anzahl = in.getBytes().length;
						if(anzahl>0){
							in = in.substring(0, anzahl - 1);
							rxMsgBuf.replace(0, rxMsgBuf.length(),in);
						}
						
						System.out.println(rxMsgBuf);
					}else{
						receive();
					}
					
					//AVS3.fuelleWerte(rxMsgBuf);
				}else{
					rxMsgBuf.setLength(0);
				}
			}
		}.start();
	}
    
	public int available(){
		return(inputBuffer.length());
	}
    
	public synchronized String receive(){
		String str = inputBuffer.toString();
		inputBuffer.delete(0, inputBuffer.length());
		return(str);
	}
	
	public void run() { 
		try { 
			while (running) { 
				sleep(1000);
			} 
		} catch (Exception e){} 

		try {
    		outputStream.close();
            inputStream.close();
        }catch (IOException e) {
    	    System.err.println("SerialIO(close): " + e.toString());    	
        }
        serialPort.close();
        
        System.out.println("Serial Port " + portId.getName() + " closed!");
		
        scanner.removeThread(this); 
	} 
	
	public void serialEvent(SerialPortEvent event){
    	int newData = 0;
    	//System.out.println("empfange was...");
    	switch(event.getEventType()) 
        {
        case SerialPortEvent.BI:
        case SerialPortEvent.OE:
        case SerialPortEvent.FE:
        case SerialPortEvent.PE:
        case SerialPortEvent.CD:
        case SerialPortEvent.CTS:
        case SerialPortEvent.DSR:
        case SerialPortEvent.RI:
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
            break;
   	    case SerialPortEvent.DATA_AVAILABLE:
   		    while ( newData!=-1 ){
   		    	try {
   		    		StringBuffer inputBuffer_old = new StringBuffer(inputBuffer.length());
   		    		inputBuffer_old=inputBuffer;
   		    		inputBuffer = new StringBuffer((inputBuffer_old.length()+1));
   		    		inputBuffer=inputBuffer_old;
   		    		
   		    		newData = inputStream.read();
    			    if (newData == -1)
    			    	break;
   			    	inputBuffer.append((char)newData);
   		    	} 
   		    	catch (IOException ex) {
   		    		System.err.println("SerialEvent(1): " + ex.toString());
    		    	return;
    		    }
   		    }
    		break;
    	default:
    		break;
        }
    }
}
```


----------



## tuxedo (14. Dez 2007)

Mal ne Frage am Rande:

Was für ne Kamera ist das? Ne Art WebCam per RS232?

Sowas könnt ich nämlich auch gebrauchen...


----------



## Kaladial (14. Dez 2007)

das is ne ODI-MAC344 von omnitron... die wird über rs232 angesteuert ist aber eigentlich als datamatrix scanner für die industrie gedacht


----------



## tuxedo (14. Dez 2007)

Hmm, bei google hab ich jetzt nix gefunden. Hört sich aber nicht billig an ...

hab allgemein nur das hier gefunden: http://www.sander-electronic.de/gm00021.html

Aber rund 75€ ist n bisschen zu viel des guten, dafür dass ich noch ein Gehäuse, Pegelkonverterplatine etc. brauche.

-- Alex


----------



## Kaladial (17. Dez 2007)

/push... 
back to topic


----------



## tuxedo (17. Dez 2007)

Hmm, ist n bisschen viel Code ;-)

Wen ich das Problem richtig verstanden habe, dann sendest du die Anfrage bzgl. des Bildes hin, bekommst aber erst nach der 3. Anfrage (gleicher natur) die Bilddaten zurück?

Ohne den Code im Detail betrachtet durchforstet zu haben:

Wenn du auf den OutputStream der Verbindung drauf schreibst (und mit einem flush() sicher stellst dass das KOmmando auch sofort am Stück weggeht (was du ja tust)), dann sollte dein Programm als nächstes ja auch solange warten bis die Antwort von der Kamera komplett da ist. Wenn dein Programm das nicht tut, dann hast du irgendwas schlecht designed und beispielsweise das sequentielle Frage-Antwort-Spiel mit einem Thread oder so dermaßen entkoppelt, dass nicht auf die Antwort gewartet wird.

Ich empfehle dir ein Minimalbeispiel zu basteln. Eins mit definitiv unter 100 Zeilen Code. In "komplexen" Konstrukten ist das Testen nicht immer empfehlenswert.

- Alex


----------



## Kaladial (17. Dez 2007)

hmmm

die frage ist wie bekomm ich ein minimales programm hin?

ich will an den comport folgendes senden:


```
comand="IG1"; 
for(int be=7; be>=0; be--){ 
         for(int zb=0; zb<(480/20); zb++){ 
            int zb_aktuell=zb*20; 
            setzteWerte("IG1",0); 
             
            String zb_str=""; 
            if(Integer.toHexString(zb_aktuell).length()==4){ 
               zb_str=Integer.toHexString(zb_aktuell); 
            }else{ 
               for(int i=0; i<(4-Integer.toHexString(zb_aktuell).length()); i++){ 
                  zb_str=zb_str+"0";    
               } 
               zb_str=zb_str+Integer.toHexString(zb_aktuell); 
            } 
            String comand="IG2:0000"+zb_str+"0001000100500014"; 
            setzteWerte(comand,0); 
            String comand2="IG3:0"+be+"00000000"; 
            setzteWerte(comand2,0); 
         }          
      }
```

also die befehle: 
comand="IG1"; 
comand="IG2:0000"+zb_str+"0001000100500014"; 
comand2="IG3:0"+be+"00000000"; 

und ich will nur die antwort von IG3 auswerten .... 
wie soll ich das denn machen?


----------



## Kaladial (17. Dez 2007)

ahja ig3 liefert 
<ACK>IG3=0640<1600 Byte an pixel>

diese 1600 byte will ich in ne datei umlenken und beim 2. 3. usw aufruf an die datei anhängen


----------



## tuxedo (17. Dez 2007)

Kommt denn auf IG1 eine Antwort? Bzw. kommt auf jeden Befehl eine Antwort?

Wenn auf jeden Befehl eine Antwort kommt, dann ist das doch ganz einfach...

Verstehe nicht wo das Problem ist:



			
				pseudocode hat gesagt.:
			
		

> while(!interrupted()){
> Befehl senden
> Antwort erhalten
> Auswerten ob Antwort weiterverarbeitet werden muss, ggf. an Vater-Thread die Antwort weitergeben
> }


----------



## Kaladial (17. Dez 2007)

naja was ich für nen problem hab, ist folgende tatsache:

ich schicke z.b. IG1 
und bekomme instant die antwort: 
<ack>IG1=0001<ln><lf>

wenn ich IG2 (samt parameter) schick
bekomm ich nur 
<ack><ln><lf>

wenn ich nun aber IG3 schick (samt parameter)
bekomm ich:
<ack>IG3=0640[Daten]
[Daten]
[Daten]
[Daten]
[Daten]

bis halt die 1600 bytes fertig sind

das problem ist, ist halt wann sind die daten alle übertragen?
es muss ja mehr oder weniger so laufen:
hole ab bis nix mehr kommt...

nur wie definiert ich: "bis nix mehr kommt"
ich hab im mom das problem das ich halt warte bis ne antwort kommt, da der 1600er block aber aufgesplittet wird weil die komm keine 1600 byte auf einmal schickt, das ich den ersten teil der antwort mitbekomm und der rest dann wild durcheinander geht,....


----------



## tuxedo (17. Dez 2007)

Aha, und wird ig3 auch mit <ln><lf> (new line, form-feed??) abgeschlossen?

Wenn du weißt dass das Bild als 1600 Bytes besteht:

Wo ist das Problem fix "<ack>IG3=0640" zu lesen, und danach ein read(byte[]) zu machen, und zwar mit einem Array das exakt 1600 groß ist?

Deine Aussage "wild durcheinander" versteh ich nicht. Das ganze basiert doch auf einem Stream. Da kommt nix wild durcheinander, sondern schön nacheinander.


- Alex

- Alex


----------



## Kaladial (17. Dez 2007)

also ich geb nur die daten aus die ich bekomm und es kommt halt auch vor (warum auch immer) das ich sowas bekomm:


IG3:064
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ


----------



## tuxedo (17. Dez 2007)

Na 3 mal darfst du raten warum das so aussieht... Das Bild wird dir als Binary geliefert. D.h. du kannst das nicht auf der Console ausgeben, sonst kommt halt sowas dabei raus  (lauter nicht darstellbare Sonderzeichen etc...). Sieh zu dass du "<ack>IG3=0640" erkennst, und dann speichere die kommenden 1600 Bytes in ein Byte-Array, welches du dann per neuen OutputStream in eine Datei schreibst. Fertig. 

- Alex


----------



## Kaladial (17. Dez 2007)

nein das is mir klar... 
das problem "IG3:064 "

^^ das hat er mir geschickt und hat irgendwie die 0 verschluckt... und das weis ich nicht wieso er das einfach macht...


----------



## tuxedo (17. Dez 2007)

Woher weißt du dass er die 0 verschluckt hat? Hast du das allei mit der Console geprüft?

Hat die Kamera denn ein Handbuch oder sowas wo deren Protokoll beschrieben ist? Gibts das vielleicht irgendwo im Netz?

- Alex


----------



## tuxedo (17. Dez 2007)

Woher weißt du dass er die 0 verschluckt hat? Hast du das allei mit der Console geprüft?

Hat die Kamera denn ein Handbuch oder sowas wo deren Protokoll beschrieben ist? Gibts das vielleicht irgendwo im Netz?

- Alex


----------



## Kaladial (17. Dez 2007)

```
Pseudocode um Bilddaten vom MAC340/344 anzufordern
Fehlerbildzähler abfragen: EI
Fehlerbild auswählen: EI1 oder EI2 oder EI3 oder EI4 oder EI5 oder EI6
//Schleife um Daten anzufordern:
für alle Bitebenen (7,6,5,4,3,2,1,0)
{
für alle 20er Zeilenblöcke (0, 20, 40, ... ,440, 460)
{
sende seriell: "IG1"
ignoriere Antwort
sende seriell: "IG2:0000" + aktueller Zeilenblock (4stellig, führende Nullen, in hex) + "0001000100500014"
ignoriere Antwort
sende seriell: "IG3:" + aktuelle Bitebene (2stellig, führende Nullen, in hex) + "00000000"
akkumuliere Antwortbytes: 9 Bytes header + 1600 Bytes Bilddaten,
entferne die 9 Bytes vom Anfang und schreibe die restlichen 1600 Bytes in Datei,
falls Datei schon vorhanden, hänge Daten an.
}
}
// Datei besteht aus 192 Blöcken (8 Bitebenen x 24 Zeilenblöcke mit je 20 Zeilen) mit jeweils 1600 Bytes
// Der Dateiname ist ein Aufrufparameter für die compose.exe, der zweite Aufrufparameter
// ist der Dateiname der neu zu generierenden Datei (Typ: Bitmap, BMP).
```
^^ das is die beschreibung zum auslesen des bildes...


----------



## tuxedo (17. Dez 2007)

Na also.. Ist doch "kein Problem". Lesen tust du dann mit einem primitiven "InputStream". Da liest du nach dem senden von "IG3" erst ein 9 Byte großes byte[], und danach ein 1600byte großes byte[] ...

Steht auch noch irgendwo was man alles aus den 9 Byte Headerdaten interpretieren kann?

- Alex


----------



## Kaladial (17. Dez 2007)

nein... 

aber sorry ich bin trotzdem etwas verwirrt... ich bastel jetzt schon seit 3 tagen dran rum und bekomms net gebacken noch dazu bin ich erkältet und kann nich richtig denken *ggg* 

also nen netter beispielcode wäre nett


----------



## tuxedo (17. Dez 2007)

Solltest mal ein wenig frische Luft schnappen gehen ;-) 


```
// Meine Dummy-Streams. Musst du dir halt aus der seriellen Verbindung holen...
		OutputStream outputStream = null;
		InputStream inputStream = null;
		
		// lesean mit read(byte[]) KANN vorher abbrechen so 
		// dass nicht das ganze byte[] gefüllt wurde. Deshalb verwende ich gern
		// die readFully() Methode aus dem DataInputStream. Die garantiert das komplette
		// füllen des byte[] (sofern so viele Daten überhaupt ankommen)
		DataInputStream dataInputStream = new DataInputStream(inputStream);
		
		// aktuelle Bitebene (2stellig, führende Nullen, in hex)
		String aktuelleBitebene = "0000"; 
		
		// String für die Bildanfrage
		String bildAnfrage = "IG3:" + aktuelleBitebene + "00000000";
		
		// Bildanfrage senden
		outputStream.write(bildAnfrage.getBytes());
		
		// Container für den Bildheader und das Bild
		byte[] bildHeader = new byte[9];
		byte[] bild = new byte[1600];
		
		dataInputStream.readFully(bildHeader);
		dataInputStream.readFully(bild);
		
		// Bild in File schreiben. 
		FileOutputStream fileOutputStream = new FileOutputStream(new File("meinBild.bmp"));
		fileOutputStream.write(bild);
		fileOutputStream.close();
```

Habs nicht getestet (kann ich hier ja auch gar nicht). Aber so in etwa sollte es funktionieren. Was mir noch unklar ist, ist das "überspringen" der Antworten aus IG1 und IG2. Gelesen werden MÜSSEN diese bytes. Nur kannst du sie eben ggf. wieder verwerfen. Aber RAUS müssen sie aus dem Puffer.

Deshalb hab ichs hier mal weggelassen. Das bisschen Doku sagt ja leider nicht wie die Ende der Antwort jeweils signalisiert wird. Wenn es ein "normaler" Zeilenumbruch ist, dann kannst du für diese Antworten  einen BufferedReader nehmen der "readLine()" kennt. Oder du liest solange byte-weise bis du selbst den Zeilenumbruch gefunden hast.

Kommt denn (auch) ein Zeilenumbruch nach den Bilddaten? bzw. kommt nach jeder Antwort ein Zeilenumbruch?

- Alex


----------



## Kaladial (17. Dez 2007)

das weis ich leider nicht, da es in der doku nicht drin steht ... aber ich werd das mal versuchen raus zu bekommen  

dank dir dann erstmal und werd ma versuchen das einzubauen


----------



## tuxedo (17. Dez 2007)

Kaladial hat gesagt.:
			
		

> das weis ich leider nicht, da es in der doku nicht drin steht ... aber ich werd das mal versuchen raus zu bekommen



Sollte im Handbuch stehen. Wenn du da ein Link zu einer PDF oder so hast wär's klasse wenn ich auch ein Blick reinwerfen dürfte. So ne Kamera interessiert mich nämlich auch ....


----------



## tuxedo (17. Dez 2007)

*gefunden*, aber leider nur das Datenblatt bis jetzt ...


----------



## Kaladial (18. Dez 2007)

jo also ich hab jetzt was programmiert was so ziehmlich funktionieren müsste.. 
nur dein file-write überschreibt jedesmal die datei... 

wie war das mit anhängen an eine datei?


----------



## tuxedo (18. Dez 2007)

Dann mach doch einfach die File nach den 192 Blöcken zu und nicht nach jedem ....192 mal File öffnen und Daten anhängen ist alles andere als performant.

Zum FileWriter: Die API-Doc hilft da ungemein: http://java.sun.com/javase/6/docs/api/java/io/FileWriter.html#FileWriter(java.io.File,%20boolean)

- Alex


----------



## Kaladial (18. Dez 2007)

ok so wie ich es mir gedacht hab funktioniert es net... 

aber hab schon ne neue idee ...
allerdings: 
wie bekomm ich den kompletten stream aus dataInputStream?


----------



## Kaladial (18. Dez 2007)

bzw wie bekomm ich die anzahl der zeichen die im dataInputStream drin stehn?


----------



## tuxedo (18. Dez 2007)

Streams haben eigentlich keinen Anfang und Ende ... D.h. du kannst die größe des Streams nicht bestimmen. Das ist wie wenn du den Anfang und das Ende des Rhein bestimmen wolltest.. Wo fängst du an den Anfang zu definieren? An der Quelle? Und was ist mit der Quelle? Wo fängt die an? Und wo hört der Rhein auf? Klar, der fließt ins Meer. Aber wo hört das auf? Und wo fließt das Meer hin?

Du siehst: Ganz so einfach ist das nicht. Und Streams sind da nicht wirklich besser. Die hören auf wenn nix mehr kommt. Aber wann nix mehr kommt, weiß der Stream nicht. Das weiß nur der, der die Quelle der Daten darstellt. Und der müsste diese Information auch als Daten über den Stream übertragen. 

Aber wieso stellst du dich so an? 

Mach die File einfach VOR dem ersten Block der 192 auf und mach das .close() des Streams NACH den 192 Blöcken. Dann hast du doch was du willst, oder nicht?

- Alex


----------



## Kaladial (18. Dez 2007)

du hast mein programm noch nich so richtig verstanden... 
also ich hab das im moment so, das jedesmal wenn was auf der COM ankommt, er in ne funktion geht die den ankommenden datenstream auswertet... 

wenn also 3 zeichen ankommen dann geht er da rein und wenn 50000 ankommen geht er auch nur einmal da rein ,... 

das problem: 
es kommt zwar alles nacheinander, aber nicht befehl für befehl sondern irgend ne größe die der COM grad für richtig hält... 

und da zu dem zeitpunkt wo der COM die daten abschneidet net unbedingt die komunikation fertig sein muss muss ich halt alles ankommende überprüfen und zusammen packen um es dann wieder auseinander zu nehmen... 

sagen wir es so: es is einfach grausam... 


gibt es net so ne möglichkeit ala: 
while(solange wie noch nen zeichen da is)
überprüfe das zeichen auf i
überprüfe das nächste zeichen auf g
überprüfe das nächste zeichen auf 3
überprüfe das nächste zeichen auf :

dann lass die nächsten 4 zeichen weg
und nun schreibe 1600 zeichen (zeichen für zeichen) in die datei

wenn der stream kürzer is merk dir den rest und warte auf den nächsten input

wenn nun die 1600 zeichen fertig sind 
suche wieder nach i g 3 :


----------



## tuxedo (18. Dez 2007)

Doch, ich hab das schon verstanden...Aber du hast mich nicht verstanden ;-)

a) Du solltest heraus finden wann eine Antwort von der Kamera "fertig" ist. Kommt da ein extra Zeichen? Zeilenumbruch? Oder ist die Länge der Antwort (speziall bei den IG1 und IG2 Antworten) irgendwie spezifiziert?
b) mit readFully() liest du exakt die Menge an Bytes die dein übergebenes byte[] groß ist. Aber das hab ich ja schonmal geschrieben und sogar mit Beispielcode aufgezeigt. Wenn du das ignorierst oder nicht ausprobierst, dann kann ich dir nicht helfen. 

Wenn du genau weißt dass die Antwort mit igX: (x kann 1-3 sein) anfängt, dann weißt du doch: Die Antwort beginnt mit 4 Zeichen. Also machst du ein 4 Zeichen großes Byte[] und liest das mit readFully(). Daraus kannst du einen String basteln und den mit equals() auf ig1, ig2 oder ig3 oder igX vergleichen und dann entsprechend weiterlesen oder aufhören. 

btw: die Com-API schneidet nix ab. Sowas nennt sich Sender und Empfangspuffer. Und damit kann man ohne Probleme umgehen wenn man weiß DASS ES so ist.

- Alex


----------



## Kaladial (18. Dez 2007)

das was ich gesucht hab ist : dataInputStream.available()
das liefert zurück wie groß der stream ist ... 

readFully()is ja toll nu was bringt es mit wenn ich nicht weiß was full heist?

ich habe hier stringts die ma 5 zeichen und ma 5000 zeichen gro0 sind (die werden so von der com übermittelt) 
daher kann ich auch nicht einfach sagen lies ma 1600 zeichen... ich weis ja gar nicht ob die com mit grad eben soviel geliefert hat ... 

noch dazu kann ich net einfach 4 zeichen einlesen, dann es kann auch passieren das mit die com 3 zeichen im 1. stream schickt und das 4. im 2. stream ... 

oder das er mir 
20 zeichen vom letzten bild danach den nächsten ig befehl 1 dann ig befel 2 und dann ig befehl3 davon dann aber wirder nur die hälfte des befehls oder den ganzen befehl und nur die hälfte der daten oder 3/4 der daten oder die ganzen daten schickt ... 

das ist das was ich mein mit: die größe der übergegeben streams variiert ...


----------



## tuxedo (18. Dez 2007)

Du bist auf dem Holzweg... available liefert dir nur "etwa" zurück wieviel gerade "lesbar" ist. Und keinesfalls wie groß der Stream überhaupt ist. Insgesamt ist es mehr ein Schätzeisen auf das man sich nicht verlassen sollte:



			
				JavaAPI hat gesagt.:
			
		

> available
> 
> public int available()
> throws IOException
> ...




- Alex


----------



## tuxedo (18. Dez 2007)

Ach ja:

Noch was zu deinem:

>> wenn ich nicht weiß was full heist?

DU Held. Ich schreibst jetzt zum dritten und letzten mal:

readFully liest exakt so viel aus dem Stream wie dein übergebenes byte[] groß ist. Aber auch das steht in der JavaApiDoc ...



> readFully
> 
> void readFully(byte[] b)
> throws IOException
> ...



man man man... ich sags ungern, aber manchmal hilft es wenn man versucht das gelesene zu verstehen.


----------



## Kaladial (18. Dez 2007)

ja und du verstehst mich trotzdem nicht... 

readFully liest alles bis mein byte-feld voll ist... 
^^ das bringt mir aber NIX...
dazu müsste ich vorher mein BYTE-Feld so groß machen wie mein Stream ist ... und woher wenn nicht durch available soll ich wissen wie groß mein Stream ist damit ich mein bytefeld so definieren kann und dann mit readFully diesen komplett auslesen kann?


----------



## tuxedo (18. Dez 2007)

Du weißt doch aber das 192mal 9 Bytes Header und 1600 Bytes Bilddaten kommen, oder etwa nicht?

Keiner spricht davon mit readFully "alles" auf einmal zu lesen. Halte dich doch an die Doku der Kamera und lese wie dort vorgeschlagen das ganze Blockweise "am stück". Soll heissen: die 1600Bytes immer jeweils auf einmal und nicht in kleinen Häppchen die man dann erst wieder zu ganzen 1600 bytes zusammenbauen muss.

- Alex


----------



## Kaladial (19. Dez 2007)

ja und genau das funktioniert nicht ...
da die daten nicht zusammenhängend in einer übertragung kommen bzw nicht kommen müssen...

ich hab daten die so aussehn:
<ack>IG3:064

das wars... 

und ich hab daten da passen die 1600 5 mal rein ... 

oder ich hab daten da kommt erst der rest vom letzten bild dann kommt ig1 ig2 und ig3 der anfang... 

aber ich glaub ich hab keine lust mehr ... 
ich lass den mist einfach weg... ist eh viel zu langsam... 
und man braucht das nicht unbedingt ...


----------



## tuxedo (19. Dez 2007)

In keiner Stream-Verbindung kannst du _alles_ auf einmal lesen. So sind Streams nunmal. 


> ich hab daten die so aussehn:
> <ack>IG3:064
> das wars... 

Hmm, was ist "<ack>" für ein Zeichen? Aus deinem bisschen Doku das du gepostet hast geht das nicht hervor.
Kommen nach "IG3:064" überhaupt noch welche Zeichen? Was sagt available() wenn du soweit schon gelesen hast?
Wenn available "0" liefert, dann stimmt was mit der Kamera nicht. Dann scheint die nicht weiter Daten zu senden. 

> und ich hab daten da passen die 1600 5 mal rein ... 

Ein Bild besteht doch auch aus 192 x 1600Byte?

> oder ich hab daten da kommt erst der rest vom letzten bild dann kommt ig1 ig2 und ig3 der anfang... 

Das sieht mir stark danach aus, als ob der lese-zyklus durcheinander gerät und nicht wirklich am Ende des Bildes aufhört, sondern zu früh. Das würde erklären warum im nächsten Durchlauf noch Reste der Bilddaten kommen, bevor du wieder die Antwort von IG1 und IG2 ließt.

> aber ich glaub ich hab keine lust mehr ... 

Das heisst du gibtst dich geschlagen? Jetzt wo's anfängt interessant zu werden ;-) *g*


----------



## Kaladial (19. Dez 2007)

<ack> = das normal bestätigungszeichen... "\u0006"

also wie gesagt es ist nicht wirklich reproduzierbar... 
die daten kommen in ziehmlich willkürlicher länge an meinem com an ... daher kann ich nicht sagen los liess 9 zeichen und sag: du bist der header... 

da es sein kann das es eigentlich daten vom letzten bild / daten von den anderen beiden befehlen sind oder nen abgeschnittener ig3 befehl.... 

"IG3:064": available sagt das sind sei 7 zeichen lang 

aber meist kommt ja nicht "IG3:064" alleine sondern das sieht dann eher so aus:

"<restdaten>

<ack>IG1=0001

<ack>

IG3:064"


>Ein Bild besteht doch auch aus 192 x 1600Byte? 

ja ich mein ja das sehr oft daten in der größe von 4096 byte oder so ankommen... aber das halt auch net immer...

hmmm und ich weiß nicht ... ich habs schon versucht einfach nur 
in einerschritten auszulesen aber selbst da bringt er mir diese daten so... 

>Das heisst du gibtst dich geschlagen? Jetzt wo's anfängt interessant zu werden  *g*

 naja wir können ja gern noch weiter versuchen das hinzubekommen


----------



## tuxedo (19. Dez 2007)

Die größe von 4096 ist erklärbar. Das wird die Puffergröße sein.

Hast du mal mit Hyperterminal probiert so ein Bild anzufordern? 

Kannst du mir da mal einen Mitschnitt von IG1 2 und 3 (nicht alle 192 blöcke) posten?

Die Reihenfolge der Daten scheint ja zu stimmen, nur sind sich beide Seiten (Kamera und Programm) nicht wirklich einig wo was anfängt und wo es aufhört. Läuft quasi nicht wirklich synchron. 

- Alex


----------



## Kaladial (19. Dez 2007)

antwort auf (im Hyperterm):
IG1
IG2:000000200001000100500014
IG3:00100000000

=

IG1=0001

IG3:0640upÕwUUÉfKE<UTEEUwQÑô“]t55}TuDWEÇUMmT[~…ð}Ñ•ÅÅWÃe¥\WDNÛqQEUuU\W5U^ùU
UTUÔGGPÔVTYwUWWÄ2qQ×U]Ô]à×”“DvÐ]`ÉWDÑtô5DUÝ×]]]´UuÝ"ÍUTUEU±q†ÝUUm¼Sõ]
ÔõÑuÕEÕwd5=DUÑTÕUFWeSá‘ƒ5\^}×cA”qETU]GUUW}gUeWWEGUuUUU9]…Y·QUUWQ^ÕU×Õ
^YU…uWUguUUEUQuSUqÜugDÕEEYUQYmTCÑÆVUiUEET}]uuW—]5Á}PoØU×|DUU5ö]}wuUuÕu
QQ\÷ÍUÑeEUUTWßùÐUÕDWtQUMmQUUEU·atUM×UÕUUÄUWU—UUUsW”UÓ}ÜugúH¶yö]çUAñE
ÂUU0eåwtRU5UustµGÀŒÔ`ÑÞ5YóDÕDEUÕ_U5ÕEÝUEyPUuÓ¼Ûu_wEßÕ×M•Ôñß”EEÕUQDÕu
Ñs]]VÔýOCÖô\BUUUVÐUÄQÙe0ÑÔaÓuuÝEQÍÑuRÔÇU]UÝ©tW×ÕÕÕÒ]—ÙOWWÓÕyÕU ÌUÜuEV^Ç
”DW×Ww]]}'UTGÖUu]Uõ}EAEUUUUÅ5UåUUUÝÕt]ýuU×í]ÇTÝ}|ÕEUýÅÙuuÕUÕTUYÝ÷FÖ
QU UUW~}µ×T$UEMÔdETt”UUÍ@]Q×ÐAQôõÑ]TœéuuuÅUQµUUÕwÕÕWQWÕW ]W]ÓÕþ}GU•üuQUÞç
Q^ÕÕoEñUq•U]%UUe0UV-TÅvWAUUGWUW]W•TQDQÑTS'ØÇÑDUTP_ÔUUÑOÖUT\VÍd|}QU;U
UAG§ÄQ™WÀUÕUQWÉUQPHQØUUHÕ\yÕÝuÅUÕ]Õ%UEUWñU×WUWÕA}y·äQOEU__Q\]UÔ\%KC]ÄUaÃ
UUÇ÷ÓŒPUTDX•W4UÀÖ±WAÕÕE×WuQøE5^\õµ:ÕTUUÝDuWUWyña5qetMG\UTOÕ]Õ|\wÇÑ×
Åå[D_DdQåWÕ
             UQUUUUEÕQxUwTÕ‘U‘bTÔEQGUUW]ÜU'üõQõE_e\²%EUÕwUUœåÕTR@ñlUTÍW
ÇO6ÕEÞƒÕåOÖÕST˜Q<YUQ‚uEYTÕ]•UUARTVT@&6W]QGEw×U]CWuU“ÅE=UUU!µ'GÜÅÝuU
Ô AS@;ØÕEÕómWuUÑFUqUgUUQØUEW
MõuTQHÑEUUx/GvÕÔGAUdUVQé6u
                                $QÑTýRGU$õUWUuVqÕõY|qU]Ä'ÕGUUÔqQUWU\E‘üÅu
S]E@}\ÕU}\QCRGLEPUEUEA      EÉU[]UuEoPEÕM


-> hier macht der hyperterm aber ne neue seite (also ka ob das nun ne neue antwort oder ob hyperterm einfach nur die vorherige eingabe löscht weil zuviel drin steht)

MõuTQHÑEUUx/GvÕÔGAUdUVQé6u
                                $QÑTýRGU$õUWUuVqÕõY|qU]Ä'ÕGUUÔqQUWU\E‘üÅu
S]E@}\ÕU}\QCRGLEPUEUEA      EÉU[]UuEoPEÕM


----------



## Kaladial (19. Dez 2007)

-> hab die aufzeichnungsoption vom hyperterm gefunden  

hab hier diese befehle hintereinander eingegeben (paste and copy):

IG1
IG2:000000000001000100500014
IG3:00000000000
IG1
IG2:000000200001000100500014
IG3:00100000000
IG1
IG2:000000400001000100500014
IG3:00200000000

ergebnis: 

IG1=0001

IG3:0640Õ 7Murwý×uUÝw
3]QHWU5}ÀWE3Ä.¥5ÑUUU@uUvYAL]T…QUqDÁ7ewöTEmQu”AÓÖEwq]ËÑ1ÝÅUO]uD×4$ßE¤5Å7Q•UUNcDÉ¨ƒÍáDMQQQUI]½U_åEo6MDVU￾@Õ\d•uUUTQzDTÅ]TU•EÓ|uswWUUuÅOÐQE÷Fy÷uUQCG\¿4´UqQFEUueUÝ\µõ7QÁAqU$w\]UÜT]QUUBSÔÿÕUU]UtåeEPÐW]UUÕŸI=õU@QYoUTVõ·cÝQu(lA2PW\]SL•u8UÕÓ÷õ]UUUOYUUmwGUEtÖTQuU]MMtq}ÕíöY￾UUtåtÕUÕSY×5GYÕ]UuQ4￾UÜ$Vó&WUD]u_Tq||¥ÔEÓ'UUEUÉe_QÔÕtMUUUu—UequE[ÖT’ÕÿÙ]}×ôåôuGÝUÝÚuwÄõ_TýQU_•Å%E mDETW1Ññ—ÙïÔyç}³X—€U—UERU=y}7ÅQUEUUQ]eUÕR=_”}G
]5ÇÅEU￾wUU[õ}½õYUÍ]P1ÃLHEWU\_qÉÃ¨UUU]ûóÑEWXUU•ÄíwYÕEUDÑQWP6]EÑÅ•WÜ’U1QTUßSÒÙÄuUWSD0%EEUeMU_QWÕ}ÔEBÓAUÕW“Yu\UuUuDUUUdEÕUÑÝT7Ý·‘õgU|UWí=5ÝÑÔpUWÉ×E{×yýÍ‡QdíÑ5QQoW￾u]VtwnèZ7ÐtGÿÝSF×eÑMŽtQUÕUTWPtQ]ZÓ^YUÙ…ºM…\RUT￾ñÄd¥TTUq\U5}T|UTÁÈuV]UÕÅ_YU·q”qQU“aEVUDOuSÝ•￾ßmUuSUWQATUWUu]××ÖpçÑUMñÇ]QFU5MVqUE\UUÕå@Q&^EQ-Ño\uÜW÷üÑoVÕ]Uv}±e,UGÑTQÝTuy@ß]UUTL•ÍTÁUÝµUGÕÃ×_EUåUEEeC\P9uùBED%V=ÔTUUPÅWÖsë–qDuuUYUÕÇRTÄu[qEPOTTemTU•]uT×Tž¥—UUöÔAW5÷ñ]E)U]uutžÕÅe%õTÃSôMQÝUTu_…ÐÓE]TUõ•u\ÕUM×T÷ÝQq¤WõeuME]•]UMwUüõWýQU^™aTW××ÅWUEQUuSUÕEDÀ’*UUUU]uUýÝuVÛ￾ßUusEvQ￾S…[ÅÕUÞÝÚWW UUXUi]Õõ]uQUQMQ’UÕAW×WwCWeUq cGa]åUUP“ÍÔ}ÞUçgEFÐáUR÷DÔq½ÛU]e}Yž
UUPVT7@×wEGP”UVUçT]áñ\|•pÝUUÅ=EÐÔÓCGpÕEpE}E_UUWÿþ§QF5›ÑáREö?aQS[UŒUwÄWuPA@pu￾QQEYU=\Õ÷¤ÁåU6L]u}wÝW]TWŠ]Ptu}R}Uõ}UØç—]W5Ÿ}pÕw}”WŸPmÍu;ÑÕWxñ•Ae9DeœLc}UTQÁ]UI7%¡@<U•Õ±EW_]×Í1`UóžO	AÍÑUE4TuvµÅòÕR￾™Ð´LÌEÝ{µ9qÅ|}EÝÍTEU5UTWWU_½ðUU,yAu^õE’õBUX¡Uu}v@–W•XÐÝEUuWß]w5Õp_ÅWGUÒu†ÚtÕUwUKvÅ´ §É|ÅÅÒq<]ÕyÑ%7Ý5UWq￾ù…DTT]ý\o´XPuWüOPA_0½eDÐtÁ•ÕÇuVÕQQ×T|u]ÑvUGUÕTÔ5Õ××YuUU1V]
IG1=0001

IG3:0640upÕwUUÉfKE<UTEEUwQÑô“]t55}TuDWEÇUMmT[~…ð}Ñ•ÅÅWÃe¥\WDNÛqQEUuU\W5U^ùUUTUÔGGPÔVTYwUWWÄ2qQ×U]Ô]à×”“DvÐ]`ÉWDÑtô5DUÝ×]]]´UuÝ"ÍUTUEU±q†￾ÝUUm¼Sõ]ÔõÑuÕEÕwd5=D￾UÑTÕUFWeSá‘ƒ5\^}￾×cA￾”qETU]GUUW}gUeWWEGUuUUU9]…Y·QUUWQ^ÕU×Õ^YU…uWUguUUEUQuSUqÜugDÕEEYUQYmTCÑÆVUiUEET}]uuW—]5Á}PoØU×|DUU5ö]}wuUuÕu]uGÕUSÔ
QQ\÷ÍUÑeEUUTWßùÐUÕ￾DWtQUMmQUUEU·atUM×UÕUUÄUWU—UUUsW”UÓ}ÜugúH¶yö]çUAñEÂUU0eåwtRU5UustµGÀŒÔ`ÑÞ5YóDÕDEUÕ_U5ÕEÝUEyPUuÓ¼Ûu_wEßÕ×M•Ôñß”EEÕU￾QDÕuÑs]]VÔýOCÖô\BUUUVÐUÄQÙe0ÑÔaÓuuÝEQÍÑuRÔÇU]UÝ©tW×ÕÕÕÒ]—ÙOWWÓÕyÕUÿÌUÜuEV^Ç”DW×Ww]]}'uUTGÖUu]Uõ}EAEUUUUÅ5UåUUUÝÕt]ýuU×í]ÇTÝ}|ÕEUýÅÙuuÕUÕTUYÝ÷FÖe…UQTUQUÕUÓŸ˜UUauFMUŸEu7ÔTTEtÕUý5Á×EYUÕwW]EBuU]×TUÕuyoYV_aå
A QU UUW~}µ×T$UEMÔdETt”UUÍ@]Q×ÐAQôõÑ]TœéuuuÅUQµUUÕwÕÕWQWÕWÿ]W]ÓÕþ}GU•üuQUÞçURVÜWE—U=Ue@UUUe
™UA]p ]UUEETTØåUU]ÛUWqÕUD^M]Wå‘W7ÕUõWmWÔw_ÒÜV0EVteýUUUUwdxpÕUTUQU
Q^ÕÕoEñUq•U]%UUe0UV-TÅvWAUUGWUW]W•TQDQÑTS'￾ØÇÑDUTP_ÔUUÑOÖUT\VÍd|}QU;UUAG §ÄQ™WÀUÕUQWÉUQPHQØUUHÕ\yÕÝuÅUÕ]Õ%UEUWñU×WUWÕA}y·äQOEU__Q\]U￾Ô\%KC]ÄUaÃUUÇ÷ÓŒPUTDX•W4UÀÖ±WAÕÕE×WuQøE5^￾\õµ:ÕTUUÝDuWUWyña5qetMG\UTOÕ]Õ|\wÇÑ×qå[D_DM]T@ 
Å	dQåWÕ
UQUUUUEÕQxUwTÕ‘U‘bTÔÔEQGUUW]ÜU'üõQõE_e\²%EUÕwUUœåÕTR@ñlUTÍWÇO6ÕEÞƒÕåOÖÕST˜Q<YUQ‚uEYTÕ]•UUARTVT@&6W]QGEw×U]CWuU“ÅE=UUU!µ'GÜÅÝuUÔÿAS@;ØÕEÕómWuUÑFUqUgUUQØUEWAÕÑMrÿCÕõU×UUõÑPEtUIQUô^uuQVGˆÇmeÇlEUÆOUUVeTU”DeÅ4EY_wßqeWU5ÕÕQÔÕAUuõ]WÕUýUõUu÷LWô@U]uýwÝœÎÖv=•uQÝ×ru@QMõuTQHÑEUUx /GvÕÔG AUdUVQé6u$QÑTýRGU$õUWUuVqÕõY|qU]Ä'ÕGUUÔqQUWU\E‘üÅuÔT5QFÇWD]'RGLEPUEUEA	EÉU[]UuEo PEÕM
S]E@}\ÕU}\QC
IG1=0001

IG3:0640P\QE ￾PTYUÕ]T}fATøUX^pU×Œ\ŒAUqÝHLW5WQS`AA5@p€QTtTðESWqUU O5ôÑTTYÕÔô}TQ••‘tETU‰DP 
@	…T”UU¼1†U#•MPUqU5UâQpŽ]TtT'URÖW}µW—ðTWPÕUNUÜ]UEÑ ÅÕ]5G]‚u¹ÅIAP`UT@HõMU`UDPUuQUpMSDˆ2uVwWYTuQEÔsß†p×DÕU+·9t?UAÝUe•Ç!CUx@DFÁeU]YÕ@I¥yVµVeE–QyYE5TUdddpEtQQ9ÅEÇ…]TUUU￾µ—ùÿ|aPUMøFUT@T￾ÅuÕµW•q￾@ BTXÐX•LE@c@À„EÐW´ PT‘T?QTõQÕE`UôFôTFuDWuYÕuU5Q}ßT?áDYA•p\WQ—T@G1FbEQaQUuMUÖUTU•Á`F½É@\EPMSÕEUyQQ5VU]]TäñWUsT×ñAq}•ÔWeeA\¨5àÇ
ÑMXUET4mG]]<Lu”HD@1SU]ÑTPUzA\UY_UPQ4W‹ÝdUT@ÕesWWpEtuPQÄUáUIe/ÔU	1UA}eQUUU uPDeAM7ÕEÔUDBUQUÅU\wU]
Õß\]ôhíE€U•QTÅUOÇÕVwXAAUôyPN_Ä UrBíÁšUAEQPT8%SâIeQç–￾PAI•AsGZA˜MsÅUWTUyLWßUU¼FCQd_‹T^WÕ5TAQAðDQ@EAL•ÑUSÔQ]UÀgQ=Í\`@TmQAaUUNÄIT…Uþ4UÉPÝUVUÀETFUõ•	F ÔQE7ÐDø õõEEP…ÕÔ 7 B•\XHuÔDDRQõTM]ÔüR!]ýÝM!Qt@]QUÄgpUÕqYTX_tVePQJ1FEiUÄPÜTÐUHAZÄASå•pbL`FUC}TAEUÕÕQEAÕcÌmvUDYÄ}UE
ÝVQTM×ãÀD”µ4Õ|€DE
@5WuÅpmT5DÂP„U…EÂt=TDEÌÄ‰E!e×ÕU 8EPUD|ÅE]]uTGÆsMß¥•UõUu…Ö1P@ˆEÓÄW€E7T0ô€"	￾EAudRQP0@ôL  VPô@Þ1Q@]Ua&DˆÄuT2u\TQeUUUWEGV\|%ÐLgEóAQu_@T „D%Qv) ”AMAd‘fXP€	Õ\ ”TY…DãEEU ×ÒU\DqáŽuÅU¿]•UUUTUßHÌUÔäUESgiEÖvóUs)ao5“ç4QdÔUPBC*IHTÖTYQR]Á¥……QPW]5pW11õeD]ÔU
UUz¼uh_tTETuA2AdW–
ÑED:'AB


----------



## tuxedo (19. Dez 2007)

Hm, das sieht doch schon recht "sauber" aus.

Auf IG1 gibts eine Antwort mit "IG1=0001", gefolgt von einem offensichtlichen Zeilenumbruch
Auf IG2 gibts scheinbar eine "leere" Antwort, sprich eine Leerzeile
und auf IG3 kommen die Daten. Und auch IG3 scheint mit einem Zeilenumbruch abgeschlossen zu werden. 

Da liegt es fast nahe einen BufferedReader zu benutzen, und ein "readLine()" zu machen.
Wobei ich nicht weiß wie sich Binärdaten (Bild) in einem String verhalten. 
Ergo würde ich bei den DataInputStream bleiben.

Deine Anfragen an die Kamera formulierst du als String "IG1\n", machst ein Byte[] daraus, und sendest das ganze in den Ausgabestrom. Gefolgt von einem "flush()".

Danach musst du lesen. Da wir wissen dass die Anwort auf IG1 "IG1=0001" ist, wissen wir dass es mindestens 8 Zeichen zzgl. Zeilenumbruch sind. Der Zeilenumbruch kann entweder nur ein "\n" sein, oder auch ein "\n\r". Das solltest du versuchen rauszufinden. Einfach mal die ersten 8 Bytes nach dem IG1-Befehl lesen und die kommenden 2 Zeichen jeweils einzeln auf \n und \r vergleichen. Dann weißt du wie der Zeilenumbruch aussieht und kannst dann erkennen wann die nächste antwort anfängt.

Wenn du das hast, sollte es nicht schwer sein den Rest auch zu lesen. Bei IG2 kommt ja nix, nur der Zeilenumbruch.

Die Antwort von IG3 fängt ja immer mit "IG3:0640" an. Dummerweise sind das nur 8 Zeichen. In der Doku stand aber was von 9 Bytes Header.

.. Hmm... Wo taucht denn das "<ack> = das normal bestätigungszeichen... "\u0006" " auf?
Ich vermute mal das kommt noch VOR dem "IG3:0640" und kann nicht angezeigt werden? Wenn ja, dann muss das bei der Antwort von IG1 und 2 natürlich noch berücksichtigt werden und aus dem Strom rausgelesen werden.

Wichtig: Zeichen im Strom überspringen heisst: Trotzdem lesen, aber das gelesene verwerfen. Alternativ kann man in den meisten Streams auch die skip() Methode benutzen. Aber trotzdem auslesen und das ausgelesene verwerfen tut's auch.

Wenn das mit dem <ack> dann geklärt ist, kannst du den Header der IG3 Antwort lesen und ggf. wegwerfen. DANN liest du die 1600Bytes Bilddaten:


```
byte[] bild_teil = new byte[1600];
readfully(bild_teil);
```

Nicht vergessen: Auch hier den Zeilenumbruch wieder lesen und erkennen. Ohne einen korrekt erkanntes Ende der Antwort gerät dir alles durcheinander und es kommt das dabei raus was du vorhin beschrieben hast. Wichtig ist vor allem ob das Ende aus 1 oder 2 Zeichen besteht (also \n oder \n\r).

- Alex


----------



## Kaladial (19. Dez 2007)

also das <ack> wird in dem gepostet fall als viereck dargestellt () und bei IG2 kommt ebenfals ein <ack> + zeilenumbruch 

und auf IG1<CR> antwortet der scanner mit:
06 49 47 31 3D 30 30 30 31 0A 0D                  .IG1=0001..

<ACK> I G 1 = 0 0 0 1 <LF> <CR>

auf IG2:000000000001000100500014<CR>:

 06 0A 0D                                          ...

<ACK> <LF> <CR>

auf IG3:00000000000<CR>:

06 49 47 33 3A 30 36 34 30 D5 20 37 4D 75 72 77   .IG3:0640Õ 7Murw ... rest daten ...
59 75 55 55 31 56 5D 1D 1D 0A 0D                  YuUU1V]....

<ACK> I G 3 : 0 6 4 0 DATEN <LF> <CR>


----------



## tuxedo (19. Dez 2007)

Na das wird immer besser.

Wenn du jetzt nirgendwo ein Zeichen vergisst zu lesen, so müsste das ganze doch recht prima klappen?!

Wie gesagt: Durcheinander kanns nur kommen, wenn der Zeilenumbruch nicht korrekt berücksichtigt wird, oder du ein einfaches read() benutzt und nicht berücksichtigst, dass vielleicht nicht das ganze byte[] zu diesem zeitpunkt gefüllt werden konnte. Am besten alles mit readFully machen und das übergebene byte[] in die korrekte größe (wissen wir ja schon vorher anhand deinen eben geposteten aufzeichnungen) bringen.

- Alex

- Alex


----------



## Kaladial (19. Dez 2007)

hmmm also ich find nicht wirklich das mich die letzten posts irgendwie weiter gebracht haben ... 

wenn ich in meinem programm die befehle schicke kommen die ja nicht einfach so zurück sondern ich hab zum einen nen zeitversatz drin ...

also ich bin mir nicht ganz sicher aber viellicht muss ich meinen thread nochmal umbauen ... hmmm *arg* nur das is so nervig ...


----------



## tuxedo (19. Dez 2007)

Vielleicht solltest du dir ein minimales beispiel basteln, ohne thread, in dem du nur die kamera mit befehlen fütterst und alles was ankommt in die console, oder besser in eine Datei schreibst. 

Und dran denken: 
Wenn du das Programm neu startest, solltest du auch die Kamera neu starten. Denn die hat unter umständen noch irgendwelche Daten die gerade unterwegs sind und beim letzten mal nicht abgeholt wurden. Sicher ist sicher -> beides jeweils neu starten.

- Alex


----------



## Kaladial (19. Dez 2007)

hmmmm ich hab keine idee wie ich da anfangen soll...


----------



## tuxedo (19. Dez 2007)

Naja, ich kanns nicht ausprobieren da ich die Kamera nicht hab, abe rich würds mal so versuchen:


```
String portName = "COM1";
		
		CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
		
		if (portIdentifier.isCurrentlyOwned()) {
			
			System.out.println("Error: Port is currently in use");
			
		} else {
			
			CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);

			if (commPort instanceof SerialPort) {
				SerialPort serialPort = (SerialPort) commPort;
				serialPort.setSerialPortParams(57600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
		
				InputStream in = serialPort.getInputStream();
				OutputStream out = serialPort.getOutputStream();
		
				// für's readFully()
				DataInputStream dis = new DataInputStream(in);
				
				
				// für den zeilenumbruch
				byte[] umbruch_gelesen = new byte[2];
				byte[] umbruch_vergleich = new String("\n\r").getBytes();
				
				
				// Die 3 Befehle definieren
				String befehl1 = "IG1\n";
				String befehl2 = "IG2:000000000001000100500014\n";
				String befehl3 = "IG3:00000000000\n";
				
				
				
				// Sende Befehl 1
				out.write(befehl1.getBytes());
				out.flush();
				
				// Lese Antwort 1
				byte[] antwort1 = new byte[9]; 
				
				dis.readFully(antwort1);
				dis.readFully(umbruch_gelesen);
				if (umbruch_gelesen!=umbruch_vergleich) {
					System.err.println("Umbruch von Antwort 1 nicht gefunden");
					System.exit(1);
				}
				System.out.println(new String(antwort1)); // Auf der Console ausgeben
				
				// ----------
				
				// Sende Befehl 2
				out.write(befehl2.getBytes());
				out.flush();
				
				// Lese Antwort 2
				byte[] antwort2 = new byte[1]; 
				
				dis.readFully(antwort2);
				dis.readFully(umbruch_gelesen);
				if (umbruch_gelesen!=umbruch_vergleich) {
					System.err.println("Umbruch von Antwort 2 nicht gefunden");
					System.exit(1);
				}
				System.out.println(new String(antwort2)); // Auf der Console ausgeben
				
				// ----------
				
				// Sende Befehl 3
				out.write(befehl2.getBytes());
				out.flush();
				
				// Lese Antwort 3
				byte[] antwort3 = new byte[9];
				byte[] antwort3_bilddaten = new byte[1600];
				
				dis.readFully(antwort3);
				dis.readFully(antwort3_bilddaten);
				dis.readFully(umbruch_gelesen);
				if (umbruch_gelesen!=umbruch_vergleich) {
					System.err.println("Umbruch von Antwort 3 nicht gefunden");
					System.exit(1);
				}
				System.out.println(new String(antwort3)); // Auf der Console ausgeben
				System.out.println(new String(antwort3_bilddaten)); // Auf der Console ausgeben

		
			} 
		}
```

Wenn das Programm vor der ausgabe des antwort3_bilddaten Arrays hängt, dann dürfte was mit der kamera nicht stimmen oder du musst\n\r in \r\n umdrehen.

- Alex


----------



## Kaladial (19. Dez 2007)

hmmm der meine byte-arrays net miteinander vergleichen ... 
umbruch_vergleich und umbruch_gelesen verweisen ja nur auf ne speicheradresse ... ich glaub net das man die so einfach miteinander vergleichen kann


----------



## Kaladial (19. Dez 2007)

also nachdem ich den vergleich angepasst hab muss ich sagen das es geht  

ich werd das jetzt mal versuchen bei mir einzubauen  dank dir


----------



## tuxedo (19. Dez 2007)

Na dann wirst du doch im stande sein das bisschen so umzuschreiben dass Element für Element verglichen wird?! Sind ja nur 2. Oder du machst es ganz anders. Was ich damit bezwecken wollte ist ja ersichtlich, oder?

Habs noch weiter auf Fehler überprüft da ich weder so ne kamera, noch die RXTX Library aufm Rechner hab. Hab einfache in Beispiel von RXTX.org genommen und ein wenig umgeschrieben/angepasst/reduziert

- Alex


----------



## Kaladial (19. Dez 2007)

siehe letzten post


----------



## tuxedo (19. Dez 2007)

Ah, da war ich zu schnell.

Läuft das Programm nur oder macht es auch noch das was es soll?
Sprich: Kommt noch was durcheinander?

Wenns mal soweit funktioniert, dann würd ich dieses einfache beispiel, bevor du das ganze in dein Programm reinfrickelst, ein wenig ausbauen und versuchen mit der schleife die in der Doku beschrieben ist, alle 192 Blöcke zu lesen und gesammelt in eine File zu schreiben.

- Alex


----------



## Kaladial (19. Dez 2007)

also es macht das was es soll...

ich werde jetzt als erstes mal die bildausgabe so einbauen wie du es gemeint hast und das ganze dann in die bilddatei speichern ... 

ich geb dir dann bescheid ob alles so funktioniert wie gewollt aber bisher sieht es auf jedenfall sehr gut aus


----------



## tuxedo (19. Dez 2007)

Na dann bin ich ja beruhigt. Lag wohl doch an "vergessenen" oder "nicht berücksichtigten" Zeichen, oder einem einfachen "read()", welches weniger gelesen hat als es sollte und das nicht abgefangen wurde.

- Alex


----------



## Kaladial (19. Dez 2007)

jup... 
also ich hab jetzt auch meine ersten bilder eingelesen und es geht  

also nochmal vielen vielen dank


----------



## tuxedo (19. Dez 2007)

Was lange währt wird endlich gut... Und du wolltest schon das Handtuch werfen, wo es doch "so einfach" ist das Bild da raus zu bekommen ;-)

Also, viel Spass mit der Kamera. Abhaken nicht vergessen ;-)


----------



## Kaladial (20. Dez 2007)

is doch schon abgehackt


----------

