Java - seriovy port – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Java - seriovy port – Java – Fórum – Programujte.comJava - seriovy port – Java – Fórum – Programujte.com

 

martin
~ Anonymní uživatel
1600 příspěvků
22. 10. 2012   #1
-
0
-

Ahoj, 

potrebuju v Jave komunikovat se zarizenim pripojenym na seriovy port (RS-232). Nyni mam program napsany a funkcni ve FreePascalu, potrebuji ho ale prepsat do Javy. Nasel jsem knihovnu RXTX. Vypada docela dobre, co si o ni myslite? http://rxtx.qbang.org/

Do zarizeni se posilaji prikazy ve forme pismen, napr. "E", zarizeni odpovi textem, napr. "+21.8", nebo "A_ON".

V Jave se mi to porad nedari.

Pokousim se upravit ukazkovy kod, co jsem nekde stahnul: 

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test {
	public Test() {
		super();
	}

	void connect(String portName) throws Exception {
		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();

				(new Thread(new SerialReader(in))).start();
				(new Thread(new SerialWriter(out))).start();

			} else {
				System.out
						.println("Error: Only serial ports are handled by this example.");
			}
		}
	}

	/** */
	public static class SerialReader implements Runnable {
		InputStream in;

		public SerialReader(InputStream in) {
			this.in = in;
		}

		public void run() {
			byte[] buffer = new byte[1024];
			int len = -1;
			try {
				while ((len = this.in.read(buffer)) > -1) {
					System.out.print(new String(buffer, 0, len));
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/** */
	public static class SerialWriter implements Runnable {
		OutputStream out;

		public SerialWriter(OutputStream out) {
			this.out = out;
		}

		public void run() {
			try {


				// this.out.write(c);
				this.out.write('B');
			//	this.out.write('\r');
				//this.out.write('\n');

				// int c = 0;
				// while ((c = System.in.read()) > -1) {
				// this.out.write(c);
				// }
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		try {
			(new Test()).connect("/dev/ttyUSB0");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

ale porad to nejde. :-(

Muzete mi prosim nekdo poradit?

Nahlásit jako SPAM
IP: 93.89.146.–
sleepy0
Stálý člen
23. 10. 2012   #2
-
0
-

Skus dopisat v SerialWirter-i v metde run() hned za this.out.write('B'); this.out.flush();

Nahlásit jako SPAM
IP: 158.195.195.–
sleepy0
Stálý člen
23. 10. 2012   #3
-
0
-

Inak napis co ti to vypisuje

Nahlásit jako SPAM
IP: 158.195.195.–
martin
~ Anonymní uživatel
1600 příspěvků
28. 10. 2012   #4
-
0
-

#2 sleepy
Diky za pomoc. this.out.flush(); to vyresilo :-)

Nahlásit jako SPAM
IP: 93.89.146.–
martin
~ Anonymní uživatel
1600 příspěvků
28. 10. 2012   #5
-
0
-

Zapis uz mi funguje, ale nyni mam problem se ctenim. 

Do zarizeni poslu pismeno, zarizeni neco vykona a odesle zpet do PC nejaky text. Napr. kdyz poslu do zarizeni 'C', tak odpovi 'STOP'. Po odeslani 'C' do zarizeni reaguje spravne, ale na PC uz se mi nedari prescist 'STOP'. 

Zkousel jsem pridat  

serialPort.disableReceiveTimeout();
serialPort.enableReceiveThreshold(1);

coz jsem neasel v nejakem navodu, ale nepomohlo to.

Vystup po spusteni je: 

precteno: null

Muzete mi prosim poradit, kde je chyba? 

/* ##################################################### */
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.InputStream;
import java.io.OutputStream;

public class Hlavni {
	public static String nactenyText;
	private SerialPort serialPort;

	private void connect(String portName, int baudRate) throws Exception {
		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 = (SerialPort) commPort;
				serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

				// http://mattiaslife.blogspot.cz/…locking.html
				
				serialPort.disableReceiveTimeout();
				serialPort.enableReceiveThreshold(1);
								
				InputStream in = serialPort.getInputStream();
				OutputStream out = serialPort.getOutputStream();
				
				new SerialReader(in).start();			
				new SerialWriter(out, 'a').start();
				new SerialWriter(out, 'c', 2000).start();	

				System.out.println("precteno: " + nactenyText);
				

			} else {
				System.out
						.println("Error: Only serial ports are handled by this example.");
			}
		}
	}

	public static void main(String[] args) {
		try {
			new Hlavni().connect("/dev/ttyUSB1", 57600);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
/* ##################################################### */
import java.io.IOException;
import java.io.InputStream;

public class SerialReader extends Thread {
		InputStream in;

		public SerialReader(InputStream in) {
			this.in = in;
		}

		public void run() {
			byte[] buffer = new byte[1024];
			int len = 0;
			try {
				while ((len = this.in.read(buffer)) == -1) {
					Thread.sleep(10);
					String nacteno = new String(buffer, 0, len);
					System.out.print("ABC: " + nacteno);
					Hlavni.nactenyText = nacteno;
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
/* ##################################################### */
import java.io.IOException;
import java.io.OutputStream;

public class SerialWriter extends Thread {
	OutputStream out;
	private char znak;
	private int uspat = 0;

	public SerialWriter(OutputStream out, char znak, int cekat) {
		this.out = out;
		this.znak = znak;
		this.uspat = cekat;
	}

	public SerialWriter(OutputStream out, char znak) {
		this.out = out;
		this.znak = znak;
	}

	public void run() {
		try {

			Thread.sleep(uspat);
			this.out.write(znak);

			this.out.flush();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
/* ##################################################### */
Nahlásit jako SPAM
IP: 93.89.146.–
sleepy0
Stálý člen
30. 10. 2012   #6
-
0
-

tu mas nieco o CommPorte: http://docs.oracle.com/cd/E17802_01/products/products/javacomm/reference/api/javax/comm/CommPort.html#getInputStream()

Skus mozno vypnut RecieveTreshold: serialPort.disableRecieveTreshold(). Inak to Thread.sleep() v SerialReadri je podla vsetkeho zbytocne, kedze CommPort by mal vediet InputStream blokovat.

To System.out.print("ABC: "+nacteno) ti nieco vypisuje, alebo len "ABC :", alebo to uplne preskoci. Skus za while((len = in.read(b))!=-1){} Dat System.out.println("Dlzka retazca:" +len); Aby si zistil ci to vobec cita, ale to si uz asi skusal.

Alebo to urob ako je to na tom blogu:

Nahlásit jako SPAM
IP: 158.195.195.–
sleepy0
Stálý člen
30. 10. 2012   #7
-
0
-

ze si vytvoris tie dve metody na citanie. Alebo si stiahni verziu 2.2 pre release tam by to malo byt funkcne.

Nahlásit jako SPAM
IP: 158.195.195.–
martin
~ Anonymní uživatel
1600 příspěvků
4. 11. 2012   #8
-
0
-

#6 sleepy

Tak jsem to upravil a porad to nejde:

V Hlavni tride mam:

serialPort.disableReceiveTimeout();
serialPort.disableReceiveThreshold();
import java.io.IOException;
import java.io.InputStream;

public class SerialReader extends Thread {
		InputStream in;

		public SerialReader(InputStream in) {
			this.in = in;
		}

		public void run() {
			byte[] buffer = new byte[1024];
			int len = 0;
			String nacteno = "";
			try {				
				while ((len = this.in.read(buffer)) == -1) {
					nacteno = new String(buffer, 0, len);
					System.out.print("X: " + nacteno);
				}
				System.out.println("ABC: " + nacteno);
				System.out.println("DelkaRetezce: " + len); 
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
	}

Po spusteni to vypise:

B: 
DelkaRetezce: 1
Nahlásit jako SPAM
IP: 93.89.146.–
martin
~ Anonymní uživatel
1600 příspěvků
4. 11. 2012   #9
-
0
-

#8 martin
Spletl jsem se, vypise to:

ABC: 
DelkaRetezce: 1
Nahlásit jako SPAM
IP: 93.89.146.–
liborb
~ Redaktor
+18
Guru
5. 11. 2012   #10
-
+1
-
Zajímavé

Máš obráceně podmínku.

while ((len = this.in.read(buffer)) == -1) {

To v překladu znamená, dělej dokud se nic nenačte a když se načte, tak to skončí a ke zpracování dat v těle cyklu už nedojde. To se děje jen, když je len == -1. A dále, data po sériové lince chodí velmi pomalu, takže ti to nejspíše skončí, když to načte písmeno S, ale na ty další už by se ti stejně nedostalo.

Normálně se konec zprávy rozezná buď meziznakovou mezerou (to na PC uděláš těžko) nebo se zvolí speciální startovací a ukončovací znak nebo víš, co ti má přijít a zprávu rozebíráš hned jak ti chodí jednotlivé znaky. A nepřijetí odpovědi se vyhodnocuje po nějakém timetoutu (dle rychlosti).

Takhle nějak by mohlo vypadat načítání odpovědi, u které neznáme strukturu, ale víme, že přijde do 3s. V nacteno je celá zpráva o délce total.

nacteno = "";
long start = System.currentTimeMillis();
long total = 0;

while (1) {
	len = this.in.read(buffer));
	if (len > 0) {
		nacteno += new String(buffer, 0, len);
		System.out.print("X: " + nacteno);
		total += len;
	}
	else Thread.sleep(50);

	if ((System.currentTimeMillis() - start) > 3000)
		break;
}
Nahlásit jako SPAM
IP: 188.75.135.–
tux.martin
~ Anonymní uživatel
15 příspěvků
5. 11. 2012   #11
-
0
-

#10 liborb
Diky, uz to funguje!

Jen jeste jeden detail. Mam: 

public void run() {
			byte[] buffer = new byte[1024];
			int len = 0;
			String nacteno = "";

			long start = System.currentTimeMillis();
			while (true) {
				try {
					len = this.in.read(buffer);
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (len > 0) {
					nacteno += new String(buffer, 0, len);
					System.out.println("Nacteno: " + nacteno);
				} else
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				if ((System.currentTimeMillis() - start) > 5000)
					break;
			}	
			System.out.println("NactenoEND: " + nacteno);
		}

A po spusteni to vrati: 

Nacteno: S
Nacteno: STO
Nacteno: STOP
Nacteno: STOP_OK

Proc se vubec neprovede ten radek System.out.println("NactenoEND: " + nacteno); ?

Nahlásit jako SPAM
IP: 93.89.146.–
sleepy0
Stálý člen
5. 11. 2012   #12
-
0
-

skus to slusne obzatvorkovat a dopis tam:

if (len > 0) {
	nacteno += new String(buffer, 0, len);
	System.out.println("Nacteno: " + nacteno);
 
}
else
{
	try {
		Thread.sleep(50);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}
if ((System.currentTimeMillis() - start) > 5000)
	break;

alebo nepuzivaj toto ale sprav to ako predtym ale vo while musi byt ina podmienka, lebo vyzera ze "length" odosiela spravne:

// tento riadok
while ((len = this.in.read(buffer)) == -1) 
// nahrad
while ((len = this.in.read(buffer)) != -1)

ono by to malo fungovat spravne. A metoda read(byte[] a) by mala cakta dovtedy pokial nieco nedorazia nejake data. Inak vwlmi sa ospravedlunujem, ze som si nevsimol u teba == a potom som ta nevedomky plietol.

Nahlásit jako SPAM
IP: 213.215.67.–
sleepy0
Stálý člen
5. 11. 2012   #13
-
0
-

#11 tux.martin
nechal si to bezat aspon 5 sekund?

Nahlásit jako SPAM
IP: 213.215.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 3 hosté

Podobná vlákna

Seriovy port v C — založil jatagan

Sériový port — založil Yety

Seriovy port v C — založil jatagan

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý