Dieses Forum nutzt Cookies
Dieses Forum verwendet Cookies, um deine Login-Informationen zu speichern, wenn du registriert bist, und deinen letzten Besuch, wenn du es nicht bist. Cookies sind kleine Textdokumente, die auf deinem Computer gespeichert sind; Die von diesem Forum gesetzten Cookies düfen nur auf dieser Website verwendet werden und stellen kein Sicherheitsrisiko dar. Cookies auf diesem Forum speichern auch die spezifischen Themen, die du gelesen hast und wann du zum letzten Mal gelesen hast. Bitte bestätige, ob du diese Cookies akzeptierst oder ablehnst.

Ein Cookie wird in deinem Browser unabhängig von der Wahl gespeichert, um zu verhindern, dass dir diese Frage erneut gestellt wird. Du kannst deine Cookie-Einstellungen jederzeit über den Link in der Fußzeile ändern.

Themabewertung:
  • 3 Bewertung(en) - 4 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Fahren mit 2 Autos pro Spur
#81
Hallo Finbar,

jawohl, bitte weiter verfolgen , da bin ich auch dran interessiert. Mein Arduino PWM ist noch nicht
abgeschlossen, bzw weiter gediehen. Wurde durch einen Festplatten Crash ausgebremst.
Was braucht man zusätzlich zu den PWM Teilen für die Drehzahlregelung an Hardware?

Schöne Grüße
Lothar
Zitieren
#82
(06-09-2020, 01:18)Piffpaffpoltrie schrieb: Hallo Finbar

...

Es gab hier schon vor einigen Jahren einen Faden, in dem eine analoge PWM (Pulsbreitensteuerung) beschrieben wurde (https://www.h0slot.eu/showthread.php?tid...nsteuerung); die Details sind aber leider nicht mehr erhältlich, da der erwähnte Download-Bereich nicht mehr zu existieren scheint - zumindest kann ich ihn nicht finden. ...

robi

Hallo zusammen,

Ja, das war wirklich schon etwas lang her. Zischenzeitlich gab es diverse Sofware und Server-Wechsel des Forums, Mit einigen Datenverlusten. Die Schaltung existiert moch, und mein Bruder (Heiko) sucht auch wo, er die Schaltplan-Datei geparkt haben könnte. Ist aber halt ei bissel her ... . Blush Und mittlerweile hat auch er andere Baustellen am laufen.


Holger (HeHo) Heikos Bruder.
Holger aus Kassel. 
Zitieren
#83
Hallo AMSler,
ja, es handelt sich um eine Regelung, da ich mit PWM-Steuerungen bisher nicht das gewünschte Resultat erzielen konnte. Für den Leistungsschalter bin ich beim L293 geblieben, der zwar an der Leistungsgrenze arbeitet, er bietet aber den Vorteil, dass die Ausgänge nicht nur die Zustände 0 und 1 beherrschen, sondern durch den enable Eingang auch hochohmig geschaltet werden können. Dies ist erforderlich zur Messung der Generatorspannung, entsprechende H-Brücken sind rar. Ich schalte also einen Motoranschluss gegen die Betriebsspannung, den anderen Anschluss hochohmig. Dann kann die Betriebsspannung minus die Generatorspannung gemessen werden. Pro Fahrzeug sind eine Diode, zwei Zenerdioden, zwei, drei Widerstände und ein Kondensator für die Messschaltung erforderlich. Ausserdem ein 4051 Multiplexer, um die 6 A/D Eingänge des Arduino auf 8 zu erweitern. Ich benötige Eingänge für 4x Sollwert und 4x Istwert. Und es benötigt ein stabilisiertes Netzteil, ich arbeite z.Zt. mit einem Faller-Trafo 4016? mit anschliessender Stabilisierung, welche auf 20 Volt eingestellt ist. Ich werde den Schaltplan die nächsten Tage hier einstellen.
Ciao, Finbar.

Hallo Holger,
Vielen Dank für deine Mühe. Ich glaube ich kenne die analoge Impulssteuerung von Heiko (Herrlich?, wenn ich mich richtig erinnere) hab mich damals auch lange damit befasst. Die war ohne Rückmeldung des Motors, richtig? Was ich vorhabe ist folgendes: ich sage dem Motor er soll z.B. mit 10% Drehzahl drehen. Sehr kurz danach messe ich, ob der Motor mit 10% Drehzahl dreht. Dreht er langsamer, erhöht der Arduino automatisch die Spannung, wenn der Motor schneller dreht, verringert der Arduino die Motorspannung. Und das ganze vielleicht 100 mal pro Sekunde. Damit erreiche ich letztendlich eine konstante Drehzahl.
Finbar
Zitieren
#84
Question 
Hallo Herr Finbar,

interessantes Projekt Smile .

Ein paar Fragen drängen sich mir auf:
Arrow Werden Sie die Schaltung zwar mit Lastregelung aber ohne PWM realisieren? Oder planen Sie eine lastgeregelte PWM-Ansteuerung?
Arrow Bisher war ich davon ausgegangen, dass die Messung der Generatorspannung immer direkt am Motor erfolgen muss, um wirksam zu sein. Haben Sie das Problem in anderer Weise gelöst? Oder ist das Regelverhalten auch bei fernem Verbraucher noch zufriedenstellend?
Arrow Unsere (Verkehrs-)Autochens ziehen um die 100 mA. Welche Grenzwerte für den L293 meinen Sie?
ciao michaelo
... und wer zuletzt aufgibt gewinnt.
Zitieren
#85
Hallo Michaelo,
die Schaltung misst die Generatorspannung des Motors, welche proportional ist zur Drehzahl. Als Regler habe ich verschiedene Versionen ausprobiert, der Zweipunktregler funktioniert am besten. Also, fällt der Istwert unter den Sollwert, so wird für die komplette Halbwelle der Motor eingeschaltet, ist der Istwert höher als der Sollwert, bleibt der Motor ausgeschaltet. Die Pulsbreite bleibt gleich und ist somit keine PWM. Versuche die Pulsbreite mittels PID Regler zu regeln haben bei mir nicht befriedigend funktioniert.
Ich habe die Motorspannung auf 20Volt hochgesetzt, die Schleifer der Autos optimiert und die Schienen gereinigt. Natürlich ist der Kontakt zum Auto doppelt wichtig, da nicht nur die Steuerspannung zum Auto übertragen, sondern auch der Messwert zurückübertragen wird. Bei Fehlmessungen hilft mir aber die Software und ich messe jeden Wert 20 mal und arbeite mit der Summe der Messwerte.
Es geht um die Leistung, am L293 haben wir einen Spannungsabfall von ca. 3 V bei (ich rechne)150mA ergibt 0,45 Watt pro Fahrzeug.
Ciao, Finbar
Zitieren
#86
Hallo AMSler,

Wie versprochen stelle ich hier zunächst einen Schaltplan für die Drehzahlregelung vor.
Den Arduino Sketch dazu lade ich in den nächsten Tagen hoch. Ich möchte noch ein paar Justierschrauben einbauen.

Ciao, Finbar


Angehängte Dateien
.pdf   AMS Control V1.3.pdf (Größe: 46,26 KB / Downloads: 51)
Zitieren
#87
Danke!

Bin auf die Fortsetzung (& evtl. eine Schaltungsbeschreibung?) sehr gespannt! (aber kein Grund, etwas zu überstürzen, gell?)

Grüsse
robi
Zitieren
#88
Moin Finbar,

interessante Schaltung, insbesondere der De/Multiplexer Smile .

Klar nutzt du die Generatorspannung. Ich vermute allerdings, dass mit der Entfernung des Autos von der Schaltung signifikante Unterschiede auftreten. Das wird m.E. aber nicht so schlimm sein, da es ja "nur" die Lastregelung betrifft.

Die Versorgung der Fahrzeuge mit 20 V halte ich für zu hoch, selbst wenn da noch Spannungsabfall durch die Schaltung hinzu kommt - die armen 12V-Autochens. Gibt es einen Grund dafür, weil der von dir verwendete Baustein 4051 ja auch niedrigere Spannungen zulässt?

Eine Idee Idea : Wir verwenden ja standardmäßig je nach Motortyp Regler zwischen 40 und 120 Ohm. Den könnte man über eine Grätzbrücke an einen 4:1/2-channel Multiplexer (z.B. CD4052B) anschließen und die dann zwei Ausgänge im Arduino auswerten. Insbesondere die Faller-Reglerpulte (100 Ω ) wären dafür interessant. Wäre das eine Option für dich?
ciao michaelo
... und wer zuletzt aufgibt gewinnt.
Zitieren
#89
Moin, moin Michaelo,


Also die Idee den 4051 zu verwenden stammt nicht von mir, die verdanke ich dem Arduino Kochbuch. Im Übrigen wird der Multiplexer natürlich mit 5V vom Arduino betrieben. Sorry, die Versorgungsspannung habe ich im Schaltplan glatt vergessen. Wird korrigiert.

Richtig, die 20V Betriebsspannung sind hoch angesetzt. Nun, ich wollte als Netzteil den Faller Trafo 4016 verwenden, Gleichrichterbrücke dahinter und einen Elko, dann hats schnell 27 Volt. Die überschüssigen 7 Volt muß ein zur Stabilisierung benutzter LM317 verbraten. Die Verlustleistung ist nicht gering bei 4 Autos aber ich brauche die Stabilisierung unbedingt, da letztendlich die Betriebsspannung minus die Generatorspannung gemessen wird.

Dir ist klar, dass zur Messung z.B. der Ausgang 1Y des L293 auf High geschaltet wird, während der Ausgang 4Y hochohmig geschaltet wird (deshalb 1Y und 4Y, nicht 1Y und 2Y). Dann messe ich die Ausgangsspannung (bei stehendem Motor) von 1Y (18,5V) über den Motor und dessen Diode (17,8V), dann über D9(17,1V), Zenerdiode D11(5,1V), Spannungsteiler R2 und R6(4,6Volt). Damit liege ich knapp unter der als Schutzdiode für den Arduino dienende Zenerdiode D16, und ich habe fast den gesamten Arduino A/D Eingangsspannungsbereich abgedeckt. Das ergibt die bestmögliche Auflösung. Also, wenn die Betriebsspannung geändert werden soll, muss entsprechend auch die Zenerdiode D11 geändert werden zur Beibehaltung der bestmöglichen Auflösung.

Ich denke, bei einer idealen Leitung wäre es eigentlich egal, wo man misst. Jetzt kommen aber die Fallerschienen und Schleifer ins Spiel! Meine Versuche haben gezeigt, dass durch die 20V einfach eine zuverlässigere Messung stattfindet als bei 12V Betriebsspannung. (Ich gebe zu, ich habe reichlich alte Schienen).

Zu den Reglern: Ich mache hier nur einen Vorschlag wie man die Schaltung aufbauen kann. Die Regler kann man natürlich ändern, ich glaube es gab da auch schon entsprechende Vorschläge. Aber: ich verwende die volle Auflösung des Arduino A/D Eingangs 10-bit, 0...1023, die gleiche Auflösung verwende ich auch bei meinen Sollwert-Potis. Und es gelingt mir nicht die Potis stufenweise einzustellen, sodaß ich über die Verwendung von 10-Gang Potis nachdenke. Je langsamer die Autos werden, und dies ist der interessante Bereich, desto geringer ist die Generatorspannung und da kommt selbst die Auflösung des Arduino an ihre Grenzen.

Ciao Finbar
Zitieren
#90
Hallo,

Ich habe auf Anregung von mos im Schaltplan die Betriebsspannung auf 12 Volt reduziert, dazu die Zenerdioden D10, D11, D14 und D15 von 12V auf 4,7 Volt abgeändert und ein paar Kleinigkeiten ergänzt. Und hier ist ein vorläufiger Code.

Ciao Finbar

Code:
/* AMS controller 2 State using PWM outputs V0.8.2.ino
//
// Before starting:
//
//    - double check direction of Zenerdiodes and measurement circuit to avoid 12V on Arduino input!
//    - use stabilized power supply 12 Volt!
//    - add heatsink to L293!
//    - check each car is using diode
//
//    - checked with and optimized for zinc motors
//
// controls 2 x 2 Faller AMS cars by measuring motor rpm via Back EMF and
// using L293N dual H bridge module, a CD4051 multiplexer and 4 potmeters
//
//  *** Version 0.8.2 preliminary ***
//       (c) Rainer Woerthmann
//
//
//  ->  No warranty
//  ->  Have fun
//
//
// ================================= [global variables ] ==========================================
*/
// input pin definition
const byte bemf1pin = A0;                                         //  Back-EMF input car 1 track A
const byte bemf2pin = A1;                                         //  Back-EMF input car 2 track A
const byte bemf3pin = A2;                                         //  Back-EMF input car 3 track B
const byte bemf4pin = A3;                                         //  Back-EMF input car 4 track B

const byte mx0 = 2;                                               //  to multiplexer 4051 pin 11, LSB
const byte mx1 = 3;                                               //  to multiplexer 4051 pin 10, HSB
const int analogPin =A5;                                          //  setpoint readings via multiplexer 4051, cars 1...4

// output pin definition H-bridge 1, track A (L293 V1 und V4)
const byte L293V1pin = 11;                                        //  track A, car 1, L293 pin 2, PWM
const byte L293V4pin = 6;                                         //  track A, car 2, L293 Pin 15, PWM

// output pin definition H-bridge 2, track B, (L293 V2 and V3)
const byte L293V2pin = 10;                                        //  track B, car 3, L293 pin 7, PWM
const byte L293V3pin = 9;                                         //  track B, car 4, L293 pin 10, PWM

// output pin definition H-bridge, high state
const byte L293V12ena = 7;                                        //  car 1+2 enable, L293 Pin 1
const byte L293V34ena = 8;                                        //  car 3+4 enable, L293 Pin 9

// constant value to equalize speed of different motors           //  increase value => car faster, decrease value => car slower
const byte carfactor1 = 3;                                        //  f.e. zinc, 5 or 6
const byte carfactor2 = 3;                                        //  Truck Flachanker = 1
const byte carfactor3 = 3;
const byte carfactor4 = 3;                                        //   

int Setpoint1, Setpoint2, Setpoint3, Setpoint4;                   //  setpoints cars 1...4
int bemf1,bemf2,bemf3,bemf4;                                      //  back-emf cars 1...4
int ref1,ref2,ref3,ref4;                                          //  reference values cars 1...4, standstill
int data1,data2;
byte pwm1,pwm2,pwm3,pwm4;                                         //  output cars 1...4
word i;                                                           //  counter

const int pulsetime =5000;                                        //  frequency (around (2*(5ms+4ms measurement))
                                                                  //  increase if motor does not start, decrease for running smooth
// =========================== [ set up ]=========================================================================

void setup() {

  Serial.begin(9600);                                             //  monitor everything
  Serial.println(" ");    
  Serial.println("START Programm AMS RPM controller");
 
  pinMode(2,OUTPUT);                                              //  multiplexer 4051, LSB                                         
  pinMode(3,OUTPUT);                                              //  multiplexer 4051, HSB
 
  pinMode(analogPin,INPUT);                                       //  setpoints cars 1...4
 
  pinMode(bemf1pin,INPUT);                                        //  back-emf car 1
  pinMode(bemf2pin,INPUT);                                        //  back-emf car 2
  pinMode(bemf3pin,INPUT);                                        //  back-emf car 3
  pinMode(bemf4pin,INPUT);                                        //  back-emf car 4
 
  pinMode(L293V12ena,OUTPUT);                                     //  H-bridge V 1,2 high state
  pinMode(L293V34ena,OUTPUT);                                     //  H-bridge V 3,4 high state
  digitalWrite(L293V12ena,LOW);
  digitalWrite(L293V34ena,LOW);
 
  pinMode(L293V1pin,OUTPUT);                                       // H bridge input, cars 1..4
  pinMode(L293V2pin,OUTPUT);
  pinMode(L293V3pin,OUTPUT);
  pinMode(L293V4pin,OUTPUT);
 
// read reference values
  digitalWrite(L293V34ena,LOW);                                    //  cars 1 + 3 high state
  digitalWrite(L293V1pin,HIGH);                                    //  car 1 to plus
  digitalWrite(L293V2pin,HIGH);                                    //  car 3 to plus
  digitalWrite(L293V12ena,HIGH);                                   //  cars 1 + 3 enable
  delay(1000);
 
      ref1 = analogRead(bemf1pin);                                 //  read reference (standstill) value car 1
      ref1 = constrain(ref1,300,950);
      ref3 = analogRead(bemf3pin);                                 //  read reference (standstill) value car 3
      ref3 = constrain(ref3,300,950);
 
  digitalWrite(L293V12ena,LOW);                                    //  cars 2 + 4 high state
  digitalWrite(L293V3pin,HIGH);                                    //  car2 to plus
  digitalWrite(L293V4pin,HIGH);                                    //  car 4 to plus
  digitalWrite(L293V34ena,HIGH);                                   //  cars 2+4 enable
  delay(1000);
 
      ref2 = analogRead(bemf2pin);                                  //  read reference (standstill) value car 2
      ref2 = constrain(ref2,300,950);
      ref4 = analogRead(bemf4pin);                                  //  read reference (standstill) value car 4
      ref4 = constrain(ref4,300,950);
                                           
  Serial.print(ref1,DEC);                                           // Show reference values   
  Serial.print(" ");
  Serial.print(ref2,DEC);
  Serial.print(" ");
  Serial.print(ref3,DEC);
  Serial.print(" ");
  Serial.println(ref4,DEC);
 
}                                                                   // end of setup
// =========================== [ main ] ==========================================================================
void loop() {
 
// 1. halfwave
    
        //  setup L293 for bemf measurement car 1 + 3
              digitalWrite(L293V34ena,LOW);                         //  L293 cars 1 + 3 high state
              digitalWrite(L293V1pin,HIGH);                         //  car 1 to plus
              digitalWrite(L293V2pin,HIGH);                         //  car 3 to plus
              digitalWrite(L293V12ena,HIGH);                       
              delayMicroseconds(500);                               //  allow settings (0,5ms)
       
        // measure bemf car 1 + 3
              
              bemf1 = 0;
              bemf3 = 0;
              
              for (i = 0; i < 20; i++) {                            //  do 20 readings
                  data1 = analogRead(bemf1pin);                     //  read supply voltage minus bemf car 1
                  if (data1 < 100){                                 //  poor contact?
                       data1 = ref1;
                       }
                   bemf1 += ref1-min(data1,ref1);                   //  calculate rpm car1
                                         
                   data2 = analogRead(bemf3pin);                    //  read supply voltage minus bemf car 3
                   if (data2 < 100) {                               //  poor contact??
                       data2 = ref3;
                       }
                   bemf3 += ref3-min(data2,ref3);                   //  calculate rpm car1  
                   }
        
       // return to pwm
              analogWrite(L293V1pin,pwm1);                          
              digitalWrite(L293V4pin,LOW);
              analogWrite(L293V2pin,pwm3);
              digitalWrite(L293V3pin,LOW);
              digitalWrite(L293V34ena,HIGH);                        //  end of measurement
      
       // calculate new PWM value car 1
              if (Setpoint1 < 1) {                                  
                    analogWrite(L293V1pin,0);                       //  standstill
                    }
              else {
                    if (bemf1 <1) {                                 //  f.e. poor contact
                       analogWrite(L293V1pin,255);                  //  add power car 1
                       }
 
                    else {
                         bemf1 = constrain(bemf1/carfactor1,0,1023);//  include carfactor
                         if (Setpoint1>bemf1) {                     //  power calculation car 1
                            pwm1 = 255;                             //  value may be reduced for smooth drive car1 (0...255)
                         }
                         else {                                     
                            pwm1 = 0;                               //  PWM off                                                 
                         }
                         analogWrite(L293V1pin,pwm1); }             //  write new PWM value car 1
                   }
                            
       // calculate new PWM value car 3                                
              if (Setpoint3 <1) {                                   
                     analogWrite(L293V2pin,0);                      //  standstill
                  }
              else {
                    if (bemf3 <1) {                                 //  f.e. poor contact
                       analogWrite(L293V2pin,255);                  //  add power car 3
                       }
                       
                    else {
                         bemf3 = constrain(bemf3/carfactor3,0,1023);// include carfactor
                         if (Setpoint3>bemf3) {                     // power calculation car3
                            pwm3 = 255;                             // value may be reduced for smooth drive car3 (0...255)
                         }
                         else {
                            pwm3 = 0;                               //  PWM off
                         }                                                                 }
                         analogWrite(L293V2pin,pwm3);               //  write new PWM value car 3                
                   }
          
        // check setpoints car 1 and 3
            digitalWrite(mx0,LOW);                                  //  initialize multiplexer 4051
            digitalWrite(mx1,LOW);
            Setpoint1 = (analogRead(analogPin));                    //  read Setpoint 1
            digitalWrite(mx1,HIGH);                                 //  
            Setpoint3 = analogRead(analogPin);                      //  read Setpoint 3
       
            Serial.print(Setpoint1,DEC);                                
            Serial.print(" ");
         /* Serial.print(bemf1,DEC);                                    //  helpful for diagnose
            Serial.println("   "); */
            Serial.print(Setpoint2,DEC);
            Serial.print(" ");
         /* Serial.print(bemf2;DEC);                                    //  helpful for diagnose
            Serial.print("   ");   */       
            
            delayMicroseconds(pulsetime);                           //  hold signal until end of halfwave
     
     // end 1. halfwave       
   
     // 2. halfwave
     
       // setup L293 for bemf measurement car 2 + 4
             digitalWrite(L293V12ena,LOW);                          //  L293 cars 2 + 4 high state
             digitalWrite(L293V3pin,HIGH);                          //  car 2 to plus
             digitalWrite(L293V4pin,HIGH);                          //  car 4 to plus  
             digitalWrite(L293V34ena,HIGH);         
             delayMicroseconds(500);                                //  allow settings (0,5ms)
        
       // measure bemf car 2 + 4
       
             bemf2 = 0;
             bemf4 = 0;
             
             for ( i = 0; i < 20; i++) {                            //  do 20 readings
                   data1 = analogRead(bemf2pin);                    //  read supply voltage minus bemf car 2
                   if (data1 < 100){                                //  poor contact?
                       data1 = ref2;
                       }
                   bemf2 += ref2-min(data1,ref2);     //  calculate rpm car 2
                                      
                   data2 = analogRead(bemf4pin);                    //  read supply voltage minus bemf car4
                   if (data2 < 100) {                               //  poor contact?
                       data2= ref4;
                       }
                   bemf4 +=ref4-min(data2,ref4);     //  calculate rpm car 4
                   }
             
        // return to pwm  
             analogWrite(L293V4pin,pwm2);
             digitalWrite(L293V1pin,LOW);
             analogWrite(L293V3pin,pwm4);                      
             digitalWrite(L293V2pin,LOW);
             digitalWrite(L293V12ena,HIGH);                         // end of measurement
    
        // calculate new PWM value car 2
             if (Setpoint2 < 1) {                                                     
                 analogWrite(L293V4pin,0);                          //  standstill  
                  }
              else {
                    if (bemf2 < 1) {                                //  f.e. poor contact
                        analogWrite(L293V4pin,1);                   //  add power car 2
                        }
                    else {
                        bemf2 = constrain(bemf2/carfactor2,0,1023);  //  include carfactor
                        if (Setpoint2>bemf2) {
                            pwm2 = 255;                              //   value may be reduced for smooth drive car2 (0...255)
                            }
                        else {
                            pwm2 = 0;                                //  PWM off
                            }                                    
                        analogWrite(L293V4pin,pwm2);                 //  write new PWM value car 2
                         }
                   }
           
       // calculate new PWM value car 4
            if (Setpoint4 < 1) {
                  digitalWrite(L293V3pin,0);                          //  standstill
                  }
              else {
                    if (bemf4<1) {                                     //  f.e. poor contact
                        analogWrite(L293V3pin,255);                    //  add power car 4
                        }
                    else {
                         bemf4 = constrain(bemf4/carfactor4,0,1023);   //  include carfactor
                         if (Setpoint4>bemf4) {                        //  power calculation car 4
                             pwm4 = 255;                               //  value may be reduced for smooth drive car 4 (0...255)
                             }
                         else {
                             pwm4 = 0;                                 //  PWM off
                             }                                                  
                         digitalWrite(L293V3pin,pwm4);                 //  write new PWM value car 4
                         }
                   }
     
     // check setpoints car 2 and 4    
           digitalWrite(mx0,HIGH);                                    //  initialize multiplexer 4051
           digitalWrite(mx1,LOW);
           Setpoint2 = (analogRead(analogPin));                       //  read Setpoint 2
           digitalWrite(mx1,HIGH);
           Setpoint4=(analogRead(analogPin));                         //  read Setpoint 4
     
           
           Serial.print(Setpoint3,DEC);                               //  need for diagnose purposes only
           Serial.print(" ");
        /* Serial.print(bemf4,DEC);                                   // helpful for diagnose
           Serial.print("  ");*/
           Serial.print(Setpoint4,DEC);
     /*    Serial.print(" ");                                         // helpful for diagnose
           Serial.print(bemf4,DEC);*/
           Serial.println(" ");
        
           delayMicroseconds(pulsetime);                              //  hold signal until end of halfwave
    
}                                                                     //  repeat forever
            



 
 
// ==========================[ end main ] ========================================================================


Angehängte Dateien
.pdf   AMS Control 1.4.pdf (Größe: 47,88 KB / Downloads: 34)
Zitieren
#91
Ich habe noch mal über dein Schaltplan nachgedacht...  Die eine 4051 Multiplexer wird nur 50% benutzt, mit zwei multiplexer, 8 Potis und 2 H-brücken ist es auch möglich 8 Autos mit PWM und feedback zu fahren. Dein Arduino Programm bleibt im Grunde gleich, nur 4 regler zufugen:


Angehängte Dateien Thumbnail(s)
   

Martin H.
Zitieren
#92
Thumbs Up 
Coole Idee, 8 Fahrzeug mit einem Arduino zu regeln. Cool Dann benötigt man die Digitalausgänge des Arduino. In dieser  Software-Version werden die Analogausgänge benutzt, also eine PWM mit festem Tastverhältnis ausgegeben. Ich habe das gemacht, da ich einmal die Pulsbreite in der Software variieren kann und  ich zweitens auch eine Software-Version untersuche, die wirklich die Pulsbreite regelt. Also, wenn du die Software mit Digitalausgängen benötigst, die könnte ich dir geben. Wink

Noch ein allgemeiner Hinweis zu Software: während der Initialisierung des Arduino werden die Referenzwerte der Motoren gemessen. Das oder die zu regelnde(n) Fahrzeug(e) müssen also auf der Bahn stehen, sonst wird es nicht korrekt geregelt. Der gemessene Wert wird auf dem Bildschirm angezeigt  (falls angeschlossen) und sollte zwischen 800 und 900 liegen. Danach werden die Sollwerte angezeigt.

Ciao Finbar
Zitieren
#93
Mit 'Analogausgänge' meinst du hier 'PWM Ausgänge' ? Ja dann reicht ein Arduino Uno oder Nano nicht aus, die haben nur 6 PWM Ausgänge (3, 5, 6, 9, 10, 11) und mann brauche dan 8.

Mit ein Arduino Mega wurde das aber gehen, die hat 15 PWM ausgänge (2 - 13, 44 - 46).

Martin H.
Zitieren
#94
Das kann mit dem Uno schon funktionieren. Du musst in der Software nur alle analogWrite..,255 ersetzen durch digitalWrite...,HIGH.  Für das Fahrzeug funktioniert das ebenso.
Die Messung für zwei Fahrzeuge (Fahrzeug1 Track 1 und Fahrzeug3, Track 2) dauert etwa 4ms,  beide Autos werden in jeder Halbwelle 20 mal gelesen. Danach bleiben 5ms Pause pro Halbwelle. In dieser Zeit könnten zwei weitere Fahrzeuge gelesen werden. Zeitlich müsste es also auch funktionieren.
Übrigens, ich habe die Betriebsspannung von 20 Volt auf 12 Volt reduziert, siehe Version 1.4.

Viele Grüße
Finbar
Zitieren
#95
(12-09-2020, 00:30)finbar schrieb: Das kann mit dem Uno schon funktionieren. ... in der Software nur alle analogWrite(..,255) ersetzen durch digitalWrite(...,HIGH)  ...

Das habe ich gemacht, das Programm für 4 Autos sieht dann so aus:

Code:
// AMS controller 2 State using PWM outputs V0.8.2
//
// Before starting:
//
//    - double check direction of Zenerdiodes and measurement circuit to avoid 12 V on Arduino input!
//    - use stabilized power supply 12 Volt!
//    - add heatsink to L293!
//    - check each car is using diode
//
//    - checked with and optimized for zinc motors
//
// controls 2 x 2 Faller AMS cars by measuring motor rpm via back EMF and
// using L293N dual H bridge module, a CD4051 multiplexer and 4 potmeters
// --------------------------------------------------------------
//  *** Version 0.8.2 preliminary ***
//       (c) Rainer Woerthmann
//  ->  No warranty
//  ->  Have fun
//
// ---------------------------------------------------------------
//  *** Version 0.8.3 preliminary ***
//  analogWrite()            replaced with digitalWrite()
//  pwm1,pwm2,pwm3,pwm4      variables eliminated
// 
// ================================= [global variables ] ==========================================
//
// input pin definitions feedback voltage
const byte bemf1pin = A0;                                         //  Back-EMF input car 1 track A
const byte bemf2pin = A1;                                         //  Back-EMF input car 2 track A
const byte bemf3pin = A2;                                         //  Back-EMF input car 3 track B
const byte bemf4pin = A3;                                         //  Back-EMF input car 4 track B

const byte mx0 = 2;                                               //  to multiplexer 4051 pin 11, LSB
const byte mx1 = 3;                                               //  to multiplexer 4051 pin 10, HSB
const int setpointspin =A5;                                          //  setpoint potmeter readings via multiplexer 4051, cars 1...4

// output pin definition H-bridge 1, track A (L293 V1 und V4)
const byte L293V1pin = 11;                                        //  track A, car 1, L293 pin 2, PWM out
const byte L293V4pin = 6;                                         //  track A, car 2, L293 Pin 15, PWM out

// output pin definition H-bridge 2, track B, (L293 V2 and V3)
const byte L293V2pin = 10;                                        //  track B, car 3, L293 pin 7, PWM out
const byte L293V3pin = 9;                                         //  track B, car 4, L293 pin 10, PWM out

// output pin definition H-bridge, high state
const byte L293V12ENpin = 7;                                      //  car 1+2 enable, L293 Pin 1, dig out
const byte L293V34ENpin = 8;                                      //  car 3+4 enable, L293 Pin 9, dig out

// constant value to equalize speed of different motors           //  increase value => car faster, decrease value => car slower
const byte carfactor1 = 3;                                        //  f.e. zinc, 5 or 6
const byte carfactor2 = 3;                                        //  Truck Flachanker = 1
const byte carfactor3 = 3;
const byte carfactor4 = 3;                                        //   

int setpoint1, setpoint2, setpoint3, setpoint4;                   //  setpoints cars 1...4
int bemf1,bemf2,bemf3,bemf4;                                      //  back-emf cars 1...4
int ref1,ref2,ref3,ref4;                                          //  reference values cars 1...4, standstill
int data1,data2;
//byte pwm1,pwm2,pwm3,pwm4;                                         //  output cars 1...4
word i;                                                           //  counter

const int pulsetime =5000;                                        //  frequency (around (2*(5ms+4ms measurement))
                                                                  //  increase if motor does not start, decrease for running smooth
// =========================== [ set up ]=========================================================================

void setup() {

   Serial.begin(9600);                                             //  monitor everything
   Serial.println(" ");    
   Serial.println("START Programm AMS RPM controller");
 
   pinMode(2,OUTPUT);                                              //  multiplexer 4051, LSB                                         
   pinMode(3,OUTPUT);                                              //  multiplexer 4051, HSB
 
   pinMode(setpointspin,INPUT);                                       //  setpoints cars 1...4
 
   pinMode(bemf1pin,INPUT);                                        //  back-emf car 1
   pinMode(bemf2pin,INPUT);                                        //  back-emf car 2
   pinMode(bemf3pin,INPUT);                                        //  back-emf car 3
   pinMode(bemf4pin,INPUT);                                        //  back-emf car 4
 
   pinMode(L293V12ENpin,OUTPUT);                                   //  enable H-bridge V 1,2 high state
   pinMode(L293V34ENpin,OUTPUT);                                   //  enable H-bridge V 3,4 high state
   digitalWrite(L293V12ENpin,LOW);
   digitalWrite(L293V34ENpin,LOW);
 
   pinMode(L293V1pin,OUTPUT);                                       // H bridge input, cars 1..4
   pinMode(L293V2pin,OUTPUT);
   pinMode(L293V3pin,OUTPUT);
   pinMode(L293V4pin,OUTPUT);
 
// reference values
   digitalWrite(L293V34ENpin,LOW);                                  //  cars 1 + 3 high state
   digitalWrite(L293V1pin,HIGH);                                    //  car 1 to plus
   digitalWrite(L293V2pin,HIGH);                                    //  car 3 to plus
   digitalWrite(L293V12ENpin,HIGH);                                 //  cars 1 + 3 enable
   delay(1000);
                                  
   ref1 = constrain(analogRead(bemf1pin),300,950);                  //  read reference (standstill) value car 1
   ref3 = constrain(analogRead(bemf3pin),300,950);                  //  read reference (standstill) value car 3
 
   digitalWrite(L293V12ENpin,LOW);                                  //  cars 2 + 4 high state
   digitalWrite(L293V3pin,HIGH);                                    //  car2 to plus
   digitalWrite(L293V4pin,HIGH);                                    //  car 4 to plus
   digitalWrite(L293V34ENpin,HIGH);                                 //  cars 2+4 enable
   delay(1000);
                                        
   ref2 = constrain(analogRead(bemf2pin),300,950);                   //  read reference (standstill) value car 2
   ref4 = constrain(analogRead(bemf4pin),300,950);                   //  read reference (standstill) value car 4
                                           
   Serial.print(ref1,DEC);                                           // Show reference values   
   Serial.print(" ");
   Serial.print(ref2,DEC);
   Serial.print(" ");
   Serial.print(ref3,DEC);
   Serial.print(" ");
   Serial.println(ref4,DEC);
}                                                                   // end of setup
// =========================== [ main ] ==========================================================================
void loop() {
 
// 1. halfwave
   //  setup L293 for bemf measurement car 1 + 3
   digitalWrite(L293V34ENpin,LOW);                       //  L293 cars 1 + 3 high state
   digitalWrite(L293V1pin,HIGH);                         //  car 1 to plus
   digitalWrite(L293V2pin,HIGH);                         //  car 3 to plus
   digitalWrite(L293V12ENpin,HIGH);                       
   delayMicroseconds(500);                               //  allow settings (0,5ms)
       
   // measure bemf car 1 + 3
   bemf1 = 0;
   bemf3 = 0;
   for (i = 0; i < 20; i++) {                            //  do 20 readings
      data1 = analogRead(bemf1pin);                      //  read supply voltage minus bemf car 1
      if (data1 < 100){                                  //  poor contact?
         data1 = ref1;
      }
      bemf1 += ref1-min(data1,ref1);                   //  calculate rpm car1
                                         
      data2 = analogRead(bemf3pin);                    //  read supply voltage minus bemf car 3
      if (data2 < 100) {                               //  poor contact??
         data2 = ref3;
      }
      bemf3 += ref3-min(data2,ref3);                   //  calculate rpm car3  
   }
        
   // return to pwm
   //analogWrite(L293V1pin,pwm1);       // pwm1 VALUE IS NOT INITIALISED !                  
   digitalWrite(L293V4pin,LOW);
   //analogWrite(L293V2pin,pwm3);       // pwm3 VALUE IS NOT INITIALISED !
   digitalWrite(L293V3pin,LOW);
   digitalWrite(L293V34ENpin,HIGH);                     //  end of measurement
      
   // calculate new PWM value car 1
   if (setpoint1 < 1) {                                  
      //analogWrite(L293V1pin,0);                       
      digitalWrite(L293V1pin,LOW);                      //  standstill
   }
   else {
      if (bemf1 <1) {                                   //  f.e. poor contact
         //analogWrite(L293V1pin,255);                  //  add power car 1
         digitalWrite(L293V1pin,HIGH);                  //  add power car 1
      }
      else {
         bemf1 = constrain(bemf1/carfactor1,0,1023);//  include carfactor
         if (setpoint1>bemf1) {                     //  power calculation car 1
            //pwm1 = 255;                             //  xxxxxxxxxxx
            digitalWrite(L293V1pin,HIGH);              //  write new PWM value car 1
         }
         else {                                     
            //pwm1 = 0;                               //  PWM off 
            digitalWrite(L293V1pin,LOW);              //  write new PWM value car 1                                                
         }
         //analogWrite(L293V1pin,pwm1);               //  write new PWM value car 1
      }             
   }
                            
   // calculate new PWM value car 3                                
   if (setpoint3 <1) {                                   
      //analogWrite(L293V2pin,0);                      
      digitalWrite(L293V2pin,LOW);                     //  standstill
   }
   else {
      if (bemf3 <1) {                                  //  f.e. poor contact
         //analogWrite(L293V2pin,255);                 //  xxxxxxxxxxx
         digitalWrite(L293V2pin,HIGH);                 //  add power car 3
      }
      else {
         bemf3 = constrain(bemf3/carfactor3,0,1023);     // include carfactor
         if (setpoint3>bemf3) {                          // power calculation car3
            //pwm3 = 255;                                // xxxxxxxxx
            digitalWrite(L293V2pin,HIGH);                // write new PWM value car 3 
         }
         else {
            //pwm3 = 0;                                  // PWM off
            digitalWrite(L293V2pin,LOW);                 // write new PWM value car 3 
         }                                                                 
         //analogWrite(L293V2pin,pwm3);                  // xxxxxxxxxxxxxxxx
      }               
   }
          
   // check setpoints car 1 and 3, mx2 hard wired to 0                                     b210
   digitalWrite(mx0,LOW);                                  //  initialize multiplexer 4051 %000 = 0
   digitalWrite(mx1,LOW);
   setpoint1 = analogRead(setpointspin);                   //  read setpoint 1
   digitalWrite(mx1,HIGH);                                 //  initialize multiplexer 4051 %010 = 2
   setpoint3 = analogRead(setpointspin);                   //  read setpoint 3
       
   Serial.print(setpoint1,DEC);                                
   Serial.print(" ");
   // Serial.print(bemf1,DEC);                                    //  helpful for diagnose
   // Serial.println("   "); 
   Serial.print(setpoint2,DEC);
   Serial.print(" ");
   //Serial.print(bemf2;DEC);                                    //  helpful for diagnose
   //Serial.print("   ");          
            
   delayMicroseconds(pulsetime);                           //  hold signal until end of halfwave
     
 // end 1. halfwave       
 // --------------------------  
 // 2. halfwave
   // setup L293 for bemf measurement car 2 + 4
   digitalWrite(L293V12ENpin,LOW);                        //  L293 cars 2 + 4 high state
   digitalWrite(L293V3pin,HIGH);                          //  car 2 to plus
   digitalWrite(L293V4pin,HIGH);                          //  car 4 to plus  
   digitalWrite(L293V34ENpin,HIGH);         
   delayMicroseconds(500);                                //  allow settings (0,5ms)
        
   // measure bemf car 2 + 4
   bemf2 = 0;
   bemf4 = 0;
   for ( i = 0; i < 20; i++) {                            //  do 20 readings
      data1 = analogRead(bemf2pin);                    //  read supply voltage minus bemf car 2
      if (data1 < 100){                                //  poor contact?
         data1 = ref2;
      }
      bemf2 += ref2-min(data1,ref2);     //  calculate rpm car 2
                                    
      data2 = analogRead(bemf4pin);                    //  read supply voltage minus bemf car4
      if (data2 < 100) {                               //  poor contact?
          data2= ref4;
      }
      bemf4 +=ref4-min(data2,ref4);     //  calculate rpm car 4
   }
           
   // return to pwm  
   //analogWrite(L293V4pin,pwm2);   // pwm2 VALUE IS NOT INITIALISED !  
   digitalWrite(L293V1pin,LOW);
   //analogWrite(L293V3pin,pwm4);   // pwm4 VALUE IS NOT INITIALISED !                     
   digitalWrite(L293V2pin,LOW);
   digitalWrite(L293V12ENpin,HIGH);                         // end of measurement
   
   // calculate new PWM value car 2
   if (setpoint2 < 1) {                                                     
      //analogWrite(L293V4pin,0);                          //  standstill 
      digitalWrite(L293V4pin,LOW);                         //  standstill  
   }
   else {
      if (bemf2 < 1) {                                //  f.e. poor contact
         //analogWrite(L293V4pin,255);                   //  add power car 2 (255, not 1)
         digitalWrite(L293V4pin,HIGH);                   //  add power car 2
      }
      else {
         bemf2 = constrain(bemf2/carfactor2,0,1023);  //  include carfactor
         if (setpoint2>bemf2) {
            //pwm2 = 255;                              //  xxxxxxxxxxxx
            digitalWrite(L293V4pin,HIGH);            //  write new PWM value car 2
         }
         else {
            //pwm2 = 0;                                //  PWM off
            digitalWrite(L293V4pin,LOW);             //  standstill 
         }                                    
         //analogWrite(L293V4pin,pwm2);                 //  write new PWM value car 2
      }
   }
          
   // calculate new PWM value car 4
   if (setpoint4 < 1) {
      //analogWrite(L293V3pin,0);                             //  standstill
      digitalWrite(L293V3pin,LOW);                          //  standstill
   }
   else {
      if (bemf4<1) {                                     //  f.e. poor contact
         //analogWrite(L293V3pin,255);                    //  add power car 4
         digitalWrite(L293V3pin,HIGH);                    //  add power car 4
      }
      else {
         bemf4 = constrain(bemf4/carfactor4,0,1023);   //  include carfactor
         if (setpoint4>bemf4) {                        //  power calculation car 4
            //pwm4 = 255;                               //  xxxxxxxxxxxxx)
            digitalWrite(L293V3pin,HIGH);             //  write new PWM value car 4
         }
         else {
            //pwm4 = 0;                                 //  PWM off
            digitalWrite(L293V3pin,LOW);                 //  write new PWM value car 4
         }                                                  
         //analogWrite(L293V3pin,pwm4);                 //  write new PWM value car 4
      }
   }
   
   // check setpoints car 2 and 4                                                                   b210
   digitalWrite(mx0,HIGH);                                    //  initialize multiplexer 4051 %001 = 1
   digitalWrite(mx1,LOW);
   setpoint2 = analogRead(setpointspin);                      //  read setpoint 2
   digitalWrite(mx1,HIGH);                                    //  initialize multiplexer 4051 %011 = 3
   setpoint4 = analogRead(setpointspin);                      //  read setpoint 4
       
   Serial.print(setpoint3,DEC);                               //  need for diagnose purposes only
   Serial.print(" ");
   // Serial.print(bemf4,DEC);                                // helpful for diagnose
   // Serial.print("  ");
   Serial.print(setpoint4,DEC);
   // Serial.print(" ");                                      // helpful for diagnose
   // Serial.print(bemf4,DEC);
   Serial.println(" ");
       
   delayMicroseconds(pulsetime);                              //  hold signal until end of halfwave
}
                                               //  repeat forever
// ==========================[ end main ] ========================================================================

Auch pwm1, pwm2, pwm3, pwm4 gibt es nicht mehr (wurden nie initialisiert). Ohne "analogWrite()" könnte das Arduino nano Programm einfach ausgebreitet werden für 8 Autos.

Martin H.
Zitieren
#96
Hallo,

Ich habe die Drehzahlregelung für die Autos nochmal upgedated, V 1.5. Die Schaltung wird jetzt mit 15V betrieben, dazu habe ich die Zenerdioden D5,D6,D7,D8 durch 8,2 Volt Typen ersetzt. Außerdem wurden die Widerstände R2, R4, R5 und R8 durch 150 Ohm ersetzt.
Ich habe eine Funktionsbeschreibung beigefügt und einen Sketch geschrieben, bei dem ein PID Regler die PWM regelt.

Have fun!


Code:
/* AMS controller myPID Control V0.8.7.ino

This sketch controls rpm of 2 x 2 Faller AMS cars by measuring motor rpm via back EMF using circuit diagram AMS control with feedback V 1.5.

Before starting:

    - double check direction of zenerdiodes and measurement circuit to avoid supply voltage on Arduino input!
    - use stabilized power supply!
    - add heatsink to L293!
    - check each car is using diode

    - checked with and optimized for Faller zinc, LKW-Flachanker and PKW-Flachanker

*** Version 0.8.7 preliminary ***
     (c) Rainer Woerthmann

  ->  No warranty
  ->  Have fun
================================= [include libraries ] ==========================================*/
#include <PID_v1.h>
/*
================================= [global variables ] ===========================================*/
// input pin definition
   const byte bemf1pin = A0;                                         //  Back-EMF input car 1 track A
   const byte bemf2pin = A1;                                         //  Back-EMF input car 2 track A
   const byte bemf3pin = A2;                                         //  Back-EMF input car 3 track B
   const byte bemf4pin = A3;                                         //  Back-EMF input car 4 track B

   const byte mx0 = 2;                                               //  to multiplexer 4051 pin 11, LSB
   const byte mx1 = 3;                                               //  to multiplexer 4051 pin 10, HSB
   const byte analogPin =A5;                                         //  setpoint readings via multiplexer 4051, cars 1...4

// output pin definition H-bridge 1, track A (L293 V1 und V4)
   const byte L293V1pin = 11;                                        //  track A, car 1, L293 pin 2, PWM
   const byte L293V4pin = 6;                                         //  track A, car 2, L293 Pin 15, PWM

// output pin definition H-bridge 2, track B, (L293 V2 and V3)
   const byte L293V2pin = 10;                                        //  track B, car 3, L293 pin 7, PWM
   const byte L293V3pin = 9;                                         //  track B, car 4, L293 pin 10, PWM

// output pin definition H-bridge, high state
   const byte L293V12ena = 7;                                        //  car 1+2 enable, L293 Pin 1
   const byte L293V34ena = 8;                                        //  car 3+4 enable, L293 Pin 9

// variables
   double setpoint[4];                                               //  setpoints cars 1...4
   double rpm[4];                                                    //  rpm cars 1...4
   double pwm[4];                                                    //  output voltage cars 1...4
   double data1,data2;                                               //  bemf readings
   const double carspeed[4] = {1,1,1,1};
   int ref[4];                                                       //  reference values cars 1...4, standstill
   byte carenable[4] = {0,0,0,0};
   word i;                                                           //  counter
   const word samples = 20;                                          //  number of bemf-readings: manipulates overall car speeds and system frequency, original set to 20
   const int pulsetime = 6;                                          //  frequency (around (2*(6ms+measurement))
   
                                                                     //  examples: zinc=1, truck Flachanker = 3.5, PKW Flachanker = 4...8
// myPID control parameters
   PID myPID1(&rpm[0], &pwm[0], &setpoint[0],0.2,2,0.0001, DIRECT);  //  values of PID-controller to play with; first P-value, second I-value, third D-value
   PID myPID2(&rpm[1], &pwm[1], &setpoint[1],0.1,1,0.0008, DIRECT);  //  f.e. zinc motor: P=0.2,I=1,D=0.0001 by 15V supply, pulsetime 6ms
   PID myPID3(&rpm[2], &pwm[2], &setpoint[2],0.18,3,0.0008, DIRECT); //  f.e. Truck Flachanker P=0.2,I=2,D=0.0006
   PID myPID4(&rpm[3], &pwm[3], &setpoint[3],0.15,2,0.0008, DIRECT); //  f.e. PKW Flachanker P=0.35,I=2,D=0.0008
                                                                 
// =========================== [ set up ]=========================================================================

void setup() {

   Serial.begin(9600);                                              //  monitor everything
   Serial.println(" ");    
   Serial.println("AMS RPM controller V.0.8.7");

// pin definition
   pinMode(2,OUTPUT);                                               //  multiplexer 4051, LSB                                         
   pinMode(3,OUTPUT);                                               //  multiplexer 4051, HSB
 
   pinMode(analogPin,INPUT);                                        //  setpoints cars 1...4
 
   pinMode(bemf1pin,INPUT);                                         //  back-emf car 1
   pinMode(bemf2pin,INPUT);                                         //  back-emf car 2
   pinMode(bemf3pin,INPUT);                                         //  back-emf car 3
   pinMode(bemf4pin,INPUT);                                         //  back-emf car 4
 
   pinMode(L293V12ena,OUTPUT);                                      //  H-bridge V 1,2 high state
   pinMode(L293V34ena,OUTPUT);                                      //  H-bridge V 3,4 high state
   digitalWrite(L293V12ena,LOW);
   digitalWrite(L293V34ena,LOW);
 
   pinMode(L293V1pin,OUTPUT);                                       // H bridge input, cars 1..4
   pinMode(L293V2pin,OUTPUT);
   pinMode(L293V3pin,OUTPUT);
   pinMode(L293V4pin,OUTPUT);
 
// read and show reference values
   digitalWrite(L293V34ena,LOW);                                   //  cars 1 + 3 high state
   digitalWrite(L293V1pin,HIGH);                                   //  car 1 to plus
   digitalWrite(L293V2pin,HIGH);                                   //  car 3 to plus
   digitalWrite(L293V12ena,HIGH);                                  //  cars 1 + 3 enable
   delay(1000);
 
      ref[0] = analogRead(bemf1pin);                               //  read reference (standstill) value car 1
      ref[2] = analogRead(bemf3pin);                               //  read reference (standstill) value car 3
       
   digitalWrite(L293V12ena,LOW);                                   //  cars 2 + 4 high state
   digitalWrite(L293V3pin,HIGH);                                   //  car2 to plus
   digitalWrite(L293V4pin,HIGH);                                   //  car 4 to plus
   digitalWrite(L293V34ena,HIGH);                                  //  cars 2 + 4 enable
   delay(500);
 
      ref[1] = analogRead(bemf2pin);                               //  read reference (standstill) value car 2
      ref[3] = analogRead(bemf4pin);                               //  read reference (standstill) value car 4
                                                 
   for (i = 0;i<4;i++) {                                           //  show reference value information
      Serial.print ("Car ");
      Serial.print (i+1);
      if (ref[i] < 800 || ref[i] > 950) {
          Serial.print(" error: ");                                 
         }
      else {
          Serial.print (" ok:    ");
          carenable[i] =1;
          }
      Serial.println(ref[i],DEC);                                     
      }
   delay(3000);

   Serial.println();
   Serial.println("running...");
     
// initialize myPID controller
   myPID1.SetMode(AUTOMATIC);
   myPID1.SetSampleTime(10);
   myPID2.SetMode(AUTOMATIC);
   myPID2.SetSampleTime(10);
   myPID3.SetMode(AUTOMATIC);
   myPID3.SetSampleTime(10);
   myPID4.SetMode(AUTOMATIC);
   myPID4.SetSampleTime(10);

}  
/* =========================== end of setup ======================================================================
 
   =========================== [ main ] ========================================================================== */
void loop() {
 
// 1. halfwave
    
   // setup L293 for bemf measurement car 1 + 3
      digitalWrite(L293V34ena,LOW);                             //  L293 cars 1 + 3 high state
      digitalWrite(L293V1pin,HIGH);                             //  car 1 to plus
      digitalWrite(L293V2pin,HIGH);                             //  car 3 to plus
      digitalWrite(L293V12ena,HIGH);                       
      delayMicroseconds(500);                                   //  allow settings (0,5ms)
       
   // measure rpm car 1 + 3              
      rpm[0] = 0;
      rpm[2] = 0;
              
      for (i = 0; i < samples; i++) {                           //  do 20 or so readings
         data1 = analogRead(bemf1pin);                          //  read supply voltage minus bemf car 1
         if (data1 < ref[0]/4) {                                //  poor contact?
            data1 = ref[0];
            }
         rpm[0] += ref[0]-min(data1,ref[0]);                    //  calculate rpm car1 and limit
                                         
         data2 = analogRead(bemf3pin);                          //  read supply voltage minus bemf car 3
         if (data2 < ref[2]/4) {                                //  poor contact??
            data2 = ref[2];
            }
         rpm[2] += ref[2]-min(data2,ref[2]);                    //  calculate rpm car3 and limit  
         }
                  
         rpm[0] = constrain(rpm[0]*carspeed[0],0,1023);         //  include motor mapping and limit
         rpm[2] = constrain(rpm[2]*carspeed[2],0,1023);         //  include motor mapping and limit
                 
   // setup L293 for pwm         
      analogWrite(L293V1pin,pwm[0]);                          
      digitalWrite(L293V4pin,LOW);
      analogWrite(L293V2pin,pwm[2]);
      digitalWrite(L293V3pin,LOW);
      digitalWrite(L293V34ena,HIGH);                            //  end of measurement
      
   // calculate new PWM value car 1            
      if (setpoint[0] <1 || carenable[0]==0) {                  //  standstill
         analogWrite(L293V1pin,0);
         }
      else {
         myPID1.Compute();                                      //  calculate new PWM value     
         analogWrite(L293V1pin,pwm[0]);                         //  write new PWM value car 1   
         }
                                         
   // calculate new PWM value car 3                
      if (setpoint[2] <1 || carenable[2]==0) {                  //  standstill  
         analogWrite(L293V2pin,0);                       
         }
      else {
         myPID3.Compute();                                      //  calculate new PWM value     
         analogWrite(L293V2pin,pwm[2]);                         //  write new PWM value car 3     
         }
           
   // read setpoints car 1 and 3
      digitalWrite(mx0,LOW);                                    //  initialize multiplexer 4051
      digitalWrite(mx1,LOW);
      setpoint[0] = analogRead(analogPin);                      //  read Setpoint 1
      digitalWrite(mx1,HIGH);
      setpoint[2] = analogRead(analogPin);                      //  read Setpoint 3
            
   // show parameters                                             
      Serial.print(setpoint[0],0);                              //  useful for diagnosis and adjustment but affects timing
      Serial.print("  ");                                       //  shows car 1 and car 2 parameters
      Serial.print(rpm[0],0);                                     
      Serial.print(" ");
      Serial.print(pwm[0],0);                                
      Serial.print("   ");
      Serial.print(setpoint[1],0);                                
      Serial.print("  ");
      Serial.print(rpm[1],0);                                
      Serial.print(" ");
      Serial.print(pwm[1],0);                                
      Serial.print("   ");
            
      delay(pulsetime);                                         //  hold signal until end of halfwave
// end 1. halfwave       
   
// 2. halfwave
     
  // setup L293 for bemf measurement car 2 + 4
     digitalWrite(L293V12ena,LOW);                              //  L293 cars 2 + 4 high state
     digitalWrite(L293V3pin,HIGH);                              //  car 2 to plus
     digitalWrite(L293V4pin,HIGH);                              //  car 4 to plus  
     digitalWrite(L293V34ena,HIGH);         
     delayMicroseconds(500);                                    //  allow settings (0,5ms)
        
  // measure bemf car 2 + 4
     rpm[1] = 0;
     rpm[3] = 0;
             
     for ( i = 0; i < samples; i++) {                          //  do 20 or so readings
         data1 = analogRead(bemf2pin);                         //  read supply voltage minus bemf car 2
         if (data1 < ref[1]/5){                                //  poor contact?
             data1 = ref[1];
             }
         rpm[1] += ref[1]-min(data1,ref[1]);                   //  calculate rpm car 2
                                      
         data2 = analogRead(bemf4pin);                         //  read supply voltage minus bemf car4
         if (data2 < ref[3]/5) {                               //  poor contact?
            data2 = ref[3];
            }
         rpm[3] +=ref[3]-min(data2,ref[3]);                    //  calculate rpm car 4
         }

         rpm[1] = constrain(rpm[1]*carspeed[1],0,1023);
         rpm[3] = constrain(rpm[3]*carspeed[3],0,1023);           
             
   // setup L293 for PWM  
      analogWrite(L293V4pin,pwm[1]);
      digitalWrite(L293V1pin,LOW);
      analogWrite(L293V3pin,pwm[3]);                      
      digitalWrite(L293V2pin,LOW);
      digitalWrite(L293V12ena,HIGH);                           // end of measurement
   
   // calculate new PWM value car 2
      if (setpoint[1] <1 || carenable[1] ==0) {                //  standstill
         analogWrite(L293V4pin,0);
         }
      else {
         myPID2.Compute();                                     //  calculate new PWM value
         analogWrite(L293V4pin,pwm[1]);                        //  write new PWM value car 2  
         }
                 
   // calculate new PWM value car 4
      if (setpoint[3] <1 || carenable[3] ==0) {                //  standstill
         analogWrite(L293V3pin,0);
         }
      else {
         myPID4.Compute();                                     //  calculate new PWM value
         analogWrite(L293V3pin,pwm[3]);                        //  write new PWM value car 4   
         }
     
   // check setpoints car 2 and 4    
      digitalWrite(mx0,HIGH);                                  //  initialize multiplexer 4051
      digitalWrite(mx1,LOW);
      setpoint[1] = analogRead(analogPin);                     //  read Setpoint 2
      digitalWrite(mx1,HIGH);
      setpoint[3] = analogRead(analogPin);                     //  read Setpoint 4
     
           
      Serial.print(setpoint[2],0);                             //  useful for diagnosis and adjustment but affects timing
      Serial.print("  ");                                      //  shows car 3 and 4 parameters
      Serial.print(rpm[2],0);                              
      Serial.print(" ");
      Serial.print(pwm[2],0);                                    
      Serial.print("   ");
      Serial.print(setpoint[3],0);                               
      Serial.print("  ");
      Serial.print(rpm[3],0);                                   
      Serial.print(" ");
      Serial.print(pwm[3],0);                           
      Serial.println(" ");
           
      delay(pulsetime);                                        //  hold signal until end of halfwave
// end 2. halfwave
}                                                              //  repeat forever
            



 
 
// ==========================[ end main ] ========================================================================


Angehängte Dateien
.pdf   AMS Drehzahlregelung V1.5.pdf (Größe: 256,34 KB / Downloads: 56)
Zitieren
#97
Moin Finbar,
(23-11-2020, 14:43)finbar schrieb: ... Ich habe eine Funktionsbeschreibung beigefügt und einen Sketch geschrieben, bei dem ein PID Regler die PWM regelt.
klasse, vorbildlich  Angel .
ciao michaelo
... und wer zuletzt aufgibt gewinnt.
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste