Zählen in einem Bereich

Hallo,

bin gerade am erlernen der Basics mit Sketch und stehe am Anfang. Habe ein kleines Sketch Program geschrieben aber es macht nicht das was ich gerne hätte.

Ich möchte mit zwei Tastern vor und zurück zählen und dabei in bestimmten Bereichen aufhalten. z.B zwischen 0-3. Danach möchte die Zählvariable, auf verschiedenen Ausgängen schalten. Zunächst sollen es einfache LED's sein und später Relais. Ich habe schon gelesen dass man bei Relais mit millis arbeitet aber dafür ist es noch zu früh für mich.

Leider habe ich keinen realen Arduino zum testen und nutze leider nur einen Webbasierten Arduino von thinkercad.com.

Vielen Dank für eure Zeit!

Hier einmal das script:

int Schalter_rauf;
int Schalter_runter;
int EingangA = 2;
int EingangB = 3;
int AusgangA = 10;


void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
 
  pinMode(EingangA,INPUT);
  pinMode(EingangB,INPUT);
  pinMode(AusgangA,OUTPUT); 
}

void loop() {

 Schalter_rauf = digitalRead(EingangA);
 Schalter_runter = digitalRead(EingangB);
 int CNT=0;

 
  while (CNT < 3) {

   if (Schalter_rauf == 1)
    
       { CNT=CNT+1;}


   if (Schalter_runter == 0)
    
       {CNT=CNT-1;}}
    


    if (CNT==3) 
    
       {digitalWrite(AusgangA,HIGH);
}




}

bin offen für Kritik und Anregungen

Gruß Frank

Während der while-Schleife werden die Schalter nicht eingelesen.

Ich habe schon gelesen dass man bei Relais mit millis arbeitet

Nicht nur da.
Auch beim entprellen deines Tasters.

Leider habe ich keinen realen Arduino zum testen

Arduino kompatible Boards, sind für wenige Euronen, zu erwerben.

aber dafür ist es noch zu früh für mich

Meinst du?
:o Wenn du dir erst das falsche angewöhnt hast, dann ist es zu spät für dich. :o

Während der while-Schleife werden die Schalter nicht eingelesen.

Wie wäre es dann richtig? wenn ich digitalread() in der While Schleife einfüge ändert sich leider nichts.

void loop() {
  // put your main code here, to run repeatedly:
  
  

 int CNT=0;

  while (CNT< 5) {


 Schalter_rauf = digitalRead(EingangA);
 Schalter_runter = digitalRead(EingangB);


if (Schalter_rauf == 1)
    
   { CNT=CNT+1;}


 if (Schalter_runter == 0){
    
   CNT=CNT-1;}}
    


    if (CNT==1) {
digitalWrite(AusgangA,HIGH);
}


}

Arduino kompatible Boards, sind für wenige Euronen, zu erwerben.

ich weiß aber hier in Cebu City komme ich an keine Controller ran, da überall Straßensperren aufgestellt sind und man darf leider nicht raus.

:o Wenn du dir erst das falsche angewöhnt hast, dann ist es zu spät für dich. :o

hat mein Code schon den falschen Ansatz? :confused:

hat mein Code schon den falschen Ansatz?

Das kann ich nicht beurteilen!

Aber millis() auszublenden, wenn man ein Zeitverhalten benötigt, ist eher kontraproduktiv.

Hast ja mehr Zeit, als Arduinos.....
Ein guter Suchtipp: "Endlicher Automat"

Denn da läuft Arduino Programmierung meistens drauf hinaus!
Auch du willst offensichtlich einen Automaten bauen.
(selbst wenn dir das jetzt noch nicht klar ist)

Danke für deine Antwort

Aber millis() auszublenden, wenn man ein Zeitverhalten benötigt, ist eher kontraproduktiv.

millis() werde ich nicht ausblenden und ignorieren. Ich möchte erst einmal die Schleifen besser beherrschen und dann mich vor arbeiten.

Vielen dank für den Tip!

Hallo,

Deine ersten Gehversuche in allen Ehren, aber so wird das nichts werden. Du musst schon was zum üben und testen haben.

auf die while schleife kannst du verzichten dazu gibts loop
die Variable CTN würde ich dann global definieren, nicht im Loop da wird sie immer wieder auf 0 gesetzt
die Taster solltest Du irgendwie entprellen das kann man erst mal mit einem delay im loop machen
-die Variable CTN soll ja nur geändert werden wenn der Taster gerade gedrückt wurde und nicht wärend der gesamten Zeit. Stichwort Flankenerkennung

  • damit du sehen kannst ob das auch klappt sollte man einen Ausgabe auf dem Monitor machen.

  • Du solltes wissen wie man den Taster anschliesst. Damit der Eingang bei einem offenem Schalter nicht in der Luft hängt und irgendwas erkennt , benötigst Du eine Pullup oder pulldown Widerstand. Am einfachsten geht das wenn der Taster zwischen dem Pin und GND angschlossen wird dann kannst Du den internen Pullup einschalten. Damit ist der Eingang bei offenem Schalter H und bei geschlossenen L . Die Logik kann man beim Einlesen des Schalters wieder umdrehen (invertieren).

Um dir mal auf die Sprünge zu helfen hab ich mal was für Dich gemacht um hoch zu zählen, runter ist dann erst mal Deine Aufgabe.

Aber wie bereits gesagt du musst was zum probieren haben sonst bringt das nichts (kleines Starter-Kit). Amazon bringts nach Hause.

Heinz

const byte pinTaster = 3;
int counter;
bool merkerTaster, statusTaster;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pinTaster, INPUT_PULLUP);// taster schaltet gegen GND
}

void loop() {
  // put your main code here, to run repeatedly:
  statusTaster = !digitalRead(pinTaster);// Eingang einlesen und invertieren
  delay(10);// zum entprellen
  if (statusTaster & !merkerTaster) { // Flanke erkennen
    merkerTaster = true; // Merker setzten
    counter ++;
    Serial.println (counter);
  }
  if (!statusTaster) {
    merkerTaster = false; // reste Merker
  }
}

Vielen Dank Heinz für deine Mühe!

Ich werde mir es morgen anschauen und Rückmeldung geben.

kurze Frage! Wie ist "bool" standardmäßig eingestellt? Auf Pullup oder Pulldown habe ich in der Schaltung geachtet! :slight_smile:

Am Starterkit komme ich erstmal leider nicht ran und solange versuche mich an der Softwarelösung(leider). Bin gerade nicht in Europa und sowas wie Amazon, Shopee, Aliexpress usw. liefert nicht da hier alles geschlossen ist. Auf den Philippinen werden im Kampf gegen Corona andere Geschütze aufgefahren als in Europa. Die Millionenstadt gleicht einer Geisterstadt wo das Militär auf den Straßen patrouilliert.

Bleibt Gesund!

Wie ist "bool" standardmäßig eingestellt?

Gar nicht.

Ist ein Alias von _Bool

Oder meinst du die default initialization ?

Diese folgt natürlich den Regeln für die default initialization, wie alle anderen Initialisierungen auch!
Welche sagt:

  1. lokale werden nicht initialisiert.
  2. der Default ist ein mit 0, oder NULL, oder nullptr äquivalenter Wert.
  1. der Default ist ein mit 0, oder NULL, oder nullptr äquivalenter Wert.

Danke! ich meinte wie die Initialisierung von z.B. Bool xy; ist. 0 oder 1.

Heinz, ich habe das Skript etwas erweitert und das zurück Zählen implementiert.

const byte pinTaster2 = 4;
const byte pinTaster1 = 3;
int counter;
bool merkerTaster1, merkerTaster2, statusTaster1,statusTaster2;

void setup() {

  Serial.begin(9600);
  pinMode(pinTaster2, INPUT_PULLUP);// taster schaltet gegen GND
 pinMode(pinTaster1, INPUT_PULLUP);// taster schaltet gegen GND
  
}

void loop() {
 
  statusTaster1 = !digitalRead(pinTaster1);// Eingang einlesen und invertieren
  delay(10);// zum entprellen
  if (statusTaster1 & !merkerTaster1) { // Flanke erkennen
    merkerTaster1 = true; // Merker setzten
    counter ++;
    Serial.println (counter);
  }
  if (!statusTaster1) {
    merkerTaster1 = false; // reste Merker
  }

statusTaster2 = !digitalRead(pinTaster2);// Ausgang einlesen und invertieren
  delay(10);// zum entprellen

  
  if (statusTaster2 & !merkerTaster2) { // Flanke2 erkennen
    merkerTaster2 = true; // Merker2 setzten
    counter --;
    Serial.println (counter);}

  if (!statusTaster2) {
    merkerTaster2 = false; // reste Merker


  }

  
}

Könnt ihr einen Tip geben wie ich jetzt den Bereich zum Beispiel zwischen 0-6 einschränke? Er darf nicht weiter als 6 Zählen egal wie oft ich den Plustaster betätige und nicht weniger als 0.
Steht "const byte" dafür das ich mehrere Informationen in einer Variablen speichern kann ohne dafür Ram zu verbrauchen?

Der Unterschied zu meinem Skript ist, dass das Program nicht weiter runter zählen kann als -1, richtig?
Hat es noch andere Nachteile?

Auszug

void loop() {
  // put your main code here, to run repeatedly:
  X= digitalRead (pb);
  Y= digitalRead (pb1);
if (X==HIGH)
{CNT=CNT+1;
delay (200);}
if (Y==HIGH)
{CNT=CNT-1;
delay (200);
Serial.println (CNT);

}

Beste Grüße Frank

fraaaaank:
Danke! ich meinte wie die Initialisierung von z.B. Bool xy; ist. 0 oder 1.

So, wie Dir bereits gesagt wurde:

Als globale Variable mit 0, als lokale Veriable ist der Inhalt unbestimmt (je nachdem, was vorher an der Speicherstelle stand).

Gruß Tommy

Könnt ihr einen Tip geben wie ich jetzt den Bereich zum Beispiel zwischen 0-6 einschränke? Er darf nicht weiter als 6 Zählen egal wie oft ich den Plustaster betätige und nicht weniger als 0.

C++ bietet dir die Möglichkeit eigene Datentypen zu erfinden!

Also auch einen, welcher deinen Anforderungen gehorcht.

Steht "const byte" dafür das ich mehrere Informationen in einer Variablen speichern kann ohne dafür Ram zu verbrauchen?

byte ist ein Datentype!
Meist 8 Bit breit
Und const ein Modifizierer welche das so definierte zum "Read Only" macht

C++ bietet dir die Möglichkeit eigene Datentypen zu erfinden!

Das sieht elegant aus, aber für einmal im Leben und einmal im Sketch geht's auch direkt.
Zwei Mini-Funktionen zum Hoch/Runter-Zählen mit Begrenzung

inline byte up(byte& cnt) {if (cnt < 6) cnt++; return cnt;}
inline byte dn(byte& cnt) {if (cnt > 0) cnt--; return cnt;}

Hallo

was glaubst Du macht eine if Abfrage

if (count <=6) count++;
.
.
if (count >=0) cout--;

hier mal was zum lesen

oder auch als PDF

https://www.arduinoforum.de/referenz.php

Heinz

count++;
if (count >6) count=6;

Ich mache es immer so

Oder so, wenn man von 6 auf 0 springt beim hochzählen

count++;
if (count >6) count=0;

Vielen Dank für eure Hilfe und den links! Ich muss mich weiter mit der Thematik noch beschäftigen und viel lernen. Aber das was ich erst einmal wollte hat geklappt.

Danke !! :slight_smile:

Gruß Frank