Hallo zusammen!
Ich bin neu hier und habe schon unzählige Forenbeiträge und Tutorials
durchgelesen, aber noch keine Lösung für mein Problem gefunden...
Ich muss einen Prüfstand für eine Funktionseinheit realisieren, welche
u.a. aus einem 24Volt DC-Motor mit Getriebe besteht, der eine Welle
antreibt. Auf dieser Welle sind mehrere unterschiedliche Kurvenscheiben
montiert, auf deren Außenkanten Kugellager mittels Stahlfedern gedrückt
werden. Dreht sich nun die Welle mit den Kurvenscheiben, laufen die
Kugellager auf der Kurvenscheibe entlang und betätigen dann irgendwelche
Hebel. Die Welle macht pro Zyklus eine Umdrehung. Die Nullstellung der
Welle wird über einen induktiven Initiator detektiert, welcher von einer
Nockenscheibe betätigt wird, die sich ebenfalls auf der Welle befindet.
Der Motor wird je nach Stellung der Welle unterschiedlich
belastet(aufgrund der unterschiedl. Kurvenscheiben). Um nun
herauszufinden, ob möglicherweise zu starke/zu schwache Federn montiert
wurden, kann man ja über den Motorstrom eine Aussage über das Drehmoment
treffen (Proportionalität). Ich muss also den Motorstrom aufzeichnen
und dann mit einer zuvor definierten Hüllkurve vergleichen.
Eckdaten: 24 Volt DC Motor, Dunker-BG65SI, eingebauter Speedcontroller
mit spezieller Firmware / Getriebe 19:1
Die Motor-Firmware wurde so konzipiert, dass der Motor über zwei
digitale Ausgänge zwei 24 Volt Hall Signale liefert, welche um 90°
verschoben sind. Pro Motorumdrehung erhält man pro Hallspur 5 positive
und 5 negative Flanken. Bei zwei Hallspuren macht das dann 20
Flankenwechsel. In Verbindung mit dem Getriebe erhalte ich dann 19*20 =
380 Signalwechsel pro Zyklus (Wellenumdrehung).
Diese 380 Signalwechsel kann ich in Verbindung mit dem
Grundstellungsinitiator zählen und daraus die aktuelle Position der
Welle ermitteln. Und zu jeder einzelnen Position muss ich einen
dazugehörigen Motorstrom messen und aufzeichnen. Dazu benutze ich den
Stromsensor LEM LTS 15-NP.
Vorgehen: Mit Hilfe eines Arduino Due die Hallsignale, den
Grundstellungsinitiator und den Motorstrom erfassen (mit zusätzlicher
Vor-Beschaltung). Diese Werte an dem Serial Monitor ausgeben lassen.
Jetzt zu meinem Problem: Ein Zyklus dauert ca. eine Sekunde. Da die
Übertragung der Daten vom Arduino mit 9600 Baud erfolgt, erhalte ich nur
ca. 50 Wertepaare, welche überhaupt nicht brauchbar sind. Das Problem
ist eben, dass ich die Daten direkt übertrage.
Plan: Bei jedem der 380 Flankenwechsel eine Interruptroutine ausführen,
welche den dazugehörigen Stromwert detektiert und das ganze im RAM
speichern. Erst nach einem kompletten Zyklus dann die 380 Wertepaare
über die serielle Schnittstelle schicken.
Im Anhang befindet sich der bisherige Quellcode und eine Excel Datei
mit den erhaltenen Daten (die Skala des Motorstroms passt noch nicht,
Initiator und Hallsignale sind binär). Außerdem noch der
Motorstromverlauf, welcher mit einer Stromzange (Oszi) aufgenommen
wurde. Wenn man beide Stromverläufe vergleicht, sieht man, dass die
Messung über Stromzange(Oszi) um ein vielfaches genauer ist, als die
Daten des Arduino. Ich benötige also einen Quellcode, mit welchem man
eine ähnliche Genauigkeit erreicht als mit der Stromzange…
Leider habe ich keine Ahnung, wie ich das ganze umsetzen/ implementieren
kann, weshalb ich mich an euch wende. Ich bin wirklich für jede Hilfe
dankbar!
Hallo,
soweit ich weiß, kann man die Daten auch schneller aus dem Arduino
herausbekommen. Bis 115200 baud wird direkt von der Arduino Library
angegeben (http://arduino.cc/en/Serial/begin).
1
Serial.begin(115200);
Angeblich kann man auch mehr herausholen.
http://forum.arduino.cc/index.php?topic=21497.0
Du musst natürlich die Gegenstelle (also den PC der die Daten empfängt)
auch entsprechend umstellen.
Alternativ kannst du natürlich immer einfach vorher die Werte intern
speichern und anschießend übertragen.
Quellcode nur exemplarisch (Quelle [1]):
1
unsignedlongvalues[1000];
2
3
voidloop(){
4
unsignedinti;
5
6
// capture the values to memory
7
for(i=0;i<1000;i++){
8
values[i]=analogRead(2);
9
}
10
11
// print out the results
12
Serial.println("\n\n--- Results ---");
13
for(i=0;i<1000;i++){
14
Serial.print(values[i]);
15
}
16
}
Achtung: es könnte sein, dass der ADC die 1000 Werte deutlich schneller
eingelesen hat als eine Umdrehung deiner Welle (von der du die Daten
haben willst) dauert. Das solltest du aber anhand der anderen Signale
gut sehen können.
Liebe Grüße,
Lui
[1]
http://www.microsmart.co.za/technical/2014/03/01/advanced-arduino-adc/
Carl-Josef S. schrieb:> Da die> Übertragung der Daten vom Arduino mit 9600 Baud erfolgt, erhalte ich nur> ca. 50 Wertepaare, welche überhaupt nicht brauchbar sind.
Mit dem Arduino gehen locker 250.000 und auch 500.000 Baud, damit
sollten mind. 10.000 Samples/s und weit mehr gehen. Ich habe mit einem
Arduino Uno bei 500.000 Baud ca. 30.000 Samples/s (je 8bit binary)
geschaft. Allerdings nicht mit den schnarchigen Arduino Libs, sonder mit
LunaAvr. Mit Deinem Arduino Due müsste das trotz der langsamen Arduino
Libs event. auch gehen.
An Deiner Stelle würde ich aber den Due entsorgen, einen Uno nehmen und
dazu eine Programmiersprache, die alle Funktionen/Ports des MC sofort
ansprechen kann, wie C, Luna, Bascom. Dann bist Du warscheinlich immer
noch schneller als mit dem Due und den Arduino Libs.
Peter Luidolt schrieb:> Du musst natürlich die Gegenstelle (also den PC der die Daten empfängt)> auch entsprechend umstellen.
Das ist Unsinn, an den ComPorts im PC muss man nichts umstellen, die
Einstellungen sind absolut schnuppe. Ich wechsele die Baudraten vom MC
beim Testen dauernd, ohne im PC-Gerätemanager die ComPort Baudraten
umzustellen. Die stehen auf 9.600 Baud obwohl z.B. mit 500.000 Baud
übertragen wird.
Da schaut man höchstens nach um die aktuell benutzte Port-Nummer zu
sehen.
Albert M. schrieb:> Das ist Unsinn, an den ComPorts im PC muss man nichts umstellen, die> Einstellungen sind absolut schnuppe.
Das ist überhaupt kein Unsinn. Du redest von Comports und da muss man
die Baudrate definitiv umstellen. Wahrscheinlich meinst du virtuelle
Comports (über USB). Bei denen funktioniert das so.
avr schrieb:> Das ist überhaupt kein Unsinn. Du redest von Comports und da muss man> die Baudrate definitiv umstellen. Wahrscheinlich meinst du virtuelle> Comports (über USB). Bei denen funktioniert das so.
Und was meinst Du welche Art von ComPorts von den Arduino Treibern
generiert werden? Ja eben, virtuelle ComPorts, was sonst. Also ist Dein
Gerede vom Umstellen müssen für den TO irrelevant.
Hallo!
Erstmal DANKE für die Antworten.
Ich werde als nächstes die geposteten URLs durchschauen und dann mal die
Baudrate erhöhen und etwas rumprobieren. Werde dann wieder ein
Bild(Excel) von den neuen Wertepaaren schicken.
>An Deiner Stelle würde ich aber den Due entsorgen, einen Uno nehmen...
Das verstehe ich nicht ganz. Hab mir extra noch einen Due zugelegt, da
der ja viel bessere Leistungsdaten hat(Geschwindigkeit, RAM,...). Habe
aber auch noch einen Uno und einen Mega zur Verfügung.
Carl-Josef S. schrieb:> Flankenwechsel. In Verbindung mit dem Getriebe erhalte ich dann 19*20 => 380 Signalwechsel pro Zyklus (Wellenumdrehung).
Kannst Du irgendwas zu Ablaufgeschwindigkeit oder Drehzahl sagen?
In welcher Zeit kommen diese 380 Signalwechsel?
> Und zu jeder einzelnen Position muss ich einen> dazugehörigen Motorstrom messen und aufzeichnen.
Wenn Du das musstt, solltest Du das auch machen.
Dein bisheriger Code macht das nicht. Insbesondere mißt und sendet Dein
Code nicht beim Auftreten eines Flankenwechsels, sondern "mit maximaler
Geschwindigkeit". Dadurch läuft Dir der serielle Sendepuffer zu und dann
kannst Du alle gesendeten Werte vergessen.
Der erste Flaschenhals Deines Programms ist die serielle Schnittstelle.
Die Anzahl der Zeichen, die Du pro Sekunde senden kannst, beträgt
Baudrate geteilt durch 10. Bei 9600 Baud wären dass max. 960 Zeichen/s.
Bei 115200 Baud (max. Baudrate des "Seriellen Monitor" von Arduino)
wären es 11520 Zeichen/s, Bei 500000 als maximale Baudrate eines Arduino
UNO (nur mit anderen Terminalprogrammen auf dem PC nutzbar) wären es
50000 Zeichen/s.
Welches die maximale Baudrate eines DUE ist, weiß ich nicht.
> Im Anhang befindet sich der bisherige Quellcode
Sende den Quellcode lieber zwischen Code-Tags oder als Dateianhang.
> mit den erhaltenen Daten (die Skala des Motorstroms passt noch nicht,> Initiator und Hallsignale sind binär).
Wie gesagt: Solange Du versuchst, die serielle Schnittstelle zu
überdrehen kannst Du alles vergessen.
Wenn Du die Signale immer zu dem Zeitpunkt benötigst, zu dem bei den
Hallsignalen ein Flankenwechsel auftritt, solltest Du genau diese
Flanken auswerten und beim Flankenwechsel den Stromsensor auslesen und
den Wert senden. Das benötigt keine Interrupt-Routine.
Hallo Jürgen,
> Carl-Josef S. schrieb:>> Flankenwechsel. In Verbindung mit dem Getriebe erhalte ich dann 19*20 =>> 380 Signalwechsel pro Zyklus (Wellenumdrehung).>> Kannst Du irgendwas zu Ablaufgeschwindigkeit oder Drehzahl sagen?> In welcher Zeit kommen diese 380 Signalwechsel?
Das hat er irgendwo oben im Text versteckt, 1 U/s, also 380 Hz für die
Messungen bzw. die Hallsignale. Dafür sind 9600 Baud klar zu wenig,
sobald mehr als ein paar Byte pro Messung übertragen werden sollen.
Mit freundlichen Grüßen
Thorsten Ostermann
Hallo!
Ich habe nochmal ein Messversuch mit höherer Baudrate (115200)
durchgeführt und das Resultat sieht schon besser aus (Anhang).
Jedoch hat Jürgen S recht, dass ich nicht die positionsbezogenen
Motorströme erhalte, sondern einfach nur mit maximaler Taktung die Werte
übertrage. Ich habe dann das Programm nach Vorlage von "Peter Luidolt
(luidoltp)" umgeschrieben, aber das funktioniert noch nicht (Anhang). Da
muss ich morgen noch etwas herumprobieren. Falls jemand weiß, wie ich
das Programm verändern muss, wäre ich sehr dankbar. Im Moment bekomme
ich zwar Werte über den "Serial Monitor" angezeigt, jedoch ändern sich
diese nicht. Wenn ich die Zählvariable "i" auf 5 (statt auf 500) stelle,
bekomme ich eben fünf mal die gleichen Wertepaare und das immer
fortwährend. Bei i=500 kommen eben 500 mal die gleichen,unveränderten
Werte und dann beginnt es wieder von vorne (mit "---Results---").( Motor
wurde während der Messung angesteuert).
Carl-Josef S. schrieb:> Ich habe nochmal ein Messversuch mit höherer Baudrate (115200)> durchgeführt und das Resultat sieht schon besser aus (Anhang).> Jedoch hat Jürgen S recht, dass ich nicht die positionsbezogenen> Motorströme erhalte, sondern einfach nur mit maximaler Taktung die Werte> übertrage.
Ich habe Dir mal ein neues Programm gemacht, das immer nur beim
Flankenwechsel an den Drehgeberausgängen eine Messung macht.
1
constintanalogInPin=A0;// Analog input pin that the LEM LTS 15-NP is attached to
2
intIniB13=2;//Grundstellung
3
intHall1=3;//Hallspur 1
4
intHall2=4;//Hallspur 2
5
6
7
voidsetup(){
8
Serial.begin(115200);
9
pinMode(IniB13,INPUT);
10
pinMode(Hall1,INPUT);
11
pinMode(Hall2,INPUT);
12
analogReadResolution(12);//Auflösung auf 12 Bit erhöhen
13
}
14
15
staticbooleangrundStellungsImpuls()
16
// Flankenwechselerkennung Grundstellung
17
{
18
staticbytelastStellung;// letzte Stellung in statischer Variablen merken
// Flankenwechselerkennung an den Drehgeberausgängen
29
{
30
staticbytelastA,lastB;
31
booleanresult=false;
32
bytenowA=digitalRead(Hall1);
33
bytenowB=digitalRead(Hall2);
34
if(nowA!=lastA||nowB!=lastB)result=true;
35
lastA=nowA;
36
lastB=nowB;
37
returnresult;
38
}
39
40
41
intstepcounter=0;
42
43
voidloop(){
44
if(grundStellungsImpuls())stepcounter=0;
45
if(hallSensorImpuls())
46
{
47
intstrom=analogRead(analogInPin);//Analogwert von Stromsensor
48
stepcounter++;
49
Serial.print(stepcounter);
50
Serial.print("\t");
51
Serial.print(strom);
52
Serial.print('\n');
53
}
54
}
Da pro Messung eine Zeile auf Serial mit der Drehstellung
("stepcounter") und dem Messwert ausgegeben wird, entsprechend ca. 10
Zeichen pro Messung, sollten bei 380 Impulsen pro Sekunde ca. 3800
Zeichen pro Sekunde auf der seriellen Schnittstelle auszugeben sein.
Wobei man bei 115200 Baud bis zu 11520 Zeichen ausgeben könnte. Passt
also für Realtime-Ausgabe.
Beim Setzen der ADC-Auflösung mit "analogReadResolution(12);" bin ich
mal davon ausgegangen, dass das nicht vor jeder Messung gemacht werden
muss, und es daher in die setup-Funktion verschoben. Ich kenne mich mit
dem DUE nicht aus, wenn nicht, schiebe die Zeile in die loop zurück.
Beim "grundStellungsImpuls()" habe ich eine Flankenerkennung gemacht,
die vom Übergang Low-nach-High reagiert und dann den Schrittzähler
zurücksetzt. Das kann man ggf. einfach auf die andere Flanke
umprogrammieren. Etwas mehr Aufwand wäre es, wenn Schritt 1 irgendwo in
der Mitte auftreten würde, aber auch das wäre machbar, die
Schrittzählung auf einen anderen Nullpunkt zu setzen.
Kannst ja mal bei Bedarf damit testen. Falls Du dabei feststellen
solltest, dass der Stepcounter höher als bis 380 läuft, dann prellen die
Ausgänge Deiner Hallsensoren und die Schrittzählung ist nicht
zuverlässig. In dem Fall müßte man statt der Flankenwechselerkeunnung
eine richtige Drehgeberauswertung machen und die Impulse vor- und
rückwärts zählen, um das Prellen aus den Signalen zu eliminieren.
Albert M. schrieb:> Und was meinst Du welche Art von ComPorts von den Arduino Treibern> generiert werden? Ja eben, virtuelle ComPorts, was sonst. Also ist Dein> Gerede vom Umstellen müssen für den TO irrelevant.
Hier geht es nicht nur um den TO, sondern auch um andere, die das später
lesen. Und so wie dein Beitrag da steht ist er einfach inhaltlich
falsch. Das kleine Wörtchen virtuell macht nämlich einen gewaltigen
Unterschied aus.
Hallo!
Zu der "Diskussion" über ComPorts kann ich mich nicht wirklich
beteiligen, davon verstehe ich zu wenig. Ich habe jedenfalls nur im
Arduino-Sketch die Baudrate erhöht und bekam so eine bessere Auflösung
der Messung. In der Systemsteuerung des PC habe ich nichts verändert.
@ Jürgen S: Vielen Dank für dein Programmcode. Habe ihn nur auf
"Flankenwechsel auf LOW" ändern müssen. Das Problem ist jetzt nur, dass
der Motor für eine Wellenumdrehung keine kontinuierliche Bewegung
ausführt, sondern in fünf unterschiedlichen Positionen kurz anhält. Wenn
er dann wieder anläuft aus der jeweiligen Position, bekomme ich einen
relativ hohen und steilen Strompeak. Das kann man in dem Bild sehen,
welches ich mit dem Oszi und der Stromzange (siehe Anfangsbeitrag,
LeCroy.png)gepostet habe. Mit dem Programmcode von Jürgen S bekomme ich
immer ein Stromwert geliefert, wenn sich eine der beiden Hallspuren
ändert (=wenn sich der Motor bewegt). Die Peaks treten aber in dem
Anlaufmoment auf, kurz bevor eine Motorbewegung stattfindet. Deshalb
werden sie nicht (immer) in voller Höhe erfasst. Außerdem verharrt der
Motor kurz in den fünf unterschiedlichen Positionen und während dieser
Zeit wird auch kein Stromwert detektiert (weil kein Hall-wechsel). Es
ist also nicht wirklich möglich (bzw.aussagekräftig), positionsbezogene
Ströme zu erfassen und mit einer zuvor definierten Hüllkurve zu
vergleichen.
Mir bleibt jetzt noch die Möglichkeit, den Bewegungsablauf so
abzuändern, dass der Motor eine gleichmäßige Bewegung mit konstanter
Geschwindigkeit ausführt. Dies entspricht zwar nicht dem späteren
Bewegungsablauf, aber für den Prüfstand ist das erst mal egal. Hier geht
es ja nur darum, eventuelle Montagefehler zu erkennen. Probleme könnten
sich jetzt nur ergeben, dass ich keine 100%ig gleichmäßige
Umdrehungsgeschwindigkeit realisieren kann, da der Motor ja
unterschiedlich belastet wird-je nach Position der Welle aufgrund der
unterschiedlichen Kurvenscheiben.
Möglichkeit 2: alle positiven Ströme einer Umdrehung addieren und der
Gesamtwert muss dann in einem bestimmten Bereich liegen ( und das
gleiche mit negativen Strömen auch machen). Sollte der Gesamtwert zu
hoch sein, kann man davon ausgehen, dass etwas klemmt oder zu starke
Federn montiert wurden. Ich weiß aber nicht, wie groß hier der
Toleranzbereich gewählt werden muss.
...Ich habe also die nächsten Tage noch einiges an Messversuchen etc.
vor mir. Werde euch auf dem Laufenden halten.
Falls jemand eine Idee hat, welche Möglichkeiten ich noch habe, den
Motorstrom zu erfassen und v.a. auszuwerten- ich bin für jeden
Tipp/Hilfe dankbar!
Carl-Josef S. schrieb:> Das Problem ist jetzt nur, dass> der Motor für eine Wellenumdrehung keine kontinuierliche Bewegung> ausführt, sondern in fünf unterschiedlichen Positionen kurz anhält. Wenn> er dann wieder anläuft aus der jeweiligen Position, bekomme ich einen> relativ hohen und steilen Strompeak. Das kann man in dem Bild sehen,> welches ich mit dem Oszi und der Stromzange (siehe Anfangsbeitrag,> LeCroy.png)gepostet habe. Mit dem Programmcode von Jürgen S bekomme ich> immer ein Stromwert geliefert, wenn sich eine der beiden Hallspuren> ändert (=wenn sich der Motor bewegt). Die Peaks treten aber in dem> Anlaufmoment auf, kurz bevor eine Motorbewegung stattfindet. Deshalb> werden sie nicht (immer) in voller Höhe erfasst.
OK, Du brauchst also sehr viel mehr Samples mit sehr viel kürzeren
Zeitabständen.
Um den Flaschenhals "Serial" zu umgehen, dann also doch wieder zurück zu
Deiner ersten Idee: Erst schnell die Werte in den RAM-Speicher sampeln,
und dann die Werte ausgeben. Du verwendest ja den DUE und der hat
erhebliche Mengen RAM-Speicher, da sollte das kein Problem sein.
> Motor kurz in den fünf unterschiedlichen Positionen und während dieser> Zeit wird auch kein Stromwert detektiert (weil kein Hall-wechsel). Es> ist also nicht wirklich möglich (bzw.aussagekräftig), positionsbezogene> Ströme zu erfassen und mit einer zuvor definierten Hüllkurve zu> vergleichen.
OK, ich habe mal einen geänderten Sketch gemacht, der nicht
positionsbezogen sampelt, sondern zeitbezogen, und zwar zunächst mal "so
schnell wie möglich". Das Sampling wird getriggert durch:
- Erkennung des Impulses für die Grundstellung
- Auf einen frei wählbaren Step-Impuls der Hall-Sensoren
Das ist in der loop-Funktion diese Zeile:
1
if(waitForStart&&stepcounter==4)// Triggern auf einen bestimmten Impuls
Falls nach diesem Triggerimpuls zunächst eine uninteressante Standzeit
auftritt, kann dort ein optionales delay die Sampling-Aufzeichnung
verzögert starten.
Und falls die Samplings zu schnell aufeinander folgen, kann in der
recordSamples() Funktion ein kleines Mikrosekunden-delay in der
Einleseschleife eingefügt werden, um die Aufzeichnungsdauer zu strecken.
Vollständiger Code:
1
constintanalogInPin=A0;// Analog input pin that the LEM LTS 15-NP is attached to
2
intIniB13=2;//Grundstellung
3
intHall1=3;//Hallspur 1
4
intHall2=4;//Hallspur 2
5
6
structsample_t{
7
uint16_ttime;// Zeit in Mikrosekunden nach Startimpuls
8
uint16_tstepcount;// Schritte vom Drehgeber
9
int16_tstrom;// ADC-Messwert
10
};
11
12
#define NUMSAMPLES 5000
13
14
sample_tsamples[NUMSAMPLES];
15
16
voidsetup(){
17
Serial.begin(115200);
18
pinMode(IniB13,INPUT);
19
pinMode(Hall1,INPUT);
20
pinMode(Hall2,INPUT);
21
analogReadResolution(12);//Auflösung auf 12 Bit erhöhen
22
}
23
24
staticbooleangrundStellungsImpuls()
25
// Flankenwechselerkennung Grundstellung
26
{
27
staticbytelastStellung;// letzte Stellung in statischer Variablen merken
if(waitForStart&&stepcounter==4)// Triggern auf einen bestimmten Impuls
97
{
98
// delay(10); // Optional ein delay zur Überbrückung einer uninteressanten Standzeit
99
recordSamples(stepcounter);
100
showSamples();
101
waitForStart=false;
102
}
103
if(hallSensorImpuls())stepcounter++;
104
}
Ich habe die Anzahl der Samples mal auf 5000 gesetzt, und da jedes
Sample 6 Bytes belegt, sollten die Samples im Array ca. 30 KB RAM
benötigen, was auf einem DUE ja locker möglich ist.
> Falls jemand eine Idee hat, welche Möglichkeiten ich noch habe, den> Motorstrom zu erfassen und v.a. auszuwerten- ich bin für jeden> Tipp/Hilfe dankbar!
Probier's mal aus mit den schnellen Samplings ab einem bestimmten
Schritt! Wie gesagt, nach Starten des Sketches muß einmal der
grundStellungsImpuls() erfolgen, und dann wird das Sampling für die
Anzahl der definierten Samples gestartet, sobald die Hallsensoren den
gewünschten Schritt erreicht haben. Nach dem Sampeln werden die Daten
sofort auf Serial ausgegeben.
Der Zeitstempel läuft in dem Sketch ab Start der Aufzeichnung und wird
zur Ausgabe auf Serial in Sekunden mit sechs Nachkommastellen
(Mikrosekunden) umgerechnet.
Falls Du irgendwelche Fragen hast, einfach fragen.
Hallo!
Erstmal wieder ein großes DANKE an Jürgen.
Ich habe den neuen Quellcode ausprobiert und den Trigger auf
stepcounter==40 gesetzt. Ich bekomme dann ab dem 40. Hallwechsel 5000
Samples ausgegeben. Das Problem ist jetzt nur, dass die 5000 Samples nur
von stepcounter==40 bis stepcounter = 79 reichen(Anhang). Das heißt,
dass 39 Hallwechsel auf 5000 Wertepaare aufgelöst werden.
Ich habe dann mal die Samples erhöht, aber mehr als 10000 Samples ist
nicht möglich. Ab ca. 11000 Samples bekomme ich eine Fehlermeldung, dass
irgendwas außerhalb des RAM liegt. Des Weiteren bekomme ich bei 10000
Samples nur 83 Hallwechsel. Das liegt daran, weil bei stepcounter = 82
der Motor kurz anhält (insgesamt 0,029062 Sekunden) und ich aber
(zeitabhängig) insgesamt 3720 Samples für diesen Zeitraum
bekomme(Anhang).
Ich habe mich außerdem beim Startbeitrag leicht geirrt. Das Getriebe ist
kein 19:1 sondern ein 34:1. Das heißt, dass ich 680 Hallsignalwechsel
pro Wellen-Umdrehung erhalte.
...
Ich bin zu dem vorläufigen Ergebnis gekommen, dass es wahrscheinlich das
Beste wäre, den Motor mit gleichbleibender Geschwindigkeit anzusteuern
und dann zeitabhängig z.B. alle 1ms eine Messung zu machen. Wenn ich
also die Drehzahl verringere, dass eine Wellenumdrehung ca. zwei bis
drei Sekunden dauert (und das ganze bei einer konstanten
Geschwindigkeit), erhalte ich pro Wellenumdrehung 3000 Werte (bei 1ms
Abtastrate). Es sollte also möglich sein, den Motor kontinuierlich
laufen zu lassen, und erst ab der (z.B.) dritten oder vierten
Wellenumdrehung (dem dritten/vierten Flankenwechsel des
Grundstellungsinis von HIGH auf LOW) eine Messung von drei weiteren
Wellenumdrehungen aufzuzeichnen mit einer festen Abtastrate von 1ms.
Das bisherige Problem wird dadurch hoffentlich etwas entschärft, dass
ich relativ steile und gleichzeitig sehr schmale Strompeaks erfassen
muss. Durch eine zeitgetriggerte Abtastung kann es zwar immer noch
passieren, dass ich nicht die Spitze des Peaks erfasse (sondern kurz
davor messe und dann wieder kurz danach), aber eine andere(bessere)
Möglichkeit fällt mir gerade nicht ein. Durch die langsamere und v.a.
gleichmäßige Drehzahl hoffe ich, dass die Peaks nicht mehr so steil
sind, da der Motor ja nicht mehr aus der Ruhelage beschleunigen/bremsen
muss. Eine 100%ig gleichmäßige Geschwindigkeit wird nicht realisierbar
sein, da der Motor durch die unterschiedlichen Kurvenscheiben nicht
konstant belastet wird, aber einigermaßen konstant sollte klappen. Ich
habe mir zu diesem Zweck eine SPS besorgt, bei der ich mithilfe eines
Poti ein Analogwert von 0-10 Volt ausgeben lassen kann. Dieser
Analogwert steuert dann die Drehzahl des Motors. Werde aber frühestens
morgen dazu kommen, das ganze zu verdrahten und dann auszuprobieren.
Sollte jemand noch eine andere Möglichkeit einfallen, ich bin für jede
Inspiration dankbar.
>Falls Du irgendwelche Fragen hast, einfach fragen.
Wenn du Zeit und Lust hast, würdest du mir wieder helfen beim Quellcode
zur zeitabhängigen Abtastung der Stromwerte? Wäre dir wirklich sehr
dankbar...
Carl-Josef S. schrieb:> stepcounter==40 gesetzt. Ich bekomme dann ab dem 40. Hallwechsel 5000> Samples ausgegeben. Das Problem ist jetzt nur, dass die 5000 Samples nur> von stepcounter==40 bis stepcounter = 79 reichen(Anhang). Das heißt,> dass 39 Hallwechsel auf 5000 Wertepaare aufgelöst werden.> Ich habe dann mal die Samples erhöht, aber mehr als 10000 Samples ist> nicht möglich.
Irgendwann sind auch die 96 KB RAM eines Arduino DUE aufgebraucht. An
RAM benötigen wie gesagt 5000 Samples ca. 30 KB, d.h. 10000 Samples ca.
60 KB RAM.
> Ab ca. 11000 Samples bekomme ich eine Fehlermeldung, dass> irgendwas außerhalb des RAM liegt. Des Weiteren bekomme ich bei 10000> Samples nur 83 Hallwechsel.
Ich habe den Sketch ja erstmal auf möglichst schnelles Sampling
gestellt. Wie lange dauern denn die 10000 Samples? Zeit in Sekunden wäre
in der ersten Spalte der Serial-Ausgabe? Ich habe keinen DUE und weiß
daher nicht, wie schnell die sind.
> Ich bin zu dem vorläufigen Ergebnis gekommen, dass es wahrscheinlich das> Beste wäre, den Motor mit gleichbleibender Geschwindigkeit anzusteuern> und dann zeitabhängig z.B. alle 1ms eine Messung zu machen.
Bei meinem zuletzt geposteten Sketch hatte ich die Stelle schon
auskommentiert gepostet, wo Du das Sampling langsamer einstellen kannst,
beim Einlesen der Samples:
1
// delayMicroseconds(100);
Wenn Du hier die Kommentarstriche entfernst, bekommt jedes Sample ein
delay von 100 Mikrosekunden, mal 10000 Samples sind das 1 Mio
Mikrosekunden oder 1 Sekunde. D.h. mit diesem delay kannst Du es
steuern, in welcher Zeit die 10000 Samples gemacht werden. Mit 100µs
extra delay pro Sample wird auf jeden Fall länger als eine Sekunde nach
dem Triggern gesampelt. Kürzeres oder kein delay ==> 10000 Samples sind
schnell voll. Längeres delay ==> 10000 Samples dauern länger.
> Möglichkeit fällt mir gerade nicht ein.
Außerdem habe ich ja vorgegeben, dass Du das Sampeln bei einem
beliebigen "Stepcounter" beginnen lassen kannst. Dadurch kannst Du Dir
über verschiedene Vorgaben für den Trigger-Startwert in mehreren
Umläufen auch einen Gesamtumlauf zusammenstellen. Einmal mit
stepcounter==40 triggern, einmal mit stepcounter==80 triggern, einmal
mit stepcounter=120 triggern, und dann kopierst Du Dir die Daten manuell
zu einem vollen Umlauf zusammen.
Hallo!
Ich habe jetzt zwei Tage verschiedene Messversuche gemacht...
Um die Strompeaks in den Griff zu bekommen, werde ich dem Motor einen
konstanten Analogwert vorgeben(3,3Volt des Arduinos). Mit diesem Wert
erreiche ich ziemlich genau eine Wellenumdrehung des 34:1 Getriebes pro
Sekunde (bei konstanter Geschwindigkeit).
Als Prüfablauf habe ich mir folgendes vorgestellt: Ich steuere den Motor
an, dass er im Dauerbetrieb läuft. Nach einer bestimmten Anzahl
Umdrehungen ohne Messung (z.B. fünf) möchte ich dann von den drei
darauffolgenden Umdrehungen den Strom messen (Motor läuft die ganze Zeit
über im Dauerbetrieb). Erst nach Vollendung dieser drei Umdrehungen
werden die Werte seriell übermittelt. Sollte der Motor irgendwann mal
zwischen/während Startzeitunkt (den Umdrehungen ohne Messung) und dem
Ende der Messung (nach den Umdrehungen ohne Messung UND den gemessenen
Umdrehungen) kurz zum Stillstand kommen (zu große Zeitspanne zwischen
zwei Hallwechsel), ist die Messung wertlos. In diesem Fall sollte eine
Fehlermeldung ausgegeben werden, die Messwerte verworfen werden und das
Programm bereit sein, für eine neue Messung. Wenn die eingestellten
10000 Samples nicht genügen sollten, um die Werte von drei kompletten
Umdrehungen speichern zu können, d.h. die 10000 Samples sind nach 2,5
Umdrehungen schon fertig, soll ebenfalls eine Fehlermeldung kommen. Dann
weiß ich, dass ich das delay etwas erhöhen muss. Wenn für drei
Umdrehungen nur ca. 9300 Samples benötigt werden, sollen auch nur 9300
Samples übertragen werden. (Um eine aussagekräftige Auswertung
durchführen zu können, benötige ich die Stromwerte von drei kompletten
Umdrehungen, welche mit konstanter Geschwindigkeit ausgeführt wurden.)
Wenn der Motor nach erfolgreich übermittelter Messung immer noch weiter
läuft, soll das keine Auswirkung haben. Sobald er dann irgendwann
stoppt, sollte das Programm nach einem delay von ca. 5 Sekunden wieder
bereit sein, für eine neue Messung. Diese Zeit wird für die Übertragung
der Daten benötigt.
Zusammenfassung:
Möglichkeit 1: Motor wird angesteuert und läuft mit
(annähernd)konstanter Geschwindigkeit. Nach vier Umdrehungen stoppt der
Motor kurz. =>Meldung "Messung fehlgeschlagen" =>Programm für neuen
Prüfablauf bereit
Möglichkeit 2: Motor wird angesteuert und läuft mit
(annähernd)konstanter Geschwindigkeit. Nach sechs Umdrehungen stoppt der
Motor kurz. Das heißt, er hat fünf Umdrehungen ohne Messung und eine
Umdrehung mit Messung=>Meldung "Messung fehlgeschlagen" =>keine Daten
seriell übertragen/Daten verwerfen =>Programm für neuen Prüfablauf
bereit
Möglichkeit 3: Motor wird angesteuert und läuft mit
(annähernd)konstanter Geschwindigkeit. Nach (mehr als) acht Umdrehungen
stoppt der Motor kurz. Das heißt, er hat fünf Umdrehungen ohne Messung
und drei Umdrehung mit Messung=>Meldung "Messung erfolgreich" => Daten
seriell übertragen=>Programm nach fünf Sekunden für neuen Prüfablauf
bereit.
Ich habe versucht,den Code von Jürgen auf den gewünschten Prüfablauf
anzupassen, aber irgendwie bekomm ichs nicht hin. Im Moment werden nach
dem fünften Flankenwechsel (von HIGH auf LOW) des Grundstellungsinis
10000 Samples aufgenommen und übertragen. Da ich ein delay von 200us
eingestellt habe, bekomme ich also die Stromwerte der darauffolgenden
zwei Sekunden. Wenn während der ersten fünf Umdrehungen der Motor
(mehrmals) stoppt, werden trotzdem nach fünf Umdrehungen die Werte der
darauffolgenden zwei Sekunden übertragen(es soll aber das passieren, was
in Möglichkeit 1 beschrieben wurde). Wenn während der zwei Sekunden der
Motor stoppt, werden trotzdem die Samples übertragen(es soll aber das
passieren, was in Möglichkeit 2 beschrieben wurde). Irgendwie bekomm ich
es nicht hin, den Motor zu überwachen, dass er sich mit konstanter
Geschwindigkeit bewegt um dann damit die Freigabe für die Messung
korrekt zu erteilen...
Im Anhang befindet sich der derzeitige Code. Falls jemand eine Idee hat,
wie ich die gewünschten Funktionen implementieren kann, wäre ich sehr
dankbar.
Hallo allerseits,
ich hatte auch schon das Problem (Ausgabe von uController-internen
Mess-/Rechen-Zustandsgrößen).
Die Serielle Schnittstelle ist zu langsam und vermutlich auch nicht
rückwirkungsfrei (frißt Rechenzeit, was bei interruptgesteuerten
Vorgängen das eigentliche Hauptprogramm komplett in die Knie zwingt).
Als work-around hatte ich in meiner Anwendung (DC-Motor-Drehzahlregelung
mit PID-Regler) zur Kontrolle alle relevanten Daten über die
DA_Wandler-Kanäle ausgegeben. Der UNO gibt nur PWM-Muster aus, muß also
somit mit einem RC-Glied noch befiltert werden.
Vorteil:
* lief mit Oszi-Auflösung bis 200ms / DIV relativ glatt durch (sollte
also bei Deiner Motor-Applikation gut funktionieren)
* visualisiert die Daten im Zeitbereich
* erschiene mir - rein subjektiv- schneller als die serielle
Schnittstelle
Das ist sicherleich auch nicht die beste Lösung, aber vielleicht hat ja
jemand noch eine bessere Idee.
Miss Franken