Bluetooth - Serial Communication Issue

Dear Arduino Forum,

I need your help regarding my current development project. The project looks like this:

I have an Arduino Uno hooked up to a HC-05 Bluetooth breakout board on PINs 2 and 3 by using software serial. I also have an app built with MIT App Inventor that I want to use to control the Arduino from my smartphone. Later the Uno will also open and close four Relais and handle three LEDs plus a stepper motor driver but right now that is not important.
My problem lies in the communication between app and Arduino or in how to handle the serial data.

Before somebody asks: Yes, I know the HC-05 only wants 3.3V ... I put a voltage divider in the circuit to make sure of it and testet the breakout board several times with a simpler app on baud rate 9600, it works perfectly.

I think it would be best to just hop in, so here is my code:

//TESTCODE for ARDUINO UNO


// add serial communiction port
#include <SoftwareSerial.h>
SoftwareSerial SecSerial(2,3);          // RX | TX extra ports


const int tx = 15;                      // amount of Array values
long txArray[tx] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // at the start array shall contain only zeros


// test code only uses the DPIN13 LED and skipps the relais and stepper motor driver module
const int LED13 = 13;
int i;                                  // for-loop integer
bool DataWaiting = false;               // Array beschrieben aber noch nicht ausgewertet




void setup()
{     
    SecSerial.begin(9600);              // start Bluetooth Serial on D2 & D3 with rate 9600
    Serial.begin(9600);                 // start Standard Serial on D0 & D1 with rate 9600


    pinMode(LED13, OUTPUT);             // OUTPUT for DPIN 13 possible
  
    SecSerial.setTimeout(50);           // ends reading time for the second serial
    // tested just "Serial." and I tested the code with this line at all but no effect
    
    Serial.println("started");          // info that setup complete
}




void loop() 
{   
    DataTransfer();


    if (DataWaiting == true)            // if there is data to iterate then:
    {
        for (i = 0; i < tx; i++)        // start for loop to iterate the array data
        {
             if (i % 2 == 0)            // for 0,2,4,6,8,10,12,14 of the Arrays (ZEROINDEX)
             {
                 ExampleFunctionA(i);   // start ExampleFunctionA
             }
             
             else if (i % 2 == 0)       // for 1,3,5,7,9,11,13 of the Arrays (ZEROINDEX)
             {
                 ExampleFunctionB(i);   // start ExampleFunctionB
             }


             else if (i == 15)          // for loop complete: [i is now 15]
             {            
                 long txArray[tx] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};     //Array zurücksetzen
                 
                 DataWaiting = false;               // there is no more data to iterate
                 digitalWrite(LED13,LOW);           // LED13 OFF because no more data to iterate
                 delay(10000);                      // Cooldown, all processes finished nothing more to do
             }
        }
    }
}


void DataTransfer()
{
    if (Serial.available())
    {
        txArray[0]  = Serial.parseInt();  // take first Integer and save on Array
        txArray[1]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[2]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[3]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[4]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[5]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[6]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[7]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[8]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[9]  = Serial.parseInt();  // take following Integer and save on Array
        txArray[10] = Serial.parseInt();  // take following Integer and save on Array
        txArray[11] = Serial.parseInt();  // take following Integer and save on Array
        txArray[12] = Serial.parseInt();  // take following Integer and save on Array
        txArray[13] = Serial.parseInt();  // take following Integer and save on Array
        txArray[14] = Serial.parseInt();  // take following Integer and save on Array
        
     // App sends "\n" now as info that it's end of transmission
    
        if (SecSerial.read() == '\n')     // if last Byte \n stop reading and send 'd' for done to App
        {              
            Serial.flush();               // clear all other commands piled in the buffer
            SecSerial.flush();            // clear all other commands piled in the secondary buffer
            // don't know which one so I chose both
            
            Serial.print('d');            // send completion of the command
            // does that have to be "SecSerial." ??


            DataWaiting = true;           // there is data to use
            digitalWrite(LED13,HIGH);     // LED 13 ON, because there's data now
        }
    }
}




void ExampleFunctionA(int tAx)
{
    int t_App = txArray[tAx];             // needed time from array
    int t_milli = t_App * 1000;           // time in milliseconds
    
    Serial.println("Start Example A");    // info that process begins
    Serial.println(tAx);                  // info that process begins


    delay(t_milli);                       // block till time is up 
    // in complete code a relais opens and the motor turns for time t_milli


    Serial.println("Example A finished");   // info that process ended
    Serial.println(tAx);                    // info that process ended


    t_App = 0;                            // set back time variables to be sure nothing bad happens
    t_milli = 0;                          // set back time variables to be sure nothing bad happens
    
    delay(2000);                          // short Time-Out for the Arduino to get some digital snacks
}




void ExampleFunctionB(int tAx)
{
    int t_App = txArray[tAx];             // needed time from array
    int t_milli = t_App * 1000;           // time in milliseconds


    Serial.println("Start Example B");    // info that process begins
    Serial.println(tAx);                  // info that process begins


    delay(t_milli);                       // block till time is up
    // in complete code a relais opens and the motor turns for time t_milli


    Serial.println("Example B finished");   // info that process ended
    Serial.println(tAx);                    // info that process ended


    t_App = 0;                            // set back time variables to be sure nothing bad happens
    t_milli = 0;                          // set back time variables to be sure nothing bad happens
    
    delay(2000);                          // short Time-Out for the Arduino to get even more digital snacks
}

When I run this code, open the serial monitor and send data from the app, nothing is happening in the serial monitor. The LED on PIN 13 doesn't light up either. Something with the communication does ot work or the data is not handled properly. The program seems to never reach the second if-loop in the DataTransfer function.

To fully understand he problem, you of course need to know what my app is doing. I have attached two pictures from App Inventor that show how the values are calculated and how they are send. They are at the end of my post. :smiley:

I have to admit I'm not completely understanding the topic serial communication, but I have seen a similar solution on instructables with sliders and the robot arm:

It is currently quite late in Germany. But I hope that I have explained my problem in a recognizable way and have not made any obvious mistakes.

I thank you for your time and hope that you can help me.
Have a pleasant evening/day!

I’m not familiar with Appinventor. Please provide an example of a message that Appinventor sends.

If you are having trouble with communication I suggest you start with a much simpler program that just sends “Hello World”

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

Thanks for the quick reply!
I will run some tests tomorrow with your Info in mind and test that 3rd example!

Greetings and Good Night!

It’s been a long time, but just now I have found a solution and I wanted to share it.

Unfortunately the forum does not allow me to attach a picture from the App Inventor Blocks area that shows what data I send from the app now in the final solution. But the changes are basically minimal, but instead of “\n” we will now use “*” as an end marker.

And this is my Arduino function to receive via Bluetooth and format the data into my array:

void Datentransfer()
{
    if (SecSerial.available())
    {
        BluetoothText = SecSerial.read();
        StringText = StringText + BluetoothText;
        // Bluetooth Zeichenkette endet auf *
        
        if (BluetoothText == '*')         // wenn letzter Byte * stoppe auslesen
        {   
            StringText = StringText.substring(0, StringText.length() - 1);
            // Abschlussmarker '*' von Bluetooth Zeichenkette wird entfernt

            // Teile Zeichenkette auf und bestücke Array für Weiterverarbeitung
            int_t1 = StringText.indexOf(',');
            String_t1 = StringText.substring(0, int_t1);
            long_t1 = String_t1.toInt();
            txArray[0] = long_t1;
            
            int_t2 = StringText.indexOf(',', int_t1+1 );
            String_t2 = StringText.substring(int_t1+1, int_t2);
            long_t2 = String_t2.toInt();
            txArray[1] = long_t2;
            
            int_t3 = StringText.indexOf(',', int_t2+1 );
            String_t3 = StringText.substring(int_t2+1, int_t3);
            long_t3 = String_t3.toInt();
            txArray[2] = long_t3;
    
            int_t4 = StringText.indexOf(',', int_t3+1 );
            String_t4 = StringText.substring(int_t3+1, int_t4);
            long_t4 = String_t4.toInt();
            txArray[3] = long_t4;
    
            int_t5 = StringText.indexOf(',', int_t4+1 );
            String_t5 = StringText.substring(int_t4+1, int_t5);
            long_t5 = String_t5.toInt();
            txArray[4] = long_t5;
    
            int_t6 = StringText.indexOf(',', int_t5+1 );
            String_t6 = StringText.substring(int_t5+1, int_t6);
            long_t6 = String_t6.toInt();
            txArray[5] = long_t6;
    
            int_t7 = StringText.indexOf(',', int_t6+1 );
            String_t7 = StringText.substring(int_t6+1, int_t7);
            long_t7 = String_t7.toInt();
            txArray[6] = long_t7;
    
            int_t8 = StringText.indexOf(',', int_t7+1 );
            String_t8 = StringText.substring(int_t7+1, int_t8);
            long_t8 = String_t8.toInt();
            txArray[7] = long_t8;
    
            int_t9 = StringText.indexOf(',', int_t8+1 );
            String_t9 = StringText.substring(int_t8+1, int_t9);
            long_t9 = String_t9.toInt();
            txArray[8] = long_t9;
    
            int_t10 = StringText.indexOf(',', int_t9+1 );
            String_t10 = StringText.substring(int_t9+1, int_t10);
            long_t10 = String_t10.toInt();
            txArray[9] = long_t10;

            int_t11 = StringText.indexOf(',', int_t10+1 );
            String_t11 = StringText.substring(int_t10+1, int_t11);
            long_t11 = String_t11.toInt();
            txArray[10] = long_t11;
    
            int_t12 = StringText.indexOf(',', int_t11+1 );
            String_t12 = StringText.substring(int_t11+1, int_t12);
            long_t12 = String_t12.toInt();
            txArray[11] = long_t12;
    
            int_t13 = StringText.indexOf(',', int_t12+1 );
            String_t13 = StringText.substring(int_t12+1, int_t13);
            long_t13 = String_t13.toInt();
            txArray[12] = long_t13;
    
            int_t14 = StringText.indexOf(',', int_t13+1 );
            String_t14 = StringText.substring(int_t13+1, int_t14);
            long_t14 = String_t14.toInt();
            txArray[13] = long_t14;
    
            int_t15 = StringText.indexOf(',', int_t14+1 );
            String_t15 = StringText.substring(int_t14+1, int_t15);
            long_t15 = String_t15.toInt();
            txArray[14] = long_t15;
            
            StringText = "";              // gesendeter String zurückgesetzt
            i = 0;                        // for Schleife zurücksetzen     
            DatenInWarteschleife = true;  // es gibt nun Daten abzuarbeiten
            digitalWrite(LED1,HIGH);      // LED 1 leuchtet auf, weil es Daten gibt
            delay(100);                   // verzögere für eine zehntel Sekunde
        }
    }
}

To all the fellow people that will read this and have a similar problem, I hope this will help you. 2020 wasn’t perfect, I wish you a better 2021.