Bluetooth Car - Verständnisfragen

#include <SoftwareSerial.h>

//BT

SoftwareSerial BlueTooth(13, 12);

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start..."));
  BlueTooth.begin(9600);
}

void loop() {
  getData();
  setDrive();
}
void getData() {
  while (BlueTooth.available()) {
    //char myChar = Serial.read();
    char myChar = BlueTooth.read();

    if (isAlpha(myChar)) {
      myChar = ucase(myChar);
      switch (myChar) {
        case 'X':  //automatic
        case 'Y':  //linefollow
        case 'B':  //backward
        case 'F':  //forward
        case 'L':  //left
        case 'R':  //right
        case 'S':  //stop
          Serial.print(F("Input Char: "));
          Serial.println(myChar);
          BT_input = myChar;
          break;  //gültiges Zeichen
        default:
          if (myChar >= ' ') {
            Serial.print(F("FailChar: "));
            Serial.println(myChar, HEX);
            BT_input = 'S';
          }
      }
    }
  }
  if (oldInput != BT_input) {
    drive(stop);
    delay(20);  // kurze Pause schont die Antriebe!
    oldInput = BT_input;
  }
}

int setDrive() {
  switch (ucase(BT_input)) {
    case 'X':
      automatic();
      break;
    case 'Y':
      linefollower();
      break;
    case 'B':
      drive(backward);
      break;
    case 'F':
      drive(forward);
      break;
    case 'L':
      drive(turnLeft);
      break;
    case 'R':
      drive(turnRight);
      break;
    case 'S':
      drive(stop);
      break;
  }
}

char ucase(const char c) {
  if (c >= 'a' && c <= 'z') {
    return (c + ('A' - 'a'));
  }
  return c;
}

Danke nochmal Danke für die Hilfe an my_xy_projekt. Ich versuche aktuell, das Projekt altes Thread vereinfacht von der Pieke an zu verstehen. Sicherlich kann mir jemand helfen.

1.BT_input,oldInput und myChar werden im Head nicht deklariert. Wieso? Normal sagt man doch z.B. int BT_input=0;
2. Was ist "isAlpha" und ucase(myChar)?
3. Was bewirkt:

char ucase(const char c) {
  if (c >= 'a' && c <= 'z') {
    return (c + ('A' - 'a'));
  }
  return c;
}

Zu 1)
MyChar wird nur als temporäre Variable in der Funktion genutzt um das einmalige Ergebnis von .read() zu behalten und mehrfach zu verwenden.
myChar braucht ausserhalb der Funktion keinen Speicherplatz und der Inhalt kann beim Verlassen der Funktion verloren gehen.
Drr Speicherplatz steht dann anderen Variablen zur Verfügung.

Mit den beiden anderen reiche ich nach, da muss ich drauf schaun um nix falsches zu sagen, sitze aber im SEV Bus.

IsAlpha ist eine Funktion, die auf alphanumerische Zeichen, also Buchstaben und zahlen prüft und wahr zurückgibt, wenn das übergebene Zeichen dem entspricht.
Im Gegensatz dazu sind Satzzeichen, leer-, oder Steuerzeichen (enter) nicht alphanumerische.

Ucsse ist eine Funktion, die aus Kleinbuchstaben Großbuchstaben macht.
Es gibt dazu verschiedene Ansätze, das ist einer davon.

Ich hatte Dir ein .PDF empfohlen, wenn mich nicht alles täuscht.
Dort sind u.a. Arduino-spezifische Funktionen erklärt.

Die sind ganz normal daklariert:
Post #64 vom 9. Mai:

char BT_input;
char oldInput;
char ucase(const char c) {       // Funktionsaufruf, übergeben wird ein char und zurückgeben ebenfalls
// Das const char c bewirkt, dass c selbst schreibgeschützt gestellt wird  
  if (c >= 'a' && c <= 'z') {    // Prüfung, ob c ein Klenbuchstabe a bis z ist
    return (c + ('A' - 'a'));    // Wenn ja: mache daraus einen Grossbuchstaben, indem du den Wert dazu addierst
  }
  return c; // Wenn es kein kleinbuchstabe war, gib das Zeichen genauso zurück
}

Für die Zeile:
return (c + ('A' - 'a'));
musst Du wissen, dass jedem Zeichen ein numerisches Äquivalent zugeordnet ist:

Machst Du aus dem char 'a' ein Byte b, erhält b den Wert 97 decimal und aus 'A' wird 65 decimal.
Nimmst Du jetzt die Codezeile und gehst davon aus, dass der Compiler automatisch numerisch rechnet, wird bei einem übergebenem Zeichen 'a':

return ('a' + ('A'-'a'));
-> return (97 + (65-97)) = (97 + (-32)) = 97-32 = 65
Da die Funktion einen char zurück gibt, wird jetzt das Zeichen mit dem Wert 65 ausgegeben und das ist zufällg 'A'.

Jetzt könntest Du sagen, wenn aber ein 'b' übergeben wird, müsste das ja:

return ('b' + ('B'-'b'));

heissen.

Noch Fragen? Ne gute Stunde fahr ich noch :grin:

Gerade nicht, aber super erklärt :wink: danke. Ich konnte mein Projekt mit den Informationen jetzt auch die Fehler ausradieren.

Hatte jetzt wie du schon in den anderen Threads gesagt hast (auch andere, ich weiß), debuggen und alles nacheinander :slight_smile:

Und es klappt :slight_smile:

#include <AFMotor.h>
#include <Arduino.h>
#include <HCSR04.h>
#include <SoftwareSerial.h>

SoftwareSerial BlueTooth(10, 11);  // RX, TX
byte triggerPin = 9;
byte echoPin = 7;
int duration, distance;
int number;
char BT_input;
char oldInput;


AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);
unsigned char smile[] = { 0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x5c, 0x40, 0x40, 0x5c, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00 };
unsigned char herz[] = { 0x00, 0x00, 0x00, 0x0c, 0x12, 0x21, 0x41, 0x82, 0x41, 0x21, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00 };
unsigned char vor[] = { 0x00, 0x00, 0x02, 0x04, 0x09, 0x12, 0x24, 0x48, 0x90, 0x48, 0x24, 0x12, 0x09, 0x04, 0x02, 0x00 };
#define SCL_Pin A4
#define SDA_Pin A5
void setup() {
  Serial.begin(57600);
  Serial.println(F("Start..."));
  BlueTooth.begin(9600);
  pinMode(SCL_Pin, OUTPUT);
  pinMode(SDA_Pin, OUTPUT);
}

void loop() {
  motor1.setSpeed(120);
  motor2.setSpeed(120);
  motor3.setSpeed(120);
  motor4.setSpeed(120);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
bluetooth();
getData();
 
}
void getData() {
  while (BlueTooth.available()) {
    //char myChar = Serial.read();
    char myChar = BlueTooth.read();

    if (isAlpha(myChar)) {
      myChar = ucase(myChar);
      switch (myChar) {
        case 'Y':
        case 'X':
        case 'B':  //backward
        case 'F':  //forward
        case 'L':  //left
        case 'R':  //right
        case 'S':  //stop
          Serial.print(F("Input Char: "));
          Serial.println(myChar);
          BT_input = myChar;
          break;  //gültiges Zeichen
        default:
          if (myChar >= ' ') {
            Serial.print(F("FailChar: "));
            Serial.println(myChar, HEX);
            BT_input = 'S';
          }
      }
    }
  }
  if (oldInput != BT_input) {
    car_Stop();
    delay(20);  // kurze Pause schont die Antriebe!
    oldInput = BT_input;
  }
}
char ucase(const char c) {
  if (c >= 'a' && c <= 'z') {
    return (c + ('A' - 'a'));
  }
  return c;
}
void bluetooth() {
getData();
  switch (BT_input) {
    case 'X': switchdrive();break;
    case 'Y': bluetooth();break;

    case 'B': car_back(); break;

    case 'F': car_front(); break;

    case 'L': car_left(); break;

    case 'R': car_right(); break;

    case 'S': car_Stop(); break;
  }
}


void switchdrive() {
  distance = 0;
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(4);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = round(duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay(100);
  switch (distance) {
    case 1 ... 15:
      car_front();
      Serial.println("zurueck");
      delay(1200);
      drive();
      Serial.println(number);
      matrix_display(herz);
      break;
    case 16 ... 30:
      motor1.setSpeed(90);
      motor2.setSpeed(90);
      motor3.setSpeed(90);
      motor4.setSpeed(90);
      car_back();
      Serial.println("langsam vor");
      matrix_display(smile);
      break;
    case 31 ... 45:
      car_back();
      Serial.println("Vorwaerts");
      matrix_display(vor);
      break;
    default:
      car_back();
      Serial.println("default");
      matrix_display(vor);
      break;
  }
}
void drive() {
  number = random(3);
  if (number == 1) {
    car_left();
    delay(1500);
  }
  if (number == 2) {
    car_right();
    delay(1500);
  } else {
    car_right();
    delay(3000);
  }
}
void car_back() {
  motor1.run(BACKWARD);
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);
}
void car_front() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void car_left() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}
void car_right() {
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  motor1.run(FORWARD);
  motor2.run(FORWARD);
}
void car_Stop() {
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
}
void matrix_display(unsigned char matrix_value[]) {
  IIC_start();     //the function that calls the data transfer start condition
  IIC_send(0xc0);  //select address

  for (int i = 0; i < 16; i++)  //the pattern data is 16 bytes
  {
    IIC_send(matrix_value[i]);  //Transmit the data of the pattern
  }
  IIC_end();  //End pattern data transmission
  IIC_start();
  IIC_send(0x8A);  //Display control, select 4/16 pulse width
  IIC_end();
}
//Conditions under which data transmission begins
void IIC_start() {
  digitalWrite(SDA_Pin, HIGH);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, LOW);
}
//Indicates the end of data transmission
void IIC_end() {
  digitalWrite(SCL_Pin, LOW);
  digitalWrite(SDA_Pin, LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin, HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin, HIGH);
  delayMicroseconds(3);
}
//transmit data
void IIC_send(unsigned char send_data) {
  for (byte mask = 0x01; mask != 0; mask <<= 1)  //Each byte has 8 bits and is checked bit by bit starting at the lowest level
  {
    if (send_data & mask) {  //Sets the high and low levels of SDA_Pin depending on whether each bit of the byte is a 1 or a 0
      digitalWrite(SDA_Pin, HIGH);
    } else {
      digitalWrite(SDA_Pin, LOW);
    }
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, HIGH);  //Pull the clock pin SCL_Pin high to stop data transmission
    delayMicroseconds(3);
    digitalWrite(SCL_Pin, LOW);  //pull the clock pin SCL_Pin low to change the SIGNAL of SDA
  }
}