- Offizieller Beitrag
Noch nicht ganz optimiert für den Einbau in einen Roboter, aber zum Testen durchaus brauchbar.
Noch nicht ganz optimiert für den Einbau in einen Roboter, aber zum Testen durchaus brauchbar.
So weiter im Programm. Es fehlen nur noch die Steckkontakte und eine Status LED. Getestet und funktioniert.
Oha, nicht tot zu bekommen die Regler und Speedos...
Generell ist Arduino und Co mittlerweile eine sehr gute Quelle um schnell mal was auf die Beine zu stellen, weil die Entwicklung einer funktionierenden Platine weg fällt. Das Ganze garniert mit einer IDE die Code für die wichtigsten Einheiten parat hat und erzeugen kann und als Bonus über die Shields stark erweiterbar. Was will man mehr heutzutage...?
Wenn du es leicht haben willst dann ist ein kleiner Arduino mit Motor Shield ideal.
Vorschlag: Arduino Uno mit z.B. Pololu Dual VNH5019 Motor Driver Shield oder Monster Moto Shield. Das ergibt nen Regler für 2 Motoren...
http://arduino.cc/en/Main/ArduinoBoardUno
http://www.pololu.com/catalog/product/2502
http://www.watterott.com/de/Monster-Moto-Shield
Hint für die Experten: Warum nicht einen richtig gutes Motor Shield für den Arduino designen? Ich denke da an Dual mit N-Fets, Treiber, Stromregler, usw... Das Ding kann man verkaufen, z.B. auch über den Verein...? Na Heiko, wie wärs, das wär doch genau dein Ding, oder...? Reiner hat schließlich schon einige Regler gebaut und alle anderen (inklusive mir natürlich) sind irgendwie im Rückstand...
Für den Arduino gibt es schon ein Motor Control Shield.
ZitatFür den Arduino gibt es schon ein Motor Control Shield.
Ha, das war mir irgendwie klar dass andere da schneller waren... Danke für den Hinweis Marien! :]
Das Modul benutzt auch den BZN7960B.
Aber: nur ein Kanal
Timer2:
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS21);
OCR2A = 180; 180 / 255 = 70.6%
OCR2B = 50; 50 / 255 = 19.6%
Timer 1:
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
TCCR1B = _BV(CS11);
OCR1A = 180; 180 / 255 = 70.6%
OCR1B = 50; 50 / 255 = 19.6%
Würde also beides eine Phase Corrected PWM mit 3,9KHz ergeben oder nicht?
Timer0 wird für delay und delayMicroseconds verwendet. Deswegen bleibt der unangetastet.
Stimmt das so oder habe ich mich irgendwo vertan?
Zum nachlesen.
http://www.atmel.com/Images/Atmel-8…P_datasheet.pdf Seite 623
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
https://sites.google.com/site/qeewiki/b…n-the-atmega328
So es tut sich noch was. Erstmal ein dickes Lob und danke an Reiner. Die Mosfets sind heute Mittag angekommen.
Bevor sich alle über meine super Lötkunst auslassen , das ist nur ein Prototyp. Also keinen Schreikrampf bekomen. Ja Reiner ich weis, aber Kühlkörper ist nicht. Erstmal wird ein dicker Motor besorgt und eine Bremse gebaut. Danach kommt ein verbesserte Prototyp der sich dann mal richtig auspowern darf :] . Der hier ist nur zum testen ob mein Konzept überhaupt funktioniert.
Was jetzt nur noch fehlt, sind die Brücken zum Arduino. Aber solange das Programm noch nicht fertig ist muss das noch warten, da das Programm noch nicht angepasst ist.
Ich denke ich werde erst mit 4KHz testen und den Strom auf 2-3A begrenzen.
Zum Programm hatte ich mir gedacht beide ICs an den selben PWM-Port zu hängen und dann zwei IO Pinns für vorwärts, rückwärts und Bremse zu benutzen. Die PWM würde also nur den Leistungszustand vorgeben.
Heist bei zwei kanälen würde ich nur 4 IO und 2 PWM Pinns benötigen. Hätte also noch zwei PWM und diverse IO Ports frei.
Und hier noch eine Gesamtübersicht.
Danke für die Info! Bist ja mit dem Verbauen schneller als ich mit dem Versenden...
ZitatBevor sich alle über meine super Lötkunst auslassen
Wieso? Passt doch! Dafür, dass Du eine grobe Lochraster-Streifenplatine und bedrahtete Widerstände verwendest, ist das astrein gemacht.
Schade ist nur, dass Du über das Gehäuse der MOSFETs den Pin4 mit dem Ausgang (=Kühlfahne) das Drähtchen gelegt hast. Ansonsten könntest Du einen kleinen Kühlkörper oben draufklemmen und ein bißchen Verlustleistung abführen.
Tipp für die Inbetriebnahme (falls Du es nicht schon so gemacht hast):
- Verwende anfangs ein kleines Steckernetzteil, das auch einen Kurzschluss verträgt
- Steuere die Eingänge der MOSFET-Brücke mal "statisch" an. Also einfach mit Krokoklemmen die 0V oder 5V an die Eingänge. Wenn das alles funktioniert, ist kein Lötzinnspritzer oder sonst eine Gemeinheit an der Verdrahtung, die Dir dann bei voller Akkukapazität den ersten "Smoke-Test" versaut.
ZitatZum Programm hatte ich mir gedacht beide ICs an den selben PWM-Port zu hängen und dann zwei IO Pinns für vorwärts, rückwärts und Bremse zu benutzen. Die PWM würde also nur den Leistungszustand vorgeben.
Ist das jetzt "Heiko-Prinzip" oder meine Anwendungstechnik? Ich vermute mal, Du machst das so wie ich, wenn Du schreibst, dass Du vorwärts/rückwärts mit I/O-Pins ohne PWM machst. (?)
Hab' ehrlich gesagt jetzt etwas überlegen müssen, ob das geht. .... Aber ja.... müßte klappen. Du hast dann im aktiven Betrieb zwar auf Low- und High-Side jeweils den Puls drauf und produzierst damit zusätzliche Verlustleistungen, aber .... muss bei den angedachten 2-3A gehen.
Nein die IO Pins sind keine PWM Pins.
Die syncrone Ansteuerung mache ich weil Heiko einte das das besser wäre bei Motoren mit hoher Induktivität und starkem nachdrehen. Die Ansteuerungslogik habe ich mir von dir geklaut nur halt mit dem Unterschied das beide ICs die PWM bekommen. Die Bremse sollte ich über die Highside machen oder?
Als Netzteil verwende ich ein dauerkurzschlussfestes Schaltnetzteil mit 0-30V und 0-3,5A. Das lief schon 3 Stunden mit 2A Kurzschluss. Das Netzteil überlebt das also.
Meine nächsten Programmierschritte werden also sein:
-Ansteuerung anpassen [erledigt]
-Bremse mit Rampe denke 50mS sind genug oder?
-Hochlauframpen
-besseres Failsafe mit Einschaltverzögerung (verhindert das scharfschalten nach dem ersten gültigen Impuls, für 40MHz Steuerungen)
-(Blinkkodes)
-(Temperaturüberwachung)
-(Überstromschutz)
Die Lötkünste sind doch ganz ansehnlich... *grins*
Tu Dir nen Gefallen und setz 100nF-Kondis (Keramik) direkt über die +/- Pins der Halbbrücken, dabei die Beine so kurz wie möglich halten!
Und Puffer-Elkos (möglichst geringer ESR!!!) brauchst Du auch noch! 220uF/25V an jeder Halbbrücke (auch direkt an den +/- Pins) sind ausreichend. Auch hier die Beine so kurz wie möglich halten!
Ohne die Elkos hast du an einem 3,5A Netzteil mit Strombegrenzung keinen Spaß (ich gehe jetzt mal von einem Akkuschraubermotor als erstes Testobjekt aus)
Zitatbeide ICs an den selben PWM-Port zu hängen und dann zwei IO Pinns für vorwärts, rückwärts und Bremse zu benutzen.
Die PWM würde also nur den Leistungszustand vorgeben.
hm... verstehe ich nicht so wirklich ... Da sitzen dann noch ein paar Logik-Gatter vor den Halbbrücken?
ZitatDu hast dann im aktiven Betrieb zwar auf Low- und High-Side jeweils den Puls drauf
und produzierst damit zusätzliche Verlustleistungen
Leicht ketzerisch *zwinker* gefragt: Wo treten die zusätzlichen Verlustleistungen auf? (Verstehe gerade irgendwie nicht, was Du meinst)
ZitatDie syncrone Ansteuerung mache ich weil Heiko einte das das besser wäre bei Motoren mit hoher Induktivität und starkem nachdrehen
Wann oder wo einte ich dass denn??
Primär verringert die synchrone Ansteuerung die Verluste (FET mit ein paar Miliohm statt Diode mit ca. 1.1V Spannungsabfall, beides bei gleichem Strom)
ZitatDie Ansteuerungslogik habe ich mir von dir geklaut nur halt mit dem Unterschied das beide ICs die PWM bekommen
Verstehe ich jetzt so: Logikgatter, die von den zwei IO-Pins gesteuert werden leiten die PWM je nach Fahrrichtung zu einer der beiden Halbbrücken?
ZitatDie Bremse sollte ich über die Highside machen oder?
Die LOW-Side hat bei den BTN einen geringeren Widerstand (RDS-ON) als die High-Side, also wenn möglich die LOW-Side benutzen.
ich muss nochmal ganz ketzerisch nachfragen:
- Hast Du vier Pins, die PWM können? (zwei für jede Vollbrücke)
- Hast DU einen weiteren freien IO-Pin? (gemeinsamer Shutdown/Enable beider Vollbrücken)
Wenn ja, kannst du mit zwei Pins, die PWM können, eine Vollbrücke komplett ansteuern.
Beispiel für eine Vollbrücke:
PWM_1 geht an linke Halbbrücke, PWM_2 an die rechte Halbbrücke
Vorwärts:
- PWM_1 macht PWM (bedeutet automatisch synchrone Ansteuerung der Halbbrücke)
- PWM_2 wird fest auf LOW geschaltet (oder High, jedenfalls so, dass der LOWside-FET leitet)
die PWM ist zu diesem Zeitpunkt an PWM_2 ABGESCHALTET, der Pin wird als normaler IO-Pin konfiguriert
Rückwärts:
- PWM_2 macht PWM (bedeutet automatisch synchrone Ansteuerung der Halbbrücke)
- PWM_1 wird fest auf LOW geschaltet (oder High, jedenfalls so, dass der LOWside-FET leitet)
die PWM ist zu diesem Zeitpunkt an PWM_1 ABGESCHALTET, der Pin wird als normaler IO-Pin konfiguriert
Beschleunigen:
Geschieht automatisch, wenn die PWM über eine Rampe hochgefahren wird
Bremsen:
Geschieht AUTOMATISCH, wenn die PWM über eine Rampe heruntergefahren wird!
Gleichzeitig wird die beim Bremsen anfallende Energie in den Akku zurückgespeist! Auch automatisch!!!
Das ganze funktioniert ohne weitere Logik-Gatter verbauen zu müssen!
Bremsen funktioniert AUTOMATISCH, ohne sich irgendwelche gedanken machen zu müssen (ausser, dass die PWM mit einer RAMPE auf 0 gefahren wird)
EDIT:
Zitat-(Überstromschutz)
Da bin ich ja mal gespannt die BTN haben eine kleine "Gemeinheit" parat, wenn man den Stromausgang benutzt *schäbbichgrins* bin mal gespannt, ob Du das rauskriegst
ZitatAls Netzteil verwende ich ein dauerkurzschlussfestes Schaltnetzteil mit 0-30V und 0-3,5A. Das lief schon 3 Stunden mit 2A Kurzschluss. Das Netzteil überlebt das also.
*Humor*
Eigentlich ging's mir nicht darum, dass das Netzteil überlebt, sondern dass bei der Erstinbetriebnahme (= "Smoke-Test") die Schaltung eine Chance kriegt, bei einem eventuellem kleinen Verdrahtungs- oder Softwarefehler zu überleben. )
(Die BTN7960 sind in dieser Art ja sehr robust. Aber wenn Du mit Standard-MOSFETs eine Brücke aufbaust und versehentlich mal bei einer Halbbrücke alle beiden MOSFETs (Low- und High-Side) gleichzeitig aktivierst, dann weist Du, was ich meine. Bei einem kleinen Steckernetzteil fließen Dir 500mA und die Kontrollleuchte am Netzteil geht aus. Aber die Zuleitungen und das kleine Platinchen (Leiterbahnen) gehen nicht in Flammen auf...)
ZitatAlles anzeigenOriginal von UnskilledWorker
ok, mal wieder was technisch gehaltvolles:
in dem ersten link, den ich weiter oben gepostet habe, ist der fall deines "verlorenen" stroms recht gut beschrieben: "fast decay mode"
der strom fliesst nach öffnen aller FETS über zwei body-dioden in die batterie + stützkondensator zurück.
allerdings nur solange, bis das magnetfeld der induktivität (in diesem fall der motorwicklung) kollabiert ist.
das geht in diesem speziellen fall und bei "langsamer" PWM (500Hz bis 2kHz) und geringer induktivität recht schnell!!!
und zwar VIEL schneller, als bei Freilauf (freewheeling) über beide High- oder lowside FET's.
Wenn du nur etwas zu spät gemessen hast, ist der Strom schon auf 0 abgefallen, weil das magnetfeld schon kollabiert ist.
deshalb heisst das ja auch "fast decay".
Zitat
Die syncrone Ansteuerung mache ich weil Heiko einte das das besser wäre bei Motoren mit hoher Induktivität und starkem nachdrehen
Das hatte ich so Interpretiert.
Kondensatoren werde ich auf den nächsten Prototypen draufpacken. Sobald ich ein Schaltplan, Layout und meine Ätsanlage habe.
Die ansteuerung ist so:
PWM_Pin an IC1_Bein3 und IC2_Bein3
PIN1 an IC1_Bein2
PIN1 an IC2_Bein2
Also keine weiteren Logik ICs oder dergleichen.
Zum bremsen wird nur der PWM Pin angestuert und zum fahren der Richtungspin und der PWM Pin zusammen.
IBF: Den Rauchtest hat die Platine bestanden. Ein kliener Servomotor hing auch schon dran und drehte sich. Allerdings von feinfühlig regeln ist noch nicht die Rede. Komt nix, komt nix, fiept, kommt bisschen, dreht auf, vollgas. Muss also die Knüppelwege noch anpassen und die Minimal-PWM noch etwas erhöhen.
Zudem wären noch zwei Dioden pracktisch die anzeigen ob der jeweilige Kanal scharf ist.
Muss man den PIN4 eigentlich anschließen? Ich denke auf dem Layout kann man ja PIN4 unter dem IC zur Kühlfäche durchverbinden.
Ich würde gerne versuchen den Regler Modular aufzubauen. D.h. eine Platiene mit dem Atmega, einem Spannungsregler und den Anschlüssen für den Empfänger. Eine weitere oben drauf mit der Leistungselektronik und noch eine für eine weitere Platiene für Zusatzkanäle o.ä. zum erweitern.
Hat den Vorteil man kann den Regler anpassen wie man will oder aus Platzgründen im Bot verteilen. Wobei darauf zu achten ist, das die PWM Leitungen kurz bleiben müssen.
ZitatMuss man den PIN4 eigentlich anschließen? Ich denke auf dem Layout kann man ja PIN4 unter dem IC zur Kühlfäche durchverbinden.
Ich tippe drauf, dass man ihn durchverbinden muss. Hab' aber jetzt die Doku nicht genau im Kopf.
Bei meinem Layout ist er auf der Top-Seite zur Kühlfahne durchverbunden. Funktioniert.
korrektur einer meiner aussagen von weiter oben:
bei den BTN ist der RDS-ON der HIGH-Side niedriger als der LOW-Side!
Irgendwie hatte ich das anders herum (wahrscheinlich in irgendeinem alten preliminary datenblatt der BTS-Serie gelesen ) in erinnerung. mea culpa
ZitatDie ansteuerung ist so: PWM_Pin an IC1_Bein3 und IC2_Bein3 PIN1 an IC1_Bein2 PIN1 an IC2_Bein2 Also keine weiteren Logik ICs oder dergleichen. Zum bremsen wird nur der PWM Pin angestuert und zum fahren der Richtungspin und der PWM Pin zusammen.
oha... das muss ich mir erstmal auf der zunge zergehen lassen *grins*
eine kurze anmerkung dazu:
es sind nirgendwo im datenblatt schaltzeiten/verzögerungszeiten für den INH-Pin (müsste Pin3 sein, der Pin an dem du die PWM anlegst) angegeben!!!
diese art der ansteuerung halte ich nur aus diesem grund schon für "suboptimal"... (ist erstmal nur nur meine persönliche meinung)
ich bin mal auf das ergebnis mit einem "echten" motor gespannt *grins*
Ich auch allerdings habe ich erstmal Probleme mit meinen Rampen. Irgendwie verarbeitet das IC die nicht schnell genug.Mal ein Beispiel:
Super schnell LED faded ganz schnell hoch und runter:
void loop() {
analogWrite(led, brightness);
brightness = brightness + 1;
// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 brightness == 255) {
fadeAmount = -1 ;
}
delayMicroseconds(100);
}
Und das hier braucht von 0 auf 100% fast 50 Sekunden:
void loop() {
RCIN1Wert = pulseIn(Kanal1, HIGH, 20000);
analogWrite(led, x);
if (x < RCOUT1Wert)
{
x = x + fadeAmount;
delayMicroseconds(2);
}
else if (x > RCOUT1Wert)
{
x = x - fadeAmount;
delayMicroseconds(2);
}
}
Das hier macht das ganze so langsam:
RCIN1Wert = pulseIn(Kanal1, HIGH, 20000);
Warum weis ich nicht. Erhöht er deswegen die Werte erst alle 20mS?
Leider gibt es kein Multithreding
Also bleibt die Rampe der Bremse vorbehalten und die Schrittweite wird nicht 1 sein sondern 15.
Aber ich habe vllt eine Lösung gefunden. Mal sehen....
So langsam wird es unübersichtlich. Ein zweiter 24" Monitor wäre hilfreich.
Bin mit dem ersten Kanal noch nicht fertig aber es sieht vielversprechend aus. Hoffe das klappt dan auch. Die Rampenzeit beträgt jetzt 0,5 Sekunden. Heißt also von Vollgas vorwärts nach Vollgas rückwärts braucht man 1 Sekunde. Die Bremse wirkt nur im Stand und wird bei einem sofortigem Richtungswechsel übersprungen
So habe jetzt viel rumexperimentiert mit den Rampen. Ich lasse sie weg. Wenn überhaupt baue ich eine für die Bremse ein.
Grund: Die Rampen funktionieren wunderbar und das Einlesen der Empfängerimpulse klappt ganz gut. Nur beides zusammen nicht.
Die Abfrage der Empfängerimpulse dauert 20mS d.h. Empfängerwert wird eingelesen (20mS), Wert wird mit Istwert verglichen, Rampe wird einen Wert hoch oder runtergesetzt. Empfängerwert wird eingelesen (20mS), Wert wird mit Istwert verglichen, Rampe wird einen Wert hoch oder runtergesetzt. USW.
Heist um die Rampe von 0 auf 255 zu setzen, brauche ich etwa 5,1 Sekunden. Würde heißen um die Fahrtrichtung zu ändern brauche ich über 10 Sekunden. Ich habe auch ausprobiert wie das mit Zeitprioritäten funktioniert. Heist der Eingansimpuls wird nur alle 40mS eingelesen. Heißt 20mS Zeit die Rampen hoch- oder runterzufahren. Funktioniert auch ganz gut, aber nur bis zu einem Wert von ~1850µS. Also vollgasgeben ist nicht. Zudem werden die Digitalen Ports bei Richtungswechsel nicht umgeschrieben. Also totaler Schrott.
Mal eine Frage. Wie soll ich bremsen? Vorwärts, bremsen rückwärts oder vorwärts, rückwärts und nur bremsen wenn Knüppel auf 0?
Mal ne andere Frage. Wer kann mir beim designen meiner Leiterplatten helfen? Ich komme mit Eagle nicht klar. Kennt jemand ein gutes Tutorial?
ZitatHeist um die Rampe von 0 auf 255 zu setzen, brauche ich etwa 5,1 Sekunden.
Missverständnis! Die Rampe muss natürlich eine andere Zeitkonstante haben als der Empfänger-Zyklus. Also zweiten Timer dafür hernehmen, der bei jedem Schleifendurchlauf dann diesen Timer zum Verstellen der Rampenvorgabe hernimmt.
Sind also zwei unabhängige Prozesse in der Arbeitsschleife.
=> Einlesen der Empfängersignale und festlegen des Sollwertes (alle 20ms)
=> Nachführen des aktuellen Istwertes auf den Sollwert (z.B. alle 1ms um einen Änderungsstep).
Der Gag: Wenn Du zu.B. mit einer PWM von 1kHz arbeitest ergibt das eine Periodendauer von 1ms. Die Rampe also so sportlich betreiben, dass in weniger als 1ms der Sollwert geändert wird, ist zwar möglich, aber dann wird nicht mehr um 1 Step, sondern um mehrere Steps verändert. Ich denke, die allersportlichst-möglichste Rampe von "Standgas" auf "Vollgas" in 255ms hochfahren, das ist schnell genug.
ZitatWürde heißen um die Fahrtrichtung zu ändern brauche ich über 10 Sekunden. Ich habe auch ausprobiert wie das mit Zeitprioritäten funktioniert.
Bei mir wird die Rampe nur dann gefahren, wenn ich in einem Quadranten bin. Wenn also ein Richtungswechsel ansteht, wird auf die Rampe gepfiffen und gleich gebremst, bevor dann in der Gegenrichtung die Rampe hochgefahren wird.
ZitatWie soll ich bremsen? Vorwärts, bremsen rückwärts oder vorwärts, rückwärts und nur bremsen wenn Knüppel auf 0?
Meine Empfehlung, folgende Fälle zu berücksichtigen.
1)
Aktuell: Vorwärtsfahrt oder Rückwärtsfahrt. Kommando = 0/Neutralstellung : => Bremsen und Räder blockiert lassen
2)
Aktuell: Vorwärtsfahrt . Kommando = Rückwärtsfahrt : => Bremsen, dann (nach der parametrierten Bremszeit): Bremse lösen und Rückwärtsfahrt mit Rampe.
3)
Aktuell: Rückwärtsfahrt . Kommando = Vorwärtsfahrt : => Bremsen, dann (nach der parametrierten Bremszeit): Bremse lösen und Vorwärtsfahrt mit Rampe.
4)
Aktuell: Vorwärtsfahrt Kommando = 0/Neutralstellung : => Bremsen ; während dem Bremsen kommt Kommando für Vorwärtsfahrt. => Bremsen nicht zuende führen, sondern gleich mit Rampe wieder auf den Wert der Vorwärtsfahrt hochstellen.