Anfänger scheitert wohl bereits am Anfang

Und bei mir an. Deswegen war ich so irritiert und der Meinung, dass sich das Ding aufhängt.
Den Pin 13 habe ich doch gar nicht erwähnt!?
Im Grunde brauche ich nur einen Pin für PWM-Eingang und Einen als Ausgang. Das sollte das Ding ja können.

Werde ich final auch. Nun hab ich ja verstanden, dass der Sketch trotz leuchtendem RX und TX funktioniert.
Es irritiert halt wie Sau.

Jepp, dahin habe ich mich selbst hingelotst... :see_no_evil_monkey:

Dann kannst Du den 'Arduino Micro' versuchen. Der steuert die Leds invertiert zum Leonardo an. Da sind dann bei mir beide LED's dauerhaft an.
Deine 'pro Micro' scheinen aber dann nicht dem Spakrfun 'original' zu entsprechen. Denn da werden die Leds wie beim Leonardo angesprochen (siehe das von @my_xy_projekt verlinkte Schaltbild)

Bezieht sich nur darauf, dass Du den Blink-Sketch versucht hast. Und als Beispiel dafür, dass nicht alle bei den Arduino-Varianten 'Leonardo' und 'Micro' definierten Pins beim 'pro Micro' herausgeführt sind.

Naja, dass die Plagiate nicht dem Original entsprechen, hätte ich höchstens insgeheim erwartet.

Jedoch unabhängig von dem Sketch den ich hochlade,
bei externer Stromversorgung leuchten PWR, RX und TX.
Und das ob als Leonardo, Micro oder Sparkfun Pro Micro.

Einzig unter Leonardo erlischt die RX, wenn via USB mit dem PC verbunden.
Setze ich dann in BareMinimum RXLED0 ein, ist natürlich Ruhe.
(aber dann schimpft mich combie wieder)

Tja, schwierig zu sagen, was Du da letztendlich hast. Irgendwie scheinen sich deine pro Micro's anders zu verhalten als die meinigen. Wobei ich schon einige verschiedene habe, die sich auch äußerlich ein wenig unterscheiden (insbesondere bezügl. der Größe des MCU-chips und der Breite des Boards.


Softwaretechnisch verhalten die sich aber alle gleich. Sind allerdings auch alle schon etwas älter.

P.S. der mini-Käfer zwischen den beiden rot-braunen Kondensatoren ist der Längsregler, der aus der RAW-Spannung die 5V macht. Der muss die gesamte Spannungsdifferenz RAW<->5V in Wärme verbraten. Wenn Du da nur etwas mehr als ein paar mA verbrauchst, wird der ganz schön ins Schwitzen kommen... :hot_face: :fire:

Meiner ist Lila.
Ich hoffe, ich darf hier nen Link einstellen:
Es ist der USB-C mit 3???-15V
https://de.aliexpress.com/item/1005006100333649.html?spm=a2g0o.order_list.order_list_main.28.39885c5f31TNrP&gatewayAdapt=glo2deu

Den Spannungsfestregler habe ich zu Beginn gleich gemessen, bevor ich mich hier anmeldete.
Der machte brav seinen Job und lieferte 4,99V an VCC.

Ich hätte im Notfall noch den einen oder anderen L7805CV rumliegen.
Wie viel mA ich für ein PWM-Signal benötige -
keiiiine Ahnung... :man_shrugging:

Moin, ich benutze die Pro Micros mit USB-C Anschluss für ein eigenes Projekt, das sehr wohl funktioniert. Es ist auf dem Bild die linke Platine nur halt mit USB-C. Ist eh anzuraten, die USB-Micro Buchse bricht schon mal gerne vom Board. Beim USB-C ist die Buchse DURCH die Platine gelötet anstatt nur AUF die Platine und somit mechanisch stabiler. Auch nutze ich die RX und TX LED ohne Probleme zur Anzeige, dass meine Schaltung (es ist auch ein MPU6050 verbaut) in Waage ist. Dann sind beide LED aus. Wird das Board zu der einen oder anderen Seite gekippt geht die eine oder andere LED an. Einzig mit dem "hohen" Spannungseingang traue ich dem Boards nicht über den Weg. Und die Dinger sind scheisse aus meiner Trägerplatine auszulöten wenn die mal defekt sind. Die Pro Micro programmiere ich auch als "Leonardo". Geht einwandfrei. Wenn du magst kann ich dir mal meinen Sketch zum testen zumailen. Bin wohl gerade noch bis Donnerstag in Urlaub und schaue selten hier rein

Wenn das bei dir klappt ist das schön, aber @mr-meeseeks nutzt dazu auch Serial, dann flackern/leuchten die LED auch ohne sein zutun
Dein "Erfolg" ist also nicht zu verallgemeinern.

Na deswegen hab ich ja auch dabei geschrieben was die bei mir anzeigen. So kann er für sich selbst entscheiden, ob das in seiner Anwendung akzeptabel ist oder nicht. Aber das man beide LED so gar nicht nutzen kann, wie in Post 12 geschrieben, stimmt so nicht. Vielleicht mit Einschränkungen, aber man kann sie nutzen.
Und mein "Erfolg" ist, das die beiden LEDs in meiner Anwendung genau das machen was ich von ihnen verlange. Von daher weiss ich nicht, was die Gänsefüßchen da zu suchen haben.

Bitte rauft euch nicht wegen meinen RX und TX-Problemen!
Ich bin euch sehr dankbar für eure Teilnahme und Unterstützung.
(Das hab ich vor längerem in einem anderen Forum ganz anders erfahren dürfen)
Ich hab jetzt etwas umhergesketcht und probiert.
Mal blinkte RX nach Frequenz, mal kam ein undefinierbares Signal an Pin 3 an usw...
Im Grunde hätte ich damit leben können, am Ende (eigentlich zu Beginn) auch TXled0 im Sketch stehen zu haben.
Und irgendwie war ich etwas angefressen, nicht gleich auf ein "vernünftiges" Board gesetzt zu haben.
Doch dann...
Plötzlich keine Verbindung mehr zum PC.
Den Gerätemanager durchwühlt und ausgemistet, Neustart, Kabel durchprobiert - nichts.
Keine LED am Board, kein "palinngg" am Rechner.
Dann das Board untersucht und letztendlich eine defekte Schottky-Diode ausgelötet. Diese durch eine 1n5819 (allerdings DO-41) ersetzt.
Okay, Frankenino tut wieder.
Aber wieso gibt eine Diode mit 1A den Geist auf?
Mein Resume: "peeeeep"

Nun hab ich auch kein Vertrauen mehr in den Festspannungsregler und das ganze Theater mit dem billigen Mist geht mir auf die Nerven.

Somit meine neue Frage:
Ich möchte ja gerne Frequenzen ändern. Und das am Liebsten in Echtzeit (oder möglichst nahe daran).
Der Bereich ist wie erwähnt von 0-ca 800 Hz
Die Bauform sollte klein sein. 5V wären toll.
Somit erschließt sich die Auswahl doch am ehesten auf den Micro mit dem 32U4?
Auf die Pin-Leiste kann ich gerne verzichten.
Wo kauft Ihr eure Originalen?
(Ich hab´s gecheckt und sollte als Anfänger auf ein Board setzen, das auch nach Bilderbuch funktioniert und somit etwaige China-Klon-Probleme ausschließen)
Würdet Ihr die Aufgabe der Spannungsregulierung im KFZ bzgl. Spannungsspitzen einem Festspannungsregler zutrauen?
Alternativ gibt´s in jedem Fahrzeug irgendwo ne Spannungsregelung auf "sauberere" 12V (oft im Tacho). Sollte ich diese suchen?
Oder Step-down-Modul?

Sowas gibts?

// Wechselblinker

const byte  rx = LED_BUILTIN_RX; // pin 17
const byte  tx = LED_BUILTIN_TX; // pin 30

bool status;

void setup()
{
  pinMode(tx, OUTPUT);
  pinMode(rx, OUTPUT);
  digitalWrite(rx, HIGH);  
}

void loop()
{
  digitalWrite(tx, status);   
  digitalWrite(rx, status = not status);    
  delay(1000);                        
}

Ach, der Kollege ist halt arg überzeugt, von seinen Erfolgen.
Soll ihm doch seine eigene Giebe gruben.

Nur muss ihm sich auch Kritik gefallen lassen, da seine "Lösung" eben nicht übertragbar ist. Nicht "ohne Probleme" funktioniert, zumindest nicht immer und überall.

Uuups...
Ich hab doch Micro geschrieben!? :man_shrugging:
lies nochmal...

// AusDieMaus
void setup() {
  pinMode(17, OUTPUT);
  TXLED0;
  pinMode(30, OUTPUT);
  RXLED0;
}
void loop() {
}

Mich hat das Geleuchte doch eigentlich nur irritiert.
Rotes Blitzlicht hat mich im Straßenverkehr schon immer genervt...

Hallo zusammen,
da sich nichts mehr in diesem Forum tat, möchte ich zumindest von meinem Teilerfolg berichten.
Zuerst, die TX-LED kann mich mal sowas von.
Es waren viele Rückschläge und verdammt nervig, eine solch vermeintlich simple Aufgabe zu lösen.
Ich weiß nicht, ob die meisten Probleme am China-Klon lagen, oder ich einfach zu dämlich für dieses Ding war.
Irgendwann schmiss ich alles über den Haufen (eigentlich öfter) und versuchte mich (als endlich ein Signal ankam - aber mit völlig unplausiblen Werten) mit input Capture.
Mein ganzes Inneres wehrte sich dagegen und wurde durch ständige Rückschläge nur bestätigt.
Dieses ständige "was macht das und warum muss ich das so schreiben" kombiniert mit "kopieren wir mal diese Zeile ein und gucken was passiert" ist für einen Anfänger einfach zu harter Tobak.
Ich versuchte mich mit Librarys - um irgendwie Ordnung ins Chaos zu bringen. Wozu gibt´s das? Es macht mehr Aufwand als es nützt.
Wieder zurück...
Nun hatte ich irgendwann eine riesige Datei, die irgendwie funktionierte.
Schon mal ein Erfolgsgefühl.
Dann ging es ans Ausmisten und permanenten Versuchen, begleitet von "wieso tut es nun anders" oder "warum geht jetzt garnix mehr?"

Das Ding mag für einen Anfänger ein Spaß sein, der sich darüber freut, ein Lämpchen zum Leuchten zu bringen, oder eine gleichbleibende Frequenz zu erzeugen.
Wenn jedoch etwas höhere Wünsche an dieses kleine miese Ding gestellt werden ist Frust vorprogrammiert.

Fazit - Ich glaube, ich mach soetwas nie wieder.

Nun läuft mein Sketch und warum weiß ich garnicht genau.

Falls sich jemand mit Input Capture auskennt, und für ihn meine Wünsche halbwegs verständlich ausgedrückt waren, würde ich mich freuen, wenn dieser mal einen Blick auf meine .ino werfen würde.

Einfach so ins Forum hochladen und für jeden zugänglich machen möchte ich aufgrund der seelischen Qualen mit dem Ding nicht.
Ich hoffe, Ihr versteht das.

LG Stefan

Welchen Sinn hat dein Post, wenn du den Sketch nicht zeigst?

2 Likes

Dann ist doch alles gut.

ist z.B. digitalRead. Wird ganz oft genutzt.

Ich vermute. ihm meint einen Timer Eingang-

Wenn ich Recht habe, dann: Wird ganz selten genutzt.

Nööö

Aber was ich verstehe, ist, dass du eher so ein Drama Type bist.

Wenn du hier seelische Qualen erwartest, warum postest du hier überhaupt ?
Erwartest Hilfe, bist aber nicht bereit die Helfer zu unterstützen.
Mach man weiter so.

Postet Ihr alle eure Sketche, die etwas aufwendiger sind, schmerzfrei ins Forum?
Ich dachte eigentlich an PN... :man_shrugging:

:rofl:
Ich wollt es dem Leser ein wenig angenehmer machen.
Wenn es nicht gut ankommt, lass ich das.

Quälerei ist ja für´s Erste vorbei.
Ich glaube kaum, dass Ihr mich hier nieder macht.

Niedermachen nicht, aber da ohne Sketch eine Hilfe sinnlos ist und Hilfe per PN, ohne dass die Allgemeinheit etwas davon hat, dem Sinn eines Forums widerspricht, wirst Du es wohl allein schaffen müssen.

Gruß Tommy

Ach, was soll´s...
Es funktioniert eigentlich stabil.
Aber vielleicht gibt´s ja was zu verändern oder verbessern


```cpp
// === Frequenzteiler (Input Capture Pin 4, PWM Pin 5) ===
#include <avr/interrupt.h>

// Konfiguration
const int sensorPin = 4;                              // Pin 4 (ICP1) für Eingangssignal
const int outputPin = 5;                              // Pin 5 (OC3A) für PWM Ausgang
const float faktor = 0.279;                           // Teilerfaktor

// Globale Variablen
// Für Input Capture (Timer1)
volatile unsigned long lastCaptureTime = 0;           // Zeitstempel des letzten Captures (Ticks)
volatile unsigned long measuredPeriodTicks = 0;       // Gemessene Periodendauer (Ticks)
volatile bool newPeriodAvailable = false;             // Flag: Neue Periode von ISR gemessen
volatile uint16_t timer1OverflowCount = 0;            // Zähler für Timer1 Überläufe

// Für PWM-Steuerung (Timer3)
float targetOutputFrequency = 0.0;                    // Ziel-Frequenz für PWM
unsigned long lastPwmUpdateTime = 0;                  // Zeitstempel letztes PWM Update
const unsigned long pwmUpdateInterval = 50;           // Intervall für PWM Update [ms]
unsigned long lastValidPulseTime = 0;                 // Zeitstempel letzte gültige Messung (für Timeout)
const unsigned long noSignalTimeout = 500;            // Timeout bei fehlendem Signal [ms]

// Status für setPWM...
unsigned int lastSetICR3 = 0;
byte lastSetPrescaler3Bits = 0;

// ISR für Timer1 Input Capture
ISR(TIMER1_CAPT_vect) {
  unsigned long captureTime = ICR1;                   // Lese Timer1-Stand bei Flanke
  uint16_t overflows = timer1OverflowCount;           // Lese Überlaufzähler
  timer1OverflowCount = 0;                            // Reset für nächste Periode

  // berechne Periode nur nach dem ersten gültigen Capture
  if (lastCaptureTime != 0 || overflows > 0) {
      // Berechne Periodendauer in Ticks (berücksichtigt dabei Überläufe)
      measuredPeriodTicks = (overflows * 65536UL) + captureTime - lastCaptureTime;
      newPeriodAvailable = true;                      // signalisiere Loop: Neue Periode verfügbar
  }
  lastCaptureTime = captureTime;                      // Aktuelle Zeit für nächsten Vergleich speichern
}

// ISR für Timer1 Überlauf
ISR(TIMER1_OVF_vect) {
  timer1OverflowCount++;                              // zählt Überläufe für niedrige Frequenzen
}

// Funktion zum Setzen der PWM Frequenz an Pin 5 (Timer3)
void setPWMOutputFrequencyT3(float frequency) {
  byte prescaler3Bits = 0;
  unsigned int icr3_top = 0;                          // Top Wert für Timer3

  // Wenn Frequenz 0 oder negativ -> Timer3 stoppen, Ausgang LOW
  if (frequency <= 0.0) {
      cli();                                          // Interrupts sperren für Registerzugriff
      TCCR3B &= ~(_BV(CS32) | _BV(CS31) | _BV(CS30)); // Kein Clock Source -> Stopp
      TCCR3A &= ~(_BV(COM3A1));                       // Trenne OC3A (Pin 5) sicherheitshalber
      sei();                                          // Interrupts wieder erlauben
      digitalWrite(outputPin, LOW);                   // Sicherstellen, dass Pin LOW ist
      // Merken, dass gestoppt wurde
      lastSetICR3 = 0; lastSetPrescaler3Bits = 0;
      return;
  }

  // besten Prescaler und ICR3 (Top) für Timer3 finden
  // Ziel: Frequenz = F_CPU / (Prescaler * (1 + ICR3)) im Fast PWM Mode 14
  unsigned int prescaler = 1; prescaler3Bits = _BV(CS30); // Start mit Prescaler 1
  float icr3_float = (F_CPU / (prescaler * frequency)) - 1.0;

  // Prüfe höhere Prescaler, wenn ICR3 > 65535 wird
  if (icr3_float > 65535.0) { prescaler = 8;    prescaler3Bits = _BV(CS31);                icr3_float = (F_CPU / (prescaler * frequency)) - 1.0; }
  if (icr3_float > 65535.0) { prescaler = 64;   prescaler3Bits = _BV(CS31) | _BV(CS30);    icr3_float = (F_CPU / (prescaler * frequency)) - 1.0; }
  if (icr3_float > 65535.0) { prescaler = 256;  prescaler3Bits = _BV(CS32);                icr3_float = (F_CPU / (prescaler * frequency)) - 1.0; }
  if (icr3_float > 65535.0) { prescaler = 1024; prescaler3Bits = _BV(CS32) | _BV(CS30);    icr3_float = (F_CPU / (prescaler * frequency)) - 1.0; }

  // begrenze ICR3 auf gültigen 16-Bit Bereich und runde
  if (icr3_float > 65535.0) icr3_float = 65535.0;     // max Wert
  if (icr3_float < 1.0)     icr3_float = 1.0;         // min Wert
  icr3_top = (unsigned int)(icr3_float + 0.5);        // runden

  // Timer3 neu konfigurieren, wenn Frequenzänderung
  if (icr3_top != lastSetICR3 || prescaler3Bits != lastSetPrescaler3Bits) {
    cli();                                          // Interrupts sperren
    TCCR3B &= ~(_BV(CS32) | _BV(CS31) | _BV(CS30)); // Timer stoppen
    ICR3 = icr3_top;                                // setze neuen Top Wert
    OCR3A = icr3_top / 2;                           // setze Compare für ~50% Zyklus
    // Setze Modus, starte Timer mit neuem Prescaler
    TCCR3B = _BV(WGM33) | _BV(WGM32) | prescaler3Bits;
    TCCR3A = _BV(COM3A1) | _BV(WGM31);              // COM3A1=non-inv PWM, WGM31=Teil Mode 14
    sei();                                          // Interrupts erlauben
    // neue Werte merken
    lastSetICR3 = icr3_top;
    lastSetPrescaler3Bits = prescaler3Bits;
  }
}

// SETUP
void setup() {
  // Ausgang Pin initialisieren
  pinMode(outputPin, OUTPUT);                       // Pin 5
  digitalWrite(outputPin, LOW);

  // PWM Setup (Timer3 an Pin 5) - Grundkonfiguration, Timer stopp
  TCCR3A = 0; TCCR3B = 0;

  // Input Capture Setup (Timer1 an Pin 4)
  pinMode(sensorPin, INPUT);                        // Pin 4
  TCCR1A = 0;                                       // Normal mode
  // Timer1: Prescaler 64, Noise Canceler AN, seigende Flanke Erfassung AN
  TCCR1B = _BV(ICNC1) | _BV(ICES1) | _BV(CS11) | _BV(CS10);
  TCNT1 = 0;                                        // Zähler zurücksetzen
  timer1OverflowCount = 0;                          // Überlaufzähler zurücksetzen
  lastCaptureTime = 0;                              // letzte Capture-Zeit initialisieren

  // Interrupts für Timer1 aktivieren: Input Capture UND Overflow
  TIMSK1 = _BV(ICIE1) | _BV(TOIE1);
  sei();                                            // globale interrupts aktivieren

  // Zeitstempel initialisieren
  lastPwmUpdateTime = millis();
  lastValidPulseTime = millis();
}

// LOOP
void loop() {
  bool periodAvailableFlag;
  unsigned long currentPeriodInTicks;
  float inputFreq = 0.0;                            // sicher initialisieren
  unsigned long currentTime = millis();             // aktuelle Zeit für alle Checks

  // 1. Sicher Flag und Periode lesen
  noInterrupts();
  periodAvailableFlag = newPeriodAvailable;
  currentPeriodInTicks = measuredPeriodTicks;       // lese die ISR-berechnete Periode
  if (periodAvailableFlag) {
     newPeriodAvailable = false;                    // Flag zurücksetzen
  }
  interrupts();

  // 2. Nur berechnen, wenn neue Periode da ist
  if (periodAvailableFlag) {
     lastValidPulseTime = currentTime;              // Zeit der letzten GÜLTIGEN Messung merken

     if (currentPeriodInTicks > 0) {
        // Frequenz aus Ticks berechnen (Annahme: Prescaler 64 für Timer1)
        // Freq = (F_CPU / Prescaler) / Ticks
        inputFreq = (float)(F_CPU / 64.0) / currentPeriodInTicks;
        targetOutputFrequency = inputFreq * faktor; // Ziel-Frequenz berechnen
     } else {
        targetOutputFrequency = 0.0;                // Ungültige Periode
     }
  }

  // 3. Timeout Check: Wenn lange keine gültige Periode kam -> Ziel = 0 Hz
  if (currentTime - lastValidPulseTime > noSignalTimeout) {
      targetOutputFrequency = 0.0;
  }

  // 4. PWM periodisch updaten
  if (currentTime - lastPwmUpdateTime >= pwmUpdateInterval) {
    lastPwmUpdateTime = currentTime;
    setPWMOutputFrequencyT3(targetOutputFrequency); // PWM aktualisieren
  }

  // delay(1); // Kleine Pause
}

Einige!
Oder ich spreche noch nicht einmal drüber.

Ein paar Kleinigkeiten wüsste ich noch zu verbessern.

Beispiele:

Braucht es nicht

volatile ist hier nicht nötig.
Verlangsamt nur die ISR, und ist damit eher hinderlich als nützlich.
Ein atomares Auslesen ist allerdings wichtig!
Dafür gibt es die ATOMIC Makros