Gleichstrommotoren mit IR Fernbedinung steuern

Hallo zusammen,

ich möchte 2 Gleichstrommotoren über eine Fernbedinung steuern, also den Roboter wie ein RC Auto herumfahren lassen.
Habe hierfür einen Arduino Rev 3 sowie einen Motorshield von Watterott im Einsatz.
Prinzipiell scheint die Ansteuerung auch zu funktionieren, aber aus irgendeinem Grund dreht immer nur Motor B. Motor A reagiert einfach nicht, ist aber funktionsfähig. Auf dem Motorshield leuchten auch immer nur die für Motor B zuständigen LEDs.

    #include "IRLibAll.h"
     
    //Create a receiver object to listen on pin 2
    IRrecv myReceiver(2);
     
    //Create a decoder object 
    IRdecode myDecoder;   

    #define UP 3772778233 
    #define DOWN 3772810873
    #define RIGHT 3772794553
    #define LEFT 3772819033
    
    ///////////////////MOTOR///////////////////
int richtungA = 12; //Richtung Motor A
int richtungB = 13;  //Richtung Motor B
int pwmA = 3; //Geschwindigkeit Motor A
int pwmB = 11;  //Geschwindigkeit Motor B
int bremseA = 9;  //Bremse Motor A
int bremseB = 8;  //Bremse Motor B

int geschwindigkeitA = 250;  //0-255 (min - max)
int geschwindigkeitB = 255;  //0-255 (min - max)


     
void setup() {
//Pins für Motorenrichtung als Ausgang
pinMode(richtungA, OUTPUT);
pinMode(richtungB, OUTPUT);
//Pins für Motorenrichtung als Ausgang (Bremse)
pinMode(bremseA, OUTPUT);
pinMode(bremseB, OUTPUT);
//Geschwindigkeit setzen
analogWrite(pwmA, geschwindigkeitA);
analogWrite(pwmB, geschwindigkeitB);
//Bremsen anziehen
digitalWrite(bremseA, HIGH);
digitalWrite(bremseB, HIGH);

      
  Serial.begin(9600);
  myReceiver.enableIRIn(); // Starten des Receivers
  Serial.println(("Ready to receive IR signals"));
    }
    ///////////////////MOTOR///////////////////
void gerade(){  
  delay(2000);
  //Bremsen lösen
  digitalWrite(bremseA, LOW);
  digitalWrite(bremseB, LOW);
  
  digitalWrite(richtungA, HIGH);
  digitalWrite(richtungB, HIGH);
  delay(1500);
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH);
}
void drehen(){
  digitalWrite(bremseA, LOW);
  digitalWrite(bremseB, LOW);
  
  digitalWrite(richtungA, HIGH);
  digitalWrite(richtungB, LOW);
  delay(1200);
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH);
  delay(600);
}
void rechts(){
  digitalWrite(bremseA, LOW);
  digitalWrite(bremseB, LOW);
  
  digitalWrite(richtungA, HIGH);
  digitalWrite(richtungB, LOW);
  delay(600);
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH);
}
void links(){
  digitalWrite(bremseA, LOW);
  digitalWrite(bremseB, LOW);
  
  digitalWrite(richtungA, LOW);
  digitalWrite(richtungB, HIGH);
  delay(600);
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH);
}
void back(){
  digitalWrite(bremseA, LOW);
  digitalWrite(bremseB, LOW);
  
  digitalWrite(richtungA, LOW);
  digitalWrite(richtungB, LOW);
  delay(600);
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH);
}
     
void loop(){
    if (myReceiver.getResults()) {
    myDecoder.decode(); //Dekodieren des Signals
        
    myDecoder.dumpResults(true);  //Ausgabe des dekodierten Signals
    myReceiver.enableIRIn();      //Neustarten des Receivers
    Serial.print(myDecoder.value);

        switch(myDecoder.value) { //Fallunterscheidung in Abhängigkeit der "value" des Dekoders
          case UP: 
          gerade();
          break;
          case DOWN: 
          back();
          break;         
          case RIGHT: 
          rechts();
          break;         
          case LEFT: 
          links();
          break;
 
        }
}
}

Bin erst seit zwei Wochen am Programmieren eines Arduino, meine Kenntnisse also noch entsprechend gering.

Gruß
Komani

Probier mal die Ansteuerung ohne Fernsteuerung. Einfach mal ein Stück vor und dann zurück.
grüße Uwe

Habe ich versucht und klappt. Die Motoren funktionieren beide ohne Probleme.

Poste mal den Link deiner eingesetzten IR-Library.

Die kommt mir sehr unbekannt vor. Und deine zahlreichen "delays" machen auch Probleme. Die solltest du besser gegen Funktionen mit "millis" austauschen. Sieh dir dazu BlinkWithoutDelay an.

Verwendete library:

Um die "Delays" werde ich mich gleich kümmern.

Komani:
Verwendete library:
GitHub - cyborg5/IRLib2: Library for receiving, decoding, and sending infrared signals using Ardui

Um die "Delays" werde ich mich gleich kümmern.

Funktioniert denn deine IR-Fernbedienung mit der Library ?
Leider kenn ich die nicht und kann daher wenig dazu sagen.

Wenn du die IR-Fernbedienung damit ohne Motoren am Laufen hast, sollte das auch hinzubekommen sein.

Habe es mit folgender library neu gemacht:

Leider hat sich an dem Ergebnis nichts geändert. Nur Motor B dreht und das sehr langsam. Kann es auch sein das der Motorshield einen Fehler hat?

#include "IRremote.h"

int IRpin = 7;
IRrecv irrecv(IRpin);
decode_results results;

int richtungA = 12; //Richtung Motor A
int richtungB = 13;  //Richtung Motor B
int pwmA = 3; //Geschwindigkeit Motor A
int pwmB = 11;  //Geschwindigkeit Motor B
int bremseA = 9;  //Bremse Motor A
int bremseB = 8;  //Bremse Motor B

int geschwindigkeitA = 250;  //0-255 (min - max)
int geschwindigkeitB = 255;  //0-255 (min - max)

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  
  //Pins für Motorenrichtung als Ausgang
  pinMode(richtungA, OUTPUT);
  pinMode(richtungB, OUTPUT);
  //Pins für Motorenrichtung als Ausgang
  pinMode(bremseA, OUTPUT);
  pinMode(bremseB, OUTPUT);
  //Geschwindigkeit setzen
  analogWrite(pwmA, geschwindigkeitA);
  analogWrite(pwmB, geschwindigkeitB);
  //Bremsen anziehen
  digitalWrite(bremseA, HIGH);
  digitalWrite(bremseB, HIGH); 
}

void loop() {
  if (irrecv.decode(&results)) 
    {
      Serial.println(results.value, DEC); // Print the Serial 'results.value'
      irrecv.resume();   // Receive the next value
    }
    switch(results.value){
    case 3772778233:
      digitalWrite(bremseA, LOW);
      digitalWrite(bremseB, LOW); 
      digitalWrite(richtungA, HIGH);
      digitalWrite(richtungB, HIGH);
      digitalWrite(bremseA, HIGH);
      digitalWrite(bremseB, HIGH); 
    break;
    case 3772782313:
      digitalWrite(bremseA, HIGH);
      digitalWrite(bremseB, HIGH);
    break;
    case 3772810873:
      digitalWrite(bremseA, LOW);
      digitalWrite(bremseB, LOW); 
      digitalWrite(richtungA, LOW);
      digitalWrite(richtungB, LOW);
      digitalWrite(bremseA, HIGH);
      digitalWrite(bremseB, HIGH); 
    break;
    }
  

}

Hi

Wenn Du die Motoren an dem Shield händisch in beide Richtungen zum Laufen bekommst - wird das Shield - auch, wenn's vom Chinesen kommt - ok sein.

Schreibe Dir erst Mal einen Sketch, Der Dir die Motoren ansteuert:

  • 1 Sek links vor (rechts stop)
  • 1 Sek rechts vor (links stop)
  • 1 Sek links zurück (rechts stop)
  • 1 Sek rechts zurück (links stop)
    Wenn Das klappt, kannst Du versuchen, die Befehle per Funk/IR/BT/Buschtrommel oder Handzeichen zu übertragen.

MfG

Dann würde ich auch erst mal in einem eigenen Sketch nur die IR-Funktionalität testen.
Einfach über Serial.println ausgeben, welches Kommando Du empfangen hast.

Danach beides vereinigen.

Gruß Tommy

Komani:
Habe es mit folgender library neu gemacht:
A Multi-Protocol Infrared Remote Library for the Arduino

Leider hat sich an dem Ergebnis nichts geändert. Nur Motor B dreht und das sehr langsam. Kann es auch sein das der Motorshield einen Fehler hat?

Das macht nun wirklich keinen Sinn, einfach eine andere Library zu verwenden.
Du sollst doch die IR-Fernbedienung erst ohne die Motorsteuerung testen.
Da gibt es doch so schöne Beispiele, mit denen du lernen kannst.
Dann kannst du das ganze erweitern.

Einfach irgend etwas ohne es zu verstehen abkupfern bringt überhaupt nix.

Zudem gehört diese Anweisung

irrecv.resume();   // Receive the next value
}

ans Ende der "Switch/case"-Auswahl.

postmaster-ino:
Hi

Wenn Du die Motoren an dem Shield händisch in beide Richtungen zum Laufen bekommst - wird das Shield - auch, wenn's vom Chinesen kommt - ok sein.

Bitte unterstelle Watterott nicht, eine Chinese zu sein. :wink: :wink:

Grüße Uwe

Komani:
Prinzipiell scheint die Ansteuerung auch zu funktionieren, aber aus irgendeinem Grund dreht immer nur Motor B. Motor A reagiert einfach nicht, ist aber funktionsfähig.

Gruß
Komani

Ist eigentlich ausgeschlossen, dass die Motoren selbst IR-Störstrahlung verursachen ?
Bei mir war es einmal ein uralter Kühlschrank. der beim Schalten sowas erzeugte.
Zufällig fand ich damals einen Artikel, der auch genau erklärte wie das geht - einschließlich der Wellenlängen.
Hab mir leider nur gemerkt DASS es geht.

Die Reichweite der Störquelle war übrigens weit größer als die der Fernbedienung. Ich hatte damals ein Speicheroszilloskop für den Commodore 64 und einen Sensor, der so ähnlich wie dieser hier war :

Heutzutage vielleicht so : CC2tv - Versteckte Kameras finden mit winzigen Infrarot-Dongle - YouTube ?

Habe mich vielleicht etwas unklar ausgedrückt.

Die Motoren funktionieren und das habe ich zuvor getestet.
Auch das Auslesen des IR-Signals mit Hilfe des 'Serial Monitors' alleine habe ich getestet und es funktioniert. Von diesem stammen die Werte der case-Anweisungen.
Nur das ansteuern der Motoren per IR-Signal bereitet Probleme.

Wie dem auch sei, danke für die Antworten. Werde mich nochmal dahinter klemmen und von vorne alles nach und nach neu programmieren. Dann wird der Fehler hoffentlich verschwinden oder ich raus finden woran es lag. :slight_smile:

Hi

uwefed:
Bitte unterstelle Watterott nicht, eine Chinese zu sein. :wink: :wink:

Hatte ich nicht, wenn Das So verstanden wurde (und man damit ein Problem hat), entschuldige ich mich dafür.
(Nicht, daß Das jetzt nur durch die Brille so aussieht gg)

Mein Ansinnen ging in die Richtung, daß selbst der billigste China-Sch... (also Das, was man für wenige Euronen bei eBay und Ali erwerben kann) in den aller meisten Fällen klaglos tut, wofür Es erworben wurde.
Warum der FC (freundliche Chinese) die Ware trotz des wesentlich längeren Weg zu einem Bruchteil des Preises zu mir schicken kann, Den ein hiesiger Händler alleine schon an Porto berappen muß, ist mir unbekannt - man muß halt warten können.
Und leider wird vermehrt in letzter Zeit bei Problemen explizit darauf hingewiesen, daß der Schrott wohl aus China bezogen wurde und Es ja fast schon offensichtlich ist, warum hier ein Problem auftritt.

Und - oh Wunder - in nahezu allen Fällen war das Problem der nicht ganz so chinesische Bastler - Ausnahmen (also wirkliche chinesische Bastler) wären mir dazu noch nicht aufgefallen - könnte aber auch an der hier verwendeten Sprache liegen.

Und seien wir Mal ehrlich: In Sachen Service ist mir ein deutscher Händler immer noch lieber, als 'Refund' und Ersatzlieferung aus Fern-Ost.
Wenngleich das Groh meiner Bestellungen eben doch am anderen Ende der Welt die Reise beginnt.
(Ausnahmen, wenn's zeitlich schneller gehen soll - Da haben aber auch schon deutsche Händler gegen chinesische Weltreisen verloren)

MfG

Hallo,

edit: guck mal:

 case 3772778233:
  digitalWrite(bremseA, LOW);  // Variable 1 wird geändert
  digitalWrite(bremseB, LOW);  // Variable 2
  digitalWrite(richtungA, HIGH);
  digitalWrite(richtungB, HIGH);
  digitalWrite(bremseA, HIGH); // Variable 1, wieder auf HIGH, geändert was Stillstand bedeutet
  digitalWrite(bremseB, HIGH);  // Variable 2

/edit

Auf dem Motorshield leuchten auch immer nur die für Motor B zuständigen LEDs.

Kann es sein, das etwas mit der Verkabelung nicht stimmt?

Ich hab damals im Grunde genau das selbe gemacht und hatte keine Probleme, der Code stimmt im Großen und Ganzen auch mit meinem überein. Die einzigen Unterschiede...

Ich bin mir nicht sicher, aber braucht man nicht ein pinMode() für analogWrite? Ist ja OUTPUT.

Mach Dir mal ne Serielle Ausgabe, dann siehst Du in welchen case Du wirklich landest. Außerdem ein default, falls der Befehl von der Fernbedienung nicht erkannt wird.

// Setup
  pinMode(pwmA, OUTPUT);
  analogWrite(pwmA, geschwindigkeitA);

Ich hab den Pin 11 für den IR Empfänger verwendet, aber daran wirds wohl nicht liegen... Ist allerdings der einzige verbleibende Unterschied zu meinem Code. Und ich hab die Serielle Ausgabe in if (irrecv.decode(&results)) rausgenommen.

case 3772810873:
  digitalWrite(bremseA, LOW); // Variable 1, kannst du rausnehmen
  digitalWrite(bremseB, LOW); // Variable 2, kannst Du rausnehmen, denn
  digitalWrite(richtungA, LOW);
  digitalWrite(richtungB, LOW);
  digitalWrite(bremseA, HIGH); // Variable 1, die ist hier ja wieder.
  digitalWrite(bremseB, HIGH); // Variable 2

  Serial.print("Motor Richtung X"); // Das würde ich dazuschreiben!

  break;
default: 
  Serial.print("other button: ");
  Serial.println(results.value, DEC); // Ich hab da halt HEX verwendet aber das macht keinen Unterschied.
  break;

Grüße,
Donny