|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
irn : 59 Новичок
|
Май 13, 2009 9:32 |
|
|
Здравствуйте.
Имеется устройство подсоединенное к LPT порту. Оно выдает разные коды в порт на которые нужно реагировать. Можно ли как то с помощью java реализовать данный механизм? И какими средствами? |
|
|
|
 |
gidravlic : 402 Бывалый Откуда: Латвия, Рига
|
Май 13, 2009 10:02 |
|
|
|
|
|
|
 |
irn : 59 Новичок
|
Май 13, 2009 18:36 |
|
|
| Спасибо. Сегодня попробую |
|
|
|
 |
irn : 59 Новичок
|
Окт 28, 2009 12:17 |
|
|
Пробовал пользоваться javax.comm Sun овский.
| Цитата: |
portList = CommPortIdentifier.getPortIdentifiers();
|
Этот код не возвращает мне никаких портов в моей системе. В чем может быть проблема?! |
|
|
|
 |
gidravlic : 402 Бывалый Откуда: Латвия, Рига
|
Окт 28, 2009 13:30 |
|
|
| Sun'овский не развивается. Пробуйте, то что я вам рекомендовал |
|
|
|
 |
tender_swallow : 472 Бывалый Откуда: Ivanovo
|
Окт 28, 2009 14:02 |
|
|
| irn писал(а): |
Пробовал пользоваться javax.comm Sun овский.
| Цитата: |
portList = CommPortIdentifier.getPortIdentifiers();
|
Этот код не возвращает мне никаких портов в моей системе. В чем может быть проблема?! |
Вы не правильно установили библиотеку. Скорее всего вы просто положили библиотеку comm.jar, а про dll забыли.
Вот инструкция по установке sun библиотеки:
<jdk> корневой каталог JDK.
Положите файл win32com.dll в директорию <jdk>\jre\bin .
Положите архив comm.jar в директорию <jdk>\jre\lib\ext.
Положите файл javax.comm.properties в <jdk>\jre\lib . |
|
|
|
 |
alon4ik : 923 free butterfly Откуда: Харьков
|
Окт 28, 2009 14:09 |
|
|
| занимаюсь аналогичной задачей, работаю через COM c самодельным контроллером, всё работает наура! есть кое-какие наработки, если интересует - могу поделиться. |
|
|
|
 |
gidravlic : 402 Бывалый Откуда: Латвия, Рига
|
Окт 28, 2009 14:19 |
|
|
Интересно было бы посмотреть  |
|
|
|
 |
alon4ik : 923 free butterfly Откуда: Харьков
|
Окт 28, 2009 14:44 |
|
|
| gidravlic писал(а): |
Интересно было бы посмотреть  |
смотря что.
например у меня стояла задача работать с контроллером, подключенным к com-порту следующим образом: устройство периодически посылает данные в ком-порт в зависимости от своего состояния, а я в программе перехватываю их, обрабатываю, выполняю какие-то действия и посылаю команды в этот же порт. Устройство получает их и в зависимости от команды тоже что-то выполняет. Собственно, задача не сильно сложная, создается объект класса, который работает с портом. В нем реализованы такие действия, как получение списка портов в системе, открытие порта, создание инпут- и аутпут-стрима, установка параметров порта и т.д. Также в конструкторе создаю экземпляр класса, который в отдельном потоке будет постоянно прослушивать порт на наличие новых данных, если таковые пришли - записывать из в буфер и ставить флаг, что доступны новые данные.
Вот собственно наброски.
| Код: |
import javax.comm.*;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.TooManyListenersException;
/**
*
*
*/
public class ComPort {
// Скорость обмена данными с ком-портом
private final int portSpeed = 19200;
// Список указателей на порты в системе
private Enumeration portListEnum;
// Список имен портов (напр, "COM1","COM2","COM5" ..)
private ArrayList portList = new ArrayList();
// Порт, с которым будет ассоциирован объект, напр. COM1
private String comPort;
// Указатель на идентификатор порта
private CommPortIdentifier portId;
// Serial Port
private SerialPort serialPort;
// Поток для записи данных в порт
private OutputStream outputStream;
// Поток для чтения данных
private InputStream inputStream;
// Длина буфера для чтения данных
private static final int readBufferLength = 2;
// Буфер для чтения данных с ком-порта
private byte[] readBuffer = new byte[readBufferLength];
// Состояние буфера. Если доступны новые данные, принимает значение true
private boolean newDataAvailable = false;
// Фактическое количество прочитанных в буфер байт
private int numBytes;
// Хранит состояние порта, тоесть был ли порт инициализирован
private boolean comInitialized = false;
// -------------------------------------------------------------------------
// Возвращает true, если доступны новые данные в буфере
public boolean dataAvailable(){
return this.newDataAvailable;
}
// Возвращает длину буфера
public int getReadBufferLength(){
return readBufferLength;
}
// Метод возвращает количество фактически прочитанных байт
public int getNumBytes(){
return numBytes;
}
// Был ли инициализирован порт
public boolean initialized(){
return comInitialized;
}
public String getName(){
return comPort;
}
// Конструктор
ComPort(String comPort){
super();
// Получаем список портов в системе
portListEnum = CommPortIdentifier.getPortIdentifiers();
// Запоминаем порт, с которым будет работать объект
this.comPort = comPort;
while (portListEnum.hasMoreElements()) {
portId = (CommPortIdentifier) portListEnum.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
// Добавим имя в List
portList.add(portId.getName());
// Работа с портом
if (portId.getName().equals(comPort)) {
// Открываем порт
try {
serialPort = (SerialPort) portId.open("ComPortApp", 2000);
}
catch (PortInUseException e) {
MessageBox.message("Не могу открыть порт! Порт " + comPort + " используется другим приложеним!");
System.exit(1);
}
// Открываем потоки для чтения и записи в порт
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
}
catch (IOException e) {
MessageBox.message("Ошибка открытия входного/выходного потока ком-порта!");
System.exit(1);
}
// Устанавливаем параметры порта
try {
serialPort.setSerialPortParams(portSpeed,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e) {
MessageBox.message("Не могу установить параметры ком-порта!");
System.exit(1);
}
// Создаем экземпляр объекта, которые в новом потоке будет прослушивать ком-порт
// и если будут доступны данные, считывать их в readBuffer
new SimpleRead();
}
// Порт открыть не удалось
}
}
if (serialPort == null) {
MessageBox.message("Не могу открыть порт " + comPort);
System.exit(1);
}
// Установим флаг, что порт инициализирован
comInitialized = true;
}
// Метод возвращает данные из буфера в виде строки
public synchronized byte[] getData(){
return readBuffer;
}
// Возвращает список доступных портов
public ArrayList portList(){
return portList;
}
// Возвращает ком-порт, на который настроен текущий объект класса
public String getComPort(){
return comPort;
}
public void resetDataAvailableFlag(){
newDataAvailable = false;
}
// Метод пишет в ком-пор строку символов
public void writeString(String writeString) throws IOException{
// Пишим в порт
try{
outputStream.write(writeString.getBytes());
}
catch (IOException e) {}
}
// Метод пишет в ком-пор байт
public void writeByte(byte b) throws IOException{
// Пишим в порт
try{
outputStream.write(b);
}
catch (IOException e) {
MessageBox.message("Ошибка записи в ком-порт!");
System.exit(1);
}
}
// Внутренний класс
class SimpleRead implements Runnable, SerialPortEventListener {
// Поток, в котором будет осуществляться чтение порта
Thread readThread;
// Конструктор
public SimpleRead(){
read();
}
public synchronized void read(){
// Зарегистрируем оповещение
try {
serialPort.addEventListener(this);
}
catch (TooManyListenersException e) {
MessageBox.message("Не могу установить слушатель для порта, слишком много слушателей!");
System.exit(1);
}
// Включим оповещение о доступности данных
serialPort.notifyOnDataAvailable(true);
// Запускаем прослушиватель в новом потоке
readThread = new Thread(this);
readThread.start();
}
public void run() {
}
public void serialEvent(SerialPortEvent event) {
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:
try {
while (inputStream.available() > 0) {
// Читаем данные в буфер и запоминаем кол-во прочитанных байт
numBytes = inputStream.read(readBuffer);
}
// Устанавливаем флаг, что доступны новые данные
newDataAvailable = true;
} catch (IOException e) {
MessageBox.message("Ошибка при чтении данных с ком-порта!");
//System.exit(1);
}
}
break;
}
}
}
} |
В основной программы делаем что-то типа
| Код: |
| ComPort comPort = new ComPort("COM1"); |
далее, если надо что-то записать в порт -
| Код: |
| comPort.writeByte(1); |
если проверить, если надо подождать данные то делаем что-то типа:
| Код: |
// Переменная для считывания данных с порта
byte[] data = new byte[comPort.getReadBufferLength()];
comPort.resetDataAvailableFlag(); // сброс флага доступности новых данных
while (!comPort.dataAvailable()){ // Ожидаем получения данных
sleep(50);
if ( comPort.dataAvailable()) { // Если есть данные
data = comPort.getData(); // Получаем их
switch (data[0]) {
case 1 : {}
case 2 : {}
}
}
} |
|
|
|
|
 |
gidravlic : 402 Бывалый Откуда: Латвия, Рига
|
Окт 28, 2009 16:10 |
|
|
| Хороший пост! Я думаю, что вопрошающему будет достаточно этого примера |
|
|
|
 |
irn : 59 Новичок
|
Окт 31, 2009 11:10 |
|
|
Попробовал выполнить операции что сказал tender_swallow. Под виндой все получилось. Но я программу пишу и на Windows и на Fedora 11 x64. Вижу что у RXTX есть библиотеки под 64-х битный линух. Выполнил все действия по установке этой библиотеки под мою федору. При запуске приложения ошибок не выдает, но и имена портов тоже.. Ниже код:
| Код: |
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier port;
while (portList.hasMoreElements()){
port = (CommPortIdentifier) portList.nextElement();
System.out.println(port.getName());
}
}
|
|
|
|
|
 |
alon4ik : 923 free butterfly Откуда: Харьков
|
Окт 31, 2009 13:12 |
|
|
| значит по какой-то причине CommPortIdentifier.getPortIdentifiers(); ничего не возвращает |
|
|
|
 |
tender_swallow : 472 Бывалый Откуда: Ivanovo
|
Окт 31, 2009 16:05 |
|
|
| irn писал(а): |
Попробовал выполнить операции что сказал tender_swallow. Под виндой все получилось. Но я программу пишу и на Windows и на Fedora 11 x64. Вижу что у RXTX есть библиотеки под 64-х битный линух. Выполнил все действия по установке этой библиотеки под мою федору. При запуске приложения ошибок не выдает, но и имена портов тоже.. Ниже код:
|
Под линукс с com портами не работал, но предполагаю ,что раз поведение такое же как и при неправильной установке библиотек, то предполагаю, что под линукс вы так же не правильно поставили библиотеки, попробуйте поискать инструкции по установке данных библиотек под линукс. |
|
|
|
 |
irn : 59 Новичок
|
Окт 31, 2009 19:26 |
|
|
| Дело было таки в правах доступа к устройствам /dev/lpX and /dev/ttySX. Как только дал права на чтение, сразу это устройство отобразилось в цикле.. |
|
|
|
 |
tender_swallow : 472 Бывалый Откуда: Ivanovo
|
Окт 31, 2009 21:19 |
|
|
| Отлично! Учту это на будущее, т.к. тоже хочу свое приложение заточить еще по linux. |
|
|
|
 |
|
|
Страница 1 из 2 На страницу 1, 2 След. |
Список форумов
-> Файлы и потоки ввода/вывода |
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|