BTM-222 mit Arduino - Servo/Motor steuerung

Hallo liebes Forum.
Ich bastel zur Zeit an einem Quadcopter, ich werde mir bald Bluecopter und Arducopter ansehen, möchte aber erstmal meine Bluetooth-steuerung testen. Habe den btm-222 als Bluetoothmodul, als “Fernsteuerung” ein Google Nexus 4.

Die Regler der Motoren steuere ich an wie einen normalen Servo.

Funktioniert normal: Sweep example. Motor dreht ruhig auf und ab.

Funktioniert nicht ganz: vom Btm-222 (über rx-pin gelesene) Werte auf Servo/Motor schreiben.
Symptome: Der Motor dreht auf und ab wie im sweep-example, ABER: Er “spuckt” und “ruckelt” ganz leicht. und manchmal dreht er “voll auf” oder “geht vom gas”.

Falsch übertragene Werte (so seltsame ASCII Symbole) filtere ich bereits raus. Werte vom Handy werden mit “?” getrennt. Dadurch können 11 und 12 nicht als 1112 erfasst werden.
Außerdem lasse ich alle Werte, die ich zum Motorregler sende im Serial Monitor ausgeben. Da ist alles normal. Werte von 0-120 und wieder zurück. (120, um nicht auf volllast zu gehen)

An der Verkabelung dürfte es eigentlich nicht liegen, da diese ja beim Sweep-example gleich bleibt. Allerdings ist das BT-modul mit 3,3V - 5V - GND und RX,TX(softwareserial auf PIN 3 und PIN 5) verbunden.
Da Signale zum Regler gehen, muss dieser gemeinsame Masse mit dem Arduino haben.

Ich hatte gedacht, dass die Werte über das “?” zwar getrennt werden, aber manchmal welche (nahezu) gleichzeitig ankommen. Habe daher vor jedem Schreibvorgang ein “delay(15)” eingebaut gehabt, das änderte nichts, außer einem langsameren Ansprechverhalten natürlich.

Falls es eurer Meinung nach an der Verkabelung liegt, füge ich hier Bilder ein. Falls ein Video zum Verhalten des Motors gewünscht ist, einfach melden. PS: Habe verschiedene Regler und Motoren getestet.

Meiner Meinung nach muss es am Code liegen, daher hier mein Code:

#include <Servo.h> 
#include <SoftwareSerial.h>
#include <ctype.h>

SoftwareSerial btm222_serial(3, 5); // RX, TX

String rx="";
char character;
Servo motorOL;
Servo motorOR;
Servo motorUL;
Servo motorUR;
int speedOL = 0;
int speedOR = 0;
int speedUL = 0;
int speedUR = 0;


void setup() {
  motorOL.attach(9);
  motorOR.attach(10);
  motorUL.attach(11);
  motorUR.attach(12);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  Serial.begin(38400);
  btm222_serial.begin(38400);
} 

void loop(){
  if (Serial.available()){
    //Daten vom Serial Monitor (PC)
    //zum Bluetoothmodul weiterleiten.
    btm222_serial.write(Serial.read());
  }

  //Jeden Loop auf Datenverfügbarkeit prüfen
  if(btm222_serial.available()) {
    character = btm222_serial.read();
    Serial.write(character);
    if(character=='?'){//"paket"-Ende erreicht, zahl (ohne "?") auswerten:
      if(isValidNumber(rx)){//Überprüfung, ob wirres ASCII zeichen enthalten ist.
        verarbeiten(rx.toInt());//Gültige Zahlen in speed variable speichern
        rx = "";//puffer resetten
      }else{
        //Es ist ein wirres Zeichen enthalten (Fehlübertragung)
        // -> Wert Überspingen, aber Error ausgeben.
        Serial.println("");
        Serial.print("ERROR :");
        Serial.println(rx);
        rx = "";
      }
    }else{
      //Paket noch nicht zu ende, Ziffer an (Zahlen)-String anhängen
      //(das "?" wird nicht angehängt)
      rx.concat(character);
    }
    //Aktuellen Speed-wert dem Motorregler melden
    motorOL.write(speedOL);
  }
}//end loop

void verarbeiten(int rx_value){
  //Tatsächlich verarbeitete Werte im Serial Monitor überwachen.
  Serial.print("wrote : ");
  Serial.println(rx_value);
  speedOL = rx_value;
}

//Überprüfen, ob der Übertragene String eine gültige Zahl ist
boolean isValidNumber(String str){
  for(byte i=0;i<str.length();i++){
    if(!isDigit(str.charAt(i))) return false;
  }
  return true;
}

Ich würde mich sehr über Tipps freuen :slight_smile:

SoftwareSerial ist Schrott. Du kannst mal AltSoftSerial probieren: https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html Das ist zuverlässiger

AltsoftSerial beisst sich mit Servo.h :/

Ich teste jetzt mal die Pins 0 und 1 (hardwareSerial?).

Ach wegen dem Timer. Die verwenden beide Timer1. Und das kann man leider nicht ändern (außer bestimmte andere Boards zu verwenden) :(

Hier ist eine Library die 8 Servos mit Timer2 steuern kann: https://github.com/DerekK19/Arduino/tree/master/libraries/ServoTimer2

Sollte ansonsten so wie Servo funktionieren.

Hatte beim Googlen der Fehlermeldung auch was von ServoTimer2 gelesen. Habe wie angekündigt erstmal mit Hardwareserial getestet und siehe da: Es geht fehlerfrei. Kann mir nicht erklären wieso das Probleme macht, da ich ja alle Werte kontrolliert und falsche Werte gefiltert habe.

Jedenfalls ein dickes Dankeschön an Dich Serenifly :) Fehler gefunden. Werde mir jetzt ServoTimer2 mal ansehen, aber das sollte kein Problem sein :)