java jssc modem send msg - java

I am trying to send text messages from Java/Netbeans using a cell modem based on the SIM900. Using TeraTerm, I verify that I can send messages using the modem with basic AT commands. The following code attempts to use jssc to send messages.
I do not get errors and the data appears to be written to the modem, but I never receive a text message. For the phone number, I have tried both with an +, and without.
In TeraTerm, the number must be without the + to work. Many variations have been tried, and many .println's used. Still not making progress.
I hope someone can see the error of my ways.
Thanks in advance. Doug
package jssc_test;
import jssc.SerialPort;
import jssc.SerialPortException;
import jssc.SerialPortList;
public class Jssc_test {
public static SerialPort serialPort=null;
public static void main(String[] args) throws InterruptedException {
try {
String[] portNames = SerialPortList.getPortNames();
for(int i = 0; i < portNames.length; i++){
System.out.println(portNames[i]);
}
if(portNames.length < 1){
System.out.println("No ports available");
System.exit(0);
}
else{
serialPort = new SerialPort(portNames[0]);
}
System.out.println("Port opened: " + serialPort.openPort());
System.out.println("Params set: " + serialPort.setParams(9600, 8, 1, 0));
System.out.println("\"Hello World!!!\" successfully writen to port: " + serialPort.writeBytes("Hello World!!!".getBytes()));
serialPort.writeBytes(" AT+CMGF=1".getBytes());
Thread.sleep(1000);
System.out.println("bytes back = " + serialPort.readString());
serialPort.writeBytes(" AT+CMGS=\"585*******\"".getBytes()); // \r = <CR>. Tried both with and without '+'. In TeraTerm, only works without +. error if use: \r\n
//Thread.sleep(1000);
//System.out.println("bytes back = " + serialPort.readString());
//serialPort.writeBytes("0x0D".getBytes()); // send <CR>
Thread.sleep(1000);
System.out.println("bytes back = " + serialPort.readString());
serialPort.writeBytes("THIS IS A TEST from DS.".getBytes()); // placing Cntr-Z string in text did not work: \u001A
//serialPort.writeBytes("0x0D".getBytes()); // send <CR>
serialPort.writeBytes("0x1A".getBytes()); // send <ctrl>Z
Thread.sleep(1000);
System.out.println("bytes back = " + serialPort.readString());
System.out.println("Port closed: " + serialPort.closePort());
}
catch (SerialPortException ex){
System.out.println(ex);
}
} // ******************* end main ***************
} // *********************** end main class ***********************

I was able to answer the question I posed above. Below code works. The event listener does not need to be in there. The major changes that helped are defining the new line and end of file as bytes "public static final Byte eof = 0x1A, nl=0x0D;" then writing the bytes to the serialPort separately from the commands "serialPort.writeByte(nl);". I hope this helps others.
Doug
PS: I wrote a java class that may simplify sending code to the SIM900 using jssc, if anyone is interested.
package jssc_test;
//import jssc.SerialPort;
//import jssc.SerialPortException;
//import jssc.SerialPortList;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import jssc.*;
import static jssc.SerialPort.PURGE_RXCLEAR;
import static jssc.SerialPort.PURGE_TXCLEAR;
import static jssc_test.Jssc_test.serialPort;
/**
*
* #author DStockman
*/
public class Jssc_test {
public static SerialPort serialPort=null;
public static final Byte eof = 0x1A, nl=0x0D;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws InterruptedException {
//SerialPort serialPort = null;
try {
String[] portNames = SerialPortList.getPortNames();
for(int i = 0; i < portNames.length; i++){
System.out.println(portNames[i]);
}
if(portNames.length < 1){
System.out.println("No ports available");
System.exit(0);
}
else{
serialPort = new SerialPort(portNames[0]);
}
System.out.println("Port opened: " + serialPort.openPort());
System.out.println("Params set: " + serialPort.setParams(9600, 8, 1, 0));
serialPort.writeBytes("ATI".getBytes()); // get modem ID
serialPort.writeByte(nl);
Thread.sleep(1000);
System.out.println("modem ID = " + serialPort.getEventsMask());
/*
int mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR;//Prepare mask
serialPort.setEventsMask(mask);//Set mask
try{
serialPort.addEventListener(new SerialPortReader());//Add SerialPortEventListener
}
catch (SerialPortException ex) {
System.out.println(ex);
}
*/
// just looking up settings
System.out.println("events mask = " + serialPort.getEventsMask());
System.out.println("flow control mode = " + serialPort.getFlowControlMode());
System.out.println("output buffer bytes = " + serialPort.getOutputBufferBytesCount());
//serialPort.purgePort(PURGE_RXCLEAR | PURGE_TXCLEAR);
serialPort.writeBytes(" AT+CMGF=1".getBytes());
serialPort.writeByte(nl);
Thread.sleep(1000);
System.out.println("bytes back set modem to text mode = " + serialPort.readString());
System.out.println("Success entering number: " + serialPort.writeBytes(" AT+CMGS=\"5857738696\";".getBytes())); // \r = <CR>. Tried both with and without '+'. In TeraTerm, only works without +. error if use: \r\n
serialPort.writeByte(nl);
Thread.sleep(1000);
System.out.println("bytes back after number entered = " + serialPort.readString());
serialPort.writeBytes("THIS IS A third TEST from DS 09/29/16.2.".getBytes());
serialPort.writeByte(nl);
Thread.sleep(1000);
serialPort.writeByte(eof);
Thread.sleep(1000);
System.out.println("bytes back = " + serialPort.readString());
Thread.sleep(10000);
//serialPort.purgePort(SerialPort.PURGE_TXCLEAR);
//attempt to get msgs received by modem
serialPort.writeBytes("AT+CMGL=\"ALL\"".getBytes());
serialPort.writeByte(nl);
Thread.sleep(1000);
System.out.println("bytes back = " + serialPort.readString());
System.out.println("Port closed: " + serialPort.closePort());
}
catch (SerialPortException ex){
System.out.println(ex);
}
} // ******************* end main ***************
} // *********************** end main class ***********************
class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()){//If data is available
if(event.getEventValue() == 1){//Check bytes count in the input buffer
//Read data, if 10 bytes available
try {
System.out.println("bytes back inside listener = " + serialPort.readString());
byte buffer[] = Jssc_test.serialPort.readBytes(10);
System.out.println("listener text:");
System.out.print(Arrays.toString(buffer));
System.out.println("End listener text:");
}
catch (SerialPortException ex) {
System.out.println(ex);
}
}
}
else if(event.isCTS()){//If CTS line has changed state
if(event.getEventValue() == 1){//If line is ON
System.out.println("CTS - ON");
}
else {
System.out.println("CTS - OFF");
}
}
else if(event.isDSR()){///If DSR line has changed state
if(event.getEventValue() == 1){//If line is ON
System.out.println("DSR - ON");
}
else {
System.out.println("DSR - OFF");
}
}
}
}

Related

Java to Arduino communication out of sync - leap motion

I'm trying to control a robotic arm with a leap motion controller. Right now I'm just controlling two servos. I'm using java to read data from the leap motion, process and format it, and send it to the Arduino. The Arduino just receives the data, translates it, and sends it to the servos.
The format that I send the data to the Arduino in is, in string form:
z-rotation:shoulderPos:elbowAngle:wristAngle:clawPos
with each of these variables formatted with leading zeroes so that exactly 19 bytes are always sent to the Arduino at a time.
The issue is that data seems to be being lost in communication between the java on my laptop and the Arduino. If I send one command string, "000:180:000:000:000"
for example, the Arduino tells me that it's received "000:180:000:000:000"
and it correctly sends "000" to one servo and "180" to the second servo.
If I send a string of nine commands:
000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000
The Arduino tells me that it's received all of the commands individually and it correctly sends all of the commands to the servos (evident by the twitching of the servos) and ends with sending "000" to both servos.
However, when I run my code with the leap motion, which effectively constantly transmits strings of 19 bytes to the Arduino, the servos just begin to twitch, moving between 0, 180, and the position that I'm sending to them. When I move my hand closer to the 100 position, the twitching servos have a net movement towards the 100 position, but never actually reaches it. The Arduino tells me that it's receiving the commands correctly for a few seconds before beginning to receive distorted messages like "0:180:0000:0018:00". I can only assume that the transmission and reception of commands are getting out of sync, but I'm not sure.
Here's my Java code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import com.leapmotion.leap.*;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
class SampleListenerMain extends Listener {
//define position lock booleans
public boolean leftLock = false;
public boolean rightLock = false;
String data = "";
static DecimalFormat df = new DecimalFormat("000");
//Displacement variables
double deltaX, deltaY, deltaZ, angle;
public void onInit(Controller controller) {
System.out.println("Initialized");
}
public void onConnect(Controller controller) {
System.out.println("Connected");
controller.enableGesture(Gesture.Type.TYPE_CIRCLE);
controller.enableGesture(Gesture.Type.TYPE_KEY_TAP);
}
public void onDisconnect(Controller controller) {
System.out.println("Disconnected");
}
public void onExit(Controller controller) {
System.out.println("Exited");
}
public void onFrame(Controller controller) {
//Define position variables
double shoulderAngle, elbowAngle, wristPos, clawPos, zRotationPos, wristAngle;
//Define object variables
//Frame
Frame frame = controller.frame();
//Hands
Hand leftHand = frame.hands().leftmost();
Hand rightHand = frame.hands().rightmost();
//Arms
Arm leftArm = leftHand.arm();
Arm rightArm = rightHand.arm();
/* Control of robotic arm with Z-rotation based on the left hand, arm 'wrist' position based on the wrist,
* arm 'elbow position based on the elbow, and claw based on the fingers. 'Shoulder' is based on the left elbow
*/
//Control position locks for left hand controls and right hand controls
//Gesture gesture = new Gesture(gesture);
for(Gesture gesture : frame.gestures()) {
HandList handsForGesture = gesture.hands();
switch(gesture.type()) {
case TYPE_KEY_TAP:
System.out.println("Key tap from" + handsForGesture + " Hand");
try {
wait(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
leftLock = !leftLock;
break;
default:
System.out.println("Unrecognized gesture");
break;
}
}
//'Shoulder' control
//find angle between the left elbow and the left wrist center
Vector leftElbow = leftArm.elbowPosition();
Vector leftWrist = leftArm.wristPosition();
deltaZ = leftElbow.getZ() - leftWrist.getZ();
deltaY = leftElbow.getY() - leftWrist.getY();
angle = Math.atan(deltaY/deltaZ);
//map angle so servo can understand it
shoulderAngle = leapArm.map(angle, 0, 90, 0, 180);
//System.out.println("ShoulderPos: " + shoulderAngle);
//Write position to 'shoulder'
//Z-rotation control
Vector leftHandPos = leftHand.palmPosition();
//rotate z-axis with speed proportional to left hand X position
//map X position to motor power
zRotationPos = leapArm.map(leftHandPos.getX(), -230, 230, 0, 180);
//System.out.println("zRotationPos: " + zRotationPos);
data += df.format(zRotationPos);
data += ":" + df.format(shoulderAngle);
//write power to rotational servo
//'elbow' control
//find angle between the right elbow and right wrist center
Vector rightElbow = rightArm.elbowPosition();
Vector rightWrist = rightArm.wristPosition();
//refresh deltas and angle
deltaZ = rightElbow.getZ() - rightWrist.getZ();
deltaY = rightElbow.getY() - rightWrist.getY();
angle = Math.atan(deltaY/deltaZ);
//map angle so the servo can understand it
elbowAngle = leapArm.map(angle, -1.25, 0, 0, 180);
data+= ":" + df.format(elbowAngle);
//System.out.println("ElbowPos: " + elbowAngle);
//'wrist' control
//update vectors
rightWrist = rightArm.wristPosition();
Vector rightHandPos = rightHand.palmPosition();
//update deltas
deltaZ = rightWrist.getZ() - rightHandPos.getZ();
deltaY = rightWrist.getY() - rightHandPos.getY();
System.out.println("Wrist pos: " + rightWrist.getX() + ", " + rightWrist.getY() + ", " + rightWrist.getZ());
System.out.println("Right hand pos: " + rightHandPos.getX() + ", " + rightHandPos.getY() + ", " + rightHandPos.getZ());
angle = Math.atan(deltaY/deltaZ);
wristAngle = leapArm.map(angle, -0.5, 0.5, 0, 180);
data += ":" + df.format(wristAngle);
//System.out.println("wristAngle: " + wristAngle + " degrees");
//pinch control
//define fingers
FingerList fingerList = rightHand.fingers().fingerType(Finger.Type.TYPE_INDEX);
Finger rightIndexFinger = fingerList.get(0);
fingerList = rightHand.fingers().fingerType(Finger.Type.TYPE_THUMB);
Finger rightThumb = fingerList.get(0);
//find the distance between the bones to detect pinch
Vector rightIndexDistal = rightIndexFinger.bone(Bone.Type.TYPE_DISTAL).center();
Vector rightThumbDistal = rightThumb.bone(Bone.Type.TYPE_DISTAL).center();
//Calculate distance between joints
double distalDistance = Math.sqrt(Math.pow((rightIndexDistal.getX()-rightThumbDistal.getX()),2) + Math.pow((rightIndexDistal.getY()-rightThumbDistal.getY()),2) + Math.pow((rightIndexDistal.getZ()-rightThumbDistal.getZ()),2));
if(distalDistance <= 10) {
clawPos = 180;
} else {
clawPos = 0;
}
data += ":" + df.format(clawPos);
System.out.println("ClawPos: " + clawPos);
/* Write data to arduino
* FORMAT: z-rotation:shoulderPos:elbowAngle:wristAngle:clawPos
*/
System.out.println("Data: " + data);
/* wait for arduino to catch up ~30 packets/sec
* basically see how long the arduino takes to process one packet and flush the receiving arrays to prevent 'pollution'.
*/
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//send to arduino
leapArm.writeToArduino(data);
System.out.println("Sent");
}
}
public class leapArm implements SerialPortEventListener {
public static double map(double input, double in_min, double in_max, double out_min, double out_max) {
return ((input - in_min) * (out_max - out_min) / (in_max - in_min)) + out_min;
}
static OutputStream out = null;
static BufferedReader input;
public static void main(String[] args) {
//Connect to COM port
try
{
//Device
(new leapArm()).connect("/dev/cu.usbmodem14101");
Thread.sleep(3000);
//leapArm.writeToArduino("000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000000:000:000:000:000180:000:000:000:000");
//System.out.println("sent");
}
catch ( Exception e )
{
e.printStackTrace();
System.exit(0);
}
// Create a sample listener and controller
SampleListenerMain listener = new SampleListenerMain();
Controller controller = new Controller();
// Have the sample listener receive events from the controller
controller.addListener(listener);
// Keep this process running until Enter is pressed
System.out.println("Press Enter to quit...");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
// Remove the sample listener when done
controller.removeListener(listener);
}
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(4800,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
out = serialPort.getOutputStream();
//input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
// add event listeners
try {
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
else
{
System.out.println("Selected port is not a Serial Port");
}
}
}
public static void writeToArduino(String data)
{
String tmpStr = data;
byte bytes[] = tmpStr.getBytes();
try {
/*System.out.println("Sending Bytes: ");
for(int i = 0; i<bytes.length; i++) {
System.out.println(bytes[i]);
}*/
out.write(bytes);
} catch (IOException e) { }
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
System.out.println("Received: " + inputLine);
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
}
And here's my Arduino code:
#include <SoftwareSerial.h>
#include <Servo.h>
Servo shoulder1, shoulder2;
SoftwareSerial mySerial(5,3); //RX, TX
char *strings[19];
char chars[19];
int loopno = 0;
byte index = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(4800);
mySerial.begin(9600);
mySerial.println("Started");
shoulder1.attach(2);
shoulder2.attach(4);
chars[19] = NULL;
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()>18) {
loopno++;
Serial.readBytes(chars, 19);
/*for(int i = 0; i< sizeof(chars); i++) {
mySerial.print("Character ");
mySerial.print(i);
mySerial.print(": ");
mySerial.println(chars[i]);
}*/
String str(chars);
/*mySerial.print("In string form: ");
mySerial.println(str);*/
char* ptr = NULL;
index = 0;
ptr = strtok(chars, ":");
while(ptr != NULL) {
/* mySerial.print("Pointer: ");
mySerial.println(ptr);*/
strings[index] = ptr;
index++;
ptr = strtok(NULL, ":");
}
//mySerial.print("shoulder1: ");
mySerial.println(atoi(strings[0]));
/*mySerial.print("shoulder2: ");
mySerial.println(atoi(strings[0]));
mySerial.print("Loop no: ");*/
mySerial.println(loopno);
shoulder1.write(atoi(strings[0]));
shoulder2.write(atoi(strings[1]));
}
flush();
}
void flush() {
for(int i = 0; i<19; i++) {
chars[i] = NULL;
strings[i] = NULL;
}
}
And here's the circuit that I'm using (The top Arduino is used for serial readout and debugging)
I'm very confused as to why this is happening. I've tried:
Decreasing the baud rate (115200 to 4800).
Sending commands one at a time or in small groups as described earlier.
Commenting out all debugging and unnecessary print statements to decrease processing time and reduce the amount of Serial calls in the Arduino program.
Commenting out all print statements in the Java code as well as rewriting my formatting and transmission code with an eye for effifiency to increase data collection -> transmission speed.
I'd appreciate it if anyone has experience with this or knows what the probelem could be!
Thanks,
Gabe
Edit:
I messed around with it when I got home and I think I might have isolated (one of) the issue(s). When I have all my debugging print statements uncommented and I send the arduino `
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000"); Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");, it starts to give me weird feedback starting at loop 7:
However, when I run my code with all the debugging statements commented out except for the first data value and the loop number, it is able to successfully keep track of 51 loops worth of data:
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("180:000:000:000:000000:000:000:000:000000:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000180:000:000:000:000");
Tests.writeToArduino("000:000:000:000:000000:000:000:000:000777:000:000:000:000");
gives me:
This leads me to believe that either data is being lost in serial communication, as softwareserial is known to have this issue (which would make sense because less readout -> less jumbled data), or that I might be running into memory issues on the Arduino. Could either of these be the case? I'm still having the original issue, just thought these insights might help.
I found the solution: my arduino code was taking ~30ms to go through one loop but my java-side code was looping faster than that. The 64 byte arduino serial buffer was getting filled up after a few loops, and, since 64 is not a multiple of the 19 bytes I was sending, the dropped bytes would mean that the number:number format would get messed up.
If it helps anyone, I just tracked the time of the arduino loop and added a 50ms delay to the java-side code so that the arduino-side can catch up.

Android multicast.receive() dying and no exception

I am making a multicast messenger for part of my masters degree. I have previously successfully made this exact same implementation on desktop Java and had no issues what so ever. HOWEVER, when I run the code from Android problems occur. I can send to the multicast group just fine, but receiving does not work.
The output simply stops in the console after "2".
The application just stops giving me feedback on the line that is socket.receive()I am getting no exceptions either.
Below I have attached the class that I am using to receive the messages.
For the full android implementation I have the dropbox link available at: https://www.dropbox.com/s/vuoifbxqk01c079/MyApplication.zip?dl=0
It is pretty rough, but it does successfully send, just not receive.
public class EMMS extends Thread{
MulticastSocket socket;
InetAddress ip;
byte [ ] buffer;
int usedPort;
public boolean isSending;
private MainActivity view;
public EMMS(MainActivity view, int port, String ipAddress){
try {
// Create Multicast socket
socket = new MulticastSocket(port);
usedPort = port;
// Set address to join
ip = InetAddress.getByName(ipAddress);
// join group
socket.joinGroup(ip);
System.out.println("Group Joined! ");
// create buffer
buffer = new byte[512];
isSending = false;
this.view = view;
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void run(){
try {
System.out.println("Incoming Message! ");
while (isSending == false) {
// Create and receive packet
System.out.println("1");
DatagramPacket dp = new DatagramPacket(buffer, buffer.length,ip, usedPort);
System.out.println("2");
socket.receive(dp);
System.out.println("3");
String str = new String(dp.getData());
System.out.println("4");
String ipAddress = dp.getAddress().getHostAddress();
System.out.println("5");
// Create string array of components
String[] data = str.split("##");
String senderName= data[2];
String sourceIP= ipAddress;
String typeOfEmergency=data[3];
String condition=data[0];
String instruction=data[1];
System.out.println("Incoming Message! ");
System.out.println(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
// Create popup window
AlertDialog alertDialog = new AlertDialog.Builder(view).create(); //Read Update
alertDialog.setTitle("ALERT");
alertDialog.setMessage(
"Sender: " + senderName + "\n" +
"Source IP: " + sourceIP + "\n" +
"Emergency Type: " + typeOfEmergency + "\n" +
"Condition: " + condition + "\n" +
"Instruction: " + instruction
);
alertDialog.show(); //<-- See This!
}
}//end of try
catch (SocketException se){
System.out.println("Socket Exception : " + se); }
catch (IOException e) { System.out.println("Exception : " + e); }
}
public void disconnect() throws IOException{
socket.leaveGroup(ip);
}

Socket help in java

I have looked a lots of examples and have asked a few people but no one seems to be able to tell me what I am doing wrong on my listen sockets. Please help.
I am making a program that reads from 3 files and then sends data in sockets in threads.
here is every thing I have done
public class Main {
public static void main(String[] args) throws Exception{
//making all threads for A,B and C
Thread T_A = new Thread(new threads ("A"));
Thread T_B = new Thread(new threads ("B"));
Thread T_C = new Thread(new threads ("C"));
//starting the threads for A,B and C
T_A.start();
T_B.start();
T_C.start();
}
}
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class threads implements Runnable {
//making temps
String name;
int listen;
int send;
String line;
BufferedReader reader;
BufferedReader input;
boolean Listening=false;
boolean Sending=false;
PrintWriter output;
ServerSocket node_listen=null;
Socket node_send=null;
Socket node_rev=null;
public threads(String x){
//name of thead A,B or C
name=x;
}
#Override
public void run(){
try{
//openinng the conf file for thread
reader = new BufferedReader(new FileReader("conf" + name + ".txt"));
//this is for node A because it only sends info does not get info
if(name.equals("A")==true){
//making a socket to send on
System.out.println("Node " + name + " is starting");
send = Integer.parseInt(reader.readLine());
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//this is for node B becuase it sends and gets info
else if(name.equals("B")==true){
//getting ports for send and listen
listen = Integer.parseInt(reader.readLine());
send = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
for(int temp=0;temp!=5;temp++)
{
temp=Checker(temp);
}
}
//node C only gets info
else if(name.equals("C")==true){
//geting listen port
listen = Integer.parseInt(reader.readLine());
System.out.println("Node " + name + " is starting");
Listening=setUpListen();
}
//sends and gets data until it has no more to send or get
while(Listening==true || Sending== true)
{
//while it needs to get data and was a node that gets data
if(Listening==true)
{
Listen();
}
//Has not sent terminate yet and is a sending node
if(Sending==true)
{
Send();
}
}
}
catch(IOException | NumberFormatException e)
{
System.out.println(e);
}
catch (InterruptedException ex)
{
Logger.getLogger(threads.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Node " + name + " has ended");
}
public boolean setUpConnection(){
try {
//making a socket for sending
System.out.println("Node " + name + " is setting up connection");
node_send = new Socket("hostname", send);
output = new PrintWriter(node_send.getOutputStream(),true);
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + send);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a sending thread
Sending=true;
System.out.println("Node " + name + " is ready for sending");
return true;
}
public boolean setUpListen(){
try{
//making socket for Listening
System.out.println("Node " + name + " is setting up listen");
nodeListen = new ServerSocket(listen);
System.out.println("Node " + name + " is trying to listen");
node_rev = node_listen.accept();
System.out.println("Node " + name + " NEVER GETS HERE");
input = new BufferedReader(new InputStreamReader(node_rev.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: " + name + " :" + listen);
return false;
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + name + " " + e);
return false;
}
//telling the thread it is a Listening thread
System.out.println("Node " + name + " is ready for listening");
return true;
}
public void Listen(){
try{
line = input.readLine();
//As long as something was sent and it was not terminate prints data
if(line.equals("terminate")==false&&line.equals("null")==false)
{
System.out.println("Node " + name + " received:" + line);
}
//When terminate was sent it no longer looks for data
if(line.equals("terminate"))
{
Listening=false;
node_listen.close();
node_rev.close();
input.close();
System.out.println("Node " + name + " done listening");
}
}catch (IOException e) {
System.out.println("Error Listening on connection: " + name + " " + e);
}
}
public void Send(){
try{
//reads in the data and sends it to node
line=reader.readLine();
System.out.println(line);
output.println(line);
//if the data sent was terminate then exit sending mode
if(line.equals("terminate")==true)
{
Sending=false;
node_send.close();
output.close();
System.out.println("Node " + name + " done sending");
}
}catch (IOException e) {
System.out.println("Error Sending on connection: " + name + " " + e);
}
}
public int Checker(int temp) throws InterruptedException{
boolean connected=setUpConnection();
if(connected==true)
{
//connected
temp=5;
}
return temp;
}
}
each conf file is setup like this
confA.txt
5002
This is a sample line of text for node A.
This is another sample line of text for node A.
Node B will be printing out these three lines for node A.
terminate
confB.txt
5002
5005
This is a sample line of text.
This is another sample line of text.
Node C will be printing out these three lines.
terminate
confC.txt
5005
That is the out put I get
run:
Node A is starting
Node A is setting up connection
Node B is starting
Node B is setting up listen
Node C is starting
Node C is setting up listen
Node B is trying to listen
Node C is trying to listen
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A is setting up connection
Error setting up socket connection: A java.net.ConnectException: Operation timed out
Node A has ended
The code never seems to get to the line System.out.println("Node " + name + " NEVER GETS HERE"); in the setUpListen();
Thanks
That is because ServerSocket.accept() blocks until an incoming connection is reported. The method returns the Socket.
So the next line (System.out.println("Node " + name + " NEVER GETS HERE")) is never executed until you get another network interface to connect to your listening ServerSocket.
I don't know exactly what it is you're trying to achieve, but you need to listen for incoming connections in an apart thread:
final ServerSocket serverSocket = createServerSocket();
new Thread(new Runnable() {
#Override
public void run() {
Socket socket = serverSocket.accept();
System.out.println("Incoming connection from " + socket.getInetAddress());
doSomethingWithSocket(socket);
}
}).start();
PS: Please persist with the Java Naming Conventions:
Classes should always start with an Uppercase letter;
Field names (or class attributes) should always start with a lowercase letter;
Method names should always start with a lowercase letter.
It turns out that my problem was node_send = new Socket("hostname", send); should have been node_send = new Socket("localhost", send);
I am dumb.
However I want to thank everyone for there help and pointers.
public class threads ?? Conventions please.
O.t:
Error setting up socket connection: C java.net.BindException: Address already in use
The port that setted up each listener on, is the same. (i.e Address already in use.)

Parsing data read from multiple sensors on Arduino

So here is the code we're implementing for our Java GUI. The problem is, since the serial data is read in bits, we can't seem to come up with a way to separate the data from three different sensors (three LM35 temperature sensors as placeholders). The problem lies in the serialevent class.
import gnu.io.*;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TooManyListenersException;
public class Communicator implements SerialPortEventListener
{
//Passed from main GUI.
GUI window = null;
//For containing the ports that will be found.
private Enumeration ports = null;
//map the port names to CommPortIdentifiers
private HashMap portMap = new HashMap();
//This is the object that contains the opened port.
private CommPortIdentifier selectedPortIdentifier = null;
private SerialPort serialPort = null;
//Input and output streams for sending and receiving data.
private InputStream input = null;
private OutputStream output = null;
//Just a boolean flag that I use for enabling
//and disabling buttons depending on whether the program
//is connected to a serial port or not.
private boolean bConnected = false;
//The timeout value for connecting with the port.
final static int TIMEOUT = 2000;
//Some ASCII values for for certain things.
final static int SPACE_ASCII = 32;
final static int DASH_ASCII = 45;
final static int NEW_LINE_ASCII = 10;
//A string for recording what goes on in the program;
//this string is written to the GUI.
String logText = "";
public Communicator(GUI window)
{
this.window = window;
}
//Search for all the serial ports
// Pre: none
// Post: adds all the found ports to a combo box on the GUI
public void searchForPorts()
{
ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements())
{
CommPortIdentifier curPort = (CommPortIdentifier)ports.nextElement();
//Get only serial ports
if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
window.cboxPorts.addItem(curPort.getName());
portMap.put(curPort.getName(), curPort);
}
}
}
//Connect to the selected port in the combo box
// Pre : ports are already found by using the searchForPorts method
// Post: the connected communications port is stored in commPort, otherwise,
// an exception is generated
public void connect()
{
String selectedPort = (String)window.cboxPorts.getSelectedItem();
selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);
CommPort commPort = null;
try
{
//The method below returns an object of type CommPort
commPort = selectedPortIdentifier.open("TigerControlPanel", TIMEOUT);
//The CommPort object can be casted to a SerialPort object
serialPort = (SerialPort)commPort;
//For controlling GUI elements
setConnected(true);
//Logging
logText = selectedPort + " opened successfully.";
window.txtLog.setForeground(Color.black);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.black);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.black);
window.txtLog2.append(logText + "\n");
//CODE ON SETTING BAUD RATE, ETC. OMITTED
//XBEE PAIR IS ASSUMED TO HAVE THE SAME SETTINGS ALREADY
//Enables the controls on the GUI if a successful connection is made
window.keybindingController.toggleControls();
}
catch (PortInUseException e)
{
logText = selectedPort + " is in use. (" + e.toString() + ")";
window.txtLog.setForeground(Color.RED);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.RED);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.RED);
window.txtLog2.append(logText + "\n");
}
catch (Exception e)
{
logText = "Failed to open " + selectedPort + "(" + e.toString() + ")";
window.txtLog.append(logText + "\n");
window.txtLog.setForeground(Color.RED);
window.txtLog1.append(logText + "\n");
window.txtLog1.setForeground(Color.RED);
window.txtLog2.append(logText + "\n");
window.txtLog2.setForeground(Color.RED);
}
}
//Open the input and output streams
// pre: an open port
// post: initialized intput and output streams for use to communicate data
public boolean initIOStream()
{
//Return value for whather opening the streams is successful or not
boolean successful = false;
try {
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
successful = true;
return successful;
}
catch (IOException e) {
logText = "I/O Streams failed to open. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
return successful;
}
}
//Starts the event listener that knows whenever data is available to be read
// pre: an open serial port
// post: an event listener for the serial port that knows when data is recieved
public void initListener()
{
try
{
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch (TooManyListenersException e)
{
logText = "Too many listeners. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
}
//Disconnect the serial port
// pre : an open serial port
// post: clsoed serial port
public void disconnect()
{
//Close the serial port
try
{
serialPort.removeEventListener();
serialPort.close();
input.close();
output.close();
setConnected(false);
window.keybindingController.toggleControls();
logText = "Disconnected.";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
catch (Exception e)
{
logText = "Failed to close " + serialPort.getName() + "(" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
window.txtLog1.setForeground(Color.red);
window.txtLog1.append(logText + "\n");
window.txtLog2.setForeground(Color.red);
window.txtLog2.append(logText + "\n");
}
}
final public boolean getConnected()
{
return bConnected;
}
public void setConnected(boolean bConnected)
{
this.bConnected = bConnected;
}
//What happens when data is received
// pre : serial event is triggered
// post: processing on the data it reads
public void serialEvent(SerialPortEvent evt) {
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
{
try
{
byte singleData = (byte)input.read();
//byte[] buffer = new byte[128];
if (singleData != NEW_LINE_ASCII)
{
logText = new String(new byte[] {singleData});
window.txtLog.append(logText);
}
else
{
window.txtLog.append("\n");
}
}
catch (Exception e)
{
logText = "Failed to read data. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
}
}
}
//Method that can be called to send data
// pre : open serial port
// post: data sent to the other device
}
If the Arduino is simply sending the temperature back as a string from each sensor in sequence (I assume it is but you haven't specified what it's sending at all, so I could be wrong) then assuming you haven't disabled reset on serial connect, you could simply take note of the order the temperatures come in at - say the first temperature read is from sensor 1, the second from sensor 2, the third from sensor 3, the fourth from sensor 1, and so on.
However, for a clearer and more reliable way I'd recommend modifying the Arduino code to send back details of what sensor each reading came from rather than just sending back the raw bits - changing the code in this way should be relatively trivial from the Arduino's side, then makes parsing the data PC side much easier.

jssc (serialPort.readBytes() ) with Arduino

This is my Java code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jsscusbconnection;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
/**
*
* #author Heshan
*/
public class JsscUsbConnection {
/**
* #param args the command line arguments
*/
static SerialPort serialPort;
public static void main(String[] args) {
serialPort = new SerialPort("COM15");
try {
System.out.println("port open :" + serialPort.openPort());//Open port
serialPort.setParams(SerialPort.BAUDRATE_9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
int mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR;//Prepare mask
serialPort.setEventsMask(mask);//Set mask
serialPort.addEventListener(new SerialPortReader());//Add SerialPortEventListener
} catch (SerialPortException ex) {
System.out.println(ex);
}
}
static class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR()) {//If data is available
//System.out.println(event.getEventValue());
if (event.getEventValue() > 4) {//Check bytes count in the input buffer
//Read data, if 10 bytes available
try {
byte buffer[] = serialPort.readBytes(4);
System.out.println(buffer[0] + " " + buffer[1] + " " + buffer[2] + " " + buffer[3]);
} catch (SerialPortException ex) {
System.out.println(ex);
}
}
} else if (event.isCTS()) {//If CTS line has changed state
if (event.getEventValue() == 1) {//If line is ON
System.out.println("CTS - ON");
} else {
System.out.println("CTS - OFF");
}
} else if (event.isDSR()) {///If DSR line has changed state
if (event.getEventValue() == 1) {//If line is ON
System.out.println("DSR - ON");
} else {
System.out.println("DSR - OFF");
}
}
}
}
}
This is my Arduino code:
int k=0;
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println(67,BYTE);
Serial.println(98,BYTE);
Serial.println(34,BYTE);
Serial.println(108,BYTE);
Serial.flush();
}
This my output of Java code:
67 13 10 98
13 10 34 13
10 108 13 10
67 13 10 98
What are those bold values? I have no idea about these unknown values.
10 and 13 bytes are \r\n symbols. The description of the println() function from http://arduino.cc:
Prints data to the serial port as human-readable ASCII text followed by a carriage return >character (ASCII 13, or '\r') and a newline character (ASCII 10, or '\n'). This command takes >the same forms as Serial.print().
If you don't need these end line symbols use the print() function or the write() function for sending raw bytes.
13 is a carriage return. 10 is a line feed. If you're dealing with serial I/O you should really know that. 9 is a tab. 12 is a form feed. Check the ASCII table.

Categories