Hi, I am experiencing the next situation :
I have an Android app which send a message ex "A", to the Arduino uno. Initially Arduino receive the message and execute the associate code. Android app wait aprox 2 sec after the message have been sent and then close the connection with the Arduino.
If the android app stays awake for ex 10 minutes while send nothing to the Arduino, after that time connection is established a message is sent to Arduino but Arduino does nothing (like he received no message).
Please help understanding what is happening and how to solve it. Thank you .
First: please, please make a better code indentation! Without it, it's hard to read (for us, but for you also!). At least before posting the code here, let the IDE do it for you by pressing Ctrl-T.
Second: to communicate, you're using onboard Serial and this voids you from using the serial as a debug. You better use SoftwareSerial (especially because you set a low speed like 9600 baud) and use onboard UART to show debug information to your PC.
Third: you need to better explain the project: what is the "Android app"? How does it communicate with Arduino? You talked about "connection", is something like Bluetooth? Please, always give us the full information.
Fourth: the problem you described doesn't sound to be a specific problem with your code, except for the actual use of "delays" instead of using "millis" and creating a so called "finite state machine", very useful to let program a "delay-free" behaviour, and a better protocol (like a byte, e.g. an "X", to tell Arduino the communication is to be closed so resetting its state). Both aspects are a bit wide to be described here, so tell us if you need more information about those topics and automation programming methods.
Apologies I forgot to mention , connection is via USB. Android app is sending me a message each time after a connection have been successfully established and that the message have been sent to the Arduino. Also I display on the lcd screen what message arduino have received.
Ok so you cannot free the onboard serial to print debug info as I suggested you before.
But you still can use Serial Monitor to emulate the app serial commands (remember Serial Monitor always sends CR+LF by default, so you better change your code to ignore such characters), and check its behaviour, don't you? This way, if Arduino seems to work fine, the problem could be elsewhere.
I must say I have never had to do with Android serial connectons via OTG cable (I often used just Bluetooth), so I can't say if there's something wrong either in the USB serial emulation, or in the app serial handling. Just to le us better know the whole environment, could you post here the Android app code also (at least all the sections/functions where you open, write, and close the serial)?
PS: Anyway you should always make a clean and good code indentation (remember you can start by pressing Ctrl-T and the IDE will do it for you!) please. For the next time you'll post your code, keep it clean!
Good afternoon , thank you for your answer.
Here is the Android code which is used to connect, send message, and close the connection with the Arduino.
public void connectArduino() {
if (arduinoDevice == null) {
Toast.makeText(this, "Dispozitiv Arduino neidentificat.... Conectați dispozitivul corect.", Toast.LENGTH_SHORT).show();
return;
}
connection = usbManager.openDevice(arduinoDevice);
if (connection == null) {
Toast.makeText(this, "Eroare la deschiderea conexiunii USB !! ", Toast.LENGTH_SHORT).show();
return;
}
UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(arduinoDevice);
if (driver == null) {
Toast.makeText(this, "Dispozitivul nu este compatibil.", Toast.LENGTH_SHORT).show();
return;
}
arduinoSerial = driver.getPorts().get(0);
try {
arduinoSerial.open(connection);
arduinoSerial.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
exec.conection = true; // deschiderea portului a reusit
exec.ok=0;// resetare variabila pt a afisa doar d 2 ori ca nu avem conexiune seriala
serialIoManager = new SerialInputOutputManager(arduinoSerial, this);
new Thread(serialIoManager).start(); // folosit pt a detectat cand Arduino a trimis date catre aplicatie
try {
Thread.sleep(2000); // se asteapta 2 sec dupa ce se deschide portul
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// Trimiterea mesajului "Program_1" către Arduino
//sendMessage("A");
} catch (IOException e) {
Toast.makeText(this, "Eroare la deschiderea conexiunii serial...", Toast.LENGTH_SHORT).show();
try {
arduinoSerial.close();
} catch (IOException ex) {
// Ignoră eroarea
}
}
}
public void sendMessage(String program) {
if (arduinoSerial != null) {
try {
arduinoSerial.write( program.getBytes(), 1000); /// 1 sec timpul cat asteapta pentru a se trimite datele
// daca datele se transmit mai repede , nu se asteapta pana la 1 secunde
// Utilizați un Handler pentru a afișa Toast-ul în UI thread
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Mesaj trimis -> " + program , Toast.LENGTH_SHORT).show();
}
});
exec.status = true; // am trimis comanda
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Eroare la trimiterea mesajului.", Toast.LENGTH_SHORT).show();
}
});
}
} else {
Toast.makeText(this, "Conexiunea serial nu este deschisă.", Toast.LENGTH_SHORT).show();
}
}
public void CloseSerial(int x) {
if (x == 0) { // se inchide conexiunea seriala si cea usb
if (arduinoSerial != null) {
handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
arduinoSerial.close();
arduinoSerial = null;
exec.conection = false;// nu mai este arduinoserial deschis
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}, 2000); // se asteapta 2 secunde pana se inchide
}
if (serialIoManager != null) {
serialIoManager.stop();
serialIoManager = null;
}
closeUsbConnection();
}
}
private void closeUsbConnection() {
if (connection != null) {
connection.close();
connection = null;
}
}
I'm not an Android expert, but as far as I can understand (it is also not easy to me to understand comments in romanian), there are some things unclear to me.
In connectArduino() I see this code:
UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(arduinoDevice);
if (driver == null) {
Toast.makeText(this, "Dispozitivul nu este compatibil.", Toast.LENGTH_SHORT).show();
return;
}
arduinoSerial = driver.getPorts().get(0);
try {
arduinoSerial.open(connection);
...
Are you sure when "driver" is not null, the "getPorts()" always returns at least one element? I'd either check it before accessing element 0, or put that line inside the "try".
when you open the port wait 2 seconds with "sleep(2000)" but then the "sendMessage("A")" is commented out so no message will be sent to Arduino! I hope it's not the code you're testing, isn't it?... Please, always send the latest, actual code under test!
After the sendMessage() I don't see any other code to perform the whole process... Where do you call "CloseSerial()"? And "closeUsbconnection()"? The code you have shown us either is partial (see previous point) and miss something you should include, or you really don't close everything to make some cleanup (and this could bring errors on subsequent calls/iterations)?
Thank you for your fast replay,
I wont paste the entire App code here because its a very long one.
If the driver would be null a message would be displayed and then a return is placed there.
If that would be the case message wont be send to the arduino.
Opening a connection to the arduino , send message, closeSerial and closeUsbConection, are initialized only when the user press a button on the application screen.
I was thinking maybe if I write arduino code to reset the serial connection each 10 minutes perhaps will help ?
And also, if the Android app is closing the serial connection doesn't have to be closed in arduino too ?
Yes but it's not exactly what I meant: I see if driver is not null, you try to get the first element returned by getPorts(). I wonder if getPorts() always returns at least one element or not. Just in case, move that statement inside the next try..catch to make sure the code won't raise an unhandled exception (stopping the code from working again).
Ok but if you don't include such button event handler code section I (we) can't know the entire flow.
Arduino doesn't have an underlying operating system like Android (it has a Java virtual machine over a Linux kernel...) so there's no "serial connection": internal UARt makes use of just two pins for RX and TX, there's no hardware handshake so no signal if a peer is connected or has closed the connection.
What I suggest you is to make things easier: keep the serial connection always opened within your app, opening it at app start and closing it when the app is closed, and then just send what you need to send when required.