Arduino Uno not processing incoming data

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 .

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

const int ledPin = 13;
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool displayInitialMessage = 0;

void setup() {
  Serial.begin(9600);

lcd.begin();
lcd.backlight();
lcd.print("Waiting ... ");

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,LOW);

  pinMode(12,OUTPUT);
  digitalWrite(12,LOW);

}

void loop() {

    if (displayInitialMessage) {
    lcd.clear();
    lcd.print("Waiting ... ");
    displayInitialMessage = 0;
  }

if(Serial.available()>0){

  lcd.clear();

  while(Serial.available()){

       char octet = (char)Serial.read(); 
  
            if (octet == 'A') { 
              // digitalWrite(12,HIGH);
              lcd.print(octet);
               program_1(5); 
               //digitalWrite(12,LOW);
               
            } else if (octet == 'B') { 
             // digitalWrite(12,HIGH);
             lcd.print(octet);
              program_2(5);
             // digitalWrite(12,LOW);
            }
            else { 
              lcd.print("else");
              programTest();
            }

  }
  delay(2000);
  displayInitialMessage = 1;
  
  } // end if 
delay(100);
} // end void loop



void programTest(){
  digitalWrite(12,HIGH);
  delay(1000);
  digitalWrite(12,LOW);

}

void program_1(int times) {
  
  for (int i = 0; i < times; i++) {
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
  }
 
}

void program_2(int times) {
  
  for (int i = 0; i < times; i++) {
    digitalWrite(ledPin, HIGH);
    delay(2000);
    digitalWrite(ledPin, LOW);
    delay(1000);
  }
 
}



If you are not using all of your 16x2 LCD, then use part of it for debugging. Maybe a counter incrementing by 1 each time a new byte is received.

Get rid of all delays in your code, and control the timing of any action non-blocking with millis.

What is device is receiving the message on the Arduino?

How do you determine if a connection has been made or not?

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.

how is Android device connectd to Arduino? did you forgot to attach Bluetooth module?

use serial monitor and check this out:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

const int ledPin = 13;
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool displayInitialMessage = 0;

void setup() {
  Serial.begin(9600);

  lcd.begin();
  lcd.backlight();
  lcd.print("Waiting ... ");

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

}

void loop() {

  if (displayInitialMessage == 16) {
    lcd.clear();
    displayInitialMessage = 0;
  }

  if (Serial.available() > 0) {
    lcd.print(Serial.read());
    displayInitialMessage++;
    digitalWrite(ledPin,   digitalRead(ledPin));
  }
}

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.

will do

Connection is via USB

Android app (phone) which sends the commands ex "A" or "B" to the Arduino is is communicating via OTG cable.

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.

  1. 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".

  1. 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!

  2. 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.

Nope.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.