Eingangsfrequenz bearbeiten (CNC Laserdiode)

Hallo zusammen,

ich habe folgenden Gedanken und wollte wissen, ob das überhaupt machbar ist:?

Ich bekomme eine Frequenz vom CNC Controller (sauberes Rechtecksignal) am Eingang eines Ardu, möchte die high und low Zeit bestimmen um dann am Ausgang eine bearbeitete Frequenz zu bekommen, mit gleicher Periodenlänge, jedoch viel mehr high und weniger low .

Bis jetzt habe ich eine einstellbare Pulslänge (Poti) fest an einen rising Interrupt gehängt. Das führt aber immer wieder zu Aussetzern, da sich die Frequenz ändert.

volatile int Laserfreigabe = 0;
volatile int Pulslaenge = 0;
//volatile int Pulslaenge = analogRead(A0); // Wert  ergibt Pulslänge in Mikrosekunden

void setup() {
// Definition der Ein- und Ausgänge

pinMode (2, INPUT); // Eingang X-Puls
pinMode (3, INPUT); // Eingang Y-Puls
pinMode (4, INPUT); // Eingang Z-Puls
pinMode (5, INPUT); // Eingang Z-Richtung
pinMode (13, OUTPUT); // Ausgang Laserpuls
pinMode (12, OUTPUT); //Testpin Ausgang Laserpuls
pinMode (6, OUTPUT); //Ausgang LD Laserfreigabe
pinMode (A0,INPUT);
Pulslaenge = analogRead(A0); // Wert  ergibt Pulslänge in Mikrosekunden
Pulslaenge = map(Pulslaenge, 0, 1023, 0, 2000);

// Interruptroutinen initialisieren

attachInterrupt (0, xachse, RISING);
attachInterrupt (1, yachse, RISING);
Serial.begin(9600);
}

void loop() {



// Abfrage der Z-Achse


int zpuls = digitalRead (4);

if (zpuls == HIGH) Laserfreigabe = (!digitalRead (5)); // Z-Achse Richtung unten = 0
zpuls = LOW;
digitalWrite (6, Laserfreigabe);
digitalWrite (12, LOW);

}

void xachse() {

// Interrupt X-Achse ausführen

if (Laserfreigabe == 1) digitalWrite (12, HIGH);
delayMicroseconds (Pulslaenge);
digitalWrite (12, LOW);
}

void yachse() {

// Interrupt Y-Achse ausführen

if (Laserfreigabe == 1) digitalWrite (12, HIGH);
delayMicroseconds (Pulslaenge);
digitalWrite (12, LOW);
}

Ich hab schon gelesen, dass eigentlich kein delay hier sein sollte beim Interrup

Ergänzung vom Oszi

Da stimmt gar nichts.

Analog Read liest keine PWM Tastverhältnis sondern eine analoge Spannung. Wenn Du einen analogen Eingang mit einem PWM Signal fütterst erhälst Du nur ca 0 und 1023.

digitalwrite() braucht zwischen 5-17 µS und ist darum auch nicht geeignet.

Grüße Uwe

Hier habe ich gezeigt wie man ein PWM Signal blockierungsfrei messen kann:

http://forum.arduino.cc/index.php?topic=360964.msg2493817#msg2493817

Die Library ist im Anhang. Geht aber nicht mit hohen Frequenzen!

In dem Beispiel wird aber nicht jeder gemessene Wert sofort ausgeben. Statt dessen werden 30 Messungen genommen und der Mittelwert gebildet. Das kann man auch wahrscheinlich auch anders machen, aber ob man damit jede einzelne Periode zuverlässig messen kann weiß ich nicht. Wenn man nicht die Ergebnisse groß auf Serial ausgibt geht es wahrscheinlich. Aber das wirklich langsame an der Sache ist die serielle Kommunikation. Außerdem sieht man es natürlich auch nicht richtig wenn man alle paar ms was auf Serial schreibt. Deshalb das delay(200). Auf jeden Fall müsste man dann die Ergebnisse schnell genug verarbeiten. Standardmäßig hat der Ringpuffer für die Messungen Platz für 12 Ergebnisse.

Auf einem UNO muss man das Signal an Pin 8 anschließen!

Danke,

dann werde ich mal weiter lesen und mein nächstes Ergebnis posten

Kommt natürlich auch darauf an wie schnell sich die Frequenz verändert und wie schnell du darauf reagieren musst. Es ist durchaus möglich, dass du auch ein paar Messungen mitteln kannst um es etwas sauberer zu haben.

Daraus dann wieder ein Signal zu machen ist das nächste Problem. So naiv wie da mit high -> delay -> low -> delay ran gehst wird das nie was werden!

Außerdem scheint es so dass du die Länge von zwei Signale messen willst. Das geht so nicht! Nur eines. Man kann solche Zeiten aber auch mit micros() messen. Dazu gab es hier irgendwo glaube ich schon mal Code...