I'm trying to send some bytes from java code to a bluetooth module that is connected to an Arduino. Here is my code.
import gnu.io.*;
import java.io.IOException;
import java.io.OutputStream;
public class ArduinoSerialWriter {
private static OutputStream arduinoOutputStream;
public static void init() throws NoSuchPortException, PortInUseException,
UnsupportedCommOperationException, IOException {
SerialPort arduino = (SerialPort) CommPortIdentifier.getPortIdentifier("COM6")
.open(ArduinoSerialWriter.class.getName(), 2000);
arduino.setSerialPortParams(9600,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
arduinoOutputStream = arduino.getOutputStream();
}
public static void writeToArduino(byte[] bytes) throws IOException {
arduinoOutputStream.write(bytes);
}
public static void main(String[] args) {
try {
ArduinoSerialWriter.init();
} catch (Exception e) {
e.printStackTrace();
}
try {
arduinoOutputStream.write(new byte[]{(byte) -1, (byte) 90, (byte) 40});
} catch (IOException e) {
e.printStackTrace();
}
}
}
The init() seems to be working properly and connecting to the bluetooth module. The problem is that the call to arduinoOutputStream.write() is blocking indefinitely. I can also tell that the bytes have not been sent because the Arduino is not doing anything. However, no exceptions were thrown.
I read somewhere that it might be because the Arduino is resetting and needs time before it is ready to receive data, so I tried adding Thread.sleep(10000); before writing to the port, but that didn't change anything.
I also used a debugger to figure out where exactly the code was blocking and I traced it to these lines from the write(byte[]) method from RXTXPort.class in the RXTX library:
RXTXPort.this.waitForTheNativeCodeSilly();
RXTXPort.this.writeArray(var1, 0, var1.length, RXTXPort.this.monThreadisInterrupted);
From what I can gather, waitForTheNativeCodeSilly(); is called right before the bytes are actually sent in the next line, and this is where the code freezes.
I also tried adding arduinoOutputStream.flush(); after the call to the write method, but that didn't help either because the code froze before that line was even reached.
Any help would be appreciated.
Update:
I tried using removing the bluetooth module and using the USB cable for the Arduino instead and it worked perfectly. I think there might be something I need to setup with the bluetooth module.
It is an HC-06 bluetooth module. Here's where I got it from:
https://www.amazon.ca/JMT-Wireless-Bluetooth-Serial-Arduino/dp/B00HXAE0PQ/
The only thing I'm doing to set it up is going to manage bluetooth devices on my windows 10 pc and clicking pair. It says paired underneath it, so I'm not sure what the problem is.
Update Again:
I tried sending data to the bluetooth module using the serial monitor in the Arduino IDE, and the entire IDE completely froze. The only way I could shut it down was by killing the process in task manager. I'm fairly certain the Arduino IDE is having the same problem that I am, so its definitely something to do with the bluetooth chip and not my code itself.
Turns out I had the completely wrong idea. I was much better off using bluetooth connection as opposed to trying to treat the bluetooth chip as a COM port. I guess I was just fixated on that because I was used to it from Arduino.
I used the bluecove library for java and its working great now!
Related
I'm new to Arduino. I'm trying to build a program to control a breadboard through Arduino using the bluetooth module HC-05. At the moment I don't have anything on the breadboard and I'm just trying to test the connection. This is what I've done so far:
I put the module on the breadboard and I've paired it with the computer. When it's paired, the red led starts blinking slowly. I've connected the bluetooth Rx to Arduino Tx and Arduino Rx to bluetooth Tx following this tutorial: http://playground.arduino.cc/Learning/Tutorial01
I've also implemented both Java and Arduino programs following that tutorial. Here they are:
JAVA
public class Arduino extends PApplet{
public void connect(){
String[] serials = Serial.list();
Serial port = new Serial(this, Serial.list()[0], 9600);
port.write('H');
port.dispose();
}
ARDUINO
void setup() {
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
if(Serial.available()){
int a = Serial.read();
Serial.print(a);
}
}
The Java part should send the letter H to Arduino and Arduino should detect that and print it on the Serial monitor. But what actually happens is that I send data, and the led on the HC-05 starts blinking faster (which means the connection is lost). Why does that happen? I'm pretty confused. For the communication I'm using the port COM6 and COM7. It depends on how it connects. To see what port to use I just run the Java program: if the port is not correct, it will just get stuck and send nothing.
Any help is appreciated. Thanks!
In the end, I've solved this problem by removing this line of code:
port.dispose();
It would never work with it because I was getting rid of the connection. I don't know what I was thinking at the time I did that. That was very silly of me.
Ok so I had this problem.
If you are using the L293D motor shield, you'll be running the arduino of the same power supply, which I think must affect the power output the the bluetooth HC05 module.
Take out the jumper plug on the L293D motor shield, and run the arduino of a separate power source (e.g PP3 battery) and the problem disappears, OK.
I'm programming a game in Android that uses AI, which requires big CPU power, that a normal Android device just doesn't have. So I decided to write a server in Java using sockets that will calculate everything and return a value to the client (the android device).
Now, I'm used to program for PC, but not for phones. In mobile, the IP of the device can change back and forth due to data roaming and WIFI.
My question is, how do you handle a changing IP? How do you tell a new connection is the same device? Or maybe the Android device does all of that automatically?
I'm new to stackoverflow, I hope I didn't ask too many questions. :)
Thank you very much for your answers!
You don't need to handle ip changing at all. A client(an android device) must know server host/ip and reconnect if it was disconnected from network, nothing more.
private static class ConnectionTask implements Runnable {
private boolean connected;
#Override public void run() {
try {
InetAddress serverAddress = InetAddress.getByName("host");
Socket socket = new Socket(serverAddress, 9999);
connected = true;
while (connected) {
// sending or writing data
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
//here you lost the connection due to some reason
//you need to notify user about the problem and wait for connection
}
}
}
To receive event about network state you need to register receiver:
context.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (isNetworkAvailable()) {
unregisterReceiver(this);
tryToConnect();
}
}
}, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
Okay guys I figured out a way, thank to Fox in socks' answer.
Each time a user connects to the server socket, you take his UUID (or an hashed version of it, if you want more security :P ).
Then, when that user disconnects for some reason and tries to connect to the server socket again, he'll send the same UUID. That way, you can tell both of the connections are the same, and continue with the processing.
For more information about UUID, look here:
Is there a unique Android device ID?
Thank you all! :)
Now how do I mark this question as a closed one? :P
I'm just learning Java for about a couple weeks now. My end goal is to have my Arduino measure some sensors and send the results to my android via USB cable. However I'm just trying to get my Arduino to communicate with the Java console on my computer first, and then I figure it's pretty much copy and paste from there.
I can get my Arduino and Java console to communicate with each other as long as it's a simple byte. Anything passed that is giving me a result of the quadratic equation exploding.
In my Arduino serial Monitor I get this:
Engine Temp:100
Air Temp:95
Engine Speed:10000 RPM
Wheel Speed:30 MPH
and in my Java console I get this:
Normal println
[B#6f5f6479
String
€˜3Àf`Ì󀘀
UTF
??3?f`??
Here is my reader code:
#Override
public void serialEvent(SerialPortEvent arg0) {
byte[] readBuffer = new byte[1000];
try {
int availableBytes = input.available();
if (availableBytes > 0) {
// Read the serial port
input.read(readBuffer, 0, availableBytes);
// Print it out
System.out.println("Normal println");
System.out.println(readBuffer);
System.out.println("\nString");
System.out.println(new String(readBuffer, 0, availableBytes));
System.out.println("\nUTF");
System.out.println(new String(readBuffer,"UTF-8"));
System.out.println("\nDone");
}}
catch (IOException e) {
}
}
input is my InputStream.
Ensure that the Arduino and the serial port on the android are at the same speed. The provided code does NOT show how the serial ports are defined and opened/started so its impossible to know if this is the problem.
The characters displayed at the android appear like the typical garbage seen when the two end-points of a serial line are not similarly configured.
It looks like the Arduino is correctly sensing the engine's dynamics?
I know that by using AT commands we can control the handset.As example unlocking screen we can give a specific AT command or moving right to the menu or left or bottom or up we can give specific AT commands. What all are the AT commands for doing this kind of control.
Thank you.
From what I understand, the AT commands are more used for phone-type functions (making calls, or sending SMS, etc), rather than menu navigation, etc.
I'm not entirely sure if that was your end-goal after menu navigation, but you can find more details here: http://en.wikipedia.org/wiki/Hayes_command_set (the original +AT command set)
If you wanted to send SMS from a handset connected to your computer you might want to take a peek at this page: http://www.developershome.com/sms/atCommandsIntro.asp
If you wanted more control when performing functions, like sending SMS, etc, you might want to investigate "PDU Mode."
It is entirely possible that some handset manufacturers may have implemented additional +AT commands to allow other functions to be performed, so you might do better by specifically searching for the commands related to the handset you are using.
(Of course, if you're having issues connecting to the handset hardware itself, you need to ensure you have either the javax.comm extension or some favoured Java USB API installed)
If post doesn't help, perhaps you could provide more details in your question? (eg. what you are ultimately trying to do, if you think it would help)
List of AT commands
sample java code to use AT command
public void servicesDiscovered(int transID, ServiceRecord serviceRecord[])
{
String url = serviceRecord[0].getConnectionURL(1, false);
try
{
//ClientSession conn= (ClientSession)Connector.open(url);
StreamConnection meineVerbindung = (StreamConnection) Connector.open(url);
if(conn== null)
System.out.println("Kann Service URL nicht oeffnen\n");
else
{
OutputStream out = conn.openOutputStream();
InputStream in = conn.openInputStream();
String message = "AT+CGMI\r\n";
// send AT-command
System.out.println("send AT Comand request: "+message);
out.write(message.getBytes());
out.flush();
out.close();
byte buffer[] = new byte[10000];
// read the response from mobile phone
in.read(buffer);
System.out.println("AT Comand response: "+buffer.toString());}
}
catch(IOException e)
{
System.out.println("Service Error(3): "+e.getMessage());
}
}
I'm trying to test my code that reads from a USB port (COM25 when the device is connected) that is created when a device is connected to my computer and to a boat. I cannot power the USB device when not on the boat so testing is difficult. Can someone let me know how to simulate a COM port and write data to it so my test program is able to connect to that simulated COM port and read that data?
I'm reading this from a Java program but the simulation doesn't need to be in Java or any specific language. Just a program that will simulate the COM port and allow me to connect to it. I downloaded a COM port emulator from AGG Software and it appears that it's writing to what I deem COM25 but I'm not able to connect to it from my Java test.
The general answer for this kind of problem is to wrap the code that talks to the COM port in a class that implements an interface. If you do this as a Facade (pattern) then you can also make the COM methods you call sensible from your end.
The interface can then be mocked or faked for the test. (There is a great article on test objects, but I haven't been able to find it yet.) One advantage here is that you can create a fake version that throws exceptions or otherwise does things that are possible for the port to do but hard to get it to do in practice.
Where I work, we solved a similar issue by having our emulator not spoof a COM port at all. Here's how you can do it:
Define an interface for talking with your COM port, something like IUsbCommService
Implement your real COM-communcation service, using the standard Java Comm API
For your emulator, simply kick of a thread that spits out the same sort of data you can expect from your USB device at regular intervals.
Use your IOC framework of choice (e.g., Spring) to wire up either the emulator or the real service.
As long as you hide your implementation logic appropriately, and as long as you code to your interface, your service-consumer code won't care whether it's talking to the real USB device or to the emulator.
For example:
import yourpackage.InaccessibleDeviceException;
import yourpackage.NoDataAvailableException;
public interface IUsbProviderService {
public void initDevice() throws InaccessibleDeviceException;
public UsbData getUsbData()
throws InaccessibleDeviceException, NoDataAvailableException;
}
// The real service
import javax.comm.SerialPort; //....and the rest of the java comm API
public class UsbService implements IUsbProviderService {
.
.
.
}
// The emulator
public class UsbServiceEmulator implements IUsbProviderService {
private Thread listenerThread;
private static final Long WAITTIMEMS = 10L;
private String usbData;
public UsbServiceEmulator(long maxWaitTime) throws InaccessibleDeviceException{
initialize();
boolean success = false;
long slept = 0;
while (!success && slept < maxWaitTime) {
Thread.sleep(WAITTIMEMS);
slept += WAITTIMEMS;
}
}
private void initialize() throws InaccessibleDeviceException{
listenerThread = new Thread();
listenerThread.start();
}
private class UsbRunner implements Runnable {
private String[] lines = {"Data line 1", "Data line 2", "Data line 3"};
public void run() {
int line = 0;
while(true) {
serialEvent(lines[line]);
if(line == 3) {
line = 0;
} else {
line++;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
//handle the error
}
}
private void serialEvent(String line) {
if(/*you have detected you have enough data */) {
synchronized(this) {
usbData = parser.getUsbData();
}
}
}
}
Hope this helps!
Thanks to all the answers so far! Here's what I ended up doing as a result of recommendations from someone at work.
Downloaded the COM Port Data Emulator (CPDE) from AGG Software
Downloaded the Virtual Serial Port Driver (VSPD) from Eltima Software
(I just randomly picked a free data emulator and virtual serial port package. There are plenty of alternatives out there)
Using VSPD, created virtual serial ports 24 and 25 and connected them via a virtual null modem cable. This effectively creates a write port at 24 and a read port at 25.
Ran the CPDE, connected to 24 and started writing my test data.
Ran my test program, connected to 25 and was able to read the test data from it
There are plenty of relevant answers in this section. But as for me, I personally use Virtual Serial Port Driver, which works perfect for me. But I must admit that there are plenty alternatives when it comes to creating virtual ports: freevirtualserialports.com; comOcom to name a few. But I haven't got a chance to use them, so my recommendation for solving this problem is Virtual Serial Port Driver.
I recommend fabulatech's virtual modem.
Get it at http://www.virtual-modem.com
You might also want to get a COM port monitor for your tests - You can find it at
http://www.serial-port-monitor.com
Good luck with the boat! :)
I use com0com and it works great for what I need.
In addition all others, I would like to added this nice, free emulator https://sites.google.com/site/terminalbpp/ I do use. I do also use AGG Com port data emulator.