Jeder kennt das Spiel “Ich sehe was, was du nicht siehst” aus seiner Kindheit. In diesem Arduino Projekt baust du eine elektronische Version davon.
Für den Prototyp benötigst du einen Arduino (ich verwende hier einen Arduino Uno), einen Farbsensor, ein LCD-Display (4×20 Zeichen, mit I2C-Anschluss, damit du nicht so viele Pins verwenden musst), einen Piezo-Buzzer und vier Buttons. Und natürlich einige Kabel und Widerstände.
Das Spiel funktioniert so: Der erste Spieler sucht ein Objekt im Raum in einer der vier Farben Rot, Gelb, Grün oder Blau. Dann drückt er den entsprechenden Button. Der zweite Spieler muss dann einen Gegenstand in dieser Farbe finden. Wenn er diesen innerhalb eines bestimmten Zeitraums nicht findet, muss der erste Spieler beweisen, dass dieser Gegenstand existiert und er nicht geblufft hat. Dann ist der andere Spieler dran.
Das benötigst du für dieses Arduino Projekt:
- Arduino Uno
- Breadboard
- I2C LCD-Display mit 4×20 Zeichen
- Farbsensor
- Piezo Buzzer
- 4 10kΩ Widerstände
- 4 Buttons
- Kabel (male/male, male/female)
Schritt 1: Buttons, Kabel & Widerstände
Zuerst steckst du die Buttons auf das Breadboard. Natürlich sind farbige Buttons am besten geeignet. Wenn du keine hast, kannst du die Farbe, für die sie stehen, auch auf andere Weise anzeigen: Du kannst farbige LEDs daneben platzieren oder sie einfach anmalen.
Platziere die Buttons in der Mitte des Boards, wie auf dem Foto gezeigt. Achte darauf, dass links oder rechts daneben für den Piezo Buzzer noch Platz ist. Verbinde einen Pin des Buttons per Kabel mit der + Leiste. Den anderen Pin mit einem 10k Ohm Widerstand an die Erdung (-). Wiederhole das drei Mal und schon bist du fertig.
Schritt 2: Sound mit dem Piezo Buzzer
Die Installation des Piezo Buzzers ist ebenfalls einfach. Verbinden Sie den linken Pin mit einem Kabel mit der Erde an deinem Breadboard. Der rechte Pin wird später direkt vom Arduino mit Strom versorgt. Um dieses Kabel mit dem Piezo Buzzer zu verbinden, musst du ein kleines Kabel neben den Pin legen, um wegen der Größe des Piezos an den Pin heranzukommen. Auf dem Foto ist dieses Kabel rot und darüber ist das Kabel (blau) vom Arduino zu sehen.
Schritt 3: Buttons und Buzzer mit dem Arduino verbinden
Hierfür benötigst du insgesamt 5 Kabel.
Verbinde den Piezo Buzzer mit dem digitalen Pin 11.
Schließe die 4 Buttons wie folgt an:
Rote Taste – Digital Pin 2
Gelbe Taste – Digital Pin 3
Grüne Taste – Digital Pin 4
Blaue Taste – Digital Pin 5
Schritt 4: Den Farbsensor anschließen
In diesem Projekt verwenden wir einen TCS230 / TC3200 Farbsensor. Mehr über diesen Farbsensor erfährst du hier.
Für den Anschluss des Farbsensors an den Arduino brauchst du 7 Kabel (male / female). Verbinde zwei Kabel mit den Pins “GND” (-) und “VCC” (+) und verbinde die beiden mit dem Strom auf deinem Breadboard
Verbinde die anderen 5 Pins mit deinem Arduino wie folgt:
S0 – Digitaler Pin 6
S1 – Digitaler Pin 7
S3 – Digitaler Stift 8
S2 – Digitaler Pin 9
OUT – Digitaler Pin 10
Erledigt! In diesem Tutorial erfährst du mehr über deinen Farbsensor.
Schritt 5: Das LCD-Display
In diesem Projekt verwenden wir ein I2C LCD-Display mit 4×20 Zeichen. Der Vorteil dieses Displays ist schlicht und einfach, dass es nicht so viele Pins an deinem Arduino benötigt – es sind nämlich nur 2 plus 2 für die Stromversorgung.
Du musst lediglich den Display-Pin “SCL” mit dem Pin A5 deines Arduinos und den Pin “SDA” mit dem Pin A4 verbinden. “GND” und “VCC” sind wie der Farbsensor mit der Stromleiste auf deinem Breaboard verbunden.
Der letzte Schritt ist die Stromversorgung. Verbinde das Breadboard mit dem 5V-Ausgang und einem “GND” an deinem Arduino.
In diesem Beitrag erfährst du mehr über den Anschluss eines LCD-Displays – ohne I2C.
Wie du eigene Zeichen auf einem Display darstellst, lernst du hier.
Schritt 6: Der Code und darüber hinaus
Endlich! Verbinde deinen Arduino mit deinem PC oder MAC und lade den folgenden Code hoch. Aber zuerst ein paar Punkte:
In der allerersten Zeile kannst du die Rundenzeit anpassen. Die Standardeinstellung ist 10 Sekunden (10000ms).
Du kannst jeden String im Programm anpassen, um deine eigenen Texte unterzubringen und zu verwenden.
Außerdem kannst du “Player1” und “Player2” umbenennen. Gib ihnen echte Namen!
Hinweis: Ein Farbsensor funktioniert nicht immer zuverlässig, sondern hängt stark von den Lichtverhältnissen und dem Material ab, das du “scanst”. Wenn dies zu stark reflektiert, reagiert der Sensor möglicherweise nicht.
Wenn du möchtest, experimentiere mit den Farbwerten in den entsprechenden Funktionen. Wenn dein Arduino am Computer angeschlossen ist und du eine der farbigen Tasten drückst, zeigt der serielle Monitor die Farbwerte an, die der Sensor erkennt. Verbessere z.B. den roten Farbraum, indem du verschiedene Rottöne “scanst” und die Werte in den folgenden Funktionen im Code anpasst:
checkRed()
checkRedBluff()
checkYellow()
checkYellowBluff()
checkGreen()
checkGreenBluff()
checkBlue()
checkBlueBluff()
Und jetzt der Code. Viel Spaß!
long roundTime = 10000; // Time for player to find the color
// include the library code:
#include <LiquidCrystal_I2C.h>
// define pins for color sensor
#define S0 6
#define S1 7
#define S2 9
#define S3 8
#define sensorOut 10
long currentTime; //elapsed time in round
long startTime = millis(); //start time of round
// values of each color from color sensor
int frequencyR = 0;
int frequencyG = 0;
int frequencyB = 0;
int color = 0;
// player points
int pointsPlayer1 = 0;
int pointsPlayer2 = 0;
int newGame = 0;
int keyRead = 0;
int playerOnTurn = 2;
int rightColorFound = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4); //Hier wird festgelegt um was für einen Display es sich handelt. In diesem Fall eines mit 16 Zeichen in 2 Zeilen und der HEX-Adresse 0x27. Für ein vierzeiliges I2C-LCD verwendet man den Code "LiquidCrystal_I2C lcd(0x27, 20, 4)"
void setup() {
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(sensorOut, INPUT);
pinMode(2, INPUT); //RED
pinMode(3, INPUT); //YELLOW
pinMode(4, INPUT); //GREEN
pinMode(5, INPUT); //BLUE
digitalWrite(S0,HIGH);
digitalWrite(S1,LOW);
Serial.begin(9600);
lcd.init();
lcd.backlight();
}
void loop() {
if(pointsPlayer1 == 0 && pointsPlayer2 == 0 && newGame == 0){
startGame();
newGame = 1;
}
}
void startGame(){
tone(11, 250, 150);
delay(100);
tone(11, 350, 150);
delay(100);
tone(11, 450, 150);
delay(100);
tone(11, 550, 150);
lcd.clear();
lcd.setCursor(1,1);
lcd.print("Welcome to Veo Veo");
delay(2500);
player1Chooses();
}
void player1Chooses(){
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player 1");
lcd.setCursor(3,2);
lcd.print("Choose a color");
while(keyRead == 0){
readKey();
}
}
void player2Chooses(){
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player 2");
lcd.setCursor(3,2);
lcd.print("Choose a color");
while(keyRead == 0){
readKey();
}
}
void showPoints(){
lcd.clear();
lcd.setCursor(7,0);
lcd.print("Score:");
lcd.setCursor(4,2);
lcd.print("Player 1: ");
lcd.print(pointsPlayer1);
lcd.setCursor(4,3);
lcd.print("Player 2: ");
lcd.print(pointsPlayer2);
delay(5000);
}
void newRound(){
color = 0;
keyRead = 0;
if(playerOnTurn == 2){
playerOnTurn = 1;
pointsPlayer2++;
rightColorFound = 0;
showPoints();
player2Chooses();
}else{
playerOnTurn = 2;
pointsPlayer1++;
rightColorFound = 0;
showPoints();
player1Chooses();
}
}
void readKey(){
if(digitalRead(2) == HIGH){
color = 1;
keyRead= 1;
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player " + String(playerOnTurn));
lcd.setCursor(3,2);
lcd.print("Find a RED thing");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkRed();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
proofBluff();
}else if(digitalRead(3) == HIGH){
color = 4;
keyRead= 1;
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player " + String(playerOnTurn));
lcd.setCursor(0,2);
lcd.print("YELLOW! Find YELLOW!");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkYellow();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
proofBluff();
}else if(digitalRead(4) == HIGH){
color = 2;
keyRead= 1;
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player " + String(playerOnTurn));
lcd.setCursor(2,2);
lcd.print("Something Green!");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkGreen();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
proofBluff();
}else if(digitalRead(5) == HIGH){
color = 3;
keyRead= 1;
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(6,0);
lcd.print("Player " + String(playerOnTurn));
lcd.setCursor(4,2);
lcd.print("Gimme BLUE!");
startTime = millis(); //Startzeit des Suchvorgangs
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkBlue();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
proofBluff();
}
}
void colorPicker(){
digitalWrite(S2,LOW);
digitalWrite(S3,LOW);
// Reading the output frequency
frequencyR = pulseIn(sensorOut, LOW);
//Remaping the value of the frequency to the RGB Model of 0 to 255
frequencyR = map(frequencyR, 25,72,255,0);
if(frequencyR < 0){
frequencyR = 0;
}else if(frequencyR > 255){
frequencyR = 255;
}
// Printing the value on the serial monitor
Serial.print("R= ");//printing name
Serial.print(frequencyR);//printing RED color frequency
Serial.print(" ");
// Setting Green filtered photodiodes to be read
digitalWrite(S2,HIGH);
digitalWrite(S3,HIGH);
// Reading the output frequency
frequencyG = pulseIn(sensorOut, LOW);
//Remaping the value of the frequency to the RGB Model of 0 to 255
frequencyG = map(frequencyG, 30,90,255,0);
if(frequencyG < 0){
frequencyG = 0;
}else if(frequencyG > 255){
frequencyG = 255;
}
// Printing the value on the serial monitor
Serial.print("G= ");//printing name
Serial.print(frequencyG);//printing RED color frequency
Serial.print(" ");
// Setting Blue filtered photodiodes to be read
digitalWrite(S2,LOW);
digitalWrite(S3,HIGH);
// Reading the output frequency
frequencyB = pulseIn(sensorOut, LOW);
//Remaping the value of the frequency to the RGB Model of 0 to 255
frequencyB = map(frequencyB, 25,70,255,0);
if(frequencyB < 0){
frequencyB = 0;
}else if(frequencyB > 255){
frequencyB = 255;
}
// Printing the value on the serial monitor
Serial.print("B= ");//printing name
Serial.print(frequencyB);//printing RED color frequency
Serial.println(" ");
}
void checkRed(){
colorPicker();
if(frequencyR > 200 && frequencyG < 115 && frequencyB < 115){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRound();
}
}
void checkYellow(){
colorPicker();
if(frequencyR < 200 && frequencyG > 200 && frequencyB < 210){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRound();
}
}
void checkGreen(){
colorPicker();
if(frequencyR < 200 && frequencyG > 200 && frequencyB < 210){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRound();
}
}
void checkBlue(){
colorPicker();
if(frequencyR < 120 && frequencyG < 120 && frequencyB > 150){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRound();
}
}
void newRoundBluff(){
color = 0;
keyRead = 0; //keyRead wieder zurücksetzen
if(playerOnTurn == 2){ //Spieler switchen, Punkt geben, anderen spieler aufrufen
playerOnTurn = 1;
pointsPlayer1++;
rightColorFound = 0;
showPoints();
player2Chooses();
}else{
playerOnTurn = 2;
pointsPlayer2++; // GEHT NICHT
rightColorFound = 0;
showPoints();
player1Chooses();
}
}
void proofBluff(){
if(color == 1){
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Opponent!");
lcd.setCursor(0,2);
lcd.print("Where is that color?");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkRedBluff();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
newRound();
}else if(color == 2){
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Opponent!");
lcd.setCursor(0,2);
lcd.print("Where is that color?");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkGreenBluff();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
newRound();
}else if(color == 4){
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Opponent!");
lcd.setCursor(0,2);
lcd.print("Where is that color?");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkYellowBluff();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
newRound();
}else if(color == 3){
tone(11, 450, 150);
delay(100);
tone(11, 650, 150);
delay(100);
tone(11, 750, 150);
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Opponent!");
lcd.setCursor(0,2);
lcd.print("Where is that color?");
startTime = millis();
while(rightColorFound == 0 && currentTime - startTime <= roundTime){
checkBlueBluff();
currentTime = millis();
}
lcd.clear();
tone(11, 150, 150);
delay(300);
tone(11, 50, 150);
lcd.setCursor(4,2);
lcd.print("Time is up!");
delay(1500);
newRound();
}
}
void checkRedBluff(){
colorPicker();
if(frequencyR > 200 && frequencyG < 115 && frequencyB < 115){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRoundBluff();
}
}
void checkYellowBluff(){
colorPicker();
if(frequencyR < 200 && frequencyG > 200 && frequencyB < 210){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRoundBluff();
}
}
void checkGreenBluff(){
colorPicker();
if(frequencyR < 200 && frequencyG > 200 && frequencyB < 210){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRoundBluff();
}
}
void checkBlueBluff(){
colorPicker();
if(frequencyR < 120 && frequencyG < 120 && frequencyB > 150){
lcd.clear();
tone(11, 450, 150);
delay(100);
tone(11, 650, 350);
lcd.setCursor(6,2);
lcd.print("Great!");
rightColorFound = 1;
delay(3000);
newRoundBluff();
}
}