versuche gerade die ISR(TIMER0_OVF_vect) in der wiring.c zu modifizieren, um mit einem passiven 5V Buzzer einen 1kHz und einen 500Hz Ton erzeugen zu können.
Jedoch ohne die Funktionen millis(), micros() und delay() zu beeinflussen.
Dazu habe ich mir eine 2te portable Arduino-IDE angelegt, die ich mit "*_mod" kenntlich gemacht habe. Dort habe ich die core-Files modifiziert.
Dieser Beitrag wurde auch im deutschen Arduino Forum gepostet:
wiring.c
// Modifizierung: *********************************************************
static uint8_t soft_prescaler_2msec = 2;
volatile uint8_t enable_buzzer = 0;
// ************************************************************************
#if defined(TIM0_OVF_vect)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
// Modifizierung: *************************************************
if (enable_buzzer > 0)
{
if (enable_buzzer == 1)
BUZZER_PORT ^= (1<<BUZZER_PIN); // Buzzer-Pin togglen @ 1kHz
else if (enable_buzzer == 2)
{
if (--soft_prescaler_2msec == 0)
{
soft_prescaler_2msec = 2;
BUZZER_PORT ^= (1<<BUZZER_PIN); // Buzzer-Pin togglen @ 500Hz
}
}
}
// ******************************************************************
}
Komischerweise erzeugt mein Sketch nicht 2 Töne, sondern 3.
Die ersten 2 Töne wie erwartet, der 3te ist ein hoher schriller Ton.:huh:
Wenn ich das ganze ne Weile laufen lasse, verschwindet der 3te schrille Ton auf einmal. Bevor er dann wieder plötzlich auftaucht.
Kann das was mit der Zeitkorrektur fract zu tun haben?
Leider habe ich keine Ahnung wie die core-files ineinander mit den #includes verschachtelt sind. Wo finde ich hierzu Infos?
Sind Definationen bzw. Deklaration der globalen Variablen so richtig angelegt?
Klar, lag das zu 3/4 fertig in meiner Wühlkiste.
Aber dennoch war das Arbeit. Suchen, Anpassen, testen, Frequenz messen, posten.
Die mache ich mir natürlich nicht, bei einem Crossposter.
Ok, da scheint "jetzt" Einsicht zu leuchten.
Es allerdings die Idee, die mich stört, und die war eben vorher.
Und die Idee ist halt die: Je mehr Foren, desto mehr laufen los, und machen sich Arbeit, für mich.
Es ist die sich so zeigende Egozentrik, die ich nicht unterstützen will.
Eigentlich ein fetter Grund, meine Lösung wieder zu löschen.
Wie auch immer:
Das Kind liegt jetzt im Brunnen, rückgängig machen geht nicht, oder hilft nicht.
Und die Idee ist halt die: Je mehr Foren, desto mehr laufen los, und machen sich Arbeit, für mich.
Die Idee mehr Menschen zu erreichen um eventuell eine Anwort zu bekommen, ja.
Möglichst viele Menschen für mich einzuspannen, damit sie für mich eine Lösung herbeischaffen, nein.
Da war kein bewußter egozentrischer Gedanke im Spiel.
War leider einfach nur ein "Schnellschuß" aus viel Frust heraus - nach stundenlangen lesen von englischen Anleitungen und coden ohne Erfolg.
Dies mindert aber nicht mein Wertschätzung Menschen gegenüber die anderen helfen.
Also, Danke für Deinen Post und die damit verbunde Arbeit!
Leider verstehe ich Deinen Code momentan nicht wirklich.
Könntest Du eventuell den Code etwas kommentieren?
Vielleicht hast Du auch eine Idee, wo der Fehler bei meinem Code liegt?
wegen dem nicht verändern von millis & Co. Das geht ganz gut wenn die Änderung am "millis Timer" konstant bleiben. Man schreibt sich seine eigene millis Funktion die den original millis Wert um den Änderungsfaktor korrigiert. Läuft bspw. der Timer default mit Prescaler 1 und man ändert ihn auf 2 ist millis um die Hälfte zu langsam. Die eigene Funktion gibt den millis Wert um Faktor 2 korrigiert zurück. Dann stimmts wieder.
Der Unterschied zu deinem Code:
Meiner bleibt kompatible zum Rest der Welt. Man muss allerdings Obacht geben, wenn man PWM auf dem Timer nutzen will. Weil PWM eben auch die Compareregister nutzt.
Also die Kurzfassung:
Der Timer bietet 3 Interruptquellen.
Du nutzt den Overflow Interrupt
Ich die beiden Compare Interrupts
Eine ISR für beide Interrupts.
In der ISR wird der Pin getoggelt.
Durch geschicktes setzen der Compareregister (128 Timerticks Abstand) wird ein symmetrischer Rechteck erzeugt.
Durch ein- und abschalten der zugehörigen Interruptquellen lassen sich so die Frequenzen 980Hz, (980/2)Hz und 0 Hz, an dem Pin, erzeugen. Was in etwa deinen gewünschten 1kHz und 500Hz entspricht.
Wenn dir das nicht genau genug ist, verwerfe meine Lösung.