serieller Datenaustausch, Arduino <> Smartphone Bluetooth

Hallo,

der gefundene Code von Serenifly funktioniert nur vom Arduino aus in alle Richtungen.
Dann habe Code gefunden der auch vom Smartphone aus funktioniert.
Allerdings hat der keine Endezeichen bzw. Endeerkennung.
Das äußerst sich dann darin, dass ich zum Bsp. "Hallo" mehrfach senden muß bevor das erkannt wird, scheinbar bis der Empfangspuffer voll ist und dann wird Hallo mehrfach hintereinander ausgegeben. Das ist natürlich blöd.

Dann habe ich irgendwie zufällig herausgefunden das man vom Smartphone aus mit dem HC-06 kein LF oder CR senden kann. Warum nicht?

Nun dachte ich mir, okay, dann hänge ich an meine Zeichen zum Bsp. ein @ ran als Endeerkennung. Sende dann also "Hallo@".
Das Problem von oben bleibt jedoch bestehen. Es werden erst Zeichen erkennt/empfangen wenn scheinbar der Puffer voll ist.

Wie kann man das Problem lösen?

von mir angepaßter Code von Serenifly

#include <SPI.h>
#include <DogLcdSPI.h>  // für Hardware SPI angepaßte DogLcd.h

const int SERIAL_BUFFER_SIZE = 15;
char serialBuffer[SERIAL_BUFFER_SIZE];

DogLcdSPI lcd(26, 27);  // Pins für RS und CSB

void setup()  {
  
  Serial.begin(57600);  
  Serial1.begin(57600);          
  SPI.begin();
           
  // set up the LCD type and the contrast setting for the display 
  lcd.begin(DOG_LCD_M163);     // EA-DOGM Display 3 zeilig
  lcd.noCursor();              // Cursor nicht sichtbar
  lcd.print(F("MEGA"));        // Print a message to the LCD.
 
}   // Ende setup


void loop(void) {
 
if( read_Serial_0() )  {
  ShowSerialData();
  lcd.print(serialBuffer);
}  
     
if( read_Serial_1() )  {
  ShowSerialData();
  lcd.print(serialBuffer);
}  
 
}   // Ende loop


/* ------------------------------------------------------------------------------------------------ */

boolean read_Serial_0()
{
	static unsigned int index;

	if (Serial.available() > 0)  {		
          char c = Serial.read();
	  if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
	    {
	     serialBuffer[index++] = c;
	    }
            else if(c == '\n' || '\r')   // Endeerkennung, LineFeed oder CarrierReturn
	      {
		serialBuffer[index] = '\0';
		index = 0;
		return true;
	      }
	}
	return false;
}


boolean read_Serial_1()   // vom Smartphone über Bluetooth
{
	static unsigned int index;

	if (Serial1.available() > 0)  {		
          char c = Serial1.read();
	  if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
	    {
	     serialBuffer[index++] = c;
	    }
            else if(c == '@')   // Endeerkennung @ Zeichen
	      {
		serialBuffer[index] = '\0';
		index = 0;
		return true;
	      }
	}
	return false;
}


void ShowSerialData ()
{
     Serial.print(serialBuffer);
     Serial1.print(serialBuffer);
}

das ist der Bsp. Code aus dem www, dadurch kam ich drauf das vom Smartphone/BT kein LF/CR geschickt wird.

void loop(void) {
 
  // read from port 1, send to port 0:
  if (Serial1.available() )  {
    int inByte = Serial1.read();
    if(inByte)  {
      Serial1.write(inByte);
    }     
    Serial.write(inByte);
  }
 
  // read from port 0, send to port 1:
  if (Serial.available() )  {
    int inByte = Serial.read();
    if(inByte)  {
      Serial.write(inByte);
    }     
    Serial1.write(inByte);
  }

Das Problem ist also, wie bekommt man vom Smartphone / HC-06 eine ordentliche Endeerkennung hin?

Wenn du auf ein Zeichen abfragen willst, das nicht Teil der ASCII-Steuerzeichen ist, sollte das so aussehen:

if(c == '@')
{
    serialBuffer[index] = '\0';
    index = 0;
    return true;
}
else if (index < SERIAL_BUFFER_SIZE - 1)
{
   serialBuffer[index++] = c;
}

Also erst auf das Endzeichen abfragen. Das liegt daran dass der Original-Code auf c >= 32 abfragt und damit alles was kein Steuerzeichen ist abgespeichert wird noch bevor man auf das Endzeichen abfragt.

Hallo,

gibt es denn wirklich keine Möglichkeit vom Smartphone aus ein LF/CR zu senden?
Auf dem Windowsrechner sendet doch auch das Terminal das LF/CR zum Schluss.
Mir möchte nicht in den Kopf das es am BT Adapter HC-06 liegen soll.

Hallo,

Danke Serenifly. Das funktioniert soweit. So ganz dahinter gekommen bin ich noch nicht, warum damit nicht auch '\n' oder '\r' funktioniert als Endezeichen. Überhaupt verstehe ich noch nicht wer und warum vom Smartphone aus das LF/CR verschluckt. Habe eine App gefunden (Bluetooth Terminal) wo ich explizieht einstellen kann ob LF oder CR oder beides oder nichts gesendet werden soll. Kommt aber scheinbar nichts an beim Arduino. Hab es auch mit 10 und 13 probiert, was dezimal für LF/CR steht.

/*
 Arduino Mega 2560
 EA DOGM 163 (Hardware SPI Bus)   
*/

#include <SPI.h>
#include <DogLcdSPI.h>  // für Hardware SPI angepaßte DogLcd.h

const int SERIAL_BUFFER_SIZE = 20;
char serialBuffer[SERIAL_BUFFER_SIZE];
char serialBuffer1[SERIAL_BUFFER_SIZE];

DogLcdSPI lcd(26, 27);  // Pins für RS und CSB

void setup()  {
  
  Serial.begin(57600);  
  Serial1.begin(57600);          
  SPI.begin();
           
  // set up the LCD type and the contrast setting for the display 
  lcd.begin(DOG_LCD_M163);     // EA-DOGM Display 3 zeilig
  lcd.noCursor();              // Cursor nicht sichtbar
  lcd.print(F("MEGA"));        // Print a message to the LCD.
 
}   // Ende setup


void loop(void) {
 
if( read_Serial_0() )  {
  ShowSerial_0_Data();
  lcd.clear(); lcd.print("0:"); lcd.print(serialBuffer);
}  
     
if( read_Serial_1() )  {
  ShowSerial_1_Data();
  lcd.clear(); lcd.print("1:"); lcd.print(serialBuffer1);
}  

}   // Ende loop


/* ------------------------------------------------------------------------------------------------ */

boolean read_Serial_0()
{
	static unsigned int index;

	if (Serial.available() > 0)  {		
          char c = Serial.read();
	  if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
	    {
	     serialBuffer[index++] = c;
	    }
            else if(c == '\n' || '\r')   // Endeerkennung, newline oder carriage return
	      {
		serialBuffer[index] = '\0';   // Endmarkierung eines Strings
		index = 0;
		return true;
	      }
	}
	return false;
}


boolean read_Serial_1()
{
	static unsigned int index1;

	if (Serial1.available() > 0)  {		
          char c = Serial1.read();
          // if(c == '\n' || '\r')   // funktioniert nicht
          if(c == '@')
            {
             serialBuffer1[index1] = '\0';
             index1 = 0;
             return true;
            }
          else if (index1 < SERIAL_BUFFER_SIZE - 1)
            { 
             serialBuffer1[index1++] = c;
            }
	}
	return false;       
}


void ShowSerial_0_Data ()
{
  Serial1.println(serialBuffer);
}     


void ShowSerial_1_Data ()
{
  Serial.println(serialBuffer1);
}

Auf der App-Seite sind die Stichwörter PreFix-Mode und Asynchrone Uebertragung

Hallo,

wie meinst Du das?
Ich kann das doch mittlerweile in 2 Apps einstellen. Dennoch passiert nichts. Funktioniert nur mit selbst definierten Sonderzeichen wie zum Bsp. das @.