CO2 Target - ein Anfänger mit Fragen ;)

Hallo in die Runde,

dies ist mein erster Post und auch mein erster Sketch den ich je geschrieben habe. Ich denke das werden die Profis unter euch auch sofort erkennen wenn ihr euch Ihn einmal anseht, aber es ist noch kein Meister vom Himmel gefallen und ich fuchse mich grade rein.

Mein Anliegen dabei ist es auch so wenig wie möglich drag n drop zu betreiben, sondern eher von Grund auf alles selber zu schreiben, ich denke nur so lernt man es richtig.

zum Projekt:

geplant ist ein kleines Ziel zum Plinkeln, es soll aus drei Zielen mit je einer Anzeige Led bestehen....sofern alle drei Ziele getroffen sind gibt es eine kleine Lichtorgel, die Led's erlischen wieder und es geht auf Anfang. Soweit so gut und das klappt auch wie ich möchte.

hier einmal der Code.....und bitte nicht schlagen ::)

//CO2 Shooting Target

int LEDt1 = 11;                   //Anzeige Ziel 1
int LEDt2 = 10;                   //Anzeige Ziel 2
int LEDt3 = 9;                    //Anzeige Ziel 3
int Taster1 = 7;                  
int Taster2 = 4;
int Taster3 = 2;
int TasterstatusT1 = 0;
int TasterstatusT2 = 0;
int TasterstatusT3 = 0;
int Tastercounter = 0;
int letzterTasterstatus = 0;
int LEDt1Status;
int LEDt2Status;
int LEDt3Status;



// the setup routine runs once when you press reset:
void setup() {

  pinMode(LEDt1, OUTPUT);
  pinMode(LEDt2, OUTPUT);
  pinMode(LEDt3, OUTPUT);
  pinMode (Taster1, INPUT);
  pinMode (Taster2, INPUT);
  pinMode (Taster3, INPUT);

}

// the loop routine runs over and over again forever:
void loop() {

  LEDt1Status = digitalRead(LEDt1);
  LEDt2Status = digitalRead(LEDt2);
  LEDt3Status = digitalRead(LEDt3);

  if ((LEDt3Status == HIGH) && (LEDt2Status == HIGH) && (LEDt1Status == HIGH)){         //Abfrage des Status der einzelnen Ziele, beim treffen aller drei Ziele folgende kleine Lichtorgel und dann RESET
    
    delay(1000);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, LOW);
    delay(400);
    digitalWrite (LEDt1, HIGH);
    digitalWrite (LEDt2, HIGH);
    digitalWrite (LEDt3, HIGH);
    delay(400);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, LOW);
    delay(400);
    digitalWrite (LEDt1, HIGH);
    digitalWrite (LEDt2, HIGH);
    digitalWrite (LEDt3, HIGH);
    delay(400);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, LOW);
    delay(400);
    digitalWrite (LEDt1, HIGH);
    digitalWrite (LEDt2, HIGH);
    digitalWrite (LEDt3, HIGH);
    delay(400);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, LOW);

    digitalWrite (LEDt1, HIGH);
    delay(100);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, HIGH);
    delay(100);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, HIGH);
    delay(100);
    digitalWrite (LEDt3, LOW);
    
    digitalWrite (LEDt3, HIGH);
    delay(100);
    digitalWrite (LEDt3, LOW);
    digitalWrite (LEDt2, HIGH);
    delay(100);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt1, HIGH);
    delay(100);
    digitalWrite (LEDt1, LOW);

    digitalWrite (LEDt1, HIGH);
    delay(100);
    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, HIGH);
    delay(100);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, HIGH);
    delay(100);
    digitalWrite (LEDt3, LOW);

    digitalWrite (LEDt3, HIGH);
    delay(100);
    digitalWrite (LEDt3, LOW);
    digitalWrite (LEDt2, HIGH);
    delay(100);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt1, HIGH);
    delay(100);
    digitalWrite (LEDt1, LOW);

    digitalWrite (LEDt1, LOW);
    digitalWrite (LEDt2, LOW);
    digitalWrite (LEDt3, LOW);
    
  }
  

  TasterstatusT1 = digitalRead(Taster1);

  if (TasterstatusT1 != letzterTasterstatus){
    if( TasterstatusT1 == HIGH) {
      Tastercounter++;
      digitalWrite (LEDt1, HIGH);
    }
   else{
    
   }
     }
  
  
    TasterstatusT2 = digitalRead(Taster2);

  if (TasterstatusT2 != letzterTasterstatus){
    if( TasterstatusT2 == HIGH) {
      Tastercounter++;      
      digitalWrite (LEDt2, HIGH);
    }
   else{
        
   }
     }
  
  
    TasterstatusT3 = digitalRead(Taster3);

  if (TasterstatusT3 != letzterTasterstatus){
    if( TasterstatusT3 == HIGH) {
      Tastercounter++;      
      digitalWrite (LEDt3, HIGH);
    }
   else{
       
   }
     }

    


}

und jetzt zu den eigentlichen Fragen:

zum einen wäre ich dankbar für Tips was ich grundlegend falsch oder "unschön" in dem Code gemacht habe...oder was man grundsätzlich anders machen sollte, ganz allgemein

  • Als nächsten Schritt würde Ich gerne noch eine Zeitmessung angehen, d.h. wie viele Sekunden braucht der Schütze vom ersten bis zum letzten Ziel, danach käme dann die Anzeige der Zeit etc.etc.

es geht jetzt aber grundsätzlich erstmal um das zählen und nach ein wenig recherchieren wie das mit Arduino überhaupt von statten geht mal eine ganz konkrete Frage:

Ist das auf der Basis dieses Codes eigentlich noch realisierbar oder ist das wegen der Delay's schonmal nicht mehr möglich?

Ich stehe da grade ein wenig wie der Ochs vorm Berg und frage mich ob es sich überhaupt lohnt auf der Basis weiterzumachen oder ob ich das ganze nochmal anders angehen muss.

...helft mir bitte weiter ;)

Soweit so gut und das klappt auch wie ich möchte.

Glückwunsch.

Ist das wegen der Delay's schonmal nicht mehr möglich?

Gut beobachtet. Da du offensichtich ehrgeizig bist, kannst du selbst rauskriegen, wie BlinkWithoutDelay funktioniert, und wie das Prinzip auf deinen Fall anzuwenden ist.

Tip: loop() kann als Zustandsbeschreibung jedes Moments gesehen werden. Ein Durchlauf braucht keine Zeit und wird dafür unendlich schnell wiederholt. (So ungefähr, jedenfalls...) Der Merkerpreviousmillisist nur das Minimum für das Blink-Beispiel.

TexMex:
… Plinkeln …

Was ist das? Was hat das mit CO2 zu tun? Luftgewehr/pistole wäre nur O2.

TexMex:

int LEDt1 = 11;                   //Anzeige Ziel 1

int LEDt2 = 10;                   //Anzeige Ziel 2
int LEDt3 = 9;                    //Anzeige Ziel 3
int Taster1 = 7;                  
int Taster2 = 4;
int Taster3 = 2;
int TasterstatusT1 = 0;
int TasterstatusT2 = 0;
int TasterstatusT3 = 0;
int Tastercounter = 0;
int letzterTasterstatus = 0;

Das sind Konstanten, die freuen sich über const byte, ist auch sparsamer.

TexMex:

int LEDt1Status;

int LEDt2Status;
int LEDt3Status;

Eine LED kann nur an oder aus sein, also ist der Status bool.

TexMex:

  pinMode (Taster1, INPUT);

pinMode (Taster2, INPUT);
 pinMode (Taster3, INPUT);

Benutzt Du PullUp- oder PullDown-Widerstände? Sonst sind die internen PullUp hilfreich, INPUT_PULLUP aktiviert sie.

TexMex:
Ist das auf der Basis dieses Codes eigentlich noch realisierbar oder ist das wegen der Delay’s schonmal nicht mehr möglich?

Grundsätzlich ist delay() eine Sackgasse, solltest Du Dir gar nicht erst angewöhnen. Dafür ist millis() Dein Freund.

TexMex:
…helft mir bitte weiter :wink:

Gerne, damit willkommen im Forum!

Danke schonmal an euch Beide...und ich gebe mir Mühe ehrgeizig zu bleiben, faul kann ja jeder;)

Dann waren meine Gedanken also schonmal nicht ganz falsch und das Zauberwort heisst doch "Millis".

@agmue

"plinkeln" ist das freizeitmässige schiessen auf Ziele aller Art, wie z.b auch Dosen (plink machts) und es gibt sowohl O2, also reine Lufdruckwaffen als auch CO2 Waffen die mit einer Kohlendioxidkapsel betrieben werden.

(ABER um das klar zu stellen mit Zielen aller Art meine ich natürlich keine Lebewesen oder sonstige schwachsinnige Ideen auf die einige kommen!!!)

Das sind Konstanten, die freuen sich über const byte, ist auch sparsamer.

du meinst const int, oder?

Eine LED kann nur an oder aus sein, also ist der Status bool.

tjaaaa bool und boolean...so ganz verstanden habe ich das nicht, die Puzzelteile haben sich in meinem Kopf noch nicht ganz zusammengesetzt ;)

bisher benutze ich Pulldownwiderstände auf dem Steckbrett, würde es dann aber final auch mit den internen realisieren

doch hat klick gemacht mit dem bool ;)

du meinst da die LED eben nur zwei Zustände haben kann ist int überflüssig und bool ist angebrachter...richtig?

int nimmt man nur für Variablen, die einen Wertebereich von -32768 bis +32767 brauchen. Für alle anderen gibt es bessere Datentypen. Kleinere oder größere, gerne auch welche ohne Vorzeichen.

Der große Nachteil vonunsignedist die komplizierte Schreibweise. Aber es gibt viele alternative Schreibweisen und Typdefinitionen.
Eine Zahl 0 … 255 sollte einbytesein. Ein 8bit-Controller mit 2kB RAM ist da sehr dankbar.

bool oderbooleanist hier übrigens dasselbe.

Konstanten alsconstzu definieren, gibt dir Bonuspunkte hier (wirst du weniger verhauen). Und hilft dem Compiler.

habs nochmal verschlimmbessert

//CO2 Shooting Target

byte LEDt1 = 11;                   //Anzeige Ziel 1
byte LEDt2 = 10;                   //Anzeige Ziel 2
byte LEDt3 = 9;                    //Anzeige Ziel 3
boolean value = LOW;
unsigned long previousMillis = 0;
const long interval1 = 2000;
const long interval2 = 1000;
const long interval3 = 500;

const int Taster1 = 7;                  
const int Taster2 = 4;
const int Taster3 = 2;
int TasterstatusT1 = 0;
int TasterstatusT2 = 0;
int TasterstatusT3 = 0;
int Tastercounter = 0;
int letzterTasterstatus = 0;
bool LEDt1Status;
bool LEDt2Status;
bool LEDt3Status;



// the setup routine runs once when you press reset:
void setup() {

  pinMode(LEDt1, OUTPUT);
  pinMode(LEDt2, OUTPUT);
  pinMode(LEDt3, OUTPUT);
  pinMode (Taster1, INPUT);
  pinMode (Taster2, INPUT);
  pinMode (Taster3, INPUT);

}

// the loop routine runs over and over again forever:
void loop() {

  LEDt1Status = digitalRead(LEDt1);
  LEDt2Status = digitalRead(LEDt2);
  LEDt3Status = digitalRead(LEDt3);

  if ((LEDt3Status == HIGH) && (LEDt2Status == HIGH) && (LEDt1Status == HIGH)){         //Abfrage des Status der einzelnen Ziele, beim treffen aller drei Ziele folgende kleine Lichtorgel und dann RESET
    if (millis() - previousMillis > interval1){
      previousMillis = millis();

      value = !value;

      digitalWrite (LEDt1, value);
      digitalWrite (LEDt2, value);
      digitalWrite (LEDt3, value);




      

      

    }
    
    
  }
  

  TasterstatusT1 = digitalRead(Taster1);

  if (TasterstatusT1 != letzterTasterstatus){
    if( TasterstatusT1 == HIGH) {
      Tastercounter++;
      digitalWrite (LEDt1, HIGH);
    }
   else{
    
   }
     }
  
  
    TasterstatusT2 = digitalRead(Taster2);

  if (TasterstatusT2 != letzterTasterstatus){
    if( TasterstatusT2 == HIGH) {
      Tastercounter++;      
      digitalWrite (LEDt2, HIGH);
    }
   else{
        
   }
     }
  
  
    TasterstatusT3 = digitalRead(Taster3);

  if (TasterstatusT3 != letzterTasterstatus){
    if( TasterstatusT3 == HIGH) {
      Tastercounter++;      
      digitalWrite (LEDt3, HIGH);
    }
   else{
       
   }
     }

    


  }

und jetzt werde ich doch faul ;)...wie bekomme ich am Ende meine kleine Lichtorgel hin...oder sagen wir alle drei LEDS drei mal blinken lassen?

byte LEDt1 = 11;

Das ist ein Pin am Arduino, der sich hoffentlich nicht verändert, Pin 11 eben. Du verwendest aber eine Variable, die, wie der Name sagt, variabel sein könnte. Für diese Variable wird Platz im raren Variablenspeicher belegt. obwohl da immer nur 11 drin steht.

Mit const byte optimiert der Compiler den Namen "LEDt1" komplett weg, ist nur für Dich zum Verständnis, belegt keinen Variablenspeicher.

TexMex: und jetzt werde ich doch faul ;)...wie bekomme ich am Ende meine kleine Lichtorgel hin...oder sagen wir alle drei LEDS drei mal blinken lassen?

Was Du noch benötigst, ist eine Ablaufsteuerung. Nur eine kleine, Trefferaufnahme und Lichtorgel möglicherweise. Also der richtige Zeitpunkt, faul zu werden ;)