Hello everyone, I need help with the following project:
I have a robot with 4 wheels, 2 of which are powered by 12V motors.
These motors are controlled via an Adafruit Motorshield V2.
The Motorshield sits on an Arduino UNO R3.
My smartphone serves as the interface to the user with a program I developed using MITAppInventor2
The app sends the commands via Bluetooth (as a string) to the BT receiver
The BT receiver is connected to D9,D10 of the Arduino.
I increased the BT receiver to 57600 baud.
My problem is that changing the variables takes too long to control the robot properly. I have reduced the program to just the problem:
SoftwareSerial mySerial(9, 10);
void setup() {
Serial.begin(9600);
delay(500);
mySerial.begin(57600);
}
void loop() {
if (mySerial.available() > 0) {
String fromAndroid = mySerial.readString();
// Hier kommt der Code zur Verarbeitung des Strings
char *inputString = (char *)fromAndroid.c_str(); // Konvertierung von String in char*
char *endptr;
int num1, num2, num3;
// Kopie erstellen, um den Originalstring zu erhalten
char inputCopy[strlen(inputString) + 1];
strcpy(inputCopy, inputString);
// Erste Zahl extrahieren
num1 = strtol(inputCopy, &endptr, 10);
endptr++; // Überspringe das Komma
// Zweite Zahl extrahieren
num2 = strtol(endptr, &endptr, 10);
endptr++; // Überspringe das Komma
// Dritte Zahl extrahieren
num3 = strtol(endptr, &endptr, 10);
// Ausgabe der extrahierten Zahlen
Serial.print("Zahl 1: ");
Serial.println(num1);
Serial.print("Zahl 2: ");
Serial.println(num2);
Serial.print("Zahl 3: ");
Serial.println(num3);
}
}```
Here is the generation of the sting with MITAPPInventor2: Clock2 is set so that the string is sent every 1000ms. If I increase the frequency to 500ms, I no longer receive a string on the BT module.


have already tried various things to speed up communication without success. I hope you still have ideas.
Thank you
Thank you very much for the answer, I have now read the entire post by @Robin2. I have tried countless times to split a string which is received by the Bluetooth receiver at 57600 baud on pins 9 and 10 using the strtok function and write it into variables. When I try this I get nothing at all:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
const int SERIAL_BUFFER_SIZE = 21;
char serialBuffer[SERIAL_BUFFER_SIZE];
void setup()
{
Serial.begin(9600);
Serial.println("<Arduino is ready -->");
mySerial.begin(57600);
}
void loop()
{
if (readSerial(mySerial)) //liefert true wenn das LF eingelesen wurde
parseSerial();
}
void parseSerial()
{
Serial.print("Empfangen: "); Serial.println(serialBuffer);
int val1 = atoi(strtok(serialBuffer, ",;+"));
int val2 = atoi(strtok(NULL, ",;+"));
int val3 = atoi(strtok(NULL, ",;+"));
// int val4 = atoi(strtok(NULL, ",;+"));
// int val5 = atoi(strtok(NULL, ",;+"));
Serial.println(val1);
Serial.println(val2);
Serial.println(val3);
// Serial.println(val4);
// Serial.println(val5);
Serial.println();
}
bool readSerial(Stream& stream)
{
static byte index;
while (stream.available())
{
char c = stream.read();
if (c == '\n' && index > 0) //wenn CR eingelesen und String länger als 0 ist
{
serialBuffer[index] = '\0'; //String terminieren
index = 0;
return true; //melden dass String fertig eingelesen wurde
}
else if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1) //solange noch Platz im Puffer ist
{
serialBuffer[index++] = c; //Zeichen abspeichern und Index inkrementieren
}
}
return false; //noch nicht fertig
}
I doubt that software serial will work at that high a baud rate.
What does your code do when you lower it to 9600 baud. If it works correctly, then see how high you can raise the rate.
If the incoming string is still not read at the lower baud rate, we can examine other area of your code.
The BT receiver is soldered to 9.10 and I can't change that to 0.1 so quickly. I changed it to 9.10 because I had to constantly turn off the power to the BT receiver when uploading so that there were no errors
Okay, I've now managed to receive data. But since the code is composed of several solutions and therefore still seems very bloated and not very smart, can you help me to make the code more elegant.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
const byte numChars = 90;
char receivedChars[numChars];
char tempChars[32];
char messageFromPC[32] = {0};
int integerFromPC = 0;
int floatFromPC = 0;
char recvChar;
char endMarker = '>';
boolean newData = false;
byte dLen = 0;
//boolean newData = false;
void setup() {
Serial.begin(9600);
Serial.println("<Arduino is ready -->");
mySerial.begin(57600);
}
void loop() {
recvWithStartEndMarkers();
// doOtherStuff(); // <<=== NEW --- This just simulates time spent elsewhere in a big program
strcpy(tempChars, receivedChars);
parseData();
showNewData();
// delay(10);
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
if (mySerial.available() > 0) {
while (mySerial.available() > 0 && newData == false) { // <<== NEW - get all bytes from buffer
rc = mySerial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
} // <<=== NEW
}
}
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
floatFromPC = atoi(strtokIndx); // convert this part to a float
}
void showNewData() {
if (newData == true) {
//Serial.print("This just in ... ");
// Serial.println(receivedChars);
Serial.print("Message ");
Serial.println(messageFromPC);
Serial.print("Integer ");
Serial.println(integerFromPC);
Serial.print("Float ");
Serial.println(floatFromPC);
newData = false;
}
}
/*
void doOtherStuff() {
delay(1); // <<===NEW - This just simulates time spent elsewhere in a big program
}
*/
The code you have posted in post #7 is not "bloated". This is what it takes to make it work non-blocking.
Did you accidently post the not-bloated short code?
Was your expectation that there is a code-version that will be as short as
int myInteger;
float myFloat;
myInteger = serialReceiveInt();
myFloat = serialReceiveFloat();
?
There isn't because there are trillion ways what kind of combinations of characters can be send and what all these characters mean.
Or you would have to exact specify and quote which lines of code do you see as "bloated"
Your receiving code needs some kind of information that indicates "full message received"
This can be time = a timeout that is what readString() is doing
and which takes a certain time. The default is 1000 milliseconds
or
this can be a start and endmarker like in the serial input basics-code
as soon as the end-marker is received the processing of the message can begin
You should post all commands that you want to send from your MIT-App.
Depending on what commands these are it might be possible to use a different code.