Ausgänge schneller schalten

Guten Tag zusammen,
von Weihnachten hab ich noch eine Lichterkette übrig, die soll jetzt als Nachtlicht im Bus dienen.
Die LIchterkette:
100 low Power Led's, alle warmweiß, parallel geschaltet wobei jede 2. revers angeschlossen ist.
Die Versorgungsspannung war per Batterien 2,75V 20mA bei 100 Hz AC !!
Die Betriebsspannung war rechteckförmig, also immer ein pin an + und der andere an - und das im Wechsel.
Jetzt wollte ich das mit einem Nano nachbilden, das ging gut in die Hose.
Mehr als ~50 Hz kommen nicht raus, obwohl ich die Impulslänge auf 10 ms gesetzt habe und der Nano sonst nichts zu tun hat.
Das ist nicht mein erstes Arduino-Projekt, aber in 15 Jahren das erste das an der Geschwindigkeit scheitert (50Hz sind für LED's zu langsam, die "flimmern", das gibt Augenkrebs).
Hat jemand von Euch eine Idee (und evtl. Vorgehensweise) wie ich da auf 100 Hz komme?

Vielen Dank für etwaige Hilfe

Rainer


```cpp


const int BUTTON = 12;       // Taster gegen GND
const int LEDa = 10;         // Ausgang "positive" Spannung
const int LEDb = 11;         // Ausgang "negative" Spannung


// Taster entprellen
unsigned long TastMillis;    // Variable für die Startzeit
unsigned long PrellMillis;   // Entprellzeit

//Schaltfrequenz erzeugen
unsigned long StartMillis;   // Variable für die Startzeit
unsigned long OnMillis;      // Tastzeit


int ACein;                    // Variable für die Schaltfrequenz 

int LEDstep;                  // Schrittkette LED steuern
int entstep;                  // Schrittkette entprellen
int Taster;                   // !Taster entprellt

void setup() {
//  Serial.begin(9600);
//  pinMode(LED, OUTPUT);
  pinMode(LEDa, OUTPUT);
  pinMode(LEDb, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
//  pinMode(ACaus, OUTPUT);
  entstep = 0;                 // Schrittkette löschen
  LEDstep = 0;
  
  StartMillis = 0;
  OnMillis = 10;                // Impulslänge der "Wechselspannung"
  TastMillis = 0;
  PrellMillis = 10;         

//  Serial.println("Gestartet");
}

void loop() {
  
  Frequenz();           // "Wechselspannung" erzeugen
  Entprellen();
  LEDsteuern();

//  Serial.println("Schrittkette " + String(entstep) + " Zeit " + String(TastMillis) + " Taster " + String(Taster) + " AC " + String(ACein) );

//  digitalWrite(LED, Taster);

}

void LEDsteuern(){    //LED steuern
  switch (LEDstep) {
    case 0:   //Init
      digitalWrite(LEDa, LOW);
      digitalWrite(LEDb, LOW);

      if (Taster){
        LEDstep = 10;
      }
    break;

    case 10:            // LED Ein
    
      if (!Taster){
        LEDstep = 20;
      }
    break;
    
    case 20:
      digitalWrite(LEDa, ACein);
      digitalWrite(LEDb, !ACein);

      if (Taster){
        LEDstep = 30;
      }
    break;

    case 30:
      if (!Taster){
        LEDstep = 0;
      }
    break;
  }
}
void Entprellen(){
  
  switch (entstep) {
    case 0:       //Start
      if (digitalRead(BUTTON)){      //Button schaltet gegen ground
        TastMillis = millis();
        entstep = 10;
      }
      break;

    case 10:      // Taster losgelassen
      
      if ((digitalRead(BUTTON)) && (millis() - TastMillis >= PrellMillis)){
        Taster = LOW; 
        entstep = 20;
      }
    break;

    case 20:      // Taster frei
      if (!digitalRead(BUTTON)){      //Button schaltet gegen ground
        TastMillis = millis();
        entstep = 30;
      }
    break;

    case 30:      // Taster gedrückt
      
      if ((!digitalRead(BUTTON)) && (millis() - TastMillis >= PrellMillis)){
        Taster = HIGH; 
        entstep = 40;
      }
    break;

    case 40:      // Taster losgelassen
      
      if (digitalRead(BUTTON)){
        Taster = LOW; 
        entstep = 00;
      }
    break;
  }

}

void Frequenz(){      // "Wechselspannung" erzeugen
   
    if (!ACein &&(millis() - StartMillis >= OnMillis)){
    StartMillis = millis();
    ACein = HIGH ; 
  }
  else if (ACein &&(millis() - StartMillis >= OnMillis)){
    StartMillis = millis();
    ACein =  LOW ;  
  }
//  digitalWrite(ACaus, ACein);

}

Idee: kannste nicht einfach PWM nehmen? Da kümmert sich dann dwr Prozessor selbst drum.

Mit einfacher PWM bekommst Du aber die gegensätzliche Polarität ohne Zusatzhardware nicht hin.

Gruß Tommy

Danke,
diese Idee hatte ich auch schon,
das scheitert aber daran dass ich im Wechsel pin 10 ansteuern und pin 11 auf GND legen muss und das alle 20 ms umschalten muss.
Ich bräuchte also am pin 10 eine 50% PWM und am pin 11 das negierte Signal......
Ist das machbar?

Denke schon, dass das geht:

Wenn der Arduino nichts aderes machen soll, dann geht auch

loop() {
  digitalWrite(2,LOW);
  digitalWrite(3,HIGH);
  delay(5);
  digitalWrite(2,HIGH);
  digitalWrite(3,LOW);
  delay(5);
}

Danke zwieblum,
aber die Tasterfunktion sollte er schon noch mit machen,
durch die delays wird er nicht mehr auf den Taster reagieren....
Das mit dem PWM-Signal liegt ausserhalb meines Wissens, da muss ich mich erst bilden.
Ich hab ja noch einige ESP 8266 rumliegen, morgen hänge ich mal davon einen dran,
aber das geht nur mit einem L9110S wegen der Spannung und dem Strom.

OnMillis setzt Du auf 10 - das bedeutet, dass ein ganzer Ein/Aus-Zyklus 20ms dauert. Das sind 50Hz, also alles wie befohlen :slight_smile:
Setz das mal auf 5, dann solltest Du Deine 100Hz haben.

ACein muss kein int sein, da reicht ein bool.
Geht Frequenz() nicht einfacher?

void Frequenz() // "Wechselspannung" erzeugen
{
  if (millis() - StartMillis >= OnMillis)
  {
    StartMillis = millis();
    ACein = !ACein; 
  }
  //  digitalWrite(ACaus, ACein);
}

Das wars, wer rechnen kann......
Aberich hatte schon 2 ms eingestellt, bevor ich das ganze serial-Gedöns rausgenommen habe.
Und da hatte ich nur 38 Hz....
Jetzt macht er mit 2 ms 250 Hz, super!
Es läuft jetzt so, danke Euch für die Vorschläge, manchmal sehe ich den Wald vor lauter Bäumen nicht....
Grüße
Rainer

oops, der Link oben bringt nix beim ESP, da funktioniert das anders.

Na ja, ein oder zwei delay(5); nehmen manche zum Entprellen.

Wie langsam man auf manuelle Taster reagieren kann/soll und was eine Millisekunde ist...,
muss man sich dran gewohnen um ein Gefühl dafür zu bekommen.

Beim Entprellen mit delay(5) wird der Prozessor nur kurz angehalten, eventbedingt.
Im genannten Beispiel würde er von einem delay ins nächste laufen und dazwischen nur 1 Zyklus abarbeiten. Da wird nix Gutes dabei rauskommen. Deshalb meide ich delay wo es geht.....

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.