Hilfe - Sketch vom Uno auf Attiny lauffähig machen

Hallo zusammen,

brauche euer Wissen.

Habe hier einen Gerät welches beim gleichen Pin, bei zwei unterschiedlichen Funktionen eine 5V+ Puls folge rausgibt.
Bei Funktion1 15 Pulses
Bei Funktion2 30 Pulses

Ausgelesen habe ich dies an Pin 2 vom Uno mit diesem Sketch

—————

int pin = 2;
volatile unsigned int pulse;

void setup()
{
Serial.begin(9600);

pinMode(pin, INPUT);
attachInterrupt(0, count_pulse, RISING);
}

void loop()
{
pulse=0;
interrupts();
delay(5000);
noInterrupts();

Serial.print("Pulses per second: ");
Serial.println(pulse);
}

void count_pulse()
{
pulse++;
}

——————

Jetzt benötige ich einen Sketch welcher mir auf einem Pin das Signal ausliest und dann einen Ausgang High schaltet bei Input Pulse 15
und den gleichen Ausgang LOW (ausschaltet) bei Input Pulse 30
Die gesamte Pluskette erfolgt ab dem ersten High puls innerhalb einer Zeit von 1,2 Sek

Habe das hier gefunden wo der Rest vom Sketch fehlt.

void loop() {
if (DetectPulse == true){
delay(1200);
if (PulseCount == 15){
digitalWrite(4, HIGH);
Serial.print("on");
} else if (PulseCount == 30) {
digitalWrite(4, LOW);
Serial.print("off");
} else {
Serial.print("Unknown ");
}
PulseCount = 0;
DetectPulse = false;
}

Eine Serial Ausgabe zusätzlich zum Ausgang schalten wäre cool.
Sollte der Strom wegfallen muss der Zustand nicht gespeichert werden sondern mit Ausgang off begonnen werden.

Bitte Bitte

Hallo
Der erste Sketch läßt dafür gut modifizieren.
Zähle die Ereigniss pro Sekunde und werde die aus.

digitalWrite (ledPin, (pulse>=15 && pulse<=30)); 

Hab einen schönen Tag und viel Spass beim Programieren in C++.

const byte inPin = 2;
const byte outPin = LED_BUILTIN;
volatile unsigned int pulseCount = 0;
volatile unsigned long lastmillis = 0;
volatile bool detectPulse = false;

void setup()
{
  Serial.begin(9600);
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
  attachInterrupt(0, count_pulse, RISING);
}
void count_pulse()
{
  if (!detectPulse)
  {
    lastmillis = millis();
    detectPulse = true;
  }
  pulseCount++;
}

void loop()
{
  const unsigned long ablaufZeit = 1500; // Zeit in ms
  if ((detectPulse) && (millis() - lastmillis >= ablaufZeit))
  {
    if (pulseCount == 15)
    {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.print("on");
    }
    else if (pulseCount == 30)
    {
      digitalWrite(LED_BUILTIN, LOW);
      Serial.print("off");
    }
    else
    {
      Serial.print("Unknown");
    }
    pulseCount = 0;
    detectPulse = false;
  }
}

Wäre ne Idee.

1 Like

Wow super. Werde es mal testen.
Vielen Dank für die bisherigen Antworten.

Gerne.
Der Unterschied zu Deiner Version ist das fehlende delay().
Du könntest jetzt also parallel dazu noch mehr machen ausser zählen.

und die Ablaufzeit 1500 sind wofür?
Sorry bin leider nicht so fit in Arduino Code.

Wo setzt ich meine delay 1200 noch rein?

Benötige eigentlich nur ein ganz schmales Sketch.

Serial output ist eigentlich nur für die ersten Tests und könnte danach komplett rausgenommen werden.

Es braucht nur die Abfrage vom
Input Pin3 Pulses 15 = Output Pin 4 on
Input Pin3 Pulses 30 = Output Pin 4 off

Gibt es noch eine Möglichkeit alternativ einen Bereich zu wählen

Beispiel bei 13-17 Pulses on
Bei 28-32 off

Dafür:

Das ist deine Wartefunktion.
Du kannst da jetzt 1200 rein schreiben ...

Oder den Code kopieren:



void loop()
{
  const unsigned long ablaufZeit = 1200; // Zeit in ms
  if ((detectPulse) && (millis() - lastmillis >= ablaufZeit))
  {
    switch (pulseCount)
    {
      case 12 ... 18:
        {
          digitalWrite(LED_BUILTIN, HIGH);
          Serial.print("on");
        }
        break;
      case 26 ... 32:
        {
          digitalWrite(LED_BUILTIN, LOW);
          Serial.print("off");
        }
        break;
      default:
        {
          Serial.print("Unknown");
        }
        break;
    }
    pulseCount = 0;
    detectPulse = false;
  }
}

Das ist dann auch geklärt.

Alles gut.
Hier ist in meinem Beitrag ein gutes .pdf angehangen.
Lesen von vorn bis hinten jeden Abend zur guten Nacht ein paar Seiten.
Nur wissen was drin steht - nicht auswendig lernen.

Funktioniert schonmal gut.

Jetzt hätte ich noch eine Verbesserung wenn das was möglich ist.

pulseCount 15 ist on - hier dauert es bedingt natürlich die 1500 Ablaufzeit bis LED_BUILTIN schaltet.
diese kann ich nicht mehr als auf 1200 zu reduzieren.

pulseCount 30 ist definitiv off das kann auch so bleiben mit 1200 Ablaufzeit.

Könnte man es so machen das wenn ein high Signal kommt (vorher pulseCount 15) -> einschaltet ohne auf die Ablaufzeit zu warten

und sobald es ein pulseCount30 innerhalb Ablaufzeit 1200 ist wie gehabt LED_BUILTIN ausschaltet.

Wie soll das funktionieren? Du weißt doch erst nach der Auswertung, was für ein Signal ankommt. So wie du es im Moment willst, würde die LED bei jedem Empfang angehen und wenn das Signal Aus bedeutet wieder ausgehen. Sprich LED ist aus, du sendest aus, LED geht an und nach der Auswertung wieder aus.

Einzig sinnvolle Weg wäre die Auswertung zu beschleunigen. In welchen Zeitfenster kommen die Pulse? Bestimmt im Millisekunden Bereich.

Vielleicht habe ich es aber auch nur falsch verstanden.

Der längste Pulse ist der Aus pulse der nach 1100ms abgeschlossen ist.

Vielleicht über Speicherung des Zustands. Der zurück gesetzt wird wenn die Betriebsspannung weggenommen wird.

Ne neue Scheibe von der Salami?

Also das ist wirr.
Wenn count15 durch ist, ist die LED an.
Wenn Du möchtest, das nach einem count30 die LED angeht, wenn der nächste Impuls kommt, geht das.
ABER!
Du weisst doch gar nicht, ob da 15 oder 30 Pulse kommen.

Ein Versuch:

void loop()
{
  const unsigned long ablaufZeit = 1200; // Zeit in ms
  if (detectPulse)
  {
    if (!digitalRead(LED_BUILTIN))
    {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.print("on");
    }
    else if (millis() - lastmillis >= ablaufZeit)
    {
      switch (pulseCount)
      {
        case 26 ... 32:
          {
            digitalWrite(LED_BUILTIN, LOW);
            Serial.print("off");
          }
          break;
        default:
          {
            Serial.print("Unknown");
          }
          break;
      }
      pulseCount = 0;
      detectPulse = false;
    }
  }
}

Wie wäre das ganze mit genau Pulse 30 ohne Bereich 26...32?

15 ist immer bei on
30 immer bei off

mit dem gleichen Taster

Das war doch Deine Idee!

Wenn Du das nicht willst, dann mach es weg und prüfe wieder auf die genaue Zahl.

Und ja, ich habe das verstanden, was on und was off ist.
Ich habe Dich gefragt, ob Du sicherstellen kannst, das immer nach einem off ein on kommt. Wenn das so ist, dann kannst Du das so wie oben machen.
Wenn zweimal off kommen kann, dann hast Du ein Problem.

Ja ist sichergestellt das es immer im Wechsel ist. Nach Netzausfall ist ja eh alles zurück gesetzt und es fängt mit neu on an.

Passt also. Vielen lieben Dank.

Habe jetzt auch sichergestellt dass es immer genau 15 und 30 sind somit benötige ich den Bereich doch nicht mehr.

Wäre super lieb wenn du mir das letzte Sketch nochmal ohne Bereich ändern könntest.

Habe es schon versucht bekomme aber Fehler.

Dann zeig doch mal Code und Fehlermeldung.
Es macht keinen Sinn Dir alles vorzukauen, wenn Du es nicht verstehst.
Ich hab das schon umgebaut... :wink:

1 Like

Wozu dann überhaupt die Pulse Erkennung? Einfach bei jedem Eingang die LED toggeln. Neuen Eingang erst ab 1,5s annehmen.

void loop()
{
const unsigned long ablaufZeit = 1200; // Zeit in ms
if (detectPulse)
{
if (!digitalRead(LED_BUILTIN))
{
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("on");
}
else if (millis() - lastmillis >= ablaufZeit)
{
switch (pulseCount)
{
if (pulseCount == 30)
{
digitalWrite(LED_BUILTIN, LOW);
Serial.print("off");
}
break;
default:
{
Serial.print("Unknown");
}
break;
}
pulseCount = 0;
detectPulse = false;
}
}
}

Also als erstes, mach mal STRG-T, damit Du den Code vernünftig formatiert bekommst.
Dann als nächstes gehe in Dein Post, und markiere den Code und drücke die Schaltfläche </>
Ah.. dann kann das auch vernüftig rauskopiert und weiterverarbeitet werden. Und vor allem gut lesbar.

So und Deine Fehlermeldung ist eine Warnung:

warning: statement will never be executed [-Wswitch-unreachable]
 if (pulseCount == 63)
     ~~~~~~~~~~~^~~~~

Und der Kompiler hat recht.
Du kannst das switch nicht mit einem if auswerten.
Das switch-Konstrukt kann komplett raus.
Es bleibt das if übrig. Dann musst Du nur noch die Bedingungen anpassen.

Unbedingt das pdf lesen.

void loop()
{
  const unsigned long ablaufZeit = 1200; // Zeit in ms
  if (detectPulse)
  {
    if (!digitalRead(LED_BUILTIN))
    {
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.print("on");
    }
    else if (millis() - lastmillis >= ablaufZeit)
    {
      if (pulseCount == 30)
      {
        digitalWrite(LED_BUILTIN, LOW);
        Serial.print("off");
      }
      else if (pulseCount != 15)
      {
        Serial.print("Unknown");
      }
      pulseCount = 0;
      detectPulse = false;
    }
  }
}

Das ist jetzt Perfekt. Vielen Lieben Dank an Mr. my_xy_projekt und an Plumps für die Unterstützung.
Gekonnt ist gekonnt. Super.

So um jetzt den Serial.print rauszunehmen entferne ich:
Serial.begin(9600);
Serial.print("on");
Serial.print("off");

else if (pulseCount != 41)
{
Serial.print("Unknown");
}

richtig?

ja.
Wobei das Serial.begin ruhig drin bleiben kann.
Ich würde das nur auskommentieren und nicht löschen. macht späteres debuggen einfacher.