I am trying to communicate with the Serial Port. In the following program I listed the the available ports, it is giving me proper output but when I tried to establish a communication with serial port it gave me following exception.
java.lang.ClassCastException: gnu.io.LPRPort cannot be cast to gnu.io.SerialPort
Program:
import gnu.io.CommPortIdentifier;
import gnu.io.*;
import java.io.*;
import java.util.Enumeration;
public class PortList {
private static CommPortIdentifier port;
private SerialPort serialport;
private InputStream inputstream;
private OutputStream outputstream;
private static Enumeration ports;
public static void main(String args[]) {
System.out.println("fdsgfjh");
ports = CommPortIdentifier.getPortIdentifiers();
System.out.println(ports.nextElement());
while (ports.hasMoreElements()) {
port = (CommPortIdentifier)ports.nextElement();
String type;
switch (port.getPortType()) {
case CommPortIdentifier.PORT_PARALLEL:
type = "Parallel";
break;
case CommPortIdentifier.PORT_SERIAL:
type = "Serial";
break;
default: /// Shouldn't happen
type = "Unknown";
break;
}
System.out.println(port.getName() + ": " + type);
}
PortList objOfClass=new PortList();
objOfClass.readData();
}
public void readData(){
try{
if (port.isCurrentlyOwned()) {
System.out.println("Port Is In Use");
}
else {
serialport=(SerialPort)port.open(this.getClass().getName(), 2000);//Giving Exception on this line.
System.out.println("Port Is Opened now");
int baudRate=serialport.getBaudRate();
System.out.println(Integer.toString(baudRate));
serialport.setSerialPortParams(1200, 8, 1, serialport.PARITY_NONE);
System.out.println("Properties are set");
inputstream=serialport.getInputStream();
outputstream=serialport.getOutputStream();
byte[] write={12,45,78};
outputstream.write(write);//you have to write the data in the byte format for that status is given in the byte.
outputstream.flush();
byte[] read=new byte[30];
inputstream.read(read);
for(int i =0; i< read.length;i++){
System.out.println(i+" "+read);
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
Help Appreciated.
Thanks.
According to your implementation, port will be the last listed port. The last listed port may not be a Serial Port.
In your case, it appears that the last listed port is a parallel port.
In this way I selected the particular port which is available.
CommPortIdentifier.getPortIdentifier("/dev/ttyS0");
Related
I've been trying to establish a TCP socket connection between an ESP32 board and a Java server. After establishing the connection, I want the server to send a packet to the ESP32 to request its ID (I use the ID to identify the clients, as there are going to be more of them), but the server doesn't seem to be transmitting anything (ESP32 isn't receiving anything). I even tried using Wireshark to track the packets, but upon connection, there is no message to be seen. Sorry for the horrible code, I'm still a beginner, when it comes to communication programming. Thanks in advance for your help.
Here is the code for the ESP32:
#include <WiFi.h>
WiFiClient client;
// network info
char *ssid = "SSID";
char *pass = "Password";
// wifi stats
int wifiStatus;
int connAttempts = 0;
// Client ID
int id = 128;
IPAddress server(192,168,1,14);
int port = 3241;
String inData;
void setup() {
Serial.begin(115200); // for debug
// attempting to connect to the network
wifiStatus = WiFi.begin(ssid, pass);
while(wifiStatus != WL_CONNECTED){
Serial.print("Attempting to connect to the network, attempt: ");
Serial.println(connAttempts++);
wifiStatus = WiFi.begin(ssid, pass);
delay(1000);
}
// info
Serial.print("Connected to the network, IP address is: '");
Serial.print(WiFi.localIP());
Serial.print("', that took ");
Serial.print(connAttempts);
Serial.println(" attempt(s).");
connAttempts = 0;
// connection to the main server
Serial.println("Starting connection to the server...");
while(!client.connect(server, port)){
Serial.print("Attempting connection to the server, attempt no. ");
Serial.println(connAttempts++);
delay(1000);
}
Serial.print("Connection successful after ");
Serial.print(connAttempts);
Serial.println(" attempt(s)!");
}
void loop() {
if(client.available()){
Serial.println("Incoming data!");
inData = client.readString();
}
if(inData != ""){
Serial.print("Incoming data: ");
Serial.println(inData);
if(inData == "REQ_ID"){
String msg = "INTRODUCTION;"
strcat(msg, m);
client.print(msg);
}
inData = "";
}
if(!client.connected()){
Serial.println("Lost connection to the server! Reconnecting...");
connAttempts = 0;
while(!client.connect(server, port)){
Serial.print("Attempting connection to the server, attempt no. ");
Serial.println(connAttempts++);
delay(1000);
}
Serial.print("Reconnection successful after ");
Serial.print(connAttempts);
Serial.println(" attempt(s)!");
}
delay(10);
}
And here is the client handler class from the Java server:
package org.elektrio.vsd2020;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
public class ClientHandler implements Runnable {
public Socket netSocket;
public BufferedInputStream in;
public BufferedOutputStream out;
private int clientID;
public ClientHandler(Socket skt) throws IOException {
this.netSocket = skt;
this.in = new BufferedInputStream(this.netSocket.getInputStream());
this.out = new BufferedOutputStream(this.netSocket.getOutputStream());
}
public void close() throws IOException{
this.in.close();
this.out.close();
this.netSocket.close();
}
#Override
public void run() {
while(netSocket.isConnected()){
try{
byte[] arr = new byte[2048];
in.read(arr);
String[] input = new String(arr, StandardCharsets.US_ASCII).split(";");
// if the message is tagged as "INTRODUCTION", it identifies a reply from the ESP32, which contains the client ID
if(input[0].equals("INTRODUCTION")){
clientID = Integer.parseInt(input[1]);
}
}
catch (IOException e) {
System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Exception at client ID '" + clientID + "'!");
e.printStackTrace();
}
}
System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Client ID '" + clientID + "' disconnected!");
Tools.clients.remove(this);
}
public int getID(){
return clientID;
}
public int reqID() throws IOException{
String req = "REQ_ID";
out.write(req.getBytes(StandardCharsets.US_ASCII));
}
}
Server's main class:
package org.elektrio.vsd2020;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static ServerSocket server;
public static ServerSocket remoteAccessServer;
public static ExecutorService pool;
public static boolean serviceRunning = true;
public static void main(String[] args) {
try{
// startup args
int port = args.length > 0 ? Integer.parseInt(args[0]) : 3241;
int maxClients = args.length > 1 ? Integer.parseInt(args[2]) : 10;
// startup parameters info
Tools.log("Main", "Server started with parameters: ");
if(args.length > 0) Tools.log("Main", args);
else Tools.log("Main", "Default parameters");
// server socket and the threadpool, where the client threads get executed
server = new ServerSocket(port);
pool = Executors.newFixedThreadPool(maxClients);
// main loop
while(true){
if(Tools.clients.size() < maxClients){
// connection establishment
Socket clientSocket = server.accept();
ClientHandler client = new ClientHandler(clientSocket);
Tools.log("Main", "New client connected from " + clientSocket.getRemoteSocketAddress());
// starting the client operation
pool.execute(client);
Tools.clients.add(client);
Thread.sleep(500);
client.reqID();
}
}
}
catch (IOException | InterruptedException ioe){
Tools.log("Main", "IOException at MAIN");
ioe.printStackTrace();
}
}
}
And lastly, the Tools class
package org.elektrio.vsd2020;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class Tools {
public static ArrayList<ClientHandler> clients = new ArrayList<>();
public static void log(String origin, String message){
System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + message);
}
public static void log(String origin, String[] messages){
for(String msg : messages) System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + msg);
}
}
I have some recommendations:
I- Your server implementation, i.e. while(true){... Thread.sleep(500); ... }, resembles microcontroller-style programming. Java has much more powerful tools for socket communication, such as reactive frameworks. I suggest using frameworks like Netty:
Netty 4 User Guide
Introduction to Netty
It may require some effort to learn these but their performance is much better.
And also there exists modern protocols for IoT systems, like MQTT or even RSocket. You can use them instead of plain TCP connection.
II: In IoT systems, isolating the problem is very important. So in your case, using TCP terminal tools like Hercules helps a lot. These tools can act as both server and client; so you can use them instead of ESP32 and Java Server and test if the other side works well.
III: In IoT communications, try to limit the messages. Thus Instead of this conversion between ESP32 and Java:
ESP32: Hi
Java: Hello, who are you?
. My ID is ...
. Pass me the data...
. Here is the data...
Use this:
ESP32: Hi. I am ID .. and This is my data
Server: OK Thanks!
import javax.swing.*;
import java.io.Serializable;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server implements Serializable{
public static void main(String[] args) {
String test1= JOptionPane.showInputDialog(null,"Port(0-65535):","Port",JOptionPane.QUESTION_MESSAGE);
int portnumber = tryParse(test1);
if (portnumber !=0) {
try {
Registry reg = LocateRegistry.createRegistry(portnumber); //Creates and exports a Registry instance on the local host that accepts requests
RmiImplementation imp = new RmiImplementation("C://ServerStorage");
reg.bind("remoteObject", imp);
System.out.println("Server is ready.");
System.out.println(portnumber);
} catch (Exception e) {
System.out.println("Server failed: " + e);
}
}
}
private static Integer tryParse(String text) {
try {
return Integer.parseInt(text);
} catch (Exception e) {
return 0;
}
}
}
The above code helps me to set up my file server.
when the application is run, the dialog port number is requested.
If I type letters instead of numbers the program stops running, but I want it to continue and show me the dialog again.
Try with a do-while,
int portnumber = 0;
do {
String text= JOptionPane.showInputDialog(null,"Port(0-65535):","Port",JOptionPane.QUESTION_MESSAGE);
portnumber = tryParse(text);
}while(portnumber==0);
I'm facing a problem regarding of using the data from rf transmision on a class that I wish to use to store on the database. Code 1 is the code for the RF transmission. Is there anyway I can use the data in the
highlight of data to be used in code 1?
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
String[] parts = inputLine.split(",");
String part1 = parts[0];
String part2 = parts[1];
System.out.print(part1); // data to be used
System.out.print(" , ");
System.out.println(part2); //data to be used
//System.out.println(data);
code 1
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class test implements SerialPortEventListener {
SerialPort serialPort;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = {
"COM4", // Windows
};
/**
* A BufferedReader which will be fed by a InputStreamReader
* converting the bytes into characters
* making the displayed results codepage independent
*/
private BufferedReader input;
/** The output stream to the port */
private OutputStream output;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, Find an instance of serial port as set in PORT_NAMES.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
// open serial port, and use class name for the appName.
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
/**
* This should be called when you stop using the port.
* This will prevent port locking on platforms like Linux.
*/
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* Handle an event on the serial port. Read the data and print it.
*/
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
String[] parts = inputLine.split(",");
String part1 = parts[0];
String part2 = parts[1];
System.out.print(part1); // data to be used
System.out.print(" , ");
System.out.println(part2); //data to be used
//System.out.println(data);
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
public static void main(String[] args) throws Exception {
test main = new test();
main.initialize();
Thread t=new Thread() {
public void run() {
//the following line will keep this app alive for 1000 seconds,
//waiting for events to occur and responding to them (printing incoming messages to console).
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println("Started");
}
I am probably still confused as to what your asking. I think the simplest way for another class to use the variables would be for it to be passed the values in arguments to one of its functions.
eg.
class ClassThatUsesPart1Part2 {
public void usePart1Part2(String part1, String part2) {
// put code that uses part1 and part2 here
}
}
Add another variable to your class.
private BufferedReader input;
/** The output stream to the port */
private OutputStream output;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
/** Variable of class that will use part1, part2.*/
private ClassThatUsesPart1Part2 part12User = new ClassThatUsesPart1Part2();
Then use it within your function.
String inputLine=input.readLine();
String[] parts = inputLine.split(",");
String part1 = parts[0];
String part2 = parts[1];
part12User.usePart1Part2(part1,part2);
Is this what you were looking for or have I just completely misunderstood?
Is there any better to way to check if I can receive a given IP Multicast transmission. Following code works fine but there is a problem in this code - it blocks the current thread until it gets the multicast packets.
Thank you.
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MulticastTest {
static String MCAST_ADDR = "FF7E:230::1234";// "235.1.1.1";
static int DEST_PORT = 1234;
static int BUFFER_LENGTH = 16;
public static void main(String args[]) {
try {
byte[] b = new byte[BUFFER_LENGTH];
DatagramPacket dgram = new DatagramPacket(b, b.length);
MulticastSocket socket = new MulticastSocket(DEST_PORT);
socket.joinGroup(InetAddress.getByName(MCAST_ADDR));
socket.receive(dgram); // blocks until a datagram is received
System.err.println("Received " + dgram.getLength() + " bytes from " + dgram.getAddress());
dgram.setLength(b.length); // must reset length field!
} catch (Exception e) {
}
}
}
You could set a timeout-value with the method socket.setSoTimeout(int).
http://download.oracle.com/javase/1.4.2/docs/api/java/net/Socket.html#setSoTimeout(int)
If you don't receive any data within the timeout, a SocketTimeoutException is raised
I wrote a Java application that reads and sends SMS messages from a USB GSM modem. I'm using SMSLib (which uses JavaCommAPI), and it runs on Windows. I need to pass in the COM PORT, that the modem appears to be connected to.
So far, I've been looking up the COM PORT manually using the Windows Device Manager, and write it into a properties file. I'm wondering if there's a way to detect which COM PORT, the modem is connected to programmatically?
It'll save the trouble of looking it up every time
The port number changes if I unplug/replug it sometimes
Thanks!!
package com.cubepro.util;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Formatter;
import org.apache.log4j.Logger;
import org.smslib.helper.CommPortIdentifier;
import com.cubepro.general.CommonConstants;
import com.cubepro.util.SendMessage;
public class CommPortTester {
private static final String _NO_DEVICE_FOUND = " no device found";
private final static Formatter _formatter = new Formatter(System.out);
private static Logger log = Logger.getLogger(CommPortTester.class);
static CommPortIdentifier portId;
static Enumeration<CommPortIdentifier> portList;
static int bauds[] = { 9600, 14400, 19200, 28800, 33600, 38400, 56000,
57600, 115200 };
public static final String MAINCLASS = "org.smslib.Service";
public CommPortTester() throws Exception {
Class.forName(MAINCLASS);
}
/**
* Wrapper around {#link CommPortIdentifier#getPortIdentifiers()} to be
* avoid unchecked warnings.
*/
private static Enumeration<CommPortIdentifier> getCleanPortIdentifiers() {
return CommPortIdentifier.getPortIdentifiers();
}
public String testAndQualifyPort() throws Exception {
String status = CommonConstants.MODEM_STATUS_ERROR;
SendMessage sendMessage = new SendMessage();
log.debug("\nSearching for devices...");
portList = getCleanPortIdentifiers();
while (portList.hasMoreElements()) {
portId = portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
_formatter.format("%nFound port: %-5s%n", portId.getName());
try {
if(portId.getName()
boolean comPortSuccess = sendMessage.doIt(portId.getName());
if(comPortSuccess == true){
return portId.getName();
}
} catch (final Exception e) {
log.debug(" Modem error occured -",e);
}
}
}
log.debug("\nTest complete.");
return status;
}
public static void main(String[]args){
try{
CommPortTester tester = new CommPortTester();
tester.testAndQualifyPort();
}catch(Exception e){
e.printStackTrace();
}
}
}