Neues Problem. Ich habe aktuell diesen Code:
/*
Simon Says Spiel für einen Geocache
Simon Says ist ein Reaktions- und Gedächtnisspiel, bei dem eine Abfolge von blinkenden LEDs gezeigt wird.
Der Spieler muss diese Reihenfolge durch Tastendrücke korrekt wiederholen.
Mit jeder Runde wird die Sequenz länger und dadurch schwieriger.
Geogaching ist eine Globale Schatzsuche bei dem man versuchen muss mithilfe von Beschreibungen und Koordinaten einen sogenannten Geocache suchen.
Diser Geocache ist meist eine Art Dose welche ein Logbuch enthält.
*/
//Bibliotheken Einbinden
#include <Wire.h> //I²C Bus Bibliothek
#include <SPI.h> //SPI Bus Bibliothek
#include <U8g2lib.h> //Bibliothek des Displays
#include <SD.h> //Bibliothek für den SD Karten Leser
//Initialisierungen
U8G2_SSD1327_MIDAS_128X128_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); // Display Festlegen
//Eingänge
const int ButtonsX[] = {A0, A1, A2}; //Pins der Buttonmatrix auf der X Achse
const int EncoderCLK = 6; //CLK Pin des Encoders
const int EncoderDT = 7; //DT Pin des Encoders
const int EncoderSW = 8; //SW Pin des Encoders
const int SDInserted = 9; //SD Karte eingelegt
//Ausgänge
const int ButtonsY[] = {2, 3, 4}; //Pins der Buttonmatrix auf der Y Achse
const int Buzzer = 5; //Passiver Buzzer der Passend einen Ton macht
const int SDSelect = 10; //SD Karte auswählen
//Textvariablen
String Username; //Endgültiger Benutzernamen
char InputText[21] = ""; //Aktuell ausgewähltes Zeichen bei der Benutzereingabe
char DisplayText[21] = ""; //Bisher eingetragene Zeichen bei der Benutzereingabe
const char* Characters[] = //Erlaubte Zeichen für die Benutzereingabe
{
"a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z",
"0","1","2","3","4","5","6","7","8","9","-","_","'",
"<"
};
//Array Grössen
const int MatrixSize = sizeof(ButtonsX) / sizeof(ButtonsX[0]); //Anzahl der Button in eine Richtung -> Funktioniert nur Richig bei gleichmässiger Verteilung auf X und Y
const int NumberOfButtons = sizeof(ButtonsX) / sizeof(ButtonsX[0]) * sizeof(ButtonsY) / sizeof(ButtonsY[0]); // Anzahl der Buttons
const int CharactersSize = sizeof(Characters) / sizeof(Characters[0]) - 1; //Grösse des Array für die Zeichen bei der Benutzereingabe
//Allgemeine Parameter
const int NumberOfRounds = 1; //Anzahl der Runden
const int Time = 300; //Allgemeine Verzögerung
//Paramter für die Melodien des Buzzers
const int Tones[] = {262, 294, 330, 370, 415, 466, 494, 554, 622}; //Tonhöhen bei bestimmten LED's bzw Buttons
const int RightMelody[] = {587, 698, 880}; //Tonhöhen bei der Melodie die Mitteilt das eine Runde Richtig war
const int RightMelodyDuration[] = {200, 50}; //Verzögerung bei der Melodie die Mitteilt das eine Runde Richtig war
const int LoseMelody[] = {196, 130, 98}; //Tonhöhen bei der Melodie die Mitteilt das etwas falsches gedrückt wurde
const int LoseMelodyDuration[] = {300, 100}; //Verzögerungen bei der Melodie die Mitteilt das etwas falsches gedrückt wurde
const int WinMelody[] = {523, 659, 784, 523, 523, 659, 784, 1047}; //Tonhöhen bei der Melodie die Mitteilt das das Spiel eroflgreich abgeschlossen wurde
const int WinMelodyDuration[] = {175, 175, 175, 350, 175, 175, 175, 525}; //Verzögerungen bei der Melodie die Mitteilt das das Spiel eroflgreich abgeschlossen wurde
//Parameter für das Aufzeichnen des Simon Says Feld
const int GridSize = 40; //Grösse der Felder
const int GridX[] = {0, 43, 86, 0, 43, 86, 0, 43, 86}; //Position der Felder auf der X Achse
const int GridY[] = {0, 0, 0, 43, 43, 43, 86, 86, 86}; //Position der Felder auf der Y Achse
//Variablen
int Step; //Variable für Schrittkette
int PressedButton;
int LastPressedButton; //Index des Letzten Gedrückten Buttons
int InputCount; //Anzahl der Gedrücken Buttons Innerhalb einer Runde
int Round; //Aktuelle Runde
int SavedSequence[NumberOfRounds]; //Array um die Reihenfolge der LED's zu Speichern
int CurrentCLKState; //Aktueller Status des CLK Pins am Encoder
int LastCLKState; //Letzter Status des CLK Pins am Encoder
int LastSWState; //Letzer Status des SW Pins am Encoder
int CounterCharakters; //Anzahl bisher eingetragenen Zeichen (maximal 20)
int CursorPosition; //Cursor Position auf dem Disply -> Benutzername eingabe
int Attempts; //Anzahl Versuche des Spielers bis (wird nachdem es geschafft wurde zurückgesetzt)
unsigned long Lastmillis1; //Variable für die millis() funktion
//Setup wird nur beim Start einmal ausgeführt
void setup()
{
//Eingänge / Ausgänge definieren
pinMode(EncoderCLK, INPUT);
pinMode(EncoderDT, INPUT);
pinMode(EncoderSW, INPUT_PULLUP);
pinMode(Buzzer, OUTPUT);
for (int i = 0; i < MatrixSize; i++)
{
pinMode(ButtonsX[i], INPUT_PULLUP);
pinMode(ButtonsY[i], OUTPUT);
digitalWrite(ButtonsY[i], HIGH);
}
//Ausgänge Initialisieren
noTone(Buzzer);
//Merker Initialisieren
Step = 0;
Round = 0;
PressedButton = 0;
LastPressedButton = 0;
InputCount = 0;
CounterCharakters = 0;
CursorPosition = 0;
Attempts = 0;
CurrentCLKState = 0;
Lastmillis1 = 0;
LastSWState = false;
Username = "";
LastCLKState = digitalRead(EncoderCLK);
for (int i = 0; i < NumberOfRounds; i++)
{
SavedSequence[i] = 0;
}
//Display Starten
u8g2.begin();
//Display Initialisieren
u8g2.firstPage();
do {} while (u8g2.nextPage());
//SD Kartenleser Initialisieren
if (!SD.begin(SDSelect))
{
u8g2.firstPage();
do
{
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 20, "SD-Karte Fehler!");
} while (u8g2.nextPage());
delay(2000);
}
//Zufallsgenerator Initialisieren
randomSeed(analogRead(A7));
}
//Loop wird immer wieder wiederholt
void loop() {
switch (Step) {
case 0:
noTone(Buzzer);
Round = 0;
PressedButton = 0;
LastPressedButton = 0;
InputCount = 0;
CounterCharakters = 0;
CursorPosition = 0;
Attempts++;
CurrentCLKState = 0;
Lastmillis1 = 0;
LastSWState = false;
Username = "";
LastCLKState = digitalRead(EncoderCLK);
for (int i = 0; i < NumberOfRounds; i++)
{
SavedSequence[i] = 0;
}
u8g2.firstPage();
do {} while (u8g2.nextPage());
if (digitalRead(EncoderSW) == LOW)
{
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
} while (u8g2.nextPage());
delay(Time * 2);
Step = 1;
}
break;
case 1:
InputCount = 0;
for (int i = 0; i < Round; i++)
{
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
if (b == SavedSequence[i] - 1) {
u8g2.drawBox(GridX[b], GridY[b], GridSize, GridSize);
} else {
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
}
} while (u8g2.nextPage());
tone(Buzzer, Tones[SavedSequence[i] - 1]);
delay(Time);
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
} while (u8g2.nextPage());
noTone(Buzzer);
delay(Time);
}
Step = 2;
break;
case 2:
SavedSequence[Round] = random(1, NumberOfButtons + 1);
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++) {
if (b == SavedSequence[Round] - 1) {
u8g2.drawBox(GridX[b], GridY[b], GridSize, GridSize);
} else {
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
}
} while (u8g2.nextPage());
tone(Buzzer, Tones[SavedSequence[Round] - 1]);
delay(Time);
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
} while (u8g2.nextPage());
noTone(Buzzer);
Step = 3;
break;
case 3:
for (int y = 0; y < MatrixSize; y++)
{
digitalWrite(ButtonsY[y], LOW);
for (int x = 0; x < MatrixSize; x++)
{
if (digitalRead(ButtonsX[x]) == LOW)
{
LastPressedButton = y * MatrixSize + x + 1;
InputCount++;
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
if (b == LastPressedButton - 1) {
u8g2.drawBox(GridX[b], GridY[b], GridSize, GridSize);
} else {
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
}
} while (u8g2.nextPage());
tone(Buzzer, Tones[LastPressedButton - 1]);
delay(Time);
u8g2.firstPage();
do
{
for (int b = 0; b < NumberOfButtons; b++)
{
u8g2.drawFrame(GridX[b], GridY[b], GridSize, GridSize);
}
} while (u8g2.nextPage());
noTone(Buzzer);
while (digitalRead(ButtonsX[x]) == LOW)
{
delay(10);
}
delay(Time);
Step = 4;
}
}
digitalWrite(ButtonsY[y], HIGH);
}
break;
case 4:
if (LastPressedButton == SavedSequence[InputCount - 1])
{
if (InputCount >= Round + 1)
{
Round++;
if (Round >= NumberOfRounds)
{
for (int i = 0; i < 8; i++)
{
tone(Buzzer, WinMelody[i]);
delay(WinMelodyDuration[i]);
noTone(Buzzer);
delay(50);
}
DrawUsernameDisplay ();
Step = 5;
}
else
{
for (int i = 0; i < 3; i++)
{
tone(Buzzer, RightMelody[i]);
delay(RightMelodyDuration[1]);
noTone(Buzzer);
delay(RightMelodyDuration[2]);
}
Step = 1;
}
}
else
{
Step = 3;
}
}
else
{
for (int i = 0; i < 3; i++)
{
tone(Buzzer, LoseMelody[i]);
delay(LoseMelodyDuration[1]);
noTone(Buzzer);
delay(LoseMelodyDuration[2]);
}
Step = 0;
}
break;
case 5:
CurrentCLKState = digitalRead(EncoderCLK);
if (LastCLKState == LOW && CurrentCLKState == HIGH)
{
if (digitalRead(EncoderDT) == LOW)
{
CounterCharakters++;
if (CounterCharakters > CharactersSize)
{
CounterCharakters = 0;
}
}
else
{
CounterCharakters--;
if (CounterCharakters < 0)
{
CounterCharakters = CharactersSize;
}
}
DrawUsernameDisplay ();
}
LastCLKState = CurrentCLKState;
if (digitalRead(EncoderSW) == LOW && !LastSWState)
{
LastSWState = true;
Lastmillis1 = millis();
}
if (digitalRead(EncoderSW) == HIGH && LastSWState)
{
LastSWState = false;
if (millis() - Lastmillis1 < 2000)
{
if (strcmp(Characters[CounterCharakters], "<") == 0)
{
if (CursorPosition > 0)
{
CursorPosition--;
InputText[CursorPosition] = '\0';
}
}
else
{
if (CursorPosition < 20)
{
InputText[CursorPosition] = *Characters[CounterCharakters];
CursorPosition++;
InputText[CursorPosition] = '\0';
}
}
}
else
{
Step = 6;
}
DrawUsernameDisplay ();
}
break;
case 6:
Username = String(InputText);
Step = 0;
break;
default:
Step = 0;
break;
}
}
//Funktion um das Display zu Beschreiben bei der Benutzereingabe
void DrawUsernameDisplay ()
{
u8g2.firstPage();
do
{
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(5, 20, "Benutzername:");
strncpy(DisplayText, InputText, CursorPosition);
DisplayText[CursorPosition] = *Characters[CounterCharakters];
DisplayText[CursorPosition + 1] = '\0';
u8g2.drawStr(5, 50, DisplayText);
u8g2.drawStr(5, 53, "__________________");
}
while (u8g2.nextPage());
}
Ich habe nund folgendes Display gekauft: https://www.waveshare.com/wiki/1.5inch_OLED_Module
Der grund wiso ich nicht mehr das SH1107 verwende: das SH1107 habe ich nur in der Visualisierung verwendet. Ich habe nun die Ensprechende Hardware gekauft und an dieses kam ich am einfachsten bzw. habe ich als erstes gefunden.
Bei diesem muss man ja wenn man von Standard SPI auf I2C Wechseln will umlöten. Man hat ja BS1 - BS3. BS1 und BS2 muss man bei beiden den 0 OHM Wiederstand auslöten und die andern beiden pins stattdessen verbinden. Den BS3 habe ich auch mit 1 verbunden da 0X3D die Standartadresse ist. Laut Datenblatt und auf dem Display selbst benötigt man nur VCC, GND, DIN und CLK für I2C (DIN = SDA, CLK = SCL). Genau so habe ich es angeschlossen: VCC = 5V, GND = GND, DIN = A4, CLK = A5. Unten 2 Bilder von den Verbindungen.