ich nehme immer Verbesserungen vor wenn mir was auffällt. Kann sein das eine Formel fehl schlug wegen Standard Integer Rechnung (Wertebereichsüberlauf) was ich mit korrigiert habe.
Pin 10 hatte ich im Sketch #26 schon eingebaut.
Demnach sind wir damit fertig?
Der Vorteil bei Verwendung vom MegaCoreX Package ist, es funktioniert millis und delay weiterhin korrekt.
Ich habe den Code aus #26 in meinen Sketch übernommen.
Das habe ich schon gesehen, danke.
Leider nein, theoretisch ja, praktisch nein.
MeinCode funktioniert so nicht mehr.
Ich bekomme total hohe Frequenzen am Pin 9 und 10 obwohl mir die serielle Ausgabe was ganz anderes sagt.
ja, es gibt mehrere Probleme. Eines davon ist das du in der Funktion loopreturn verwendest. Das darf man nicht machen. Dabei wird loop verlassen und sofort wieder aufgerufen. Sodass du eine Endlosschleife mit der ersten Abfrage hast. Man benötigt auch kein return an der Stelle. Setze Klammern, dann wird der Code wenn if ungültig übersprungen. Ich empfehle dir jedoch dringend die Basics zur Tasterabfrage zu lernen. Die IDE bringt Bsp. mit ohne Delay. Die Bounce2 Lib kann ich auch empfehlen.
Deine Lernkurve ist derzeit extrem steil, ich weiß, nimm dir Zeit.
Desweiteren kollidieren die Variablen min und max wenn man das MegaCoreX Package verwendet. Wenn ich beide zu echten Variablen mache, keine defines, sehe ich das in den Fehlermeldungen. Ohne Grund keine defines verwenden!
Auch solltest du die Datentypen ändern. Du verwendest zu viel int was meinstens zu klein ist.
Bsp.: const int eeprom_signatur = 231166;
Welcher Wertebereich passt in ein int?
Trotz allen verstehe ich nicht warum im Zusammenspiel des Tastencodes und MegaCoreX die Frequenz falsch eingestellt wird obwohl die Übergabeparameter stimmen. Vielleicht ein Zusammenspiel was ich noch nicht überblicke. Irgendwie ist das alles eine Zeitbombe.
was ich bestätigen kann ist das etwas mit Pin 5 nicht stimmt. Der gehört zwar zum Timer TCA zum 3. Compareausgang 0-WO2, aber den habe ich gar nicht aktiviert. Da sollte gar nichts passieren bzw. sich negativ auswirken. Was ist hier nur los. Kopfkratz. Es bleibt spannend.
Also halten wir fest. Mit MegaCoreX erstmal nicht Pin 5 verwenden. Vielleicht ist das auf allen 0-WO2 Pins so egal auf welchen Port man umroutet. Das muss ich mir näher anschauen. Damit verschone ich dich.
Machen wir allerdings alles ohne MegaCoreX weiter läuft millis und delay um Faktor 4 falsch.
Tipp. Bounce2 Lib Bsp. change anschauen und anwenden. Das räumt dein Code auf.
Die kleinen Sachen wie return und der überfüllte int, hab ich schon mal heraus gemacht.
Mit der Taster lib werde ich mal am WE etwas rumspielen.
Da muss ich mir noch überlegen wie ich das dazu bringe einmal drücken und lange drücken und drücken beider tasten zugleich unterscheiden kann.
Das sollte aber zu machen sein.
Das Schöne daran, das Pin 5 quer schlägt ist, das wir das so gefunden haben.
Das ist sicher ein Käfer
Das hast du herausgefunden. Auch sehr schön. Ich habs nur bestätigt und spiele aktuell Detektiv.
Aktueller Stand ist, pinMode hat auf Pin 5 noch keine negative Wirkung auf den Timer. Erst wenn man den Pin 5 einliest/abfragt kommt Mist raus. Weil sich damit kurioserweise der Timermode ändert. Von meinen DualSlopePwmTop auf Frequency-Mode. Damit stimmt natürlich nichts mehr. Spannend.
Man hört sich ...
Ich hole einmal etwas weiter aus. Es gibt zwischen dem originalen Arduino Framework und dem MegaCoreX Package verschiedene Ansätze den Timer TCA für analogWrite richtig vorzukonfigurieren und bei Verwendung von digital... Funktionen den Pin vom Timer zu trennen. Beiden Ansätzen gemeinsam ist das sie den 8 Bit Splitmodus von TCA konfigurieren. Unterschiede gibt es beim "löschen" der Timer Compare-Ausgänge.
Das Arduino Framework nimmt das mit der Registerbedeutung, ob Single- oder Splitmode, nicht ganz so genau und schaltet einfach die Compareausgänge ab, als ob es sich im Singlemode befinden würde. Das macht keine Probleme. Dadurch werden wirklich nur die Compare Enable Bits und nicht die WGM Bits im CTRLB Register geändert. Das Arduino Framework hat ja den Vorteil das es sich nicht mit Abhängigkeiten anderer Controller-Konfigurationen rumschlagen muss.
Letzteres Problem hat das MegaCoreX zu bewerkstelligen, weil es die gesamte Controllerfamilie unterstützt. Deswegen nimmt es das mit der Single- bzw. Splitmode Bedeutung der Register ganz genau und dementsprechend kollidiert es, wenn man eigenhändig den Timer anders konfiguriert. Das MegaCoreX Package weiß nicht das ich den Timer anders konfiguriert habe und denkt es wäre noch im 8 Bit Splitmode. Ich habe aber den Splitmode abgeschalten und der Singlemode ist aktiv. Deswegen löscht es bei Verwendung von digital... Funktionen im CTRLB Register aus seiner Sicht die richtigen Bits. Da sich TCA jedoch im Single Mode befindet löscht es nicht wie gedacht die Low Byte Compare Enable Bits sondern die WGM Mode Bits im CTRLB Register. Dadurch läuft TCA Amok sobald man man digitalRead verwendet womit das löschen der Bits ausgelöst wird.
Abhilfe kann digitalReadFast() sein. Das prüft nicht die Pin Konfiguration. Damit kann man es umgehen wenn man keine fremden Libs verwendet oder nur Eigene schreibt. Fremde Libs wissen aber nichts von digitalReadFast() und verwenden ausschließlich die Standard Arduino Funktionen wenn sie maximal kompatibel bleiben wollen. Deswegen nützt einem das leider nichts wenn man bspw. Bounce2 verwendet. Man stünde vor dem gleichen Problem.
Deswegen muss ein Workaround an der Basis herhalten der sich nur um das originale Nano Every Board dreht im MegaCoreX Package. Ich habe eine Abfrage eingebaut ob das Every Board mit Every Pinout aktiv ist und entsprechend das löschen der Bits beeinflusst, abhängig davon ob der Splitmode aktiv ist oder nicht. Dazu muss man die Funktion turnOffPWM() in der Datei wiring_digital.c ändern. Wer das machen will sichert sich vorher am Besten die gesamte Datei und ändert die Funktion wie folgt ab.
Bsp. IDE 1.8.19 Portable
Pfad: ...\arduino-1.8.19\portable\packages\MegaCoreX\hardware\megaavr\1.1.2\cores\coreX-corefiles\wiring_digital.c
Bsp. IDE 2.1.0 installiert
Pfad: C:\Users\xyz\AppData\Local\Arduino15\packages\MegaCoreX\hardware\megaavr\1.1.2\cores\coreX-corefiles\wiring_digital.c
Nach Besten Wissen und Gewissen getestet. Dennoch ohne Gewähr.
wiring_digital.c - turnOffPWM()
static void turnOffPWM(uint8_t pin)
{
/* Actually turn off compare channel, not the timer */
/* Get pin's timer */
uint8_t timer = digitalPinToTimer(pin);
if (timer == NOT_ON_TIMER)
return;
uint8_t bit_pos;
TCB_t *timerB;
switch (timer)
{
/* TCA0 */
case TIMERA0:
/* Bit position will give output channel */
bit_pos = digitalPinToBitPosition(pin);
/* Disable corresponding channel */
#if defined (NANO_EVERY_PINOUT) && defined (NONA4809_PINOUT) && defined (__AVR_ATmegax09__)
if ( 0x01 == (TCA0.SPLIT.CTRLD & 0x01) ) { // is Splitmode activ?
if (bit_pos >= 3) ++bit_pos; /* Upper 3 bits are shifted by 1 */
TCA0.SPLIT.CTRLB &= ~(1 << (TCA_SPLIT_LCMP0EN_bp + bit_pos)); // #define TCA_SPLIT_LCMP0EN_bp 0 /* Low Compare 0 Enable bit position. */
} else {
TCA0.SPLIT.CTRLB &= ~(1 << (TCA_SINGLE_CMP0EN_bp + bit_pos)); // #define TCA_SINGLE_CMP0EN_bp 4 /* Compare 0 Enable bit position. */
}
#else
if (bit_pos >= 3) ++bit_pos; /* Upper 3 bits are shifted by 1 */
TCA0.SPLIT.CTRLB &= ~(1 << (TCA_SPLIT_LCMP0EN_bp + bit_pos)); // #define TCA_SPLIT_LCMP0EN_bp 0 /* Low Compare 0 Enable bit position. */
#endif
break;
/* TCB - only one output */
case TIMERB0: /* FALLTHRU */ // requires gcc 7, modern syntax is [[fallthrough]];
case TIMERB1: /* FALLTHRU */
case TIMERB2: /* FALLTHRU */
case TIMERB3: /* FALLTHRU */
timerB = (TCB_t *)&TCB0 + (timer - TIMERB0);
/* Disable TCB compare channel */
timerB->CTRLB &= ~(TCB_CCMPEN_bm);
break;
default:
break;
}
}
da hast Du Dir ja richtig Arbeit gemacht.
Für diejenigen die das verstehen, ist das sicher auch sehr von Nutzen.
Ich würde an der Stelle einfach weiterhin Pin 5 nicht benutzen.
Ob das Problem noch an anderen Pins auftritt weis ich nicht aber die benutze ich ja in meinem Projekt auch nicht.
Vieleicht wäre das für die Zukunft interessant für die Entwickler der IDE.
Habe ich mir angesehen.
Ich habe mich aber für OneButton entschieden.
Ja, das erleichter einiges und sieht auch viel schöner aus.
IdR. gilt ja: "Schöner Code funktioniert besser
dann hälst du Pin 5 frei für den 3. verfügbaren Kanal für eine mögliche 3. Led.
Im 8 Bit Splitmode stehen zwar bis zu 6 Kanäle bereit, aber vom Port B werden nur 3 Pins herausgeführt, was die Pins 9, 10 und 5 sind (PB0, PB1 und PB2). Da besteht also keine Gefahr.
Man müßte den Portmux ändern, dass machen wir aber nicht. Wer es wissen möchte, mit Port.D hätte man alle 6 Kanäle. Das müßte man separat testen.
Vieleicht wäre das für die Zukunft interessant für die Entwickler der IDE.
Das muss ich mit MCUdude besprechen ob er dafür eine Notwendigkeit sieht und sein MegaCoreX ändert.
Ja, das erleichter einiges und sieht auch viel schöner aus.
IdR. gilt ja: "Schöner Code funktioniert besser
Das gilt immer. Aufgeräumter Code erhöht den Überblick und Fehler sind schneller sichtbar. Mir geht es nicht anders.
Dann wäre das erstmal alles soweit geklärt das du alleine weitermachen kannst. Ansonsten einfach im Forum fragen. Im Eingangsthread immer gleich angewöhnen den Namen des Arduinoboards und die IDE Version angeben. Das erleichtert den Einstieg in die Frage für alle.
hatte ich übersehen. Sorry. Ohne weiteren Test ergänzt. Alle 3 PMW Kanäle haben immer den gleichen Wert. Siehe Funktion setDuty(). Weitere notwendige Änderung in Funktion initTCA0() Zeile 83. Damit werden die Timerausgänge überhaupt erstmal aktiviert. pinMode() ist selbsterklärend.
PS:
Was du noch machen könntest ist, die Betreffzeile im Eingangsthread ändern. Im Nachgang vielleicht für die Suche hilfreich. Meinetwegen "Nano Every PWM Timer TCA" oder so ähnlich.