Forum: Mikrocontroller und Digitale Elektronik BLDC Sinus AVR449 Allradantrieb Fahrrad


von Georg S. (fulgore)


Angehängte Dateien:

Lesenswert?

Hallo allerseits!

Projekt:
2 Kollegen und ich haben ein Hobbyprojekt begonnen, bei dem wir 2 
Fahrräder mit je 2 getriebelosen BLDC Motoren auszustatten.

Problem:
1.
Je nach Anschluss der Phasen läuft der Motor ausschließlich 
blockkommutiert, erreicht den Sinus nicht, läuft unter gefühlt 20km/h 
"wie ein Sack Muscheln". Ab etwa 20km/h geht das Fahrrad richtig los, 
fährt sich aber "binär" (Vollgas, oder kein Gas).
2.
Bei einer anderen Phasenkonfiguration läuft der Motor blockkommutiert 
sehr unsauber, zieht viel Strom, erreicht dann aber den Sinus, welcher 
sauber läuft, wenn etwa 50° vorher kommutiert wird (kann im Programm 
eingestellt werden). Diese Konfiguration haben wir bisher nur am 
Labornetzteil und ohne Last betrieben, da wir nicht die Mosfets 
zerstören wollen.

Details:
Wir alle wohnen derzeit in Peking und haben die Motoren ohne Datenblatt 
erworben. Folgende Größen sind uns bekannt:
3 digitale Hallgeber (120°) mit open collector
48V 1000W
Einer der Kollegen hat ein Platinenlayout entworfen, auf dem ein Attiny 
861A verbaut ist. Dort kommt das AVR Programm AVR449 "Sinusoidal driving 
of 3-phase permanent magnet motor using ATtiny261/461/861" zum Einsatz.
Details dazu gerne auf Anfrage, da ich nicht weiß, welche Informationen 
ihr braucht. Ich möchte den Thread nicht unnötig vollladen.
In der ersten Version hatten wir die Hallgeber direkt an den 
Mikrocontroller verdrahtet und den internen Pullup-Widerstand verwendet. 
Da vermuteten wir Probleme und haben ein RC-Glied verbaut (100Ohm in 
Richtung Controller und dort 2,2kOhm Pullup und 10nF Richtung GND). 
Ebenfalls probierten wir 1nF.

Dreht man zwei Motorphasen, dreht sich logischer Weise die Drehrichtung. 
Dazu muss man die äußeren Hallgeber vertauschen, damit das Programm dazu 
passt.
Ich hatte mal die verschiedenen Konfigurationen auf dem Papier 
"zusammengepuzzlet". Meines Erachtens müsste jegliche Konfiguration der 
Phase funktionieren, sofern man die Hallgeberrichtung anpasst (entweder 
H1, H2, H3, oder H3, H2, H1).

Laut Oszilloskop sehe ich keine nennenswerten Störungen auf den 
Hallsensoren (auf Seite des Microcontrollers). Es ist zumindest nichts 
im undefinierten Bereich, wo high oder low erkannt werden könnte.

Uns gehen nun leider die Ideen aus, warum manche Phasenkonfigurationen 
besser laufen, als Andere.
Am saubersten läuft der Motor blockkommutiert ohne Last, wenn man auf L1 
die grüne, auf L2 die gelbe und auf L3 die blaue Phase verdrahtet. Hall 
muss dazu ebenso konfiguriert werden und im Programm die 
Rückwärtsrichtung konfiguriert werden.

Alle Motoren verhalten sich identisch. Ich hatte testweise die Phasen 
direkt mit dem Labornetzteil bestromt und anschließend die 
Hallkonfiguration ermittelt. Folgendes Bild stellt sich dar, nachdem der 
Motor die Position erreicht hat. Dies stellt auch die Drehung in 
Richtung Vorwärts dar:

Phasen.........Hall.......hex1.hex2
.+...-....gr...ge...bl
ge..bl....0....1....1......6....3
ge..gr....0....0....1......4....1
bl..gr....1....0....1......5....5
bl..ge....1....0....0......1....4
gr..ge....1....1....0......3....6
gr..bl....0....1....0......2....2

Die Werte "hex1" und "hex2" stellen dabei die verbundenen hexadezimalen 
Werte dar, die sich aus der Binärkonfiguration der Halls ergeben. 
Jeweils in die eine Richtung, oder in die Andere.

Hier gibts die AVR449 Appliction Note:
http://www.atmel.com/Images/doc8030.pdf

Dort gibt es die Software mit einer sehr guten Beschreibung in 
HTML-Form:
http://www.atmel.com/Images/AVR449.zip


Jetzt meine Frage an euch Profis:
Habt ihr eine Idee?
Welche Informationen braucht ihr noch?

Ich entschuldige mich direkt, sollte ich etwas elementares vergessen 
haben!

Vorab vielen Dank!
Gruß
Georg

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Der Code ist nahezu identisch mit AVR447, mit dem ich mich einige Monate 
beschäftigt habe. Entscheidend und nicht immer identisch sind die 
Sequenzen der Spulen und der Hallsensoren, sprich, es ist nicht gesagt, 
das die Sequenzen in 'expectedHallSequenceForward' und 
'expectedHallSequenceReverse' dem entspricht, was eure Motoren 
tatsächlich liefern. Wenn das der Fall ist, wird der Motor nie 
synchronisiert und läuft im Blockmode.

Apropos Blockmode, der ja zum Anlaufen immer benutzt wird: Der muss 
erstmal sauber laufen, sonst hat es keinen Sinn, auf Sinus umzuschalten. 
Für AVR447 habe ich eine Terminalumgebung mit eingebaut, um mir 
Variable, Ports und andere Werte auf den PC zu senden, und Parameter von 
da aus zu ändern. Da ich es hier mit 5 oder 6 verschiedenen Maschinen zu 
tun hatte, war das unbedingt notwendig.
Im Blockmode ist es hilfreich, sich mit den Vor- und Nacheil Parametern 
herumzuschlagen. Es gibt einen gewissen Bereich, indem der Motor zügig, 
kräftig und leise läuft, das gibt einen Hinweis auf die Beziehung 
zwischen Hallsensor Sektor und Spulensektor, die sich bei den Motoren 
teilweise krass unterscheidet.
Mir hat besonders geholfen, die Sektoren mal aufzuzeichnen und sich 
dabei zu überlegen, bei welchem Hallzustand welche Spulen bestromt 
werden müssen. Man muss daran denken, das es ja die folgende (für 
vorwärts) Kombination ist, sonst steht der Motor auf der Stelle. Für 
Rückwärtslauf (der ist für euch nicht wichtig) müsste es die vorige 
sein.

Also: Software in Blockmodus halten und damit erstmal den Motor zum 
ruhigen Lauf bringen. Dann erst mit Sinus anfangen.

Ansonsten ist zumindest AVR447 sehr brauchbar. Ich habe damit vom 
Präzisionsmotor eines Plattenspielers bis zur 48V/8kW Maschine 
laufruhige und bestens steuerbare Motoren erreicht. Die Tabellen in 
PMSM_Tables wurden dabei mit defines zwischen den Motoren umgeschaltet.

Ach, noch was. Die Beschaltung der Hallsensoren hat sich als trickig 
herausgestellt. Ich habe schliesslich die Beschaltung aus einem anderen 
Motorcontroller kopiert:
1
Sensor     Diode
2
O-----+----|<|------O MC
3
      |
4
      -
5
     | | Pullup
6
     | | 1k
7
      -
8
      |
9
+5o---+
Das war deswegen nötig, weil die Hallsensoren direkt in die Spulen 
eingebettet waren und deswegen gerade bei Sinusansteuerung immer wieder 
durch deren Magnetfeld gestört wurden und positive Peaks auf dem Ausgang 
hatten. Dioden sind normale 1N4148 o.ä.
Bei den grossen Motoren gibts noch einen 2n2 Kondensator vom 
Sensorausgang nach Masse.

: Bearbeitet durch User
von Georg S. (fulgore)


Lesenswert?

Vielen Dank für die zügige und detailreiche Antwort!

Matthias Sch. schrieb:
> Entscheidend und nicht immer identisch sind die
> Sequenzen der Spulen und der Hallsensoren, sprich, es ist nicht gesagt,
> das die Sequenzen in 'expectedHallSequenceForward' und
> 'expectedHallSequenceReverse' dem entspricht, was eure Motoren
> tatsächlich liefern. Wenn das der Fall ist, wird der Motor nie
> synchronisiert und läuft im Blockmode.
Diese Situation stellt sich bei uns auch so dar, wenn wir die Phasen wie 
in meinem Post unter Punkt 1 verdrahten. Ich vermute dort Störungen auf 
den Halls. Deswegen der Tiefpassfilter. Dies half leider nicht.

Matthias Sch. schrieb:
> Im Blockmode ist es hilfreich, sich mit den Vor- und Nacheil Parametern
> herumzuschlagen. Es gibt einen gewissen Bereich, indem der Motor zügig,
> kräftig und leise läuft, das gibt einen Hinweis auf die Beziehung
> zwischen Hallsensor Sektor und Spulensektor, die sich bei den Motoren
> teilweise krass unterscheidet.
Diesen Voreilparameter kenne ich aus dem AVR449 nur für den Sinus. Hier 
kann ich in 1,8x° Schritten einstellen, wie weit er "vorkommutieren" 
soll. Beim Block kenne ich die Parameter nicht. Hier wird beim AVR449 
direkt beim Hall-Interrupt eine neue Phasenkonfiguration geschaltet. 
Hast du da ggf. eine Variable vom AVR447, die ich mir dazu ansehen kann?

Matthias Sch. schrieb:
> Mir hat besonders geholfen, die Sektoren mal aufzuzeichnen und sich
> dabei zu überlegen, bei welchem Hallzustand welche Spulen bestromt
> werden müssen. Man muss daran denken, das es ja die folgende (für
> vorwärts) Kombination ist, sonst steht der Motor auf der Stelle. Für
> Rückwärtslauf (der ist für euch nicht wichtig) müsste es die vorige
> sein.
Ja, das habe ich ebenfalls schon gemacht. Ich habe die Phasen mittels 
Labornetzteil bestromt und bei Bestromung und Erreichen des "Ziels" die 
Hallgeber ausgewertet (natürlich mit Pullup). Dabei konnte ich 
herausfinden, wie die Phasen bestromt werden müssen, um den nächsten 
Schritt (vorwärts bzw. rückwärts) zu erreichen. Dreht mal logisch zwei 
Phasen, müssen die Halls H1 und H3 vertauscht werden. Meiner Meinung 
nach, korrigiere mich, wenn ich mich irre, müsste der Motor dann wieder 
laufen. Das tut er auch, jedoch je nach Phasenkonfig manchmal besser, 
manchmal schlechter. Warum das so ist, ist mir bis dato schleierhaft.

Matthias Sch. schrieb:
> Also: Software in Blockmodus halten und damit erstmal den Motor zum
> ruhigen Lauf bringen. Dann erst mit Sinus anfangen.
Unter Last sind wir erst einmal gefahren. Sinus war zu der Zeit 
verhindert. Da hatten wir die Hallgeber allerdings direkt verdrahtet und 
sie waren nicht entstört. Er lief zu dem Zeitpunkt wie ein Sack 
Muscheln. Erst bei größeren Geschwindigkeiten lief er relativ sauber. 
Das steht sicher im Zusammenhang mit den nicht entstörten Halls und dem 
relativ großen µC-internen Pullup.

Matthias Sch. schrieb:
> Ach, noch was. Die Beschaltung der Hallsensoren hat sich als trickig
> herausgestellt. Ich habe schliesslich die Beschaltung aus einem anderen
> Motorcontroller kopiert:
>
1
> Sensor     Diode
2
> O-----+----|<|------O MC
3
>       |
4
>       -
5
>      | | Pullup
6
>      | | 1k
7
>       -
8
>       |
9
> +5o---+
10
>
> Das war deswegen nötig, weil die Hallsensoren direkt in die Spulen
> eingebettet waren und deswegen gerade bei Sinusansteuerung immer wieder
> durch deren Magnetfeld gestört wurden und positive Peaks auf dem Ausgang
> hatten. Dioden sind normale 1N4148 o.ä.
> Bei den grossen Motoren gibts noch einen 2n2 Kondensator vom
> Sensorausgang nach Masse.
Sehr guter Hinweis. Ich gehe davon aus, dass du weiterhin die internen 
Pullups verwendet hast, andernfalls hätte man ja m.E. nie den Zustand 
high erreicht.
Ich wundere mich jedoch, warum ich auf dem Oszi keine nennenswerten 
Störungen sehe (siehe angehängte Fotos aus dem ersten Post). Ich könnte 
mir nur vorstellen, dass durch die hohe Taktfrequenz der PWR-Ausgänge 
Peaks da sein könnten, die ich auf unserem Oszi nicht sehen kann. Das 
hätte aber doch dann der Kondensator in unserer Entstörung auf ein 
erträgliches Maß reduzieren sollen. Sehe ich das falsch?

Bei 1kOhm Pullups habe ich etwas Bauchschmerzen, was unsere Hallgeber 
anbelangt. Ich weiß nicht, wie viel Strom diese "Chinahallgeber" 
vertragen. 5mA ist schon eine Hausnummer, wie ich finde. Ich spiele mit 
dem Gedanken, dort 2,2kOhm einzusetzen, die Diode wie in deinem Beispiel 
zu verwenden und zusätzlich noch einen 1nF Kondensator zu verwenden. Was 
sagst du dazu?

Vielen Dank nochmal für die klasse Hinweise!

von Harald W. (wilhelms)


Lesenswert?

Georg S. schrieb:

> Dreht man zwei Motorphasen, dreht sich logischer Weise die Drehrichtung.
> Dazu muss man die äußeren Hallgeber vertauschen, damit das Programm dazu
> passt.

Interessant. Ein Fahrrad mit Rückwärtsgang ist wirklich mal
eine völlig neue Idee!

von Georg S. (fulgore)


Lesenswert?

Harald Wilhelms schrieb:
> Interessant. Ein Fahrrad mit Rückwärtsgang ist wirklich mal
> eine völlig neue Idee!

Natürlich kann man im Programm dann die Drehrichtung ebenfalls ändern, 
sodass das Rad wieder vorwärts fährt. ;-)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Um die Abfrage der Hallsensoren zu verbessern, habe ich ein etwas 
komplizierteres Verfahren benutzt als in AVR449 und 447.
In der ISR wird einige µs nach dem Auslösen nochmal eingelesen und 
geschaut, ob es auch wirklich eine neue Sensorstellung ist, ansonsten 
wird verworfen und die ISR verlassen. Das war sehr hilfreich bei 
Störungen auf den Hallsensoren, vor allem kurze Spikes. Falls gültig, 
speicherte ich diesen neuen Wert, um ihn im nächsten Zyklus als 
Vergleich zu haben.

Georg S. schrieb:
> Ich gehe davon aus, dass du weiterhin die internen
> Pullups verwendet hast, andernfalls hätte man ja m.E. nie den Zustand
> high erreicht.

Jo.

> Ich weiß nicht, wie viel Strom diese "Chinahallgeber"
> vertragen. 5mA ist schon eine Hausnummer, wie ich finde.

Damit muss man experimentieren. Ich hatte hier 6kW Chinamotore, bei 
denen die Phasenleitungen direkt parallel mit den Hallsensorkabeln 
liefen - und das über einen Meter. Kräftige Pullups haben da geholfen 
und hat den Sensoren nicht geschadet.
Ich habe viel mit den Tabellen experimentiert. Unter anderen bin ich 
auch Schritt für Schritt die 'blockCommutationTableForward' 
durchgegangen und habe dabei den Motor von Hand zum nächsten Sektor 
bewegt und dabei mit wenig PWM geschaut, ob er noch in die richtige 
Richtung zieht. Es stellte sich heraus, das jeder meiner Motore da etwas 
anders war.

: Bearbeitet durch User
von Georg S. (fulgore)


Lesenswert?

Matthias Sch. schrieb:
> Um die Abfrage der Hallsensoren zu verbessern, habe ich ein etwas
> komplizierteres Verfahren benutzt als in AVR449 und 447.
> In der ISR wird einige µs nach dem Auslösen nochmal eingelesen und
> geschaut, ob es auch wirklich eine neue Sensorstellung ist, ansonsten
> wird verworfen und die ISR verlassen.

Hallo Matthias,
wäre es okay für dich, mir diesen Codeabschnitt zur Verfügung zu 
stellen? Ich werde vermutlich erst übernächstes Wochenende wieder zum 
Testen kommen, da ich momentan beruflich arg eingespannt bin. Dann wären 
alle Hinweise hilfreich. Vielen Dank schonmal!

Gruß
Georg

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> wäre es okay für dich, mir diesen Codeabschnitt zur Verfügung zu
> stellen?

Das ist aber nichts besonderes:
1
volatile uint8_t lastHall;
2
ISR(PCINT1_vect)
3
{
4
  uint8_t hall = GetHall();
5
// spurious trap - this routine should only be fired if we have a 
6
// real sensor change not a spurious injection. 
7
  if (lastHall != hall ) {
8
    MotorSynchronizedUpdate();
9
//  and so on until
10
//  end of ISR
11
    lastHall = hall;
12
  } 
13
}

: Bearbeitet durch User
von komisch (Gast)


Lesenswert?

Ahoi Peking,

ihr seid schon bisschen lustig. Fiese E-Bikes zusammenlöten, Block-Kommu 
usw. - fehlt nur noch die Raumzeigermodulation aber keine nicht 
blockierende Warteschleife programmmieren können? Irgendwie passt das 
nicht...

Mal ein Denkansatz:

Du bist in einer ISR (voll abgespaceter asm DJ an den Discs)
und kriegst gerade keine Luft. Voll Stickig hier in dem Zappelbunker.
Nimmst du diesen Zustand hin, oder nicht? genau:

1. Nehm ich nicht hin:
-Erstmal draußen die Weiber abchecken, kucken was da so läuft :D
-Aber vorher Kumpel sagen, "Mustafa, muss gleich wieder rein, so in 5 
min...) Kumpel: "Ok, in 5 min sag ich dir bescheid, feier in der Zeit 
weiter, schauen wir ob das Klima dann besser ist."

1. Nehm ich hin:
Ich quäle mich gerne, warte, und warte und warte, nichts tuend, nichts 
leistend...

Ich hoffe der Unterschied ist klar?

Du brauchst um eine bestimmte Zeit abzuwarten, ohne dabei blockierend 
den Rest des Programms aufzuhalten einen tata: Timer. Hast du noch 
welche frei? Viele haben mehrere Compare-Register...somit lassen sich 
mit einem Timer mehrere unterschiedliche Zeitintervallereignisse 
generieren, auf die man in den ISR reagieren kann...

Gruß J

von PeterZ (Gast)


Lesenswert?

Hallo,

ich habe den gleichen Motor in meinem Rad. den habe ich aber zusammen 
mit dem Controller gekauft. 48V 1000W

Der Motor läuft sehr sauber auch bei langsamen Drehzahlen.

Glaube das hilft die nicht viel weiter. Hast du einen Fahrrad Controller 
an dem du die Ansteuerung evtl. Rausmessen kannst?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

komisch schrieb:
> fehlt nur noch die Raumzeigermodulation aber keine nicht
> blockierende Warteschleife programmmieren können?

> somit lassen sich
> mit einem Timer mehrere unterschiedliche Zeitintervallereignisse
> generieren, auf die man in den ISR reagieren kann..
Du hast offensichlich nicht kapiert, das die Jungs da AVR449 am Laufen 
haben. Vllt. solltest du dich entweder darüber belesen oder einfach mal 
nichts absondern.

PeterZ schrieb:
> Hast du einen Fahrrad Controller
> an dem du die Ansteuerung evtl. Rausmessen kannst?

Wäre das Optimum und ich habe das bei meinen AVR447 Derivaten mit den 
fetten E-Bike Maschinen hier auch machen können.
Diese Kontroller konnten nur Block, aber es war sehr hilfreich, das 
Phasenschema und die Hallsensoren in ein Diagramm zu zeichnen. 
Zusätzlich habe ich an einem DirectDrive Plattenspielermotor (Pioneer 
Precision) einiges gelernt und in die Software einfliessen lassen.

von Georg S. (fulgore)


Lesenswert?

@J:
Der Beitrag liest sich, wie im "Zappelbunker" verfasst. ;-)
Wenn ich ein definiertes Delay haben wollte, vermute ich, bräuchte ich 
einen Scheduler. Das sprengt etwas den Rahmen.

@Matthias Sch.:
Eine Plausibelisierung wie aus deinem Programmcodeabschnitt ist im 
AVR449-Programm bereits vorhanden.
1
  hall = GetHall();
2
  //Make sure that the hall sensors really changed.
3
  if (hall == lastHall)
4
  {
5
    return;
6
  }
7
  MotorSynchronizedUpdate();
Im Prinzip bricht das den Trigger Interrupt ja nur ab. Erneut eingelesen 
werden die Hallgeber da ja nicht. Habe ich da ggf. etwas falsch 
verstanden?
Ich könnte eventuell die Hallgeber einfach ein weiteres Mal einlesen.

@PeterZ:
Das originale Steuergerät gibt es. Das ist allerdings gerade im 
Seecontainer von China in Richtung Deutschland unterwegs. Mein Kollege 
in Deutschland hat auch das bessere Oszilloskop. Er kann sich das in ein 
paar Monaten mal ansehen.

Derweil werde ich bei nächster Gelegenheit die Tipps und Hinweise 
umsetzen und mich wieder melden.

Vielen Dank nochmal.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> Ich könnte eventuell die Hallgeber einfach ein weiteres Mal einlesen.

Ich seh gerade, das ich auf dem Rechner hier nur ältere Versionen habe, 
in der Werkstatt ists aktueller. Im Prinzip ist es aber genau das:

Georg S. schrieb:
> Ich könnte eventuell die Hallgeber einfach ein weiteres Mal einlesen.

Ist also:
1. Check auf neuen Sektor ok, dann 2. Check nach ein paar dutzend µs, 
wenn eines der beiden durchfällt, ISR verlassen.

: Bearbeitet durch User
von komisch (Gast)


Lesenswert?

>Ich könnte eventuell die Hallgeber einfach ein weiteres Mal einlesen.

Ja, genau zur Entprellung.

>1. Check auf neuen Sektor ok, dann 2. Check nach ein paar dutzend µs,
>wenn eines der beiden durchfällt, ISR verlassen.

Wenn die paar dutzend µs dein restliches System nicht aus dem Tritt 
bringen, reicht ein einfaches delay_us() zwischen dem 1. und 2. Check, 
ansonsten halt mit Timer(Das als Scheduling zu bezeichnen versteh ich 
ehrlich gesagt nicht).

Gruß J

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

komisch schrieb:
> Wenn die paar dutzend µs dein restliches System nicht aus dem Tritt
> bringen,

Das sollte bei einem Fahrrad kein Problem sein. Mein 6kW Motor hat 39 
Pole und ist für ein Auto gedacht. Die Höchstgeschwindigkeit mit 48V 
liegt etwa bei 130km/h, der Radumfang bei 1,5 m.
Bei max. Geschwindigkeit dreht sich das Rad 24 mal in der Sekunde. Dann 
bleibt für jeden Pol immer noch  mehr als 1 ms - viel Zeit für einen MC 
der 16MHz Klasse.

Bei mir läuft noch der ADC Interrupt als non-blocking, der Hallinterrupt 
hat die höchste Priorität.

: Bearbeitet durch User
von Georg S. (fulgore)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

morgen geht es vorrausichtlich weiter. Bis dahin habe ich mir nochmal 
die Ansteuerung verinnerlicht. Dazu habe ich mal das Dokument 
Hallpuzzle.ods angehängt.

Erklärung:
Ganz oben habe ich Schritte 1 bis 6 (2 Mal hintereinandern wegen der 
Übersichtlichkeit) definiert.
Im Feld B14 steht "Messung nach Erreichen der Position". Das heißt ich 
habe eine logische Vorwärtsrichtung durch Ansteuerung der jeweiligen 
Phasen nach Farbe über das Labornetzteil erzeugt. Erst nach Erreichen 
der Position, habe ich die Hallgeber gemessen.

Da ich wie geschrieben erst nach Erreichen der Position gemessen habe, 
muss bei der jeweiligen Hallkonfiguration also folglich der nächste 
Schritt angesteuert werden. Zu sehen in Zeile 16/17. So muss es sein, 
dass es elektrische 60° Schritte weiter wandert.

In den Zeilen 18 bis 25 Habe ich mal für die beiden gültigen Hallkonfigs 
(Hall A =bl, ge, gr oder Hall B= gr, ge, bl) und beide möglichen 
Richtungen im Programm die jeweilige Ansteuerung vermerkt. Wenn wir 
davon ausgehen, dass Zeile 16 und 17 korrekt sind und ich keinen 
Denkfehler habe, dann gibt es von 4 Möglichkeiten (Hall A  B  
vorw/rückw) nur 2 funktionierende. Diese habe ich farblich definiert, 
damit ich das verstehe.

Zeilen 26-29 stellen unsere erste gangbare Konfiguration dar 
(ausschließlich Block). U war grün, V war gelb und W war blau. Wir 
hatten das Programm rückwärts laufen lassen. Damit wissen wir nun auch, 
dass die Hallkonfig gr/ge/bl, die wir hatten, ebenfalls der von mir 
"Hall B" genannten Konfiguration entspricht. Wir sehen, dass wenn meine 
Logik passt, die Phasen im Prinzip elektrisch 60° zu früh angesteuert 
wurden.

Zeilen 30-33 zeigen meine funktionierende Sinuskonfig, wo der Block wie 
ein Sack Muscheln lief. Ansteuerung war ebenfalls Rückwärts im Programm. 
Um die besten Werte im Sinus zu erreichen, musste ich das Programm etwa 
32° vorkommutieren lassen.
Bei den 32° "Frühzündung" muss man sich ja in den Zeilen 30/31 alles ein 
halbes Kästchen weiter links vorstellen. Das lasse ich mir eingestehen. 
Aber warum läuft der Block unsauber?

Klar, ich könnte jetzt passend zum "sauberen" Sinus den Block im 
Programm einfach anpassen. Aber sicherlich ist das Programm soweit 
korrekt.


Wenn noch jemand sinnvolle Hinweise basierend auf der Tabelle hat, bitte 
gerne posten. Ansonsten werde ich mich voraussichtlich morgen/übermorgen 
wieder melden und unsere Erkenntnisse kundtun.

Schönen Sonntag noch!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Angehängte Dateien:

Lesenswert?

Georg S. schrieb:
> Dazu habe ich mal das Dokument
> Hallpuzzle.ods angehängt.

Ja schade eigentlich. Ich kann mit diesem Format überhaupt nichts 
anfangen. Stattdessen habe ich dir mal die Grafik aus AVR447 angeheftet, 
die eigentlich alles erklärt. Wohlgemerkt bezieht sich das auf das MC100 
Motorkit von Atmel.
Bei Hallsensorkombi '3' (erster Sektor im Bild) werden im Blockmodus UH 
und VL angesteuert. Es geht weiter mit Kombi '2', mit UH und WL. Sodann 
Kombi '6' mit VH und WL. '4' schaltet VH und UL. Du siehst langsam das 
System. Immer die an- und abfallenden Phasen des folgenden Sektors 
werden auf 'offen' geschaltet und die auf high und low liegenden Phasen 
auf H resp. L.

So, jetzt musst du das auf die Sinuserzeugung anpassen, damit der 
Sektorstart mit den Hallsensoren übereinstimmt. Das machst du in der *.h 
mit den Tabellen:
1
const PROGMEM uint16_t CSOffsetsForward[8] =
2
{
3
  0,
4
  4 * (SINE_TABLE_LENGTH / 6),
5
  2 * (SINE_TABLE_LENGTH / 6),
6
  3 * (SINE_TABLE_LENGTH / 6),
7
  0 * (SINE_TABLE_LENGTH / 6),
8
  5 * (SINE_TABLE_LENGTH / 6),
9
  1 * (SINE_TABLE_LENGTH / 6),
10
  0
11
};
Auch hier steht ganz vorne die um 1 verminderte Hallsensorkombination. 
Beachte, das ist aus meinem Projekt mit dem dicken Motor, deine Nummern 
können anders sein.

Georg S. schrieb:
> musste ich das Programm etwa
> 32° vorkommutieren lassen.

Das ist von Motor zu Motor sehr unterschiedlich, hängt u.A. auch von der 
Polzahl ab. Ich habe recht kleine Werte und stelle die Advance Parameter 
für Vor- und Rückwärtslauf getrennt ein. Bei optimaler Einstellung läuft 
der Motor so gut wie lautlos und sehr sauber.

: Bearbeitet durch User
von Georg S. (fulgore)


Angehängte Dateien:

Lesenswert?

Ups, das mit dem Format ist schade. Jetzt nochmal als PDF.

Den Sinus hatte ich bisher nicht angefasst und im AVR449 gibt es nur 
einen Advanced Commutating Factor. Das ist mir soweit auch Recht, da das 
Fahrrad ohnehin nur in eine Richtung fahren soll.
Das AVR447 Programm scheint ein kleines bisschen cleverer aufgebaut zu 
sein.

Hier die Pointerzuordnung aus dem AVR449 zum Block:
1
uint8_t __flash const blockCommutationTableForward[8] =
2
{
3
  0x00,
4
  ((1 << WH_OCOE) | (1 << UL_OCOE)),
5
  ((1 << UH_OCOE) | (1 << VL_OCOE)),
6
  ((1 << WH_OCOE) | (1 << VL_OCOE)),
7
  ((1 << VH_OCOE) | (1 << WL_OCOE)),
8
  ((1 << VH_OCOE) | (1 << UL_OCOE)),
9
  ((1 << UH_OCOE) | (1 << WL_OCOE)),
10
  0x00
11
};
12
13
uint8_t __flash const blockCommutationTableReverse[8] =
14
{
15
  0x00,
16
  ((1 << UH_OCOE) | (1 << WL_OCOE)),
17
  ((1 << VH_OCOE) | (1 << UL_OCOE)),
18
  ((1 << VH_OCOE) | (1 << WL_OCOE)),
19
  ((1 << WH_OCOE) | (1 << VL_OCOE)),
20
  ((1 << UH_OCOE) | (1 << VL_OCOE)),
21
  ((1 << WH_OCOE) | (1 << UL_OCOE)),
22
  0x00
23
};

Und zum Sinus:
1
__flash const uint16_t CSOffsetsForward[8] =
2
{
3
  0,
4
  5 * (SINE_TABLE_LENGTH / 6),
5
  1 * (SINE_TABLE_LENGTH / 6),
6
  0 * (SINE_TABLE_LENGTH / 6),
7
  3 * (SINE_TABLE_LENGTH / 6),
8
  4 * (SINE_TABLE_LENGTH / 6),
9
  2 * (SINE_TABLE_LENGTH / 6),
10
  0
11
};
12
13
__flash const uint16_t CSOffsetsReverse[8] =
14
{
15
  0,
16
  1 * (SINE_TABLE_LENGTH / 6),
17
  5 * (SINE_TABLE_LENGTH / 6),
18
  0 * (SINE_TABLE_LENGTH / 6),
19
  3 * (SINE_TABLE_LENGTH / 6),
20
  2 * (SINE_TABLE_LENGTH / 6),
21
  4 * (SINE_TABLE_LENGTH / 6),
22
  0
23
};

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
1
> {
2
>   0x00,
3
>   ((1 << WH_OCOE) | (1 << UL_OCOE)),     // 1
4
>   ((1 << UH_OCOE) | (1 << VL_OCOE)),     // 2
5
>   ((1 << WH_OCOE) | (1 << VL_OCOE)),     // 3
6
>   ((1 << VH_OCOE) | (1 << WL_OCOE)),     // 4
7
>   ((1 << VH_OCOE) | (1 << UL_OCOE)),     // 5
8
>   ((1 << UH_OCOE) | (1 << WL_OCOE)),     // 6
9
>   0x00
10
> };
Denk dir dahinter immer die jeweilige Hallkombination, habs mal 
angedeutet.
Jetzt vergleichst du, ob das Schema der Hallabfolge auch so ist, das 
jeweils nur eine Phase geändert wird, wenn du das Schema durchläufst. 
Jede Phase wird während 2 Sektoren gehalten, und nur eine von Sektor zu 
Sektor umgeschaltet.
Wenn man davon ausgeht, könnte also die 'ExpectedHallSequence' sein:
2, 6, 4, 5, 1, 3   dann schliesst sich der Kreis wieder. Wie schon 
gesagt, muss das bei deinem Motor nicht passen. Es gibt einfach zu viele 
Möglichkeiten mit den drei Hallsensoren und den drei Phasen, als das das 
auf Anhieb klappen muss. Richte also erstmal die Blockkommutation so 
ein, das das alles stimmt und benutze dann die Grafik aus AVR447, um die 
SinusOffsets einzutragen.
Ich habe mir für meine verschiedenen Motoren das aufgezeichnet, während 
ich auf der seriellen Konsole mir die Hallkombis anschaute und ganz 
leicht Zug auf die Spulen gebracht habe. Schon mit Block muss der Motor 
sauber von Sektor zu Sektor ziehen und nicht ruckeln oder gar 
zwischendurch rückwärts wollen oder festhängen.

Georg S. schrieb:
> und im AVR449 gibt es nur
> einen Advanced Commutating Factor.

Ja, ich habe mittlerweile soviel an AVR447 geändert, das das fast schon 
eine Neuentwicklung ist :-) Da das für Auto sein soll, musste ich 
einfach auch den Rückwärts Faktor einführen, da der Motor sonst nicht 
schön läuft.
Mittlerweile läuft das auch nicht mehr auf einem Mega, sondern auf einem 
XMega und einem STM32, um die Wahl und vor allem Rechenleistung zu 
haben. Die ganze Schaltung ist mittlerweile mehr mit Überprüfungen 
beschäftigt als mit der Motorsteuerung - ist ja sicherheitsrelevant.

: Bearbeitet durch User
von Georg S. (fulgore)


Lesenswert?

So, ich kann eine Erfolgsnachricht verkünden. Danke nochmal für die 
Unterstützung.

Folgendes haben wir gemacht:
Blockkommutieren passiert jetzt 60° weiter in der Zukunft, als der Logik 
entsprechend. Das haben wir im Programm angepasst. Damit läuft der Block 
halbwegs sauber. Unter realer Last (abgesehen vom Einbremsen) haben wir 
das jedoch nicht getestet.
Weiterhin ist der advance commutation factor für den Sinus bei 32. Was 
bei etwa 1,8° pro Ganzzahl etwa 58° ausmacht.

Warum es so besser funktioniert, ist etwas eigenartig.
Wichtig ist, es läuft.

Gibt es noch eine Möglichkeit, die elektrische Bremse zu deaktivieren? 
Im Programm ist schon mode-coasting vorgewählt. Beim Block wird auch 
sauber die Last abgeworfen beim "vom Gas gehen". Beim Sinus wird jedoch 
elektrisch gebremst.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> Beim Block wird auch
> sauber die Last abgeworfen beim "vom Gas gehen". Beim Sinus wird jedoch
> elektrisch gebremst.

Das bereitete mir auch einiges Kopfzerbrechen, denn Coasting ist im 
Sinusmodus nicht vorgesehen. Die Strategie, wann man Coasting 
(DisablePWMOutputs()) einsetzt, muss mit dem 'Gasgriff' zusammenarbeiten 
und erfordert ein wenig Messen und Plausibilitätsprüfungen.
Dazu kannst du z.B. den PID Regler missbrauchen. Wenn der Motor im 
Sinusmodus ist, und der PID eine niedrigere Drehzahl fordert, als der 
Motor derzeit hat, könntest du Coasting aktivieren - nur mal als Idee.

Georg S. schrieb:
> Weiterhin ist der advance commutation factor für den Sinus bei 32. Was
> bei etwa 1,8° pro Ganzzahl etwa 58° ausmacht.

Das sollte dich stutzig machen, denn das ist fast genau ein ganzer 
Sektor. Es scheint, als ob du die o.a. CSOffsets genau um eins versetzt 
benutzt.

von Georg S. (fulgore)


Lesenswert?

Ja, das macht mich auch stutzig.

Zum Ausmessen der Hallsensoren und der passenden Schritte der Motoren, 
habe ich die Phasen per Labornetzteil angesteuert und nach Erreichen der 
Endposition die Hallsensoren gemessen. Dies Schritt für Schritt.
Gemäß meiner Logik müsste ich also den nächsten 60° Schritt ansteuern, 
damit der Motor sauber läuft. Er läuft aber nur sauber, wenn man 120° 
weiter ansteuert, als man eigentlich ist.

Soweit erstmal kein Problem. Damit läuft er im Block halbwegs rund. 
Störungen unter last hatte ich, als ich keinen Tiefpassfilter an den 
Hallkanälen hatte. Das mag daran gelegen haben.

Nun habe ich den Sinus allerdings nur erreicht, wenn die die Phasen in 
einer bestimmten Reihenfolge angeschlossen habe. (Also sauberes Erkennen 
der richtigen Richtung, testweise über 240 Schritte, eingestellt über 
den commutation counter, oder wie es im Programm heißt)

Naja, nun läuft es ja und Block und Sinus hängen logisch auf der etwa 
gleichen Position.

Danke auch für den Tipp mit dem Regler.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> Störungen unter last hatte ich, als ich keinen Tiefpassfilter an den
> Hallkanälen hatte. Das mag daran gelegen haben.

Das Merkwürdige bei unseren dicken Maschinen war, das Störungen im 
Blockmodus so gut wie nicht vorkamen, im Sinusmodus aber verstärkt 
auftraten.
Das liegt dummerweise an der Konstruktion der Motoren, bei denen die 
Sensoren direkt in die Anker eingelassen sind, und keine Schirmung nach 
hinten haben. Die messen eben nicht nur die Magneten des Rotors, sondern 
auch die Magnetisierung der Spulen.

von Georg S. (fulgore)


Lesenswert?

So, nochmal ein kleines Update.
Die Mosfets, die 120V und 180A Dauerstrom, sowei 750A Peak aushalten, 
werden sehr heiß. Ich bin ca. einen Kilometer mit Traktion und Bremse 
herumgefahren und sie waren heiß. Anschließend bin ich nur mit Traktion 
herumgefahren und habe beim Bremsen immer die Last abgeworfen (Notaus). 
Durch den chinesischen Straßenverkehr hatte ich allerdings dadurch nicht 
besonders viele Beschleunigungsfahrten und die Mosfets wurden nur "recht 
warm". Ich bin dann zuletzt eine kleine Rampe mit Bremse und Vollgas bei 
niedriger Geschwindigkeit hochgefahren, Das war eine dumme Idee, denn 
die Mosfets wurden unglaublich heiß. Schätzungsweise waren sie kurz vorm 
Hitzetod.
Jetzt bin ich mir unschlüssig, wie ich weiter mache.

Folgende Dinge möchte ich noch testen:
- Blockkommutiert hart beschleunigen (natürlich nicht die Rampe hoch mit 
Bremse...) und die Temperatur beobachten
- Mit dem advanced commutation factor herumspielen. Derzeit bin ich bei 
-3° (da meine Phasen 60° voreilend angeschlossen sind und ich 57° 
"vorkommutiere").

@Matthias Sch.:
Würdest du mir ggf. deine Advanced commutation factors zukommen lassen?
Ich vermute, dass keiner deiner Werte im negativen Bereich ist (geht ja 
auch nur durch meinen "Trick") und du vielleicht sogar weiter 
vorkommutierst.

Meinen Wert von -3° hatte ich durch testen ermittelt. Bei dieser 
Einstellung, plus minus einige Schritte, erreichte ich ohne Last die 
größte Geschwindigkeit.

Über weitere Vorschläge bin ich natürlich auch dankbar!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> Ich bin ca. einen Kilometer mit Traktion und Bremse
> herumgefahren und sie waren heiß.

Check bitte mal, ob deine Totzeiten alle im sicheren Bereich sind. Im 
Leerlauf sollten die MOSFets kein bisschen warm werden, und im Betrieb 
auf einigermassen anständigen Kühlkörpern nur wenig. Entweder haben sie 
zu viel RDSon oder du steuerst sie zu lasch an, korrekte Totzeiten 
vorausgesetzt.

Georg S. schrieb:
> Würdest du mir ggf. deine Advanced commutation factors zukommen lassen?

Erm, die sind im EEPROM der Steuerung, muss ich erstmal nachschauen, 
kann ne Weile dauern.

> Ich vermute, dass keiner deiner Werte im negativen Bereich ist
Nee, sind sie natürlich nicht. Ich habe mir reichlich Zeit genommen, das 
System mit den Sektoren und der Sinusmodulation zu verstehen und dann 
mit den vorhandenen verschiedenen Motoren experimentiert. Mein Ziel war 
es, erstmal mit 0° Advance bzw. Reverse auszukommen, denn dabei muss der 
Motor schon laufen, wenn auch etwas lauter, als bei optimaler Advance 
Kommutierung. Das Einstellen davon war dann nur noch Feinjustage auf 
geringstes Laufgeräusch. So läuft auch die grosse Maschine völlig 
lautlos.
Das Umschalten von Block auf Sinus muss auch ruckfrei vor sich gehen, 
sonst stimmt was grundsätzliches nicht.

von Georg S. (fulgore)


Angehängte Dateien:

Lesenswert?

Gestern habe ich mal einen Versuch ausschließlich mit Blockkommutierung 
gewagt.
Wie sich herausstellte, läuft das nun auch sauber. Das anfängliche 
Fahrproblem bestand damit wohl ausschließlich an dem fehlenden 
Tiefpassfilter in den Hallkanälen. Das Thema ist damit für mich 
abgeschlossen.

Jedoch werden die Mosfets und Zwischenkreiskondensatoren auch im 
Blockbetrieb heiß. Somit scheint das Problem grundlegender Natur zu 
sein.

Der Kollege, der die Hardware ausgelegt hat, ist leider wieder in 
Deutschland und hat da derzeit einigen Umzugsstress. Deswegen probiere 
ich mal zum relevanten Teil der Platine eine Aussage zu treffen:
Als Halbbrückentreiber kommen IR2110S zum Einsatz.
Die Mosfets sind IPB036N12N3G. Der Kühlkörper ist ausschließlich die 
Leiterbahnfläche der Platine. Bei den Gatewiderständen handelt es sich 
auf dem Layout um 2 Mal 18 Ohm parallel, also 9 Ohm. Derzeit haben wir 
jedoch nur einen verbaut, somit 18 Ohm. Das kann man au fdem Screenshot 
nicht richtig erkennen.

Anbei sind die Ausschnittes des Platinenlayouts von den Treibern, den 
Mosfets, dann noch ein Screenshot vom Eagle layout und ein Foto vom 
Laden und Entladen des Gates des oberen Mosfets unserer ersten Phase. 
Auflösung ist 5V/diff und 500ns/d, falls man das auf dem Foto nicht 
erkennt.

Zum Programm kann ich noch sagen, das die "DEAD_TIME" anstatt auf 10, 
bereits auf 15 steht. Eine höhere Totzeit kann ich nicht einstellen.

Nochmals vielen Dank für eure Hilfe, im Speziellen dir, Matthias Sch.!

von Anselm 6. (anselm68)


Lesenswert?

Klar ist doch dass die Gateladezeit geringer wird wenn du den 
Vorwiderstand kleiner machst. [Tau = R*C]
Ich würde den einfach noch einbauen den 2ten 18Ohm Widerstand.
Ob die Geschichte mit dem MOSFET und Treiber auch passt habe ich nicht 
geprüft.

Anselm

von Georg S. (fulgore)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

ich habe jetzt einige, teils merkwürdige Erkenntnisse gewonnen.
Anselm 68, ja das ist richtig, klar. Ich habe jetzt den zweiten 
Widerstand eingelötet und bin damit bei 9 Ohm. Konsequenz ist nun, dass 
ich größere Peakströme messe und es damit zur Abschaltung kam. Zuvor 
waren nur 3 Mal 470µF Zwischenkreiskondensatoren verbaut. Ich habe 
jetzt, mangels Verfügbarkeit eine andere Motorplatine geschlachtet und 
noch 3 weitere 470µF Elkos draufgelötet. Damit waren die Peakströme 
schon etwas reduziert und mein Spitzenstromeingriff schaltet nicht mehr 
ab, wenn ich es nicht zu sehr übertreibe.

Zu meinen Erkenntnissen:
1.
Im Block wird es weiterhin heiß. Gefühlt hat es sich jedoch etwas 
verbessert. Das ist allerdings nur grob geschätzt. Heiß wird es, wie 
geschrieben, immer noch. An der Stelle bin ich gerne noch für weitere 
Hinweise offen!.

2.
Zuvor hatte ich einen sauberen Lauf im Block, wenn ich 120° "in der 
Zukunft liegende" Phasen ansteuere.
Den Sinus erreichte ich jedoch nur, wenn ich die Phasen so angeschlossen 
hatte, dass theoretisch 60° "in die Zukunft" getaktet wird. Dazu musste 
ich den "advanced commutation factor" ca. 60° weiter in die Zukunft 
legen. Ich hatte es also so angesteuert, dass der Sinus erreicht wurde, 
hatte die Blöcke im Programm alle 60° (einen Schritt) in die Zukunft 
verlegt und den o.g. advanced commutation factor gesetzt.
Damit wurde der Sinus sauber erreicht und es fuhr auch unter Last gut 
(abgesehen von der hohen Temperatur).

Für den gestrigen Versuche habe ich die Beschaltung wieder so geändert, 
wie es logisch zu sein scheint. Ich habe die Ansteuerung der Blöcke 
wieder wie im Original gesetzt und die Phasen so angeschlossen, dass 
120° vorgetaktet wird. Das hatte sich ja schon als brauchbar 
herausgestellt. Weiterhin habe ich dann den advanced commutation factor 
auf 0° gesetzt. Es ist also meiner Logik nach genau so, wie zuvor. 
Lediglich die 2 Phasen und 2 Hallgeber (wegen logischen Laufrichtung) 
musste ich ändern.

Jetzt erreiche ich den Sinus nicht mehr. Das verstehe ich nicht! Hat 
jemand eine Idee, warum etwas theoretisch identisches sich abweichend 
verhält?
EDIT:
Er müsste ja nur 2 Hallinterrupts in die Solllaufrichtung sehen und er 
sollte Sinus laufen. Allein das tut er nicht. Bei der anderen 
Verdrahtung und dem modifizierten Programm kann ich sogar einstellen, 
dass er 240 Hallgeberinterrupts in die Solllaufrichtung sehen muss, 
bevor er umschaltet. Selbst das funktioniert.
EDIT ENDE

Zur Veranschaulichung nochmal eine detaillierte Beschreibung mit Bild:
Leider haben die Hallgeber die gleichen Leitungsfarben, wie die Phasen. 
Das verwirrt auf den ersten Blick etwas.
Gemäß Zeile 14/15 habe ich die Spannung auf die Phasen gegeben und nach 
Erreichen der Position die Hallkonfiguration ermittelt. Zu sehen in den 
Zeilen 6-10, Im Programm ergibt das die Hex-Werte aus den Zeilen 12 oder 
13.
Meine Logik sagte mir, dass 60° in die Zukunft getaktet werden muss, um 
eine saubere Motordrehung zu erzeugen (Vergleiche Zeilen 16/17 mit 
Zeilen 14/15). Das bewahrheitete sich nicht. Wie es sich herausstellte, 
muss 120° in die zukunft getaktet werden (Vergleiche Zeilen 28/29 mit 
14/15).
Da das Programm vorwärts und rückwärts kennt, und man die Hallgeber 
H1H2H3 oder H3H2H1 einlesen kann, ergeben sich 4 logische Zustände 
(Zeilen 18-25)
Da das Programm derzeit rückwärts läuft und ich auf dem Fahrrad 
natürlich gerne ein vorwärts drehendes Rad haben möchte, ergeben sich, 
je nachdem ob man 60° (Zeilen 30/31) oder 120° (Zeilen 28/29) in die 
Zukunft takten möchte. Da sowohl beim Sinus, als auch beim Block 
ausschließlich 120° sauber laufen, hatte ich bei der Verdrahtung gemäß 
Zeilen 30/31 im Programm sowohl den Block (60° verschieben der 6 
Schritte), als auch den Sinus (Wert 32 als "advanced commutation factor" 
entspricht ungefähr 58°) in die Zukunft verlegt.
die Verdrahtung gemäß den Zeilen 30/31, mit +60°-Trickserei im Programm 
funktioniert, die Verdrahtung gemäß Zeilen 28/29, die ja gemäß Logik 
keine Trickserei bedarf, funktioniert nur im Block. Dies jedoch sauber.

Ich bin ratlos...

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Georg S. schrieb:
> Im Block wird es weiterhin heiß.

Dein MOSFet sollte eigentlich auch mit 18 Ohm Gatewiderstand laufen, die 
Gatecharge ist ja bei dem Dings recht gering. Allerdings ist die 
Versorgung und die Ladungspumpe des IR2110 verdächtig. Du benutzt z.B. 
nur einen 470nF Pumpen-C, das sind bei mir für drei parallelgeschaltete 
IRFB2307 mit je 15 Ohm Rg satte 100µF/50V, dazu parallel noch 100nF fürs 
ESR. Auch die IR2110 VCC blocke ich grosszügig mit 100µF ab. Damit ist 
in jedem Fall sichergestellt, das die Spannung beim Zünden des Gate 
nicht zusammenbricht und den MOSFet aus seiner Sättigung zieht. Sobald 
der MOSFet gesättigt ist, gilt sein RdsON von 3,6mOhm erst. Als Diode 
nehme ich BA159, zur ES1D kann ich dir nix sagen.

Georg S. schrieb:
> die ja gemäß Logik
> keine Trickserei bedarf, funktioniert nur im Block. Dies jedoch sauber.

Das sollte deine Grundkonfiguration bleiben. Jetzt kommt es zu den o.a. 
CSOffsets in die Sinustabelle. Diese musst du so anpassen, das der 
Anstieg und Abfall wie in der Grafik aus AVR447 zusammengehören.
Ich habe in mein PMSMTables mit ifdefs verschiedene Tabellen für 
verschiedene Motoren machen müssen, weil es keine allgemeingültige 
Reihenfolge gibt. Wenn die 'ExpectedHallsequence' nicht stimmt, geht der 
Motor nie auf Sinus.

Georg S. schrieb:
> anstatt auf 10,
> bereits auf 15 steht. Eine höhere Totzeit kann ich nicht einstellen.

Das sind also 15 MC Zyklen als DEADTIMEHALF, ingesamt also 30 MC Zyklen. 
Ob das ausreicht, kannst du ja mal mittels der Anstiegs- und 
Abfallzeiten des IR und der MOSFet ausrechnen.
Ein in die Versorgungsleitung geschalteter Shunt sollte jedenfalls ohne 
Motor auch bei Vollgas kein bisschen Strom messen. Natürlich bleiben 
dabei auch die MOSFet eiskalt. Klemm also die Phasen ab und lass die 
Sensoren dran. Vollgas einstellen und dann mal des Rad durchdrehen. 
Dabei darf nichts rummucken oder gar Strom ziehen.

Die von mir benutzten Advance Werte konnte ich noch nicht nachgucken, 
liegen aber bei etwa 18-28 Grad. ($0A-$10)

: Bearbeitet durch User
von eProfi (Gast)


Lesenswert?

Eines verstehe ich nicht, die Regler sind so intelligent, aber die 
Sensoren automatisch anlernen können die wenigsten.
Die von miControl.de können das.

Die DeadTime darf auch nicht zu lange sein, da sonst die Body-Diode 
leitend wird und dann "entladen" (recovery) werden muss, was bei mir 
Ströme von 80A bedeutet hat. Die 60V sind trotz loESR-Cs um über 10V 
eingebrochen.
Dies ist von einem Shoot-Through kaum zu unterscheiden. Ich dachte 
zuerst auch, die DeadTime wäre zu kurz. Um optimal zu schalten, passe 
ich die DeadTime jetzt sogar im Betrieb abhängig vom Strom an.

von Georg S. (fulgore)


Lesenswert?

Hallo zusammen,

da ich durch die Woche nicht sonderlich viel Zeit zum testen habe, kann 
ich mich derzeit nur auf Kleinigkeiten beschränken.
Zum Pumpen-Kondensator: Ich habe den Kollegen gefragt, der die Schaltung 
entworfen hat. Er sagt, dass der 470nF Kondensator dort etwas größer 
ist, als er laut Berechnung sein müsste und das so laut ihm passt.
Zur Totzeit: Da habe ich testweise etwas herumexperimentiert und mich 
Schritt für Schritt auf 6 Zyklen heruntergetastet. Es läuft unverändert. 
Auch am Stromwandler konnte ich keinen nennenswerten Unterschiede 
erkennen.

Ich habe einen Moset auf der Unterseite der Platine mit einem 
Temperatursensor ausgestattet und bin ein bisschen durch die Gegend 
gefahren. Beim Beschleunigen oder bei leichten Steigungen steigt die 
Temperatur rapide an. Bei derzeitigen ca. 25°C Außentemperatur kam ich 
im Betrieb auf etwa 55-60°C. Bei halten der Höchstgeschwindigkeit ging 
die Temperatur dann wieder auf ca. 52-54°C herunter.

Zum Thema "ExpectedHallSequence": Da stand ich wohl auf dem Schlauch. 
Wenn ich 2 Phasen vertausche und zudem Hall 1 und Hall 3 vertausche, 
dann läuft der Motor weiterhin in die gleiche Richtung, da die Vorwärts- 
und Rückwärtsrichtung gemäß Hallkonfiguration nur jeweils von H1 H2 H3 
bzw. H3 H2 H1 zu lesen ist. Somit muss ich, wenn ich 2 Phasen tausche, 
die H1 und H3 tausche, ebenfalls die beiden Pointerlisten 
"expectedHallSequenceForward" und "expectedHallSequenceReverse" 
vertauschen. Dann sollte es auch in der logischen Grundkonfiguration mit 
dem Sinus funktionieren. Manchmal sieht man eben den Wald vor lauter 
Bäumen nicht.


Bleibt natürlich das leidige Thema mit der Temperatur.


Danke nochmal euch allen, für die tolle Unterstützung!!!
Am Wochenende habe ich dann hoffentlich wieder etwas mehr Zeit.

von Georg S. (fulgore)


Lesenswert?

Hallo zusammen,

leider ist am Wochenende das passiert, was früher oder später passieren 
musste: der Zwischenkreis ist platt (Kurzschluss).

Durch das ständige Fahren mit der provisorischen Verkabelung haben sich 
nach einem Schlagloch 2 Leitungen gelöst. L2 und Batterie Minus. Durch 
das geruckele habe ich Reflexartig den "Gashahn" zugedreht und damit 
zurückgespeist. Die Mosfets und ggf. Kondensatoren sind also vermutlich 
den Überspannungstot gestorben.


Das soviel zur schlechten Nachricht, jetzt folgen noch ein paar 
Lichtblicke. Im Block lief die niedrige Dead-Time wunderbar, im Sinus 
jedoch konnte ich durch eine größere Totzeit einen niedrigeren 
Stromverbrauch einstellen. Der Wert von 10, was auch dem Originalwert 
entspricht, stellte das vorläufige Optimum dar, soweit ich das derzeit 
beurteilen kann. Bei der darauf folgenden Fahrt blieben die Mosfets 
etwas kühler. Selten kratzte ich an 60°C, meist hielt sich die 
Temperatur bei etwa 50°C. Wie sich herausstellte, verträgt der Mosfet 
175°C, jedoch bei reduziertem Strom. Ich bin bisher von 75°C 
ausgegangen. Die 100°C Differenz muss ich irgendwie überlesen haben. :-D
Es sieht also nicht so schlimm aus, wie es anfangs den Anschein 
erweckte.

Nur nochmal was am Rande:
Den Kollegen, der das Platinenlayout entwickelt hat, habe ich heute auch 
nochmal erreicht. Es zeichnet sich ab, dass er privat demnächst auch 
wieder etwas mehr Zeit hat.
Wir sprachen über eine Masterplatine, die später beide Motorcontroller 
steuern soll und zudem die Spannungsversorgung realisieren soll.
Die Spannungsversorgung hatte der Kollege vor Verlassen Chinas bereits 
weitestgehend ausgelegt, jedoch kenne ich dazu keine Details. Ich 
erwähnte, dass wir unbedingt die Zwischenkreisspannung erfassen sollten, 
zudem die Mosfet-Temperatur des heißestens Mosfet (Mitte Unterseite). Er 
schlug noch vor, später ggf. die Motorwicklungstemperatur zu erfassen. 
SW-Grenzwerte könnte man dann auf die jeweiligen Notaus, der beiden 
Motorplatinen verdrahten.
Die Zwischenkreisspannung könnte man ja m.E. relativ simpel erfassen und 
einfach einen Spannungsteiler bauen. Mit Widerständen der E12 Reihe käm 
man auf 8,2k + 8,2k + 2,7k + 1k. Dann würden etwa 5mA fließen. Den 1kOhm 
Widerstand würde man in Minusrichtung verbauen und über diesem die 
Spannung direkt am ADC des Master µC einlesen (könnte laut Kollegen ein 
Atmega werden, der auch ein 20*4er Display ansteuert). Parallel zum 
1kOhm Widerstand würde dann noch ein kleiner Kondensator geschaltet 
werden. Als Temperatursensor schlug der Kollege noch vor, einen zu 
verwenden, der bei 5V Versorgungsspannung direkt ein 0-5V Signal 
ausgibt. Klingt für mich gut.
Ich hätte zudem ungerne die Zwischenkreiskondensatoren permanent 
geladen. Wenn sich der Aufwand in Grenzen hält, könnte man die 
Zwischenkreise noch über Vorladewiderstände laden und bei Erreichen 
einer Sollspannung zuschalten. Ist die Frage, ob das nicht zuviel des 
Guten ist.
Derzeit lade ich übrigens über eine umgebaute KFZ-Sicherung vor. Dort 
kommen 5 parallelgeschaltete 3,3kOhm Widerstände zum Einsatz. Das 
funktioniert gut.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.