Frequenz und Pulsweite messen und anzeigen lassen

Hallo

Ich bin neu im Forum und allgemein mit dem Thema programmieren.
Habe bisher schon einiges zusammengebastelt und hat bis jetzt auch immer irgendwann funktioniert.

Nun bin ich auf der Suche nach einem Sketch, der es möglich macht, ein PWM-Signal erstmal per serial anzeigen zu lassen und später denn auch auf dem zweizeiligen LCD-Display, wenn es denn funktioniert.

Ich habe hier noch eine Steuerungsplatine (ELV PWM200) liegen, mit der ich per PWM z.B. Motordrehzahlen steuern kann. Bisher konnte ich mit meinem Multimeter entweder nur die Freuquenz oder das Tastverhältnis messen, mit dem UNO will ich nun versuchen, mir beides gleichzeit anzeigen zu lassen.

Ist dies möglich mit nur einem digitalen Pin und wie müsste dann der Sketch aussehen?
Ich habe das Forum schon durchforstet, konnte aber keine klare Antwort finden.
Die anzuzeigenden Werte sollen im Bereich von 0-500Hz und 0-100% liegen.

Dazu steh ich noch etwas auf dem Schlauch, da es sich bei der Steuerung um einen eigenen Stromkreis handelt, wie ich da den Uno am besten anschließe.

MfG
Normo

Wenn du nach arduino und Oszilloskop oder arduino und Frequenzzähler googelst wirst du einige Beiträge darüber finden und diese sind meist auch mit Sketch.
Ich bin sicher, das hlft dirweiter.

Die Messspannung kannst du dann direkt (evtl. über einen Spannungsteiler, da max 5 Volt am Arduino) an den entsprechenden Port anschließen. Wichtig hierbei, die Masse der gemessenen Spannung muss mit der Masse des Arduino verbunden werden.

Leider kann ich dir hierzu keine weiteren Tipps geben, da ich bisher selber noch keine derartigen Projekte aufgebaut habe.

Er will nicht nur die Frequenz messen sondern auch das Tastverhältnis. Da ist es mit den Standard Frequenzzähler Programmen nicht getan

Externe Hardware schließt man am sichersten über Optokoppler an

Serenifly:
Er will nicht nur die Frequenz messen sondern auch das Tastverhältnis. Da ist es mit den Standard Frequenzzähler Programmen nicht getan

Externe Hardware schließt man am sichersten über Optokoppler an

Ja, ok, aber ist doch schon mal ein Anfang auf dem man aufbauen kann. Oder geht das garnicht?

Machbar ist es schon, aber nicht so einfach wie nur die Frequenz zu messen.

Ok, dann halte ich mich hier zurück. :wink:

normo:
Ist dies möglich mit nur einem digitalen Pin und wie müsste dann der Sketch aussehen?
Ich habe das Forum schon durchforstet, konnte aber keine klare Antwort finden.
Die anzuzeigenden Werte sollen im Bereich von 0-500Hz und 0-100% liegen.

Dazu steh ich noch etwas auf dem Schlauch, da es sich bei der Steuerung um einen eigenen Stromkreis handelt, wie ich da den Uno am besten anschließe.

Ein Arduino-Pin zum Messen reicht.

Wenn Deine PWM-Platine ein PWM-Signal mit 5V Logikpegel erzeugt, kannst Du sie direkt anschließen:
GND PWM-Platine mit GND Arduino-Platine verbinden
5V PWM-Ausgang mit Arduino-Eingang verbinden

Wenn Deine PWM-Platine allerdings ein PWM-Signal mit höherem Spannungspegel erzeugt, verwendest Du am besten Optokoppler zum Schalten des Signals mit galvanischer Trennung der beiden Geräte.

Die Software muß im Prinzip immer die Dauer von HIGH und LOW Pegel messen.

Die Dauer eines HIGH und eines LOW Impulses zusammen = Periodendauer des PWM-Signals.
Die PWM-Frequenz ergibt sich dann als Kehrwert 1 geteilt durch Periodendauer in Sekunden.

Das Tastverhältnis in % ergibt sich zu
T= (Dauer HIGH) * 100 / (Dauer HIGH + Dauer LOW)

Ob Du das Signal einfach "pollen" kannst oder ob Du eine aufwändigere Interruptverarbeitung benötigst, hängt von dem ab, was der Sketch sonst noch "gleichzeitig" machen soll. Wenn Du z.B. zwischen zwei Messungen noch ein 16x2 Text-LCD vollschreiben willst, mit 32 Zeichen = ca. 3,2 Millisekunden Dauer, dann kannst Du die exakten Signalzeiten natürlich nur mit einer Toleranz von 3ms messen.

Bei 500 Hz PWM-Frequenz hat eine komplette PWM-Periode eine Dauer von 2ms, da wäre es natürlich ungünstig, Zeiten von 2ms Dauer mit 3ms Messtoleranz zu messen. Also würde ich sagen, Du mußt die Signaldauern per CHANGE-Interrupt messen.

An einem UNO Board wären dazu die digitalen Pins Pin-2 und Pin-3 möglich, an denen externe Interrupts problemlos ausgewertet werden können.

jurs:
Bei 500 Hz PWM-Frequenz hat eine komplette PWM-Periode eine Dauer von 2ms, da wäre es natürlich ungünstig, Zeiten von 2ms Dauer mit 3ms Messtoleranz zu messen. Also würde ich sagen, Du mußt die Signaldauern per CHANGE-Interrupt messen.

Bei einer Auflösung von 1% Tastverhältnis komme ich auf 20µs, was mir noch ambitionierter erscheint.

Ich habe einen teensy3.2 mit einer PWM-Frequenz von 488.28 Hz 1% HIGH an einen UNO PinD2 Interrupt0 angeschlossen, der UNO also zum Messen. Die Ausgabe zeigt konstant highTime: 12 lowTime: 2028. Saleae zeigt 16 und 2032, theoretisch sollte es 20 und 2028 sein.

Die Größenordnung stimmt.

Verwendeter Sketch zum Messen:

// UNO
const byte messpin = 2;
volatile unsigned long highTime;
volatile unsigned long lowTime;
volatile unsigned long startmicros;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, messung, CHANGE);
}

void loop()
{
  delay(1000); // every second
  Serial.print("highTime: "); Serial.print(highTime); Serial.print("  ");
  Serial.print("lowTime: "); Serial.print(lowTime); Serial.print("  ");
  Serial.println();
}

void messung() {
  if ((PIND >> 2) & 1) {
    lowTime = micros() - startmicros;
  } else {
    highTime = micros() - startmicros;
  }
  startmicros = micros();
}

Hallo

Danke schonmal für die Antworten.
Ich habe bereits gegoogelt und nach allem möglichen gesucht.

Mit Interrupt hab ich mich bisher nicht beschäftigt, ist also völliges Neuland für mich.
Ich hatte schon erste Anhaltspunkt gefunden, u.a. mit dem Befehl pulseIn().
Kann man damit die Aufgabe lösen?

Habe heut mit meiner Platine rumgespielt, bzw. versucht ein messbares Signal zu generieren.
Entweder ist die Platine Schrott, der Bausat generell Murks oder ich bin einfach nur zu blöd dazu den zu benutzen... auf jeden Fall ist sie jetz reif für die Tonne.

Dabei fiel mir ein, der UNO kann doch selbst ein PWM-Signal erzeugen, um z.B. an bestimmten digitalen Pins eine LED zu dimmen.
Die Frequenz ist zwar fest, soll so weit ich weiß bei um die 500 oder eher 490Hz liegen, aber das Tastverhältnis lässt sich z.B. beliebig mittels Poti verstellen.
Ich bezweifel aber, das der UNO sein eigenes Signal messen kann, wegen der Schleife, die nacheinander durchlaufen wird, also müsste ein zweiter her... wie bei agmue der teensy3.2 ???

normo:
... wie bei agmue der teensy3.2 ???

Wobei ich dann den teensy mit 96 MHz zum Messen nehmen würde. Übrigens hat mir ein kleiner Logicanalyzer an USB geholfen, den Sketch zu überprüfen.

Man kann auch auf dem Arduino sehr genau und weitgehend blockierungsfrei messen. Dafür ist Timer1 mit der Interrupt Capture Einheit da.

Es gibt eine FrequencyMeasure Library die genau das verwendet. Aber um das Testverhältnis statt der Frequenz zu messen müsste man die abändern. Also mittendrin die Flanke ändern auf die getriggert wird und zwei Zeiten abspeichern statt eine.

normo:
Dabei fiel mir ein, der UNO kann doch selbst ein PWM-Signal erzeugen, um z.B. an bestimmten digitalen Pins eine LED zu dimmen.
Die Frequenz ist zwar fest, soll so weit ich weiß bei um die 500 oder eher 490Hz liegen, aber das Tastverhältnis lässt sich z.B. beliebig mittels Poti verstellen.
Ich bezweifel aber, das der UNO sein eigenes Signal messen kann, wegen der Schleife, die nacheinander durchlaufen wird, also müsste ein zweiter her... wie bei agmue der teensy3.2 ???

Die PWM-Frequenz lässt sich verstellen. Dazu gibt es immer wieder Threads bzw. liefert dir Google die Infos.

Du brauchst das Tastverhältnis nicht zu messen. Dein Programm weiß ja, was es eingestellt hat und der Arduino gibt das aus als Signal aus. Du liest das Poti aus, gibst den Wert als Tastverhältnis vor und der Arduino macht das.
Natürlich kann der Arduino sein eigenes Signal messen. Die PWM-Ausgabe geht in Hardware. Das Programm muss nur das Tastverhältnis einstellen. Die Erkennung des Tastverhältnisses würde im Interrupt laufen. Es ist nur nicht besonders sinnvoll, da er ja den Wert schon aus dem Programm kennt.

Ich glaube es ging eher darum das damit zu testen. Real will er ja ein externes Signal messen.

normo:
Habe heut mit meiner Platine rumgespielt, bzw. versucht ein messbares Signal zu generieren.
Entweder ist die Platine Schrott, der Bausat generell Murks oder ich bin einfach nur zu blöd dazu den zu benutzen... auf jeden Fall ist sie jetz reif für die Tonne.

Dabei fiel mir ein, der UNO kann doch selbst ein PWM-Signal erzeugen, um z.B. an bestimmten digitalen Pins eine LED zu dimmen.

Ich habe das so verstanden, dass er den ursprünglichen Plan aufgegeben hat und jetzt überlegt, das PWM-Signal mit dem Arduino direkt zu erzeugen

Ah, ja das macht Sinn. Der Arduino macht PWM übrigens vollständig in Hardware. Ohne dass Interrupts ausgelöst werden.
Wenn man das selbst implementiert sind je nachdem wie man es macht auch andere Frequenzen möglich als die die man rein über dein Prescaler einstellen kann. Auf Timer1 kann man nämlich auch den Zählbereich des Timers genau definieren.

Und dann ist der Einwand natürlich berechtigt dass sowohl Frequenz als auch Tastverhältnis bekannt ist.

Um PWM zu erzeugen gibt es 2 Techniken:

  • konstante Frequenz und das H/L Verhältnis ändert sich (das impliziert man wahrscheinlich mit PWM)
  • es ist aber auch möglich, auf einen Impuls gleicher Länge nach dem Flankenwechsel (bsp. L) einen unterschiedlich langen (H) Impuls zu schicken und so PWM zu erzeugen. Hier ändert sich die Frequenz!

Dies sollte man im Hinterkopf haben. Man kann bei der Programmerstellung nicht davon ausgehen, wenn man 1x die Freuenz bestimmt hat, das die bei einem anderen Tastverhältnis auch gleich sein muß :smiling_imp:

Der Arduino hat ja schon einen Quarz, oder manchmal auch nur einen Resonator auf dem Board. Wenn es noch genauer sein soll, kann man als Frequenznormal auch ein GPS Modul zweckentfremden. Das GPS Signal ist hochpräzise und um ein paar Zehnerpotenzen genauer, als ein Quarz und trotzdem noch wesentlich preiswerter, als ein temperaturstabilisierter Quarz (OCXO) oder gar ein Rubidium-Frequenznormal.

Genau das is der Plan, eine "unbekannte" Frequenz und das Tastverhältnis zu messen.
Das die Impulse dem Arduino denn schon bekannt sind, ist mir bewusst, er soll aber so tun, als wäre es ein externes Signal und es deshalb neu messen, soweit zumindest meine Theorie.

Wie sieht es mit dem Befehl "pulsIn()" aus, kann man darüber ggf. beides messen?

Wie sieht es mit dem Befehl "pulseIn()" aus, kann man darüber ggf. beides messen?

Ja.

Allerdings arbeitet pulseIn() blockierend. Man kann also während der Messung sonst nichts machen.

Der Vorteil gegenüber der "besseren" Lösung (Serenifly - 2015-11-22, 19:49:23) ist, dass man sich nicht um die atmega Innereien kümmern muss.

In wie weit ist dieses blockieren zum messen hinderlich?

Wird einmal die Frequenz gemessen und danach erst ausgegeben, um danach erneut zu messen und die nächste Messung auszugeben?
Wenn das so ist, denn passiert dies doch, je nach gemessener Frequenz und den restlichen Teil des Sketches, mehrfach in der Sekunde.
Das sollte doch theoretisch trotzdem noch reichen, um es sich auf Monitor oder LCD anzeigen zu lassen oder irre ich mich.

Ich habe bisher noch nicht mit Interrupt oder Timer1 gearbeitet, weiß also auch noch nicht was das ist, funktioniert, etc.
Und da englisch leider eine meiner stärksten Schwächen ist, helfen mir die meisten Google-Ergebnisse nicht wirklich weiter

Also mit der FrequencyMeasure Library kann man schon mal die PWM Frequenz eines anderen Arduinos messen. Mal sehen ob ich das hinbekomme das umzubiegen. Kann mir vorstellen dass es da an einigen Stellen Probleme gibt.

Wenn man sonst nichts machen will, gehen aber auch andere Optionen.