/*
* Description: Dice and Counter combination, displayed on an 8x8 matrix.
* Author: Flavius
* Version: 3.1
* Latest update: 03.03.2025
* Update description: General rewrite and cleanup, and new principle for displaying on the matrix: an array holding the data for the display. (Not ready)
*/
#include "MAX7219.h"
#define BUTTON 2
#define TRIG 5
#define ECHO 4
#define DIN 11
#define CLK 13
#define CS 10
bool displayMode = false; // True: Zähler, False: Würfel
volatile bool buttonState = false;
volatile unsigned long buttonPressedTimeStamp = 0;
volatile unsigned long lastButtonRisingEdgeTimeStamp = 0;
volatile unsigned long buttonRisingEdgeTimeStamp = 0;
volatile unsigned long buttonPressDuration = 0;
unsigned long counter[3]; // 0: Counter 1: Set-Time 2: Display-Time
unsigned long roll[3];
unsigned long displayModeTime[2];
byte matrixCharacters[8][26] = {
{B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000},
{B00111100, B01111100, B00111110, B01111100, B01111110, B01111110, B00111110, B01000010, B01111100, B00111110, B01000100, B01000000, B01000010, B01100010, B00111100, B01111100, B00111100, B01111100, B00111100, B01111100, B01000010, B01000100, B10000010, B01000010, B01000010, B01111110},
{B01000010, B01000010, B01000000, B01000010, B01000000, B01000000, B01000000, B01000010, B00010000, B00000010, B01001000, B01000000, B01100110, B01010010, B01000010, B01000010, B01000010, B01000010, B01000010, B00010000, B01000010, B01000100, B10000010, B01000010, B01000010, B00000010},
{B01000010, B01000010, B01000000, B01000010, B01000000, B01000000, B01000000, B01000010, B00010000, B00000010, B01010000, B01000000, B01011010, B01010010, B01000010, B01000010, B01000010, B01000010, B01000000, B00010000, B01000010, B01000100, B10000010, B00100100, B00100100, B00000100},
{B01111110, B01111100, B01000000, B01000010, B01111100, B01111100, B01001110, B01111110, B00010000, B00000010, B01100000, B01000000, B01000010, B01001010, B01000010, B01111100, B01000010, B01111100, B00111100, B00010000, B01000010, B01000100, B10010010, B00011000, B00011000, B00001000},
{B01000010, B01000010, B01000000, B01000010, B01000000, B01000000, B01000010, B01000010, B00010000, B00000010, B01010000, B01000000, B01000010, B01001010, B01000010, B01000000, B01001010, B01001000, B00000010, B00010000, B01000010, B00101000, B10101010, B00100100, B00010000, B00010000},
{B01000010, B01000010, B01000000, B01000010, B01000000, B01000000, B01000010, B01000010, B00010000, B01000010, B01001000, B01000000, B01000010, B01000110, B01000010, B01000000, B00111100, B01000100, B01000010, B00010000, B01000010, B00101000, B10101010, B01000010, B00100000, B00100000},
{B01000010, B01111100, B00111110, B01111100, B01111110, B01000000, B00111110, B01000010, B01111100, B00111100, B01000100, B01111110, B01000010, B01000010, B00111100, B01000000, B00000010, B01000010, B00111100, B00010000, B00111100, B00010000, B01000100, B01000010, B01000000, B01111110}
// 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
};
byte matrixDigits[8][10] = {
{B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // 1. Zeile
{B00111100, B00000010, B01111100, B01111100, B01000010, B00111110, B00111100, B00111100, B00111100, B00111100}, // 2. Zeile
{B01000010, B00000010, B00000010, B00000010, B01000010, B01000000, B01000000, B00000010, B01000010, B01000010}, // 3. Zeile
{B01000010, B00000000, B00000010, B00000010, B01000010, B01000000, B01000000, B00000010, B01000010, B01000010}, // 4. Zeile
{B01000010, B00000010, B00111100, B00111100, B00111100, B00111100, B00111100, B00000000, B00111100, B00111100}, // 5. Zeile
{B01000010, B00000010, B01000000, B00000010, B00000010, B00000010, B01000010, B00000010, B01000010, B00000010}, // 6. Zeile
{B01000010, B00000010, B01000000, B00000010, B00000010, B00000010, B01000010, B00000010, B01000010, B00000010}, // 7. Zeile
{B00111100, B00000010, B00111110, B01111100, B00000010, B01111100, B00111100, B00000010, B00111100, B00111100} // 8. Zeile
// 0 1 2 3 4 5 6 7 8 9
};
byte matrixDiceFaces[8][7] = {
{B00111100, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}, // 1. Zeile
{B01000010, B00000000, B01100000, B01100000, B01100110, B01100110, B11011011}, // 2. Zeile
{B00000010, B00000000, B01100000, B01100000, B01100110, B01100110, B11011011}, // 3. Zeile
{B00000010, B00011000, B00000000, B00011000, B00000000, B00011000, B00000000}, // 4. Zeile
{B00001100, B00011000, B00000000, B00011000, B00000000, B00011000, B00000000}, // 5. Zeile
{B00010000, B00000000, B00000110, B00000110, B01100110, B01100110, B11011011}, // 6. Zeile
{B00000000, B00000000, B00000110, B00000110, B01100110, B01100110, B11011011}, // 7. Zeile
{B00010000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000} // 8. Zeile
//Wüfel 0"?" Würfel 1 Würfel 2 Würfel 3 Würfel 4 Würfel 5 Würfel 6
};
byte matrixDiceAnimationFrames[8][19] = {
{B10000001, B11000011, B01111110, B00111100, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11111111, B11000011, B10000001},
{B00000000, B10000001, B10000001, B01000010, B00011000, B00000000, B00000000, B00000000, B00000000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11111111, B11000011, B10000001, B00000000},
{B00000000, B00000000, B10000001, B10000001, B00100100, B00011000, B00000000, B00011000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11100111, B11000011, B10000001, B00000000, B00000000},
{B00000000, B00000000, B10000001, B10000001, B01000010, B00100100, B00011000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11100111, B11000011, B10000001, B00000000, B00000000, B00000000},
{B00000000, B00000000, B10000001, B10000001, B01000010, B00100100, B00011000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11100111, B11000011, B10000001, B00000000, B00000000, B00000000},
{B00000000, B00000000, B10000001, B10000001, B00100100, B00011000, B00000000, B00011000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11100111, B11000011, B10000001, B00000000, B00000000},
{B00000000, B10000001, B10000001, B01000010, B00011000, B00000000, B00000000, B00000000, B00000000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11111111, B11000011, B10000001, B00000000},
{B10000001, B11000011, B01111110, B00111100, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B11111111, B11000011, B10000001}
// Frame 1 Frame2 Frame 3 Frame 4 ... 13
};
void updateMode();
long measureDistance();
MAX7219 matrix(DIN, CS, CLK);
void setup() {
Serial.begin(9600);
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), isr, CHANGE);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
matrix.begin();
matrix.clear();
matrix.setBrightness(5);
}
void loop() {
updateMode();
if (displayMode && (counter[1] > counter[2] || displayModeTime[0] > displayModeTime[1])) {
Serial.println(counter[0]);
displayMatrix(displayMode, counter[0]);
counter[2] = counter[1];
displayModeTime[1] = displayModeTime[0];
} else if (!displayMode && (roll[1] > roll[2] || displayModeTime[0] > displayModeTime[1])) {
Serial.println(roll[0]);
displayMatrix(displayMode, roll[0]);
roll[2] = roll[1];
displayModeTime[1] = displayModeTime[0];
}
}
void displayMatrix(bool mode, int number) {
if (mode) {
for (byte i = 0; i<8; i++) {
matrix.setRow(i ,matrixDigits[i][number]);
}
} else if (!mode) {
if (roll[1] > roll[2]) {
for (byte i = 0; i<=19; i++){
for (byte ii = 0; ii<8; ii++) {
if (i >= 13) {
matrix.setRow(ii ,(matrixDiceAnimationFrames[ii][i-1])|(matrixDiceFaces[ii][number]));
} else {
matrix.setRow(ii ,matrixDiceAnimationFrames[ii][i-1]);
}
}
delay(50);
}
}
for (byte i = 0; i<8; i++) {
matrix.setRow(i ,matrixDiceFaces[i][number]);
}
}
}
void updateMode() {
// Für button:
if ((buttonPressDuration >= 350) && (lastButtonRisingEdgeTimeStamp != buttonRisingEdgeTimeStamp) && !buttonState) {
lastButtonRisingEdgeTimeStamp = buttonRisingEdgeTimeStamp;
Serial.println("Langer Druck");
roll[0] = random(1,7); roll[1] = millis();
displayMode = false;
} else if ((buttonPressDuration < 350) && (lastButtonRisingEdgeTimeStamp != buttonRisingEdgeTimeStamp) && !buttonState) {
lastButtonRisingEdgeTimeStamp = buttonRisingEdgeTimeStamp;
displayMode = !displayMode;
displayModeTime[0] = millis();
Serial.println("Kurzer Druck");
} else {
// Für Ultraschall
static bool objectDetected = false;
long distance = measureDistance();
if ((distance > 0) && (distance <= 10)) {
if (!objectDetected) {
counter[0]++; counter[1] = millis();
if (counter[0] > 6) {
counter[0] = 0;
}
displayMode = true;
objectDetected = true;
Serial.println("Objekt vorbei");
}
} else if (distance > 15) {
objectDetected = false;
}
}
}
long measureDistance() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long time = pulseIn(ECHO, HIGH);
long distance = time * 0.034 / 2; // Umrechnung in cm
return distance;
}
void isr() { // Ermittelt die Länge des Tasterdrucks
buttonState = !digitalRead(BUTTON);
if (buttonState) { // Fallende Flanke
buttonPressedTimeStamp = millis();
}
if (!buttonState){ // Steigende Flanke
buttonRisingEdgeTimeStamp = millis();
buttonPressDuration = millis() - buttonPressedTimeStamp;
Serial.println(buttonPressDuration);
}
}