Arduino + L293D

hallo,
ich komme mit der pin-Belegung nicht klar:
ich habe
2 digitale I/O-Pins (dig4 + dig5) und 1 pwm pin (dig6) am Arduino,
und ich habe
enable1 (1), in1(2) und in2(6) am L293D

und was soll enable und in eigentlich beduten?
Ein einziges Chaos in den Beschreibungen.

ich raffs nicht.
was kommt wohin?

klar ist eigtl:
Motor1 an 3+6
VCC 5V an 16
VS 9V an 7
GND an 4+13

Im Moment habe ich pwm an 1 und die I/Os an 2 und 6, aber es funktioniert nicht korrekt.

int motor1_A=4;
int motor1_B=5;
int motor1_Speed=6;
 

 
void setup(){
  pinMode(motor1_A,OUTPUT);
  pinMode(motor1_B,OUTPUT);
 
  pinMode(motor2_A,OUTPUT);
  pinMode(motor2_B,OUTPUT);
}
 
void loop(){
  // motor1
  for (int i=0; i>256; i+=5){
    digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,LOW);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }
  
  delay(200);
  
  for (int i=255; i>0; i-=5){
    digitalWrite(motor1_A,LOW); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,HIGH);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }

der Motor geht hintereinander immer von schnell auf langsam und zwar immer in derselben Richtung!!

Guck mal bitte ins Roboternetz- da hatten wir in der Arduinoecke das Problem neulich.
Soweit ich mich entsinne gibts zwei Betriebsarten: einmal kann man PWM auf enable geben, und damit die Dehzahl regeln (in1 und 2 schalten dann die Drehrichtung um, wenn ich mich richtig erinnere), oder aber man benutzt nur die beiden in- spart ne Leitung, und ist dann nicht regelbar. Ich glaub, in1 und 2 mussten immer entgegengesetzt geschalten sein, einer High, und einer Low. Bei der Betriebsart ohne PWM muss noch nen Jumper rauf, glaub ich...
Such da mal bitte, ist erst ne Woche her oder so...

so wie du es beschrieben hast, habe ich es doch gemacht -
pwm6 auf enable1
dig pins4+5 auf in1+in2

aber er schaltet die Drehrichtung nicht um!
Ich will ja die Geschwindigkeit per pwm regulieren, und die Drehrichtung auch!

Nein. Wenn ich mich recht entsinne, muss man für "rechtsrum" in1 LOW setzen, in2 auf HIGH und um die Drehrichtung umzukehren, beide Pins andersrum.

Hab das "Programm,w as ich dem Lütten damals fix zusammengeschustert hatte, mal eben rüber geholt-ist alelrdings für zwei solche Doppeltreiber (er hat halt vier Motoren dran) gedacht, aber so, wie er sagte, lief das wohl:

/* ich habe deine, vorher angegebene Pinbelegung übernommen (sind nur andere Namen, weiter nix),
    wenn du die Verkabelung änderst, musst du die entsprechenden Pin-Nummern bei den defines eintragen!
    Die Variable "gasVorgabe" stellt die Motoren auf Halbgas, du kannst, indem du sie veränderst (zwischen
    0 und 255) testen, ab wann der Roboter überhaupt los fährt, und auch, wie schnell er werden kann.
    Drehen hab ich jetzt nicht eingebaut, da ich nicht weiss, welche Motornummer an welcher Stelle des
    Roboters verbaut ist. */
    
    #define M1aPin 52    // Motor1,Kabel a
    #define M1bPin 50    // Motor1 Kabel b
    #define M1GasPin  11  // PWM Motor1
    #define M2aPin 48     // Motor2 Kabel a
    #define M2bPin 46     // Motor2 Kabel b
    #define M2GasPin 10    // PWM Motor2
    
    #define M3aPin 53     // Motor3 Kabel a
    #define M3bPin 51     // Motor3 Kabel b
    #define M3GasPin 8    // Motor3 PWM
    #define M4aPin 49     // Motor4 Kabel a
    #define M4bPin 47     // Motor4 Kabel b
    #define M4GasPin 9    // Motor4 PWM
 
 int gasVorgabe=128;  // hier legen wir fest, wie schnell die Motoren laufen, wenn du den Wert erhöhst
                                // laufen sie schneller, max. 255
    void setup()  // hier legen wir lediglich alle Motorenpins als Ausgänge fest und stellen sicher, dass die Motoren
    {                  // nicht einfach los laufen
      pinMode(M1aPin, OUTPUT);   //Motor1
      pinMode(M1bPin,OUTPUT);    
      pinMode(M1GasPin,OUTPUT); //PWM Motor1
      pinMode(M2aPin, OUTPUT); // Motor2
      pinMode(M2bPin,OUTPUT);
      pinMode(M2GasPin,OUTPUT); //PWM Motor2
      pinMode(M3aPin, OUTPUT); //Motor3
      pinMode(M3bPin,OUTPUT);
      pinMode(M3GasPin,OUTPUT); // PWM Motor3
      pinMode(M4aPin, OUTPUT); //Motor4
      pinMode(M4bPin,OUTPUT);
      pinMode(M4GasPin,OUTPUT);// PWM Motor4
      analogWrite(M1GasPin,0);
      analogWrite(M2GasPin,0);
      analogWrite(M3GasPin,0);
      analogWrite(M4GasPin,0);
      delay(2000); // 2 Sekunden, um die Fingr vom Roboter zu nehmen, ehe.....
    }
    
    void vorwaerts() //******** vorwärts fahren für ungefähr 2 Sekunden ******************
    {
      //Motor_1 & 2 vorwärts
      digitalWrite(M1aPin, LOW);   // Motor1 Richtung festlegen
      digitalWrite(M1bPin, HIGH); 
      digitalWrite(M2aPin, LOW);   // Motor2 Richtung festlegen
      digitalWrite(M2bPin, HIGH);
     digitalWrite(M3aPin, LOW);   // Motor3 Richtung festlegen
      digitalWrite(M3bPin, HIGH); 
      digitalWrite(M4aPin, LOW);  // Motor4 Richtung festlegen
      digitalWrite(M4bPin, HIGH);  
      analogWrite(M1GasPin, gasVorgabe); //und hier schalten wir die PWM auf alle vier Motoren
      analogWrite(M2GasPin,gasVorgabe);
      analogWrite(M3GasPin,gasVorgabe);
      analogWrite(M4GasPin,gasVorgabe);
      delay(2000); // zwei Sekunden fahren,
      analogWrite(M1GasPin,0); //Dann alle vier Motoren stoppen (schont die Getriebe ;) )
      analogWrite(M2GasPin,0);
      analogWrite(M3GasPin,0);
      analogWrite(M4GasPin,0);
     }
    void rueckwaerts() //***Rückwärts gehts genauso, nur dass jeweils die A-undB-Pins "umgedreht" werden***
    {
       digitalWrite(M1aPin, HIGH);   // Motor1 Richtung festlegen
      digitalWrite(M1bPin, LOW); 
      digitalWrite(M2aPin, HIGH);   // Motor2 Richtung festlegen
      digitalWrite(M2bPin, LOW);
     digitalWrite(M3aPin, HIGH);   // Motor3 Richtung festlegen
      digitalWrite(M3bPin, LOW); 
      digitalWrite(M4aPin, HIGH);  // Motor4 Richtung festlegen
      digitalWrite(M4bPin, LOW);  
      analogWrite(M1GasPin, gasVorgabe); //und hier schalten wir die PWM auf alle vier Motoren
      analogWrite(M2GasPin,gasVorgabe);
      analogWrite(M3GasPin,gasVorgabe);
      analogWrite(M4GasPin,gasVorgabe);
      delay(2000); // zwei Sekunden fahren,
      analogWrite(M1GasPin,0); //Dann alle vier Motoren stoppen (schont die Getriebe ;) )
      analogWrite(M2GasPin,0);
      analogWrite(M3GasPin,0);
      analogWrite(M4GasPin,0);
    }
  
    
    void loop()  //******* das Hauptprogramm, in dem es rund geht... ***********
    {
      for (int i=0; i<3; i++) //machen wir das Ganze einfach dreimal...
      {
      vorwaerts();
      delay(500); //halbe Sekunde warten, zum "bremsen"
      rueckwaerts();
      delay(500); // das selbe nochmal, damit wir nicht aus voller Fahrt rückwärts auf volle Fahrt vorwärts gehn
      }
      while(1); //stoppt das Programm, da stehende roboter leichter einzufangen sind ;)
    }

habe ich doch!

erst

 digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,LOW);

danach

 digitalWrite(motor1_A,LOW); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,HIGH);

trotzdem dreht er beide Male in dieselbe Richtung!

wenn pwm an enable1 kommt, dann müsste es doch stimmen!
verdammt, ich verzweifle hier noch!

Die Pins nicht aus Ausgänge definiert?
Du hast zwar die in-Pins aus OUTPUT definiert, aber die PWM-Pins nicht...wenn es das obige Programm ist.
Versuch das mal..

jetzt aber:

int motor1_A=4;
int motor1_B=5;
int motor1_Speed=6;
 

 
void setup(){
  pinMode(motor1_A,OUTPUT);
  pinMode(motor1_B,OUTPUT);
  pinMode(motor1_Speed,OUTPUT);
  
}
 
void loop(){
  // motor1
  for (int i=0; i>256; i+=5){
    digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,LOW);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }
  
  delay(200);
  
  for (int i=255; i>0; i-=5){
    digitalWrite(motor1_A,LOW); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,HIGH);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }

}

dreht immer in dieselbe Richtung, auch mit nem anderen L293D .(

Also soweit sieht das alles gut aus, hmmmm...hast du irgendwelche Jumper drauf?

Vielleicht wärs gut, wenn du mal deine Treiber zeigst (Link).
Was mir noch einfiele, weil ichs grade lese: du hast nicht zufällig nen URALTDuino da, auf dem ein Mega8 werkelt?
Guck auch vorsichtshalber mal, ob du wirtklich alles so verkabelt hast, wie du glaubst.
An den Motoren ist nix weiter dran?

Verkabelung war OK - aber ein Bug in den Zählschleifen.

Oh mann is man manchaml blöd.

Jetzt gehts:

int motor1_A=4;
int motor1_B=5;
int motor1_Speed=6;
 

 
void setup(){
  pinMode(motor1_A,OUTPUT);
  pinMode(motor1_B,OUTPUT);
  pinMode(motor1_Speed,OUTPUT);
  
}
 
void loop(){
  // motor1
  for (int i=0; i<256; i+=5){
    digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,LOW);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }
  
  for (int i=255; i>0; i-=5){
    digitalWrite(motor1_A,HIGH); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,LOW);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }
  
  delay(200);
  
 for (int i=0; i<256; i+=5){
    digitalWrite(motor1_A,LOW); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,HIGH);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }
  
  for (int i=255; i>0; i-=5){
    digitalWrite(motor1_A,LOW); // A = HIGH and B = LOW means the motor will turn right
    digitalWrite(motor1_B,HIGH);
    analogWrite(motor1_Speed,i); // speed counts from 0 to 255
    delay(100);
  }

}

danke für die Geduld ! :smiley:

for (int i=0; i>256; i+=5)

Der wars oder??
Ich hab jetzt, zugegebenermassen, 5 min drauf gestarrt.... :blush:

Mach dir nix draus, somas bring ich in irgendeiner Form fast jeden Tag... :~

jap - aber ehrlich, machmal.... :cold_sweat:

aber eine Anschlussftage hätte ich doch noch:
beide digiPins in1, in2 =0 und pwm(enable1) =0 ?> dann rollt doch der Motor stromlos aus (?)

Gibt es auch eine Möglichkeit, per pin-Schaltung aktiv zu bremsen und es auch dauerhaft so eingestellt zu lassen?

Vorweg eins: das Ding kenne ich nur von dem Roboterbauer aus dem Roboternetz. Hab so eins selber auch nicht, ich rate also auch, mehr oder weniger.

Was sich rausgestellt hatte, war wohl, dass es generell zwei Betriebsarten gibt: die, die du grad benutzt und eine "digitale". Bei der muss irgendein Jumper zwischen enable und noch nem Stift daneben rauf, dann laufen die Motoren Vollgas und man kann nur die Richtung wechseln.
Meine Vermutung ist, dass man aber bremsen kann, indem man in1 und in2 gleich schaltet- also würd ich mal versuchen, beide auf LOW zu setzen.

danke,

  • dann habe ich aber vllt bisher was falsch verstanden...

bisher dachte ich:
in1=HIGH, in2=LOW, pwm>0: vorwärts
in1=LOW, in2=HIGH, pwm>0: rückwärts
das müsste ja stimmen.

aber -
du meinst also:
in1=LOW, in2=LOW, pwm=0: ergibt bremsen(=brake)

wie wäre denn deiner Meinung nach dann rollen(=coast) ?

Rollen ist PWM=0, sagtest du ja.
Oder bremst das Ding dann bereits?
Ich kann da echt nur raten, weil ich nirgends ne Doku zu den Dingern gefunden hab...
Dürft sich doch einfach rausfinden lassen: einfach mal irgendeine kleine "Schwungmasse" auf den Motor stecken-nen Rad oder so...

Die grosse Motorplatine, die ich dir mal empfahl (wird aber anders angesteuert, der reichen zwei Leitungen pro Motor) bremst bei PWM=0. Und zwar kräftig. Mit dem Digitalpin wird nur zwischen vor-und rückwärts umgestellt. Um bei der "auszurollen" brauchts PWM=1 oder sowas.

ja, ich habe es probiert - ich habe den Eindruck, es passiert nicht großartig ein Unterschied ob mit oder ohne bremsen:

#define MAXMOTORS 2

#define OUT_A   0
#define OUT_B   1

// set motor pins 
#define pinmenc0A  2
#define pinmenc0B  3 
#define pinmot0d1  4
#define pinmot0d2  5
#define pinmot0pwm 6

#define pinmenc1A  7
#define pinmenc1B  8 
#define pinmot1d1  9
#define pinmot1d2  10
#define pinmot1pwm 11



long motenc[MAXMOTORS];
byte pinmotdir[MAXMOTORS][2]={ {pinmot0d1, pinmot0d2}, 
                               {pinmot1d1, pinmot1d2} };
                    
int  pinmotpwm[MAXMOTORS]={pinmot0pwm, pinmot1pwm};
 
 
//------------------------------------------------------------------------------------
// read encoder: "Entnommen aus http://www.meinDUINO.de" 
int8_t altAB = 0;

// 1/1 Auflösung
int8_t schrittTab[16] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; 

// 1/4 Auflösung
// int8_t schrittTab[16] = {0,0,0,0,0,0,0,-1,0,0,0,0,0,1,0,0}; 

int8_t readEncoder(int pinA, int pinB) {
  altAB <<= 2;
  altAB &= B00001100;
  altAB |= (digitalRead(pinA) << 1) | digitalRead(pinB);
  return(schrittTab[altAB]);
}
 

//==============================================================================

inline void motoroff(byte motnr) {
  digitalWrite( pinmotdir[motnr][0],LOW);
  digitalWrite( pinmotdir[motnr][1],LOW);
  analogWrite(pinmotpwm[motnr],0);
}


inline void motorcoast(byte motnr) {
  digitalWrite( pinmotdir[motnr][0],LOW);
  digitalWrite( pinmotdir[motnr][1],LOW);
  analogWrite(pinmotpwm[motnr],0);
}


inline void motoron(byte motnr, int power) {
  if(power>0) {
     digitalWrite( pinmotdir[motnr][0],HIGH);
     digitalWrite( pinmotdir[motnr][1],LOW);
  }
  else
  if(power<0) {
     digitalWrite( pinmotdir[motnr][0],LOW);
     digitalWrite( pinmotdir[motnr][1],HIGH);
  }
  else
  if(power==0) {
     digitalWrite( pinmotdir[motnr][0],LOW);
     digitalWrite( pinmotdir[motnr][1],LOW);
  }
  
  power = abs(power);
  if(power>254) power=254;
  analogWrite(pinmotpwm[motnr],power);
}

//==============================================================================
 
void setup(){
  
  pinMode(pinmot0d1,OUTPUT);
  pinMode(pinmot0d2,OUTPUT); 
  pinMode(pinmenc0A,INPUT_PULLUP);
  pinMode(pinmenc0B,INPUT_PULLUP);
  pinMode(pinmot0pwm,OUTPUT);
  
  pinMode(pinmot1d1,OUTPUT);
  pinMode(pinmot1d2,OUTPUT); 
  pinMode(pinmenc1A,INPUT_PULLUP);
  pinMode(pinmenc1A,INPUT_PULLUP);
  pinMode(pinmot0pwm,OUTPUT);
  
  Serial.begin(115200);  
}
 
 
void loop(){
  // motor1
  for (int i=0; i<255; i+=5){    
    motoron(0, i);
    motoron(1, -i);    
    delay(100);
  }
  
  
  motoroff(0); 
  motoroff(1); 
  
  delay(500);
  
  
 for (int i=0; i>-255; i-=5){
    motoron(0, i);
    motoron(1, -i);    
    delay(100);
  }
  
  // ohne bremsen 
  
  delay(500);
}

Naja-es gibt verschiedene Möglichkeiten, nen Bürsti zu bremsen. Die simpelste ist es, ihn kurzzuschliessen- das wirkt aber bei niedrigen Drehzahlen kaum merklich. Viel mehr wird es auch mit dem Shield von der Hardware her (wenn überhaupt! ) auch nicht werden, denn die effektiveren Bremsmethoden laufen in der Software.

Kannst ja mal testen, ob dein Platinchen die Kurzschlussbremse beherrscht: Motor abklemmen, und dann mal beide in-Pins auf High oder auch auf Low setzen, und mitm Multimeter (Durchgangsprüfer) gucken, ob die Motoranschlüsse dann kurzgeschlossen werden-oder nicht.

Falls nicht, wirst du es per Software lösen müssen.

hallo,
ich hatte mal versehentlich den L293D kurgeschlossen (Pin verwechselt: Masse an Ausgang 3 statt 4) - das wurde er aber ganz schnell dunkelrot.
Naja, übertrieben :slight_smile:
aber ganz schön heiß.

Was ich suchte, ist eher eine Software-Lösung. Ich kenne mich damit technisch nicht aus, aber ich könnte mir vorstellen, dass er bremst , eben indem man pins auf bestimmte Werte setzt (kA, eben anstelle 0,0,0)

Das müsste dann aber als Motorzustand automatisch dann dauerhaft gebremst bleiben, bis pins irgendwann mal wieder programm-mäßig andere Werte bekommen.

Du willst also aktiv bremsen?
Mutig-ist ne kleine Herausforderung...hab ich auch noch nich gemacht (mangels Bedarf). Vor allem eine "Handbremse" ist ziemlich tricky. Da hilft nur googlen-such mal nach RC-Car-Reglern, so als Stichwort, da gibts auch welche mit Handbrems-Funktion. Vielleicht findest du irgendwo raus, wie die das genau machen (ich tippe drauf, dass der Motor pausenlos sehr kurze, wechselseitige Impulse bekommt).

ja, genau, das mit dem Dauer-Wechsstrom auf die Spulen habe ich auch schon gelesen.
das müsste man jetzt per Softare hinkriegen (keine zusätzlich RC-Hardware wenn ich dich da richtig verstanden habe)..

Möglich ist es sicher auch, zum kurzfristigen Bremsen ein paar ms lang die letzte pwm umgepolt an die Motoren zu legen - aber es soll ja nicht nur kurzfristig, sondern danach dauerhaft gebremst bleiben.

Dann würd ich folgendes versuchen:
PWM auf den entsprechenden Pin geben (testen, so niedrig wie möglich, damit die Bremse ausreichend hält), und dann die beiden digitalen Pins wechselseitig umschalten. Sollte das nicht ausreichend gut gehn (standardmässig liefert die Dino-PWM nur ungefähr 500HZ), kannst noch versuchen, die PWM-Frequenz höher zu stellen. Das "wechselblinken" würd ich versuchen, so schnell wie möglich zu erledigen, damit die "Umpolungen" nur sehr kurz sind.