Motor fernsteuern vor-zurück mit L9110

Hallo,
ich versuche gerade ein ferngesteuertes Auto zu bauen. Als Sender verwende ich einen Nano und als Empfänger einen Mega. Den Motor will ich mit einem L9110 ansteuern.
Im jeweiligen seriellen Monitor sehe ich auch das die Werte ankommen.
Jetzt habe ich aber das Problem, dass der Motor aus der Mittelstellung nur in die positiv Richtung läuft. In die entgegengesetzte Richtung nicht.
Hier der Sketch:

#include <SPI.h>
#include <RH_ASK.h>
#include <MobaTools.h>

RH_ASK driver(2000, 11, 12, 10);
MoToServo myServo;

// Motor-Pins (L9110)
const int motorA1 = 4;
const int motorA2 = 3;

void setup() {
  Serial.begin(9600);
  if (!driver.init()) {
    Serial.println("Empfänger init fehlgeschlagen!");
  }

  myServo.attach(6); // Servo an D6

  pinMode(motorA1, OUTPUT);
  pinMode(motorA2, OUTPUT);
}

void loop() {
  uint8_t buf[20];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen)) {
    buf[buflen] = 0;

    int xVal = 512;
    int yVal = 512;
    if (sscanf((char*)buf, "%d,%d", &xVal, &yVal) == 2) {
      Serial.print("Empfangen: ");
      Serial.println((char*)buf);

      // Servo-Steuerung (X)
      int pos = map(xVal, 0, 1023, 55, 135);
      pos = constrain(pos, 50, 130);
      myServo.write(pos);

      // Motorsteuerung (Y)
      int speed = map(yVal, 0, 1023, -255, 255); // -255 rückwärts, 255 vorwärts

      if (speed > 10) {
        analogWrite(motorA1, speed);
        analogWrite(motorA2, 0);
      } else if (speed < -10) {
        analogWrite(motorA1, 0);
        analogWrite(motorA2, -speed);
      } else {
        analogWrite(motorA1, 0);
        analogWrite(motorA2, 0); // Stoppen bei totem Bereich um Mitte
      }
    } else {
      Serial.println("Ungültige Nachricht!");
    }
  }
}

Ich hab testweise mal eine LED an D3 und D4 angeschlossen. In eine Richtung wird die Lampe langsam heller, in die andere gar nicht.
Ich finde leider den Fehler nicht... Vielleich kann mir jemand weiterhelfen?
Vielen Dank im Voraus!

-speed lasse das minus raus :wink:
analogWrite(motorA2, speed);

so dürfte das eigendlich klappen nur schön ist was anderes.

Für deine Funkfernbedienung hast du dir allerdings nicht gerade die stabilsten Teile ausgewählt.
Mein Tipp, verwende besser die Transceiver HC-12, diese laufen auch auf 433 MHz, sind aber leistungsstärker und sicherer in der Verwendung.

Das hat allerdings wohl nichts mit deinem aktuellen Problem zu tun.

Das ekelt mich, mit 5 cm Hennenrupfn (Gänsehaut). Bin von der Ausbildung Elektrotechniker.

Du bekommst es zusammen daß der Motor steht, abei aber in einem Teil der Zeit den Kurzschlußstrom ( = Anlaufstrom) saugt.
Ich hab jetzt nicht die genaue PWM Signal Erzeugung im ATmega2560 analysiert. Ich weiß nicht ob die beiden PWM Signale zueinander synchron sind oder irgendwie Phasenverschoben zueinander.
Laut mega 2560 PWM frequency haben die beiden PWM Ausgänge verschiedene Frequenzen.

Wenn ein Eingang und damit ein Ausgang HIGH ist und der andere LOW dreht sich der Motor in eine Richtung. Wechselt man die beiden Eingänge/ Ausgänge dreht sich der Motor in die andere Richtung.
Damit der Motor stehen bleibt setzt man beide Ausgänge auf LOW oder beide auf High.

Um die Geschwindigkeit zu regeln setzt man den einen Eingang auf LOW oder HIGH und den anderen gibt man ein PWM Signal.
Zur Drehrichtungsumkehr werden die EIngänge vertauscht.

Hat man ein PWM signal das von 0 bia 127 eine Drehrichtung bzw Geschwindigkeit darstellt und von 128 bis 255 die Andere muß man hat aus diesem Signal die Drehrichtung und die Geschwindigkeit herausrechenen.

ZB so ähnlich:
if (PWM <= 127)
IN1 = HIGH
IN2 = (127-PWM )*2
else
IN2 = HIGH
IN1 = (PWM - 127) *2

Grüße Uwe

Das geht nicht.
ChatGPT lässt grüßen?

Edit: Wenn man das aufteilt, sieht man auch, was Du da vor hast...

#include <SPI.h>
#include <RH_ASK.h>
#include <Servo.h>

RH_ASK driver(2000, 11, 12, 10);
MoToServo myServo;

// Motor-Pins (L9110)
const int motorA1 = 4; // <<< Das ist auf einem UNO kein PWM-PIN!  Dann 5 nehmen.
const int motorA2 = 3;

void setup()
{
  Serial.begin(9600);

  if (!driver.init())
  { Serial.println(F("Empfänger init fehlgeschlagen!")); }

  myServo.attach(6); // Servo an D6
  pinMode(motorA1, OUTPUT);
  pinMode(motorA2, OUTPUT);
}

void loop()
{
  getReceived();
  setServo();
  setMotor();
}

void getReceived()
{
  uint8_t buf[20];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen))
  {
    buf[buflen] = 0;
    int xVal = 512;
    int yVal = 512;

    if (sscanf((char * )buf, "%d,%d", &xVal, &yVal) == 2)
    {
      Serial.print("Empfangen: ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("Ungültige Nachricht!");
    }
  }
}

void setServo()
{
  // Servo-Steuerung (X)
  int pos = map(xVal, 0, 1023, 55, 135);
  pos = constrain(pos, 50, 130);
  myServo.write(pos);
}

void setMotor()
{
  // Motorsteuerung (Y)
  int speed = map(yVal, 0, 1023, -255, 255); // -255 rückwärts, 255 vorwärts

  if (speed > 10)
  {
    analogWrite(motorA1, speed);
    analogWrite(motorA2, 0);
  }
  else if (speed < -10)
  {
    analogWrite(motorA1, 0);
    analogWrite(motorA2, abs(speed));
  }
  else
  {
    analogWrite(motorA1, 0);
    analogWrite(motorA2, 0); // Stoppen bei totem Bereich um Mitte
  }
}

Auf was für einem Controller läuft das? Pin 4 ist auf einem UNO kein PWM-Pin.

in #1 schreibt der To Mega 2560

Dann muß man halt das Vorzeichen als Richtung decodieren und die PWM ohne Vorzeichen.
Glaube das ist ein ähnlicher Aufwand wie mein Lösungsvorschlag.
Grüße Uwe

Ja, das hab ich schon öfter gehört. Ich hab aber momentan nur die da...
Ich denke auch dass es an was anderem liegt...

Hab ich gerade probiert... Tut leider auch nicht :frowning:

Dann nimm mal Post #5 von @my_xy_projekt und Pin mal um

motorA1 = 6;
motorA2 = 7;

Und wenn der von @my_xy_projekt nicht klappt hast Du einen Hardwarefehler.

Vielen Dank für die schnelle Rückmeldung :slight_smile:
Probier ich gleich. Kann ich aber nicht kopieren, muss noch umschreiben... Hab ne andere Servobibliothek...

Und mit dem Servo . lege den auf Pin46

Solltest du denoch Probleme bei der Funkübertragung haben, dann nicht lange überlegen und die Teile wechseln. Z.B Diese hier.
Die oft verwendeten Empfänger für RH-ASK sind sehr störanfällig und werden durch Metall in direkter Nähe extrem gestört. Motoren sind dabei def. nicht hilfreich.

Danke

Hab gerade nochmal mit einer LED simuliert an PIN3 und 4. Da ging nur eine stufenlos an, die andere nicht... Hab mal testweise auf PIN 8 und 9 probiert, da ging es. Umgesteckt auf die Motorplatine und es Funktioniert :-)) Sogar mit meinem ursprünglichen Sketch. Vielen Dank an Euch für die Unterstützung!!!

Ist zwar ein Mega, aber anscheinend ist das auch kein PWM-Pin, oder der Kanal ist defekt. Danke!!!

Und wenn Du deine H-Brücke schonen willst:

void setMotor()
{
  // Motorsteuerung (Y)
  int speed = map(yVal, 0, 1023, -255, 255); // -255 rückwärts, 255 vorwärts

  if (speed > 10)
  {
    analogWrite(motorA1, speed);
    delayMicroseconds(100);
    analogWrite(motorA2, 0);
  }
  else if (speed < -10)
  {
    analogWrite(motorA1, 0);
    delayMicroseconds(100);
    analogWrite(motorA2, abs(speed));
  }
  else
  {
    analogWrite(motorA1, 0);
    analogWrite(motorA2, 0); // Stoppen bei totem Bereich um Mitte
  }
}

gönn dem eine mini Pause.

Kannst Du digital den Pin switchen?

Das ist also deine Lösung Tzzzz. Verinnerliche lieber Post#4.

Du weißt schon, daß die Servo Bibliothek Timer verwenden und darum PWM an einigen Pins nicht funktioniert?

https://docs.arduino.cc/libraries/servo/
" The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables

analogWrite()

(PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12. "

Grüße Uwe

Der TO benutzt die Mobatools.