Spiele – Pollux Labs https://polluxlabs.net Arduino, ESP32 & ESP8266 | Projekte & Tutorials Mon, 06 Sep 2021 16:01:29 +0000 de hourly 1 https://wordpress.org/?v=6.6.2 https://polluxlabs.net/wp-content/uploads/2020/05/cropped-pollux-labs-p-32x32.png Spiele – Pollux Labs https://polluxlabs.net 32 32 LCD Hill Run – Ein Arduino Jump’n’Run https://polluxlabs.net/arduino-projekte/lcd-hill-run-ein-arduino-jumpnrun/ Thu, 19 Mar 2020 19:35:30 +0000 https://polluxlabs.net/?p=1243 LCD Hill Run – Ein Arduino Jump’n’Run Weiterlesen »

]]>

Wer den ganzen Tag Daten von Sensoren ausliest hat sich eine Runde Zocken am Abend verdient! 🙂 Für dieses kleine Arduino Jump’n’Run benötigst du nur wenige Bauteile (und einige Kabel). Du baust es in wenigen Minuten auf und kannst danach gleich loslegen.

LCD Hill Run in Action

Die Idee und der Code für dieses Spiel stammt von Miles C., der es unter der Linzenz CC BY-SA 4.0 im Arduino Project Hub veröffentlicht hat. Wir erläutern nicht den ganzen Sketch des Spiels, aber erklären dir eine tolle Funktion, die du vielleicht noch nicht kennst: attachInterrupt()

Für dieses Projekt benötigst du:

* Amazon Affiliate Links – Wenn du dort bestellst, erhalten wir eine kleine Provision.

So funktioniert das Spiel

Die “Story” des Spiels ist schnell erzählt: Du spielst ein kleine Figur, die auf einem LCD-Display von alleine rennt und Hindernissen ausweichen muss. Hierbei musst du entweder springen oder dich ducken. Für jedes überwundene Hindernis erhältst du einen Punkt. Sobald du an einem Hindernis hängen bleibst, hast du verloren und dir wird dein Punktestand angezeigt.

Der Aufbau des Projekts

Wie du auf dem Screenshot unten siehst, sind bei diesem Projekt viele Kabel im Spiel. Das LCD-Display benötigt besonders viele. Wenn du ein Display mit I²C und integriertem Potentiometer verwendest, kannst du die Kabelei um einiges reduzieren.

Baue das Spiel wie folgt auf und prüfe alle Verbindungen noch einmal bevor du loslegst:

Aufbau des Arduino Spiels Hill Run
Screenshot: Tinkercad

Der Sketch des Arduino Jump’n’Runs

Wir werden an dieser Stelle nicht auf jedes Detail eingehen, viele der Konzepte im folgenden Sketch findest du in diesen Projekten und Tutorials auf pollux labs ausführlich erklärt:

Eine Funktion im Sketch ist aber recht selten anzutreffen, obwohl sie sehr hilfreich sein kann: attachInterrupt()

Die Funktion attachInterrupt()

Schauen wir erst auf ein gängiges Konzept: In diesem Sketch möchtest du auf einen gedrückten Button reagieren.

void loop() {
  
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin, LOW);
  }
}

Hier wird zunächst mit digitalRead() der Zustand des Buttons gelesen und dann in einer if/else-Abfrage mit einer LED reagiert.

Das funktioniert, ist aber etwas unpraktisch, wenn du im Loop noch etwas vorhast als nur darauf zu warten, dass jemand den Button drückt. Besser ist es da, das Überwachen des Buttons einen sogenannten Interrupt erledigen zu lassen, denn damit kannst du mehrere Prozesse gleichzeitig ablaufen lassen. In diesem Spiel sind das das Auslesen der beiden Buttons und die Animationen auf deinem LCD-Display. So ein Interrupt kann folgendermaßen aussehen:

volatile int buttonState = 0;

void setup() {
 
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, CHANGE);
}

void loop() {
}

void pin_ISR() {
  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin, buttonState);
}

Wie du siehst, ist hier der Loop sogar leer, die Abfrage des Buttons befindet sich jetzt im Setup. Das bedeutet, du hast im Loop Platz für andere Dinge. Die Funktion attachInterrupt() hat folgende Syntax:

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) 

Hierbei spielen die Parameter interrupt (der zu überwachende Pin), ISR (die beim Drücken des Buttons ausgeführte Funktion) und mode (Wann wird getriggert?) eine Rolle. Ausführliche Informationen findest du in der Arduino-Referenz.

Zurück zum Sketch des Spiels: Sobald du einen der beiden Buttons drückst, wird eine entsprechende Funktion aufgerufen, die deine Figur entweder springen – seeJumping() – oder sich ducken – seeDucking() –lässt.

Ansonsten besteht der Großteil des Sketchs dieses Arduino Jump’n’Runs aus Abfragen und Animationen, die dich auf den ersten Blick vermutlich ziemlich überrumpeln. Aber mit etwas Übung und Zeit wirst du auch durchsteigen – wenn du das möchtest und nicht einfach nur spielen willst. 🙂

Hier der gesamte Sketch:

/*
 * Copyright (c) 2020 by Miles C.
*/

#include <LiquidCrystal.h>
#include "pitches.h"
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

const int JUMP_PIN = 2;
const int BUZZER_PIN = 5;
const int DUCK_PIN = 3;

const int JUMP_PITCH = 2700; //sounds when button pressed
const int JUMP_PITCH_DURATION = 50; //sounds when button pressed
const int DUCK_PITCH = 1350; //sounds when button pressed
const int DUCK_PITCH_DURATION = 50; //sounds when button pressed
const int DIE_PITCH = 200; //sounds on death
const int DIE_PITCH_DURATION = 500; //sounds on death
const int TICKSPEED = 90; //ms per gametick, 1 gametick per hill move.
const int JUMP_LENGTH = 3; //chars jumped over when jump is pressed.
const byte stickStep1[8] = {
  B01110,
  B01110,
  B00101,
  B11111,
  B10100,
  B00110,
  B11001,
  B00001,
};
const byte stickStep2[8] = {
  B01110,
  B01110,
  B00101,
  B11111,
  B10100,
  B00110,
  B01011,
  B01000,
};
const byte stickJump[8] = {
  B01110,
  B01110,
  B00100,
  B11111,
  B00100,
  B11111,
  B10001,
  B00000,
};
const byte stickDuck[8] = {
  B00000,
  B00000,
  B00000,
  B01110,
  B01110,
  B11111,
  B00100,
  B11111,
};
const byte hill[8] = {
  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B11111,
  B11111,
  B11111,
};
const byte crow1[8] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B01110,
  B01110,
  B01110,
};
const byte crow2[8] {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B01110,
  B01110,
  B01110,
};

volatile int jumpPhase = JUMP_LENGTH + 1;
int gameTick = 0;
int crowX = 40;
int hillX = 25;
bool playerY = 0;
volatile bool ducking = LOW;
bool loopBreaker = 1;
bool crowGo = 0;
int score = 0;

void setup() {
  pinMode(JUMP_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  lcd.begin(16, 2);
  lcd.createChar(0, hill);
  lcd.createChar(1, stickStep1);
  lcd.createChar(2, stickStep2);
  lcd.createChar(3, stickJump);
  lcd.createChar(4, stickDuck);
  lcd.createChar(5, crow1);
  lcd.createChar(6, crow2);
  attachInterrupt(digitalPinToInterrupt(JUMP_PIN), seeJumping, RISING);
  attachInterrupt(digitalPinToInterrupt(DUCK_PIN), seeDucking, CHANGE);
}

void loop() {
  playerY = 0;
  if (jumpPhase < JUMP_LENGTH) {
    playerY = 1;
  }

  drawSprites();

  loopBreaker = 1;
  if (hillX < 16) {
    if (crowX < hillX) {
      hillX += 8;
      loopBreaker = 0;
    }
    if (loopBreaker) {
      lcd.setCursor(hillX, 1);
      lcd.write((byte)0);
    }
  }
  if (hillX < 1) {
    if (jumpPhase < JUMP_LENGTH) {
      score++;
      hillX = 16 + rand() % 8;
    } else {
      endGame();
    }
  }
  if (crowX < 16) {
    lcd.setCursor(crowX, 0);
    if (gameTick % 8 < 4) {
      lcd.write((byte)5);
    } else {
      lcd.write((byte)6);
    }
  }
  if (crowX < 1) {
    if (ducking) {
      score++;
      crowX = 24 + rand() % 16;
    } else {
      endGame();
    }
  }
  lcd.setCursor(0, playerY);
  lcd.print(" ");
  jumpPhase++;
  hillX--;
  crowGo = !crowGo;
  crowX -= crowGo;
  gameTick++;
  delay(TICKSPEED);
}

void endGame() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Score: ");
  lcd.setCursor(7, 0);
  lcd.print(score);
  tone(BUZZER_PIN, DIE_PITCH, DIE_PITCH_DURATION);
  while (!digitalRead(JUMP_PIN)) {
    lcd.setCursor(0, 1);
    if (millis() % 500 < 250) {
      lcd.print("Jump to Continue");
    } else {
      lcd.print("                ");
    }
  }
  lcd.clear();
  score = 0;
  hillX = 25;
  crowX = 40;
}

void drawSprites() {
  lcd.setCursor(0, 1 - playerY);

  if (!ducking) {
    if (!playerY) {
      if ((gameTick % 4) < 2 ) {
        lcd.write((byte)1);
      } else {
        lcd.write((byte)2);
      }
    } else {
      lcd.write((byte)3);
    }
  } else {
    lcd.write((byte)4);
  }
  lcd.setCursor(1, 1);
  lcd.print("               ");
  lcd.setCursor(1, 0);
  lcd.print("               ");
}
void seeJumping() {
  if (jumpPhase > (JUMP_LENGTH + 2) && !ducking) {
    jumpPhase = 0;
    tone(BUZZER_PIN, JUMP_PITCH, JUMP_PITCH_DURATION);
  }

}
void seeDucking() {
  ducking = digitalRead(DUCK_PIN);
  if (ducking) {
    jumpPhase = JUMP_LENGTH;
    tone(BUZZER_PIN, DUCK_PITCH, DUCK_PITCH_DURATION);
  }
}
]]>
Blick in die Zukunft https://polluxlabs.net/arduino-projekte/blick-in-die-zukunft-mit-zufallszahlen/ Thu, 03 Oct 2019 10:51:19 +0000 https://polluxlabs.net/?p=248 Blick in die Zukunft Weiterlesen »

]]>
Um es gleich von vorneweg zuzugeben: Die nächsten Lottozahlen wirst du mit diesem Projekt nicht vorhersagen. Dafür lernst du aber, wie du einen Servo-Motor ansteuerst und ihn mithilfe von ein paar Zufallszahlen “in die Zukunft schauen” lässt.

Für dieses Arduino Projekt benötigst du:

  • Arduino Board
  • Breadboard
  • Servo-Motor
  • Kondensator
  • 10k Ohm Widerstand
  • Schalter
  • Kabel

Simpler Aufbau – mit einem kleinen Haken

Arduino Projekt Blick in die Zukunft mit Zufallszahlen

Dieses Projekt auf dem Breadboard aufzubauen, ist kein Problem. Setze den Servo-Motor in die Mitte des Breadboards und befestige ihn z.B. mit einem Kabel, wie auf dem Foto unten zu sehen. Das ist nicht die stabilste Lösung, aber sie reicht aus, um ihn an Ort und Stelle zu halten.

Den Stecker des Motors steckst du links daneben auf das Breadboards und verbindest Plus (rot) und Minus (schwarz) mit der Stromleiste. In die Mitte – meist das weiße Kabel – setzt du eine Verbindung mit dem Digitalpin 2 am Arduino.

Übrigens: Alles Wissenswerte über Servos erfährst du in diesem Tutorial.

Wenn du einen Elektrolytkondensator verwendest (so wie ich in diesem Projekt) , musst du jetzt aufpassen. Setze den Kondensator auf das Board und verbinde das kurze Ende mit dem Minuspol. Das lange steckst du zwei Löcher weiter an den Pluspol.

Wichtig: Achte unbedingt darauf, den Kondensator richtig herum anzuschließen.

Vergewissere dich noch einmal, dass der Kondensator richtig herum eingebaut ist – auch anhand der Beschriftung am Kondensator selbst. Ihn falsch herum einzubauen, kann gefährlich werden. Denn dann kann er explodieren. Wie das aussieht und weitere Grundlagen zu Kondensatoren lernst du im folgenden Video.

Jetzt benötigst du noch einen Schalter, den du drückst, nachdem du deine Frage gestellt hast und der die Wahrsagerei in Gang setzt.

Den Schalter baust du über die Brücke deines Breadboards, sodass die zwei oberen Pins auf der einen und zwei unteren Pins auf der unteren Seite eingesteckt sind. Den Pin rechts oben verbindest du mit Plus. Der Pin links oben kommt per Kabel an den digitalen Eingang 3 deines Arduinos. Zusätzlich verbindest du ihn noch einen 10k Ohm Widerstand mit Minus. Wenn du fertig bist, sollte das ungefähr so aussehen:

Schalter am Arduino

Damit bist du fertig mit dem Aufbau dieses Projekts. Das einzige, was noch fehlt, ist eine Anzeige für die Antworten.

Die einfachste aller Anzeigen

Ich habe hierfür einfach ein Blatt Papier so ausgeschnitten, dass es um den Servo-Moto herum passt. Auf die linke Seite kommt das Nein, rechts das Ja und in die Mitte das Vielleicht.

Sicher bist du kreativer und machst etwas hübscheres. 🙂 Damit der Code unten jedoch zur Anzeige passt, achte darauf, die Antworten wie oben genannt zu verteilen.

Zufallszahlen generieren

Das Herzstück deines Projekts sind Zufallszahlen. Dein Arduino soll ja deine Fragen entweder mit Ja, Nein oder Vielleicht beantworten. Das heißt, dass du 3 Zahlen generieren musst, die jeweils für eine der 3 Antworten stehen.

Das geht ziemlich einfach. Alles was du brauchst, ist die Funktion random().

Für dieses Projekt möchten wir einfach die Zahlen 0, 1 oder 2. Hierfür tragen wir zwischen den Klammern der random-Funktion die Zahl 3 ein. Verwirrend? Auf den ersten Blick schon, aber du musst – wie so oft beim Programmieren – beachten, dass die letzte Zahl exklusiv ist. Das heißt, sie ist die äußere Grenze und wird nicht hinzugezählt. So als würdest du schreiben: < 3.

Lerne hier mehr über Zufallszahlen auf dem Arduino.

Der fertige Code

Jetzt benötigst du nur noch den Sketch, der deinen Wahrsager zum Laufen bringt. Die Generierung der Zufallszahlen haben wir uns schon angeschaut. Außerdem wichtig ist die Steuerung des Servo-Motors.

Lade den folgenden Code auf deinen Arduino und schon kann es losgehen.

#include <Servo.h> //Servo-Bibliothek einbinden
Servo myServo; //Servo-Objekt "myServo" erstellen

int angle; //Position, die der Servo anfahren soll
int switchState = 0; //Status des Schalters
int reply; //Generierte Zufallszahl

void setup() {

pinMode(3, INPUT);
  
myServo.attach(2); //Der Servo liegt an Pin 2
myServo.write(90); //1. Position des Servos - 90°

Serial.begin(9600);
}

void loop() {

switchState = digitalRead(3); //Lesen, ob der Schalter gedrückt wurde

  if(switchState == 1){
    reply = random(3); //Zufallszahl von 0 bis 2 generieren
    Serial.print(reply);
    
    switch(reply){
      
      case 0:
      myServo.write(0); //Falls 0, Servo nach links fahren - 0°
      delay(2000);
      break;

      case 1:
      myServo.write(90); //Falls 1, Servo nach oben fahren - 90°
      delay(2000);
      break;

      case 2:
      myServo.write(180); //Falls 2, Servo nach rechts fahren - 180°
      delay(2000);
      break;
      }
    }
}

Wie geht es weiter?

Du hast jetzt ein einfaches Grundgerüst für deinen Wahrsager. Sei kreativ und lass dir ein paar Verbesserungen einfallen! Zum Beispiel eine Anzeige der Antworten auf einem LCD-Display. Oder eine LED, die aufleuchtet, wenn der Schalter gedrückt wird.

]]>
Elektronischer Würfel https://polluxlabs.net/arduino-projekte/elektronischer-wuerfel/ Sun, 01 Sep 2019 17:36:16 +0000 https://polluxlabs.net/?p=239 Elektronischer Würfel Weiterlesen »

]]>
Lust auf ein einfaches Projekt, das du mit ein paar LEDs, Widerständen und Kabeln bauen kannst? Dann bist du mit diesem elektronischen Würfel gut beraten.

Der Aufbau ist nicht schwer und sollte in 15 – 20 Minuten gut zu bewältigen sein. Gerade für Kinder und Jugendliche ist dieses Projekt auch ohne Zutun eines Erwachsenen zu bewältigen. Schief oder sogar kaputt gehen sollte hier in der Regel nichts – wenn der Würfel nicht funktionieren sollte, liegt das vermutlich an einer falsch gesteckten Kabelverbindung.

Der Clou: Es kommen 7 LEDs zum Einsatz, die auf dem Breadboard so angeordnet werden, dass sie die Punkte eines Würfels nachbilden.

Für dieses Arduino-Projekt benötigst du:

  • Arduino Board
  • Breadboard
  • 7 LEDs
  • 1 Kippschalter
  • Kabel

Der Code ist recht rudimentär gehalten und könnte etwas eleganter und kürzer sein. Dafür lässt er sich auch von Anfängern gut nachvollziehen.

Du willst loslegen? Hier geht es zur Projektbeschreibung und zum Schaltplan des elektronischen Würfels.

Ideen für Erweiterungen

Wenn du den Würfel wie in der Projektbeschreibung aufgebaut hast, kannst du dir überlegen, wie du das Projekt noch erweitern kannst. Wie wäre es z.B. mit einem LCD-Display zum Anzeigen der Augen? Lerne hier, wie du ein LCD-Display anschließt.

Du könntest auch noch einen Piezo Buzzer anschließen, um die gewürfelten “Zahlen” mit einem Soundeffekt anzukündigen. In diesem Projekt wird erklärt, wie du einen Piezo Buzzer anschließt. Hier findest du im Code die Befehle, die du benötigst, um einfache Töne zu erzeugen. Eine ausführliche Beschreibung der dazugehörigen Funktion tone() findest du hier.

Zuletzt – und das erfordert schon etwas größere Kenntnisse – könntest du den Vorgang des Würfels etwas in die Länge ziehen und in dieser Zeit alle LEDs wild blinken lassen. Das wirkt realistischer und dürfte auch für Spannung bei den Spielteilnehmern sorgen.

Viel Spaß beim Zusammenbauen und Coden!

]]>