Arduino Binärzähler

Hi, ich komme gerade nicht mehr weiter.
Mein Programm soll den Druck eines Tasters erfassen (soweit ist mir alles klar)
und dann die Zahl in einer Variable um eins erhöhnen.

ich hoffen diese Frage ist nicht zu kindisch für euch und ihr helft mir
Danke schonmal im Vorraus :slight_smile:

Was hat das mit dem Binärzähler nun auf sich? :D

i++

Das ist doch ein Binärzähler oder wie nennt man das?

Einfach ein Zähler. Der Wert wird zwar Binär in einer Variablen gespeichert, aber das hat ja erstmal einen Einfluss auf Deine Aufgabe. Die Frage ist ja eher, was Du mit dem gezählten Werten anfangen willst. Wenn Du sie “binär” ausgeben willst (z.B. über eine Reihe von LEDs), dann ist es ein “Binärzähler” :slight_smile:
Poste doch mal Deinen Sketch, dann kann man Dir sicher besser helfen.
Mario.

Das kann wieder so eine Stelle sein wo ein Anfänger von der Arduino-Abstraktion reingelegt wird. Sowas sieht man einfach schöner wenn man direkt mit der Hardware arbeitet.

Wenn man 4 LEDs an Pins 8, 9, 10 und 11 anschließt kann man das machen:

int counter = 0;

void setup()
{
       DDRB = DDRB | 0x0F;        //Pins 0-3 auf PortB als Ausgang
}

void loop()
{
       PORTB = PORTB & 0xF0 | counter;   //untere 4 Bit erst auf 0 setzen und dann mit dem aktuellen Zähler verodern

        counter = (counter + 1) % 4;             //von 0-3 zählen
        delay(500);
}

Mann kann also counter in einem Rutsch auf die Ausgänge schreiben ohne da irgendwie zigmal mit digitalWrite() rumzuwurschteln. Und die LEDs gehen Binär :)

#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8,7);
int horizontal;
int vorwaerts = 2;
int zustandvorwaerts;

char a = 0;
byte figur[8] = 
{
   B01110,
   B01110,
   B01110,
   B00100,
   B01110,
   B00100,
   B01010,
   B01010,   
};


void setup()
{
  pinMode(vorwaerts, INPUT);
  lcd.begin(16,4);
  lcd.createChar(a, figur);
  
  
}

void loop()
{
  horizontal = digitalRead(vorwaerts) + 1;
  zustandvorwaerts = digitalRead(vorwaerts);
  if(zustandvorwaerts == 1)
  {
  lcd.setCursor(0,0);
  lcd.write(a);
  }
}

Ok:
Ich will dass sich ein kleines Mänchen pro Knopfdruck ein Kästchen weiterbewegt.
um das zu realisieren, muss sich die Zahl in der Variable “Horizontal” pro tasterdruck um den Wert eins erhöhen.
die Variable setze ich dann in den Befehl “lcd.setCursor(0,Horizontal)” ein.

So müsste es eigentlich klappen

Als erstes musst du mal deinen Taster entprellen und vernünftig auslesen:

Da gibt es aber noch andere Varianten. Oder auch eine Lib:

Ganz primitiv kann man auch nach dem Auslesen ca. 20-50 ms Delay machen, wenn das sonst nicht stört.

Dann musst du erst ein Leerzeichen auf die aktuelle Position schreiben. Dann inkrementieren und das Muster auf die neue Position schreiben.

ja, das entprellen und das über schreiben der alten position dürfte eigenetlich kein Problem sein, aber wie erhöhe ich den Wert der Variable den bei jedem Tastendruck um 1?

sschultewolter: i++

Mit der Bounce Lib solltest du erstmal alles soweit einrichten. Dann kannst du abfragen, ob der Taster gedrückt wurde.

   if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       value++;
     }
   }

so ich hab jetzt mal einen Code geschrieben.
der ist zwar nicht ganz allein von mir sondern aus einem “Entprell-Tutorial”.
aber ich hab das dann noch für meine Zwecke abgeändert.
Ich hab jetzt aber das Problem, dass das Zeichen, welches ich ausgeben möchte schon gleich am Anfang wenn ich das Programm auf den Arduino übertrage in der ersten Zeile und zweites Kästchen da ist, ohne dass ich den Button drücke.

Wäre nett wenn ihr euch den Code mal anschaut :slight_smile:

#include <LiquidCrystal.h>

LiquidCrystal lcd(13,12,11,10,9,8,7);

char a = 0;

  byte figur[8] = 
{
   B01110,
   B01110,
   B01110,
   B00100,
   B01110,
   B00100,
   B01010,
   B01010,   
};


const int TasterPin = 2;              // Pin Nummer des Tasters
int TasterStatus;                        // aktuelles Signal vom Eingangspin
int alterTasterStatus = LOW;    // vorheriger Status des Eingangspins
int Horizontal;                       // Nummer des Beluchtungsmodus

unsigned long letzteEntprellZeit = 0;   // letzte Zeit Änderung Status Ausgang
unsigned long entprellZeit = 50;          // Zeit für Entprellung, anpassen!


void setup()
{
  pinMode(TasterPin, INPUT);    //Taster Pin wird als Eingang gesetzt
  lcd.begin(16,4);
  lcd.createChar(a, figur);
}


void loop()
{
 //Setze Variable für das lesen des TasterPin
 int lesen = digitalRead(TasterPin);

/* 
  Überprüfe, ob Taster gedrückt ist und lange genug (entprellVerzögerung) gewartet wurde,
  um Prellen auszuschliessen
*/

  // Wenn sich der Status des Tasters geändert hat
  if (lesen != alterTasterStatus) 
  {
    letzteEntprellZeit = millis(); // stelle letzteEntprellZeit zurueck
  } 
  
  if ((millis() - letzteEntprellZeit) > entprellZeit)
  {
    // Da Taster lange genug gedrückt, wird Status aktualisiert
    TasterStatus = lesen;
    Horizontal = Horizontal +1;
    delay(500);
  }
  


  if(Horizontal = 0)
  {
    lcd.setCursor(0,0);
    lcd.write(a);
  }
  
    if(Horizontal = 1)
  {
    lcd.setCursor(1,0);
    lcd.write(a);
  }


  
  // speichere Status, wird beim naechsten Status bein naechsten Durchlauf alterTasterStatus
  alterTasterStatus  = lesen;
}
if(Horizontal = 0)

Ein Vergleich geht mit == = ist eine Zuweisung

Das kompiliert weil Zuweisungen der Wert der zugewiesen zurückgeben. Dieser wird dann automatisch mit 0 (false) und != 0 (true) verglichen.

Aber was du machen willst ist glaube ich das:

if(taster gedrückt)
{
    lcd.setCursor(horizontal, 0)
    lcd.write(' ');   //Leerzeichen um die Zelle zu löschen
    horizontal++;
    lcd.setCursor(horizontal, 0)
    lcd.write(a);   //Zeichen eins weiter schreiben
}

Wenn man es ganz genau nimmt ist das zweite setCursor() nicht nötig, da der LCD Controller das intern automatisch inkrementiert. Du musst dir nur merken wo du zuletzt geschrieben hast um das wieder zu löschen.

Danke für die Antwort Serenifly allerdings wenn ich dass mit deinem Code mache und diesen in diesie If-Abfrage reintue, also so:

 if ((millis() - letzteEntprellZeit) > entprellZeit)
  {
    // Da Taster lange genug gedrückt, wird Status aktualisiert
    TasterStatus = lesen;
    lcd.setCursor(Horizontal, 0);
    lcd.write(' ');   //Leerzeichen um die Zelle zu löschen
    Horizontal++;
    lcd.setCursor(Horizontal, 0);
    lcd.write(a);   //Zeichen eins weiter schreiben
  }

Leuchtet die Figur bei einmaligem drücken flackernd auf dem Bildschirm auf :astonished: Was kann ich da machen?

Bei millis() ist zu beachten, dass

if ( millis() - letztesMal > Zyklus )
{
     letztesMal = millis(); // sonst wird dies immer wieder durchlaufen
     // ... 
}

Man muss sich natürlich merken, dass die Aktion nach der Wartezeit gemacht wurde...

Zum Tasten-Entprellen reicht es übrigens meist, wenn ein Wechsel erkannt wurde, einfach 2 .. 10 ms zu warten. Das ist immer noch schnell für Taster-Reaktionen, aber das Prellen sollte dann vorbei sein.

Ja, so habe ich das immer in Assembler auf dem 8052 gemacht. Taste abfragen. Delay. Und dann vielleicht noch abfragen ob der Zustand noch gleich ist. Aber das braucht man auch nicht unbedingt.

Ok, es flimmert zwar jetz nicht mehr, aber dafür läuft die Figur jett Reihe für Reihe durch.

geht dein setCursor so: (x, y) oder so: (y, x) ?

Damit bestimmst du ob durch die Zeile oder die Spalte iterierst.

als erstes kommt der Charakter und dann die Zeile also (x,y)

Die Aufgaben-Stellung war das:

Ich will dass sich ein kleines Mänchen pro Knopfdruck ein Kästchen weiterbewegt.

Dann sollte es glaube ich passen. Ist halt immer schwer zu sagen, wenn man nur den Code sieht.

Wobei du das inkrementieren so machen solltest: Horizontal = (Horizontal + 1) % 16;

Sonst läuft er dir nach 16 Schritten irgendwo anders hin. Durch das Modulo 16 (Rest einer Division durch 16) wird der Index auf 0-15 begrenzt, da 16 % 16 = 0 ist

Danke, aber mein Problem dass die Figur jetzt ohne Knopfdruck von Chrakter 0 - 16 läuft ist immer noch nicht geklärt :~

Ok. Hatte vorher nicht genau verstanden was das Problem war.

Probier mal die Primitiv-Version von Entprellen:

if(taster gedrückt)
{
    delay(30);

     //Aktion
}

Taster prellen normalerweise so 10-50 ms. Wenn man da einfach wartet und erst danach weitermacht überspringt man das Prellen. Und bei so einfachen Programmen stört das nicht.

Und schau vielleicht mal ob dein Taster gedrückt Low oder High ist. Das geht so oder so.