2 RC Motors simultanliously with Motor Shield

Hallo. Wir bauen zurzeit ein Ferngesteuertes Motorboot und steuern die 2 DC Motoren über einen Arduino Motor Shield an.

via Pulsweitenmodulation wollen wir dem Motor entweder sagen ob er vorwärts oder rückwärts dreht... Leider läuft das bei uns nur so halb...

Wenn wir Gas geben, gibt der eine Motor Vollgas, und der andere bleibt aus,
wenn wir rückwärts fahren, springt der andere Motor an und der erste bleibt aus.
Es sollte ein Softwarefehler sein.
We want to run 2 seperate DC Motors at the same time, but only one is running while pressing forward and the other one runs while pressing backwards on the controller.

int ch2; // Here's where we'll keep our channel values
int ch3;
int ch4;

void setup() {
  
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel B pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel A pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel B pin

  //Eingabe durch den RC-Controller
  pinMode(2, INPUT); // Channel 2 -> Motoren
  pinMode(3, INPUT); // Channel 3 -> Hals Oben und Unten
  pinMode(4, INPUT); // Channel 4 -> Extra (Unnötig)
  
  //Stepper

  Serial.begin(9600); // Pour a bowl of Serial
  
  
}

void loop() {

  ch2 = pulseIn(2, HIGH, 25000); // Read the pulse width of 
  ch3 = pulseIn(3, HIGH, 25000); // each channel
  ch4 = pulseIn(4, HIGH, 25000);

  //Motoren ansteuern
  Serial.print("Channel 2:"); // Totenpunkt 1490 max 1986 min 990
  Serial.println(ch2);        
  
  if(ch2 > 1500){                                 //Poolnudel goes BRRRRRRRRR
    digitalWrite(12,HIGH);
    digitalWrite(9,LOW);
    analogWrite(3,255);
    digitalWrite(13,HIGH);
    digitalWrite(8,LOW);
    analogWrite(11,255);
    
  }else if(ch2 < 1475){                                     //Rückwärts
    digitalWrite(12,LOW);
    digitalWrite(9,LOW);
    digitalWrite(13,LOW);
    digitalWrite(8,LOW);
    analogWrite(3,255);
    analogWrite(11, 255);
    
  } else if(ch2 >= 1475 && ch2 <= 1500){                    //Ruhelage
    digitalWrite(9,HIGH);
    digitalWrite(8,HIGH);
  }
  
  // Hals hoch und runterstellen -> SchrittMotor
  Serial.print("Channel 3:");
  Serial.println(ch3);

  /*if (ch3 >= 1475 && ch3 <= 1500){
    myStepper.step(0);
  } else if (ch3 > 1500){
    myStepper.step(stepsPerRevolution);
  } else if (ch3 < 1475){
    myStepper.step(-stepsPerRevolution);
  }
  */
  Serial.print("Channel 4:");
  Serial.println(ch4);
  
  delay(100); // I put this here just to make the terminal 
              // window happier
}    

Hoffentlich könnt ihr mir helfen
Ach ja. Die Motoren sind direkt über die Motor Shield Pins A und B angeschlossen

Ihr Beitrag wurde an seinen aktuellen Speicherort verschoben, da er besser geeignet ist.

Du benutzt PIN 3 doppelt.

Du solltest Deine Pins benennen und definieren - Dann weisst Du, was die machen und kannst doppelBelegungen vermeiden.
Das sollte gehen, wenn ich nichts übersehen habe:

unsigned int ch2; // Here's where we'll keep our channel values
unsigned int ch3;
unsigned int ch4;

const byte motorChannelA = 12;
const byte motorChannelB = 13;
const byte brakeChannelA = 9;
const byte brakeChannelB = 8;
const byte controlChannelA = 3;
const byte controlChannelB = 11;

const byte channel[] = {2, 4, 5};

void setup()
{
  //Setup Channel A
  pinMode(motorChannelA, OUTPUT); //Initiates Motor Channel A pin
  pinMode(brakeChannelA, OUTPUT); //Initiates Brake Channel B pin
  //Setup Channel B
  pinMode(motorChannelB, OUTPUT); //Initiates Motor Channel A pin
  pinMode(brakeChannelB, OUTPUT);  //Initiates Brake Channel B pin
  //Eingabe durch den RC-Controller
  for (byte b = 0; b < sizeof(channel) / sizeof(channel[0]); b++)
  {  pinMode(channel[b], INPUT); }
  //Stepper
  Serial.begin(9600); // Pour a bowl of Serial
}

void serialAusgabe()
{
  if (millis() % 100 == 0) // Rudimentär nur alle 100ms eine Ausgabe
  {
    Serial.print("Channel 2:");
    Serial.println(ch2);
    Serial.print("Channel 3:");
    Serial.println(ch3);
    Serial.print("Channel 4:");
    Serial.println(ch4);
  }
}

void loop()
{
  ch2 = pulseIn(channel[0], HIGH, 25000); // Read the pulse width of
  ch3 = pulseIn(channel[1], HIGH, 25000); // each channel
  ch4 = pulseIn(channel[2], HIGH, 25000);
  //Motoren ansteuern
  if (ch2 > 1500)                         //Poolnudel goes BRRRRRRRRR
  {
    digitalWrite(motorChannelA, HIGH);
    digitalWrite(brakeChannelA, LOW);
    analogWrite(controlChannelA, 255);
    digitalWrite(motorChannelB, HIGH);
    digitalWrite(brakeChannelB, LOW);
    analogWrite(controlChannelB, 255);
  }
  else if (ch2 < 1475)                    //Rückwärts
  {
    digitalWrite(motorChannelA, LOW);
    digitalWrite(brakeChannelA, LOW);
    digitalWrite(motorChannelB, LOW);
    digitalWrite(brakeChannelB, LOW);
    analogWrite(controlChannelA, 255);
    analogWrite(controlChannelB, 255);
  }
  else                                    //Ruhelage
  {
    digitalWrite(brakeChannelA, HIGH);
    digitalWrite(brakeChannelB, HIGH);
  }
  // Hals hoch und runterstellen -> SchrittMotor
  /*if (ch3 >= 1475 && ch3 <= 1500){
    myStepper.step(0);
    } else if (ch3 > 1500){
    myStepper.step(stepsPerRevolution);
    } else if (ch3 < 1475){
    myStepper.step(-stepsPerRevolution);
    }
  */
  serialAusgabe();
}

Vielen dank für die Hilfe. Wir sind nun auf einen L298N Motor Driver gewechselt und nach vorne läuft das Programm gut. Aber wenn wir in die If Abfrage kommen, geht er nur nach vorne, die "if ch2<1400" ignoriert er anscheinend komplett.

unsigned int ch2; // Here's where we'll keep our channel values
unsigned int ch3;
unsigned int ch4;


const byte motor_A_Pos = 3;
const byte motor_B_Pos = 5;
const byte motor_A_Neg = 4;
const byte motor_B_Neg = 6;
const byte controlChannelA = 2;
const byte controlChannelB = 7;

const byte channel[] = {11, 12, 13}; //Kanäle zum Einlesen der PWM

void setup()
{
  //Setup Channel A
  pinMode(motor_A_Pos, OUTPUT);   //Initiates Motor Channel A pin
  pinMode(motor_A_Neg, OUTPUT);   //Initiates Brake Channel B pin
  
  //Setup Channel B
  pinMode(motor_B_Pos, OUTPUT);   //Initiates Motor Channel A pin
  pinMode(motor_B_Neg, OUTPUT);   //Initiates Brake Channel B pin

  //Channel Control
  pinMode(controlChannelA,OUTPUT);
  pinMode(controlChannelB,OUTPUT);
  
  //Eingabe durch den RC-Controller
  for (byte b = 0; b < sizeof(channel) / sizeof(channel[0]); b++)
  {  pinMode(channel[b], INPUT); }
  
  //Stepper (kommt noch)
}

void serialAusgabe()
{
  if (millis() % 100 == 0) // Rudimentär nur alle 100ms eine Ausgabe
  {
    Serial.print("Channel 2:");
    Serial.println(ch2);
    Serial.print("Channel 3:");
    Serial.println(ch3);
    Serial.print("Channel 4:");
    Serial.println(ch4);
  }
}

void loop()
{
  ch2 = pulseIn(channel[0], HIGH, 25000); // Pulsweite Channel 2 --> Motorgeschwindigkeit
  ch3 = pulseIn(channel[1], HIGH, 25000); // Pulsweite Channel 3 --> Halssteuerung
  ch4 = pulseIn(channel[2], HIGH, 25000); // Pulsweite Channel 4 --> Mögliche Rote Augen
  
  //Motoren ansteuern
  if (ch2 > 1500)  //1451                       //Poolnudel goes BRRRRRRRRR
  {
    digitalWrite(motor_A_Pos, HIGH);
    digitalWrite(motor_A_Neg, LOW);
    analogWrite(controlChannelA,255); //(ch2-1451)/1.94)
    digitalWrite(motor_B_Pos, HIGH);
    digitalWrite(motor_B_Neg, LOW);
    analogWrite(controlChannelB, 255);
  }
  else if (ch2 < 1400) //1445                    //Rückwärts
  {
    digitalWrite(motor_A_Pos, LOW);
    digitalWrite(motor_A_Neg, HIGH);
    analogWrite(controlChannelA, 125);
    digitalWrite(motor_B_Pos, LOW); 
    digitalWrite(motor_B_Neg, HIGH);
    analogWrite(controlChannelB,  125);
  }
  else                                  //Ruhelage
  {
    digitalWrite(motor_A_Pos, HIGH);
    digitalWrite(motor_A_Neg, HIGH);
    digitalWrite(motor_B_Pos, HIGH);
    digitalWrite(motor_B_Neg, HIGH);
    analogWrite(controlChannelA, 0);
    analogWrite(controlChannelB, 0);
  }
  // Hals hoch und runterstellen -> SchrittMotor
  /*if (ch3 >= 1475 && ch3 <= 1500){
    myStepper.step(0);
    } else if (ch3 > 1500){
    myStepper.step(stepsPerRevolution);
    } else if (ch3 < 1475){
    myStepper.step(-stepsPerRevolution);
    }
  */
  serialAusgabe();
}

Dann mal auseinanderlösen:

  if (ch2 > 1500)  //1451                       //Poolnudel goes BRRRRRRRRR
  {
    digitalWrite(motor_A_Pos, HIGH);
    digitalWrite(motor_A_Neg, LOW);
    analogWrite(controlChannelA, 255); //(ch2-1451)/1.94)
    digitalWrite(motor_B_Pos, HIGH);
    digitalWrite(motor_B_Neg, LOW);
    analogWrite(controlChannelB, 255);
  }
  if (ch2 < 1400) //1445                    //Rückwärts
  {
    digitalWrite(motor_A_Pos, LOW);
    digitalWrite(motor_A_Neg, HIGH);
    analogWrite(controlChannelA, 125);
    digitalWrite(motor_B_Pos, LOW);
    digitalWrite(motor_B_Neg, HIGH);
    analogWrite(controlChannelB,  125);
  }
  if ((ch2 >= 1400) && (ch2 <= 1500))                               //Ruhelage)
  {
    digitalWrite(motor_A_Pos, HIGH);
    digitalWrite(motor_A_Neg, HIGH);
    digitalWrite(motor_B_Pos, HIGH);
    digitalWrite(motor_B_Neg, HIGH);
    analogWrite(controlChannelA, 0);
    analogWrite(controlChannelB, 0);
  }

Soooo. Wir haben eine Lösung gefunden. Wir verstehen es zwar selbst nicht so 100%ig, aber wir haben nun die If Schleifen aufgelöst wie empfohlen. Zuerst hat dies auch nicht funktioniert, aber wir haben dann den Inhalt der Schleifen in eigenständige Funktionen gepackt:

{
    digitalWrite(motor_A_Pos, HIGH);
    digitalWrite(motor_A_Neg, LOW);
    analogWrite(controlChannelA, 255);
    digitalWrite(motor_B_Pos, HIGH);
    digitalWrite(motor_B_Neg, LOW);
    analogWrite(controlChannelB, 255);
}

void MOTOR_BACK()
{
    digitalWrite(motor_A_Pos, LOW);
    digitalWrite(motor_A_Neg, HIGH);
    analogWrite(controlChannelA, 255);
    digitalWrite(motor_B_Pos, LOW);
    digitalWrite(motor_B_Neg, HIGH);
    analogWrite(controlChannelB, 255);
}

void MOTOR_BREAK()
{
  digitalWrite(motor_A_Pos, HIGH);
  digitalWrite(motor_A_Neg, HIGH);
  digitalWrite(motor_B_Pos, HIGH);
  digitalWrite(motor_B_Neg, HIGH);
  analogWrite(controlChannelA, 0);
  analogWrite(controlChannelB, 0);
}

void STEPPER_CLOCKWISE()
{
  myStepper.step(stepsPerRevolution);
}
void STEPPER_COUNTERCLOCKWISE()
{
  myStepper.step(-stepsPerRevolution);
}

void loop()
{
  ch2 = pulseIn(channel[0], HIGH, 25000); // Pulsweite Channel 2 --> Motorgeschwindigkeit
  ch3 = pulseIn(channel[1], HIGH, 25000); // Pulsweite Channel 3 --> Halssteuerung
  //ch4 = pulseIn(channel[2], HIGH, 25000); // Pulsweite Channel 4 --> Mögliche Rote Augen
  
  //Motoren ansteuern
  if (ch2 > 1500)  //1451                       
  {
    MOTOR_FORWARD();                              //Poolnudel goes BRRRRRRRRR
  }
  if (ch2 < 1400) //1445                    
  {
    MOTOR_BACK();                                 //Rückwärts
  }
  if ((ch2 >= 1400) && (ch2 <= 1500))                               
  {
    MOTOR_BREAK();                                //Ruhelage
  }
  if (ch3 <= 950){
    STEPPER_COUNTERCLOCKWISE();
  }
  if (ch3 >=1900){
    STEPPER_CLOCKWISE();
  }

Naja, wohl eher erraten :wink:
Denn...

Das:

gibt es nicht.

Na schick.
Nun nur noch den Einstieg geändert und schon könnte das passen.

void loop()
{
  ch2 = pulseIn(channel[0], HIGH, 25000); // Pulsweite Channel 2 --> Motorgeschwindigkeit
  ch3 = pulseIn(channel[1], HIGH, 25000); // Pulsweite Channel 3 --> Halssteuerung
  //ch4 = pulseIn(channel[2], HIGH, 25000); // Pulsweite Channel 4 --> Mögliche Rote Augen
  //Motoren ansteuern
  switch (ch2)
  {
    case 0 ... 1399:
      MOTOR_BACK();                                 //Rückwärts
      break;
    case 1400 ... 1500:
      MOTOR_BREAK();                                //Ruhelage
      break;
    default:
      MOTOR_FORWARD();                              //Poolnudel goes BRRRRRRRRR
      break;
  }
  if (ch3 <= 950)
  {
    STEPPER_COUNTERCLOCKWISE();
  }
  else
  {
    if (ch3 >= 1900)
    {
      STEPPER_CLOCKWISE();
    }
  }
}

hab ich schleifen geschrieben? ja super :smiley: natürlich If bedingungen
Aber vielen Dank für die großzügige Hilfe ^^

Nein.
Sie ist gut gemeint. :slight_smile: Gerne.

1 Like