PWM Signal definieren

Hallo miteinander,

wollte mich mit dem PWM Signal etwas beschäftigen.
Ich habe mit dem PWM Signal schon eine LED Heller bzw. nicht so hell leuchten lassen das klappt :slight_smile:

Jedoch habe in nun eine etwas andere Anwendung.

Bildschirmfoto 2015-05-04 um 12.15.39.png
Bildschirmfoto 2015-05-04 um 12.15.39.png (17 KB)

Die Roten Zahlen sollen die Takte sein

meine Frage ist wie kann ich die einzelnen Sachen einstellen.

  1. Die Länge des Taktes (auf dem Bild min. 200ns)
  2. Die Länge Der Takt Entfernung (auf dem Bild min. 1µs max 1MHz)
  3. Die Anzahl der Takte (Auf dem Bild die Roten Zahlen)

Ich kann an meinem Arduino Mega die Pins 2 bis 13 dafür verwenden.

ein PWM Signal erzeuge ich mit dem Befehl analogWrite
dazu gebe ich dann die Pin Nr. an und einen Wert von 0 bis 255

und hier kommt das Problem, was ist das denn für ein Wert?
ich gehe mal davon aus das das was mit der Frequenz zu tun hat.

Mit der Frequenz kann ich dann allso sagen wie weit jeder Takt vom nächsten ist (Punkt 2 meiner Liste)

irgend wie ist mir das aber noch nicht so richtig klar.

Ich habe hier ein Arduino Mega und einen Logic Analyzer um mir das Signal dann auch anzuschauen.

Könner mir da jemand etwas Licht ins Dunkle bringen.

Gruß Mücke

Die Frequenz ist fest.

490Hz, bzw. 980Hz an Pin 5 + 6 (Uno)

Reference/AnalogWrite

Somit ist deine Periodendauer (in deiner Zeichung "min1µs") 1/490Hz = ca. 2ms

Mit analogwrite(x) stellst du die Länge der Pulse ein:
0 = Pulslänge 0 (daueraus)
127 = 50% der Periodendauer
255 = 100% der Periodendauer (dauerein)
oder, als Formel: t = x/(490*255)

edit: die Anzahl der Pulse ist unendlich. Oder bis du den Ausgang oder den Arduino wieder abschaltest.

wobei dir die Pulslänge meist nicht wichtig ist, es geht hier um ein Tastverhältnis x/255, mit dem du z.B. Ströme oder Spannungen einstellen kannst.

Wenn du z.B. eine LED mit PWM ansteuerst, dann kannst du damit eben die Helligkeit steuern.
mit analogWrite(255) hast du die volle Helligkeit, den vollen Strom, mit analogWrite(127) hat du den halben Strom, mit analogWrite(100) hast du 100/255stel des vollen Stromes

Öm, ja, aha.

Wie Die Frequenz ist fest ?

Kurz zur Begriffserklärung:

  • Periodendauer ==> meine Zeichnung "min1µs"
  • Länge der Pulse ==> meine Zeichnung "min. 200ns"
  • Puls ==> meine Zeichnung "Rote Nr."

Die Frequenz kann ich nicht ändern? sprich ich kann in den von dir errechneten 2ms nicht 2 oder 3 Pullse erzeugen? hmm das ist aber sch**** glaube ich jetzt für mich.

Also 200ns Pulsbreite sind 2.5MHz. Das dürfte mit Boardmitteln schon knapp werden. Du könntest das evtil per inline assembler und direkte Portmanipulation umsetzen, dann könnte es mit dem Timing klappen.

Ist das Signal denn ein festes das Du erzeugen musst, oder ist das flexibel?

Mario.

Muecke:
Öm, ja, aha.

Wie Die Frequenz ist fest ?

Kurz zur Begriffserklärung:

  • Periodendauer ==> meine Zeichnung "min1µs"
  • Länge der Pulse ==> meine Zeichnung "min. 200ns"
  • Puls ==> meine Zeichnung "Rote Nr."

Die Frequenz kann ich nicht ändern? sprich ich kann in den von dir errechneten 2ms nicht 2 oder 3 Pullse erzeugen? hmm das ist aber sch**** glaube ich jetzt für mich.

Doch, du kannst die Frequenz ändern. Dazu musst du in den Registern rumspielen.
siehe http://arduino.cc/forum/index.php/topic,72092.0.html
und PWM frequency library - Libraries - Arduino Forum

Aber 1 MHz erreichst du damit nicht.

zwei Fragen:
a) hier steht minimal 1µs - was ist der maximalwert?
b) mir scheint du möchtest die Länge der einzelnen Pulse beeinflussen. Das geht mit PWM nicht. Da sind alle Puls gleich lang

Und, grundlegend: was wird das denn?

Ich möchte den Motor PD4-C6018L4204 mit Takt/Richtung ansteuern.

--> Handbuch (Kapitel 8.6 Takt/Richtungs-Modus S. 54)

Wenn ich das Richtig verstanden habe muss ich auf der Takt Leitung angeben.

Anzahl der "Pulse" = Anzahl der Schritte
Frequenz der "Pulse" = Geschwindigkeit

daher würde ich sagen das die Frequenz Flexibel sein müsste.

Die maximale Frequenz der Eingangspulse liegt bei 1MHz

Würde ich so verstehen: Wenn Dein Mega langsamer ist, dreht der Motor nicht mit maximaler Geschwindigkeit, aber er dreht.

ich habe jetzt nicht das ganze Datenblatt gelesen, behaupte also nicht alles verstanden zu haben.

aber mit PWM hat das nix zu tun.

Was ist nicht verstehe: der Motor scheint recht kompfortable Möglichkeiten zu haben ihn zu steuern in dem man bestimmte Inhalten in Speicherzellen schreibt.

damit kann man dann direkt Positionen anfahren oder Geschwindigkeitskurven fahren. Oder geht das nur mit der Steuerung PD4C?

Dann würdest du den Takt/Richtungsmodus nur verwenden, weil der ohne Steuerung funktioniert?
auf alle Fälle wird das eine spaßige Angelegenheit.

Ich fürchte, mit Arduino Standardbefehlen geht das nicht mehr.

@agmue: ja Max sind 1MHz somit dreht mein motor nun mal nicht mit 100% Speed damit kann ich aber leben da ich nur bis 100 RPM möchte und der kann glaube ich 3.000 RPM daher würde mir das reichen.

@guntherb: du hast zum Teil recht. also die Steuerung PD4C ist eigentlich keine Steuerung sondern Steuerung (Treiber) mit Encoder und Motor.

Du hast aber recht man kann die Steuerung Konfigurieren und Rampen hinterlegen (Anfahrrampe, Abbremsrampe), man kann aber nicht darüber die Steuerung übernehmen Fahre 100 Schritte nach rechts und dann 20 Schritte Links und das mit dem Speed von xxRPM das geht nicht.

Ich definiere die Steuerung "PD4C" mit Ihren Grund Daten und gebe dann der Steuerung über das Signal Takt und Richtung an in welche Richtung der Motor Drehen soll und wie viele Schritte er machen soll und mit welcher RPM das macht der Motor dann auch bzw, die Steuerung mit Motor, sie Steuerung Kontrollort auch ununterbrochen den Motor Rotor ob diser sich bewegt hat ohne das die Steuerung das das wollte wenn das der Fall ist versucht die Steuerung das wider auszugleichen durch entgegen geätzte Bewegung, sprich der Motor Hält seine Position natürlich nicht über das Drehmoment hinaus.

Noch bin ich am verzweifeln der Konfiguration der Steuerung, jedoch kann ich nicht die ganze zeit nur die Bits Lesen udn versuchen zu verstehen daher wollte ich mich an das PWM Signal machen, ... was aber auch etwas Schwerer ist als gedacht, .... Arrrr der Motor regt mich auf, ...

Habe ich das richtig verstanden?
Bildschirmfoto 2015-05-04 um 12.15.39.png

Mit jedem Puls macht der Motor eine bestimmte Schrittweite.
je öfter die Pulse kommen, um so schneller dreht sich der Motor.
die Länge der Pulse ist irrelevant, wenn sie größer 200ns ist.

Dann würde ich mir aus deiner Wunschgeschwindigkeit einen Pulsabstand tp errechnen, und eine Funktion schreiben alle tp µs einen 4µs Puls ausgibt. (kürzer als delayMicroseconds(4) kann es der Arduino nicht).

Wenn du willst kannst du ja auch noch die Pulse zählen, dann weiß du wie weit er gefahren ist.

vielleicht so?

int VPin = 7; // Pin Geschwindigkeit
int RPin = 8; // Pin Drehrichtung
const int links = -1;  
const int rechts = 1;
const int stopp = 0;
unsigned long tp;

int Geschwindigkeit;
int inkr = 1;
unsigned long previousMillis;

void setup(){
  pinMode(VPin, OUTPUT);
  pinMode(RPin, OUTPUT);
}

void loop(){   
  if(millis() - previousMillis > 1000) {
    previousMillis = millis();   
    if (Geschwindigkeit > 100) inkr = inkr * -1; // 100 als wirkürliche Geschwindigkeitsobergrenze.
    if (Geschwindigkeit <   2) inkr = inkr * -1;
    Geschwindigkeit = Geschwindigkeit + inkr;
    tp = 10 * 100/Geschwindigkeit;  // aus der Geschwindigkeit eine Pulslänge errechen.
  }
  driveMotor(tp, links);  
}


void driveMotor(int _tp, int _d){  // _tp: Pulsabstand; _d: Richtung
static unsigned long lastPuls;

  if (_tp < 10 || _tp > 100000 || _d == stopp) return;  // auf Grenzen abtesten
  
  if (millis() - lastPuls < _tp) return;  // Abbruch, wenn kein Puls ausgegeben werden muss
  lastPuls = micros();
  digitalWrite(VPin, HIGH);
  delayMicroseconds(4);   
  digitalWrite(VPin, LOW);
  
  if (_d = links) digitalWrite(RPin, LOW); // drehrichtungspin setzen.
  else            digitalWrite(RPin, HIGH);
}

guntherb:
Habe ich das richtig verstanden?

Also die Frage ist nicht leicht für mich, jedoch so wie du es beschrieben hast habe ich das auch verstandenen.

Deinen Code werde ich mir mal anschauen, und versuchen zu verstehen.
Melde mich dann wider.

Hallo Gunter,
ein Anfangswert stimmt m. E. nicht, sollte sein:

int Geschwindigkeit = 2;

OK?

Die Konstante "rechts" ist nicht benutzt, Absicht?

Also ich muss gestehen das ich den Code bisher noch gar nicht verstehe :cry:

Wenn ich aber wie von agmue vorgeschlagen

int Geschwindigkeit = 2;

mache sehe ich zumindest was auf dem Logig Analyser


Bildschirmfoto 2015-05-04 um 18.54.10.png

Bildschirmfoto 2015-05-04 um 18.54.20.png
Bildschirmfoto 2015-05-04 um 18.54.20.png

Soweit ich das verstanden habe benötigst du für 100 RPM 100 Pulse pro Minute. Bei einer Pulsdauer von 4ms und 100 Pulsen verstreichen also 400 micros auf High insgesammt.

Du brauchst dann also insgesammt 5999600 micros Low um wieder auf 1 Minute zu kommen.

Das teilst du durch 100 und dann müsstest du doch die Puls Abstände haben, oder sehe ich das falsch?

Also das mit den
100 RPM = 100 Pulse pro Min
habe ich auch so verstanden, ich bin mir da aber noch nicht ganz sicher.
[EDIT]
bei 100 RPM = 100 Pulse pro Minute ist Falsch !!!!!!!

bei 100 Pulse in einer Minute macht der Motor 100 Schritte in einer Minute, da der Motor aber 200 Schritte pro Umdrehung macht würden 100 Pulse in der Minute 0,5 RPM entsprechen.

1 RPM = 200 Pulse / min
5 RPM = 1.000 Pulse / min
10 RPM = 2.000 Pulse / min
100 RPM = 20.000 Pulse / min

Berechnung: RPM * 200 = Pulse je Minute

Das ist bei den Vollschritten der Fall, man kann das teil ja auch auf Halb oder Viertelschritt einstellen

Ich glaube verstanden zu haben.

Die Puls Länge ist egal sie muss nur mindestens 200ns lang sein
Die zeit die vergeht von Start des Pulses bis zum Start des Nächsten Pulses gibt die Drehzahl an.

Sprich der Treiber / Steuerung reagiert auf die Ansteigende Flanke
und müsste die zeit zwischen ansteigender Flanke und wider ansteigender Flanke messen
denn daraus ergibt sich die Drehzahl.

Wobei jede Flanke mindestens 1µs auseinander sein muss.

Das würde dann wenn man jede µs eine Ansteigende Flanke hätte 1.000.000 Ansteigende Flanken machen in einer Minute das würden 1.000.000 Schritte entsprechen eine Umdrehung hat aber 200 Schritte das macht also 1.000.000 / 200 = 5.000 RPM entsprechen.
[/EDIT]

[EDIT]
Öm ich habe einen Rechen Fehler gemacht

1 second = 1 000 000 microseconds
1 minute = 60 000 000 microseconds
[/EDIT]

Was du da rechnest habe ich aber mal garniert verstanden.

Er rechnet, eine Minute ist 6000000 us, minus 400 us , Ergebnis 5999600

Ich habe meinen Beitrag Editiert :wink:

Ich glaube bei der Reichung ist ein Fehler denn es wird nur die Ansteigende Flanke für die Berechnung herangezogen.

Ich bin ja kein Mathegenie, aber fehlt da nicht womöglich eine Stelle:
1 Minute = 60 Sekunden = 60.000.000 µSekunden (µ = 10-6)
1 Minute - 400 µSekunden = 59.999.600 µSekunden

Muecke:
Also ich muss gestehen das ich den Code bisher noch gar nicht verstehe :cry:

Was denn?

Ah sorry, ja stimmt da fehlt eine 9 sry :smiley:
Schwierig bei sovielen 0en den Überblick zu behalten :smiley:

Bei 200 Schritten pro Minute für 100 RPM
kannste ähnlich rechnen

Einfach: 60.000.000/200 - 4 = 299996

Dadurch verteilst du 200 Pulse gleichmäßig auf 1 Minute,
wodurch sich dann 100 RPM ergeben müssten.

(4 µSekunden (High) + 299996 µSekunden (Low))*200 = 60.000.000 µSekunden = 1Minute

Addi2438:
Schwierig bei sovielen 0en den Überblick zu behalten :smiley:

Wohl war! :slight_smile: