Arduino Forum

International => Deutsch => Topic started by: Kay19 on Dec 08, 2019, 01:43 pm

Title: Impulsgenerator?
Post by: Kay19 on Dec 08, 2019, 01:43 pm
Hallo Forum,

nach zwei Jahren Pause möchte ich mein altes Tachoprojekt nochmal neu aufsetzen. Dazu hab ich für Testzwecke eine Art Impulsgenerator gebaut. Zuerst hatte ich tone() verwndet, bis ich gelesen hatte das ich damit nur Frequenzen >30Hz erzeugen kann. Für mein Tachoprojekt reicht das aber nicht, also dachte ich, ich könnte mittels Timer einfach einen Pin zwischen HIGH und LOW hin- und herschalten lassen. Zusätzlich noch ein Poti um die Frequenz zu verändern...
Leider scheint das Ganz nicht zu funktionieren, das Programm läuft zwar, nach einfügen der Serial.print-Funktionen sehe ich auch das das Poti funktioniert, jedoch scheint an PIN2 kein Signal anzukommen. Habe für Testzwecke mal PIN13 verwendet um anhand der verbauten LED etwas zu erkennen, aber auch hier scheinbar keine Funktion. Ich vermute die Interruptroutine wird nicht aufgerufen, warum?
Code: [Select]

int impuls=0;
volatile byte b_mode=0;
volatile int dauer_neu=0;


ISR(TIMER1_COMPA_vect) { // will be called when an interrupt occurs at timer 1
    if (b_mode==1) {
    digitalWrite(2, HIGH);
    b_mode=1;
  } else {
    digitalWrite(2, LOW);
    b_mode=0;
  }
  OCR1A=dauer_neu;
 
}

void setup() {
  // put your setup code here, to run once:
  pinMode(2,OUTPUT);
  Serial.begin(19200);
  digitalWrite(2, LOW);

  cli(); //Lösche globales Interrupt-Enable-Bit
  //CTC-Mode aktivieren
  TCCR1A = 0; //Löschen des TCCR1A-Registers
  TCCR1B = 0; //Löschen des TCCR1B-Registers
  TCNT1  = 0; // reset counter value
  OCR1A=32500;  //countervergleichsregister
  TCCR1B |= (1 << CS11) | (1 << CS10);  //Setze CS11 und CS12 (Clock Select) Takt/64
  TCCR1B |= (1 << WGM12);  //Setze CTC-Mode
  TIMSK1 |= (1 << OCIE1A); //Bit Output Compare A Match Interrupt Enable setzen
 
 
}

void loop() {
  // put your main code here, to run repeatedly:
  impuls = analogRead(A2);
  if (impuls>0){
      sei();
      dauer_neu=impuls <<5; //mit 32 multiplizieren
     
  } else {
    cli();
    dauer_neu=0;
    digitalWrite(2,LOW);
  }
  Serial.print("dauer_neu: ");Serial.println(dauer_neu);



}


Viele Grüße
Title: Re: Impulsgenerator?
Post by: combie on Dec 08, 2019, 01:51 pm
Code: [Select]
if (impuls>0){
      sei();
     
     
  } else {
    cli();
 
  }

*gekürzt*
Was soll denn das unsymetrische Zeug?
Title: Re: Impulsgenerator?
Post by: Kay19 on Dec 08, 2019, 02:04 pm
ich bin unsicher ob ich die Frage richtig verstanden habe, der If-Teil sorgt dafür das keine 0 ins OCR1A geschrieben wird.
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 08, 2019, 02:49 pm
Es geht um deine etwas willkürlich verstreuten sei() und cli(). Du kannst nicht einfach beliebig die Interrupts generell ausschalten. Das darf immer nur kurzfristig gemacht werden, d.h. cli() und sei() müssen immer paarweise kurz hintereinander auftauchen. Es gibt schließlich auch noch andere Funktionen im Arduino, die auf Interrupts angewiesen sind.
Edit: Wenn die ISR nicht mehr aufgerufen werden soll, musst Du explizit diesen Interrupt im TIMSK1 wieder abschalten.

Zu deinem Problem: Das toggeln in der ISR funktioniert nicht, da Du dein b_mode nicht umschaltest. ( wird auf 1 gesetzt, wenn es schon 1 ist, ebenso wenn es 0 ist - es bleibt einfach wie es ist ).
Den aus Ausgang toggeln kannst Du aber auch einfach mit
Code: [Select]
  digitalWrite(2, !digitalRead(2) );
Title: Re: Impulsgenerator?
Post by: postmaster-ino on Dec 08, 2019, 02:57 pm
Hi

Und?
Das entspräche 256.

Auch wird Dir das cli 'auf die Füße fallen' - lasse Dir Mal die millis() ausgeben - Die dürften von dem Dauer-cli durchaus beeindruckt sein.

MfG
Title: Re: Impulsgenerator?
Post by: combie on Dec 08, 2019, 03:02 pm
ich bin unsicher ob ich die Frage richtig verstanden habe,
Verwende besser ATOMIC_BLOCK (https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html) Konstrukte.


Quote
der If-Teil sorgt dafür das keine 0 ins OCR1A geschrieben wird.
Den Teil habe ich extra raus geschnitten, da sich meine Aussage eben genau darauf NICHT bezieht.
Meinte schon die die unsymetrische Interrupt ein/aus schalterei.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 08, 2019, 09:14 pm
Hallo,

du solltest dich vorher dringend mit dem Timer allgemein befassen.
Du möchtest dir im Grunde einen Frequenzgenerator bauen mit jederzeit änderbarer Frequenz.
Dabei gibts paar Dinge zu beachten hinsichtlich des aktualisierens der Compare-Match Register.
Lies den Abschnitt im Manual zum Timer. Sonst wird das nichts, glaube mir.
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 08, 2019, 09:55 pm
Das macht er schon richtig, und das funktioniert auch.

Sein Problem ist der Fehler beim toggeln des Ausgangs ( wobei er das auch der HW überlassen könnte ), die falschen cli/sei und den nicht ATOMIC Zugriff beim Ändern des dauer_neu.
Auch wäre es sinnvoll, die Variable dauer_neu als 'unsigned int' zu deklarieren. Schließlich hat auch OCR1A kein Vorzeichen.
Dass er 'volatile' noch nicht richtig verstanden hat, ist dabei erstmal Nebensache.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 08, 2019, 10:49 pm
Mit dem richtigen Timer mode spielt die Hardware den Ton doch ganz von alleine ab, ohne ISR.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 08, 2019, 11:11 pm
Hallo,

ja okay, wenn er OCR1A in dessen ISR aktualisiert passt das, Entschuldigung.
Beim Rest muss der TO einfach nochmal seinen Code lesen.
Ich würde ja der Einfachheit vorschlagen immer eine bool Variable negieren und diese am Pin ausgeben.

Mit dem richtigen Timer mode spielt die Hardware den Ton doch ganz von alleine ab, ohne ISR.
Würde ich pauschal immer dafür plädieren. Wenn keine anderen Gründe vorliegen irgendeinen Mode mit OCRxn Buffer.
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 09, 2019, 08:54 am
Mit dem richtigen Timer mode spielt die Hardware den Ton doch ganz von alleine ab, ohne ISR.
Die ISR braucht er immer, um die Frequenz verändern zu können ( setzen von OCR1A ). Wie ich auch schon schrieb, kann er das Toggeln des Ausgangs der HW überlassen. Der Timer-Mode bleibt dabei aber derselbe (er will ja eine variable Frequenz, und kein PWM ), er muss nur den Ausgang entsprechend aktivieren ( in TCCR1A ). Allerdings ist er dann auf einen festen Pin ( hier 9 ) festgelegt. Macht er es per SW kann er den Pin selbst frei bestimmen.

Aber jetzt schau'n wer mal, was der TO zu dem Ganzen sagt  ;) .
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 09, 2019, 10:53 am
Mehr als einen Pin braucht man ja selten mit der gleichen Frequenz. Zum Ändern der Frequenz ist IMO kein ISR notwendig, die Zugriffe erfolgen bei 16 Bit Zählern synchronisiert.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 09, 2019, 11:07 am
Hallo,

da muss ich nochmal einhaken. Man kann einen Frequenzgenerator ohne ISR inkl. Pulsweitenänderung bauen.
Hier in dem Fall müßte man nur die Pulsweite konstant auf 50% halten.
Das funktioniert zum Bsp. alles im Phase Correct Mode einwandfrei, weil die Compare Register gepuffert sind.
Dadurch kann man gefahrlos jederzeit die Einstellung ändern.
Ob das sich hier im Falle lohnt ist eine andere Frage. Möchte nur sagen es ginge auch ohne ISR.  ;)
Nach nochmaliger aktueller Überlegung würde ich an Stelle vom TO jedoch bei CTC bleiben.
Dann muss man sich nicht um die Pulsweitenanpassung kümmern.  :)


Mehr als einen Pin braucht man ja selten mit der gleichen Frequenz. Zum Ändern der Frequenz ist IMO kein ISR notwendig, die Zugriffe erfolgen bei 16 Bit Zählern synchronisiert.
:o :o :o   In Modi ohne gepufferte Compare Register macht der Timer Mist wenn du zufällig zur falschen Zeit den Comparewert änderst. Der Wert wird sofort übernommen. Wenn der TCNT zu dem Zeitpunkt schon drüber ist läuft der Timer kurzzeitig falsch. Deswegen ändert man hier im Fall CTC den Compare in der eigenen Compare ISR, da kann nichts schief gehen.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 09, 2019, 04:46 pm
Oder man löscht TCNT nach der Änderung des OCRx.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 09, 2019, 11:08 pm
Hallo,

Oder man löscht TCNT nach der Änderung des OCRx.
ich habe lange überlegt wie du das meinen könntest, komme jedoch immer zu der Überzeugung das die Aussage keinen Sinn macht. Egal welcher Timermode.

a) ich habe eine Konstellation nicht auf dem Schirm (kann was übersehen haben)
b) ich denke du hast dich gedanklich verrannt (passiert mir auch manchmal)

Du müßtest jetzt dazu sagen in welchen Mode du wann den OCR ändern und TCNT nullen möchtest.  ?
Dazu vielleicht noch ohne ISR?  Ich sehe wie gesagt keine Möglichkeiten.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 10, 2019, 03:01 am
Dann schauen wir uns doch mal die allgemeine Timer Funktion an. Dazu schlagen jetzt alle das 16-bit Timer/Counter Block Diagram im 328er Datenblatt auf, bei mir Bild 16-1. Haben das alle gefunden?

Dort finden wir das Timer-Counter-Register TCNT, 2-3 Output Compare Register OCR und ein Input Compare Register ICR. Im Betrieb läuft TCNT von BOTTOM (0) bis TOP und wird dann zurückgesetzt oder wieder heruntergezählt. TOP gibt also die Frequenz vor und kann eine Konstante sein oder in ICR oder OCRA (CTC mode) vorgegeben werden. Wer Angst hat, daß eine zu lange Pause vorkommt weil TCNT höher ist als das neue TOP, kann nach dem Setzen von TOP den TCNT auf 0 löschen.

Wenn man das einmal begriffen hat, ist der Rest (PWM...) auch nicht mehr schwer zu verstehen.

Noch Fragen?
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 10, 2019, 09:18 am
Wer Angst hat, daß eine zu lange Pause vorkommt weil TCNT höher ist als das neue TOP, kann nach dem Setzen von TOP den TCNT auf 0 löschen.
Es kommt immer darauf an, wie exakt ich es beim Übergang der Frequenzen haben will. Auch das Rücksetzen führt dazu, dass ich eine Periode bekomme, die weder der alten, noch der neuen Frequenz entspricht.
Sauber geht es nur über die ISR, oder - wie schon angesprochen - über einen PWM mode, bei dem TOP durch OCR1A mit double buffering definiert wird. Um bei einem 50% PWM-Verhältnis zu bleiben, müssen dann aber immer beide OCR-Register parallel verändert werden. Da das aber nicht wirklich gleichzeitig möglich ist, können auch da race-Bedingungen auftreten.

Ob das alles im konkreten Anwendungsfall stört, ist eine andere Frage. Warten wir doch einfach mal was Kay dazu sagt.
Title: Re: Impulsgenerator?
Post by: combie on Dec 10, 2019, 09:53 am
Quote
Um bei einem 50% PWM-Verhältnis zu bleiben,
Wie kommst du auf die Idee, dass ein Tacho ein 50% Verhältnis sehen möchte

Zumindest der Threadtitel spricht eindeutig von Pulsen.
Und das ist auch das, wie ich Tachos kenne


Ich, für meinen Teil, habe mich entschieden nicht an der Lösungsfindung teilzunehmen, bis das Thema geklärt ist.
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 10, 2019, 10:17 am
Da ist was dran. Ich hatte mich an dem Sketch im Ausgangspost orientiert - da wird ein Signal mit 50% Tastverhältnis erzeugt. Bei Impulsen gleicher Länge, aber unterschiedlicher Wiederholfrequenz sieht das alles wieder anders aus.
Ist wohl wirklich am besten wir warten mal ab was Kay sagt.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 10, 2019, 11:14 am
Noch Fragen?
Hallo,
du hast meine Frage noch nicht beantwortet.
Zu welchen Zeitpunkt möchtest du TCNT nullen?
Woher weißt du (ohne ISR ?) das du es 'jetzt' tun mußt?
Von welchen Mode redest du in dem du das machen möchtest?
Der Anspruch ist saubere Frequenzen zu erzeugen und nicht irgendwas was danach aussieht.


Wegen den 50% Tastverhältnis. Ich glaube in seinem letzten Thread dazu wollte er nur verschiedene Frequenzen erzeugen.
Title: Re: Impulsgenerator?
Post by: combie on Dec 10, 2019, 11:45 am
Quote
Wegen den 50% Tastverhältnis. Ich glaube in seinem letzten Thread dazu wollte er nur verschiedene Frequenzen erzeugen.
Was er will, ist eine Sache.
Was er muss, evtl. eine andere.

Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 10, 2019, 03:40 pm
du hast meine Frage noch nicht beantwortet.
Ich hab's versucht, aber Deine weiteren Fragen deuten an, daß Du mich nicht verstehst oder verstehen möchtest.
Quote
Der Anspruch ist saubere Frequenzen zu erzeugen und nicht irgendwas was danach aussieht.
Wo steht das? "eine Art Frequenzgenerator" läßt für mich jede Menge Optionen offen.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 10, 2019, 11:34 pm
Hallo,

nach dem Auftritt in #15 habe ich mehr erwartet.

Frequenzgeneratoren kann man auf verschiedenen Wegen programmieren. Nur gehört deine nicht dazu.

Im CTC Mode kann man in der Compare ISR fehlerfrei den Comparewert ändern. TCNT wird automatisch genullt.

Mit deiner Methode ohne ISR änderst du ohne jede Kontrolle zu beliebigen Zeiten den Comparewert, du weist nicht wo der TCNT gerade steht. Dann kannste das TCNT nullen auch sein lassen. Die Chancen stehen 50 zu 50 das TCNT vorm manuellen Nullen näher an 0 oder näher am Überlauf ist. Egal was du machst, du erzeugst beim Frequenz ändern falsche Pulse.

Warum soll man das falsch machen wenn es richtig machbar ist?

Wenn du das für dich machst ist das dein Problem.
Wenn du das im Forum als Lösung darstellst interveniere ich.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 11, 2019, 03:54 am
Man muß den TCNT nicht zwangsläufig nullen, nur wenn er höher ist als das neue TOP. Dann kann man ihn auch auf einen Wert knapp unterhalb von TOP setzen, was einen sanften Übergang ergibt.
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 11, 2019, 12:54 pm
Hallo,

egal wie du an dem falschen Ansatz rumdokterst, es wird dadurch nicht richtiger.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 11, 2019, 01:09 pm
Man kann TCNT sogar exakt auf den Wert setzen, mit dem das laufende Intervall mit der alten Dauer beendet wird. Damit sind Interrupts hier - wie so oft - nicht notwendig. Trotzdem danke für die Hilfestellung :-)
Title: Re: Impulsgenerator?
Post by: postmaster-ino on Dec 11, 2019, 01:53 pm
Hi

Da ich aber 'in diesem Moment' gar keine Ahnung habe, wo der Counter steht, ist's noch gar nicht klar, ob ich 'JETZT' einen Impuls brauche.
Da wäre Es IMHO besser, den Nächsten regulären Impuls abzuwarten (die alte Frequenz), um dann auf die Neue umzuschalten.
Wenn ich mittendrin egal was manipuliere, passt der Impuls weder zur alten, noch zur neuen Vorgabe - Jitter?

MfG
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 11, 2019, 02:06 pm
Hallo,

egal was du dir ausdenkst, es wird nur immer peinlicher für dich. Wenn du deine Theorien praktisch zu Ende denken würdest könntest du es verstehen. Dafür müßtest du jedoch von deinem Pferd runter. Du fummelst nachwievor ohne jeden Kontrollmechanismus zu einem x-beliebigen Zeitpunkt am TCNT rum. Die negativen Folgen für die Timerperiode liegen auf der Hand.
Title: Re: Impulsgenerator?
Post by: DrDiettrich on Dec 11, 2019, 06:08 pm
Auf der Hand liegt lediglich, daß Du keine große Ahnung hast, wie man mit der Hardware eines Controllers umgehen kann und sollte. Bleib doch bei Deinen Interrupts und laß andere Leute andere Lösungen bevorzugen, statt sie völlig unqualifiziert anzupissen :-(
Title: Re: Impulsgenerator?
Post by: Doc_Arduino on Dec 11, 2019, 07:25 pm
Hallo,

ich nehme die Tür.
Title: Re: Impulsgenerator?
Post by: MicroBahner on Dec 11, 2019, 09:23 pm
Ich hoffe, der TO ist nicht so verschreckt, dass er sich gar nicht mehr meldet.
Sein grundsätzlicher Ansatz für eine Frequenzerzeugung war ja nicht verkehrt, er hat nur ein paar Fehler eingebaut weshalb es nicht funktioniert hat.
Sollte er aber wirklich feste Impulse mit variabler Wiederholfrequenz brauchen, muss man das nochmal anpassen.