摇骰代码 
 
- /*
 - Blog-Artikel: Schttel-Wrfel mit LED Matrix und Bewegungssimulation
 - 
 - https://techpluscode.de/schuettel-wuerfel-mit-led-matrix-und-bewegungssimulation/
 - 
 - techpluscode.de
 - Copyright 2019 von Thomas Angielsky
 - */
 - 
 - //Bibliothek fr die Ansteuerung der 8x8 LED-Matrix einbinden
 - //Include lib for the 8x8 LED matrix
 - #include "LedControl.h"
 - 
 - 
 - int PinTiltX = 2; //Pin fr Tiltsensor X
 - int PinTiltY = 3; //Pin fr Tiltsensor Y
 - 
 - //Pins der LED-Matrix
 - //Pins of the LED matrix
 - int PinCLK = 7;  
 - int PinCS = 6;
 - int PinDIN = 5;
 - 
 - LedControl lc = LedControl(PinDIN, PinCLK, PinCS, 1);
 - 
 - //Koordinaten der Wrfelaugen in der LED-Matrix
 - //Coordinates of the Dice points in the LED matrix
 - int DicePic[8][6][2] =
 - {
 -   { //leere Matrix und Startposition:
 -     {9,9}, //1. Punkt
 -     {9,8}, //2. Punkt
 -     {9,7}, //3. Punkt
 -     {9,6}, //4. Punkt
 -     {9,5}, //5. Punkt
 -     {9,4} //6. Punkt
 -   },
 -   { //1:
 -     {4,4}, //1. Punkt
 -     {-1,-1}, //2. Punkt
 -     {-1,-1}, //3. Punkt
 -     {-1,-1}, //4. Punkt
 -     {-1,-1}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   },
 -   { //2:
 -     {2,2}, //1. Punkt
 -     {6,6}, //2. Punkt
 -     {-1,-1}, //3. Punkt
 -     {-1,-1}, //4. Punkt
 -     {-1,-1}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   },
 -   { //3:
 -     {2,6}, //1. Punkt
 -     {6,2}, //2. Punkt
 -     {4,4}, //3. Punkt
 -     {-1,-1}, //4. Punkt
 -     {-1,-1}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   },
 -   { //4:
 -     {2,2}, //1. Punkt
 -     {2,6}, //2. Punkt
 -     {6,2}, //3. Punkt
 -     {6,6}, //4. Punkt
 -     {-1,-1}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   },
 -   { //5:
 -     {2,2}, //1. Punkt
 -     {2,6}, //2. Punkt
 -     {6,2}, //3. Punkt
 -     {6,6}, //4. Punkt
 -     {4,4}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   },
 -   { //6:
 -     {2,1}, //1. Punkt
 -     {2,4}, //2. Punkt
 -     {2,7}, //3. Punkt
 -     {6,1}, //4. Punkt
 -     {6,4}, //5. Punkt
 -     {6,7}  //6. Punkt
 -   },
 -   { //Start:
 -     {-1,-1}, //1. Punkt
 -     {-1,-1}, //2. Punkt
 -     {-1,-1}, //3. Punkt
 -     {-1,-1}, //4. Punkt
 -     {-1,-1}, //5. Punkt
 -     {-1,-1}  //6. Punkt
 -   }
 -   };
 - 
 - 
 - //Variablen der Wrfelaugen: Position, Richtung, Geschwindigkeit fr X und Y
 - //Variables of the dice: position, direction, speed for X and Y
 - float DiceXpos[6];
 - float DiceXdir[6];
 - volatile byte DiceXspeed[6];
 - float DiceYpos[6];
 - float DiceYdir[6];
 - volatile byte DiceYspeed[6];
 - 
 - 
 - int DiceValue;
 - unsigned long timestamp;
 - byte Mode;
 - int volatile shakes;
 - int ShakesPerSecond;
 - int step;
 - 
 - void InterruptChecks() {
 -   //Schttel-Anzahl zhlen
 -   //Count Shakes
 -   shakes=shakes+1;
 -   //Serial.println(millis());
 -   timestamp=millis();
 - }
 - 
 - void SetSpeedX() {
 -   if (Mode==0) {
 -     //alle Wrfel in X beschleunigen
 -     //Speed-up dice in X
 -     for (int i = 0; i < 6; i++) {
 -       if (DiceXspeed[i]<255) {DiceXspeed[i]=DiceXspeed[i]+5;}
 -     }
 -   }  
 -   InterruptChecks();
 - }
 - 
 - void SetSpeedY() {
 -   if (Mode==0) {
 -     //alle Wrfel in Y beschleunigen
 -     //Speed-up dice in Y
 -     for (int i = 0; i < 6; i++) {
 -       if (DiceYspeed[i]<255) {DiceYspeed[i]=DiceYspeed[i]+5;}
 -     }
 -   }
 -   InterruptChecks();
 - }
 - 
 - void ShowLed(int x, int y, bool onoff) {
 - //LED nur anzeigen, wenn im sichtbaren Bereich
 - //show only, when x/y in matrix
 -   if ((x<8) and (y<8) and (x>=0) and (y>=0)) {
 -     lc.setLed(0, x, y, onoff);
 -   }
 - }
 - 
 - void ShowDot(int x, int y, bool onoff) {
 - //Wrfel-Auge anzeigen oder ausblenden
 - //Show or hide dice point
 -   ShowLed(x-1, y-1, onoff);
 -   ShowLed(x, y-1, onoff);
 -   ShowLed(x-1, y, onoff);
 -   ShowLed(x, y, onoff);
 - }
 - 
 - void ShowDicePic(int value) {
 - //Wurf anzeigen
 - //Show dice
 - 
 - boolean done;
 - 
 -   //alle Punkte von der aktuellen Position aus zur Zielposition von DiceValue bewegen
 -   //move all points from current position to destination of DiceValue
 -   for (int i = 0; i < 6; i++) {
 -     DiceXspeed[i]=100;
 -     DiceYspeed[i]=100;
 - 
 -     //Werte fr X berechnen
 -     //Calc x values
 -     DiceXdir[i]=0;
 -     if (int(DiceXpos[i])>DicePic[value][i][0]) {DiceXdir[i]=-1;} 
 -     else if (int(DiceXpos[i])<DicePic[value][i][0]) {DiceXdir[i]=1;} 
 -     
 -     DiceYdir[i]=0;
 -     if (int(DiceYpos[i])>DicePic[value][i][1]) {DiceYdir[i]=-1;} 
 -     else if (int(DiceYpos[i])<DicePic[value][i][1]) {DiceYdir[i]=1;} 
 -   }
 - 
 -   //Serial.println(value);
 -   //Serial.println("Bewegung Start // Start moving");
 -   //Punkte bewegen
 -   do {
 -     //Serial.println("Bewegung // Moving");
 -     for (int i = 0; i < 6; i++) {
 -       if (int(DiceXpos[i])!=DicePic[value][i][0]) {
 -         DoStep(DiceXpos[i],DiceXdir[i],DiceXspeed[i],false);
 -       }
 -       if (int(DiceYpos[i])!=DicePic[value][i][1]) {
 -         DoStep(DiceYpos[i],DiceYdir[i],DiceYspeed[i],false);
 -       }
 -     }
 - 
 -     lc.clearDisplay(0);
 -     for (int i = 0; i < 6; i++) {
 -       ShowDot(int(DiceXpos[i]), int(DiceYpos[i]), true);
 -     }
 -     
 -     delay(50);
 - 
 -     //Sind alle Augen an ihrer Zielposition
 -     //Dice points are on destition position
 -     done=true;
 -     for (int i = 0; i < 6; i++) {
 -       if (int(DiceXpos[i])!=DicePic[value][i][0]) {done=false;}
 -       if (int(DiceYpos[i])!=DicePic[value][i][1]) {done=false;}
 -     }
 - 
 -   } while (done==false);
 -   //Serial.println("Bewegung Ende // End moving");
 - 
 -   lc.clearDisplay(0);
 -   for (int i = 0; i < 6; i++) {
 -     ShowDot(DicePic[value][i][0],DicePic[value][i][1], true);
 -   }
 - }
 - 
 - 
 - void DoStep(float &pos, float &dir, volatile byte &sp, bool check) {
 -   pos=pos+float(sp)/255*dir;
 - 
 -   if (check==true) {
 -     if (pos>7) {
 -         pos=7;
 -         dir=dir*(-1);
 -         }
 -     if (pos<1) {
 -         pos=1;
 -         dir=dir*(-1);
 -       }
 - 
 -   }
 -   // Geschwindigkeit wird pro Schritt langsamer
 -   // Velocity decreases every step
 -     if (sp>0) {sp=sp-1;}
 - }
 - 
 - void MoveDots() {
 -   //alle Wrfel einen Schritt weiter bewegen
 -   //move dice points one step further
 -   for (int i = 0; i < 6; i++) {
 -     //neue Koordinaten berechnen
 -     //calc new coordinates
 -     DoStep(DiceXpos[i],DiceXdir[i],DiceXspeed[i],true);
 -     DoStep(DiceYpos[i],DiceYdir[i],DiceYspeed[i],true);
 -   }
 - 
 -     //Wrfel-Augen anzeigen
 -     //show dice points
 -     lc.clearDisplay(0);
 -     for (int i = 0; i < 6; i++) {
 -       ShowDot(int(DiceXpos[i]), int(DiceYpos[i]), true);
 -     }
 -   
 - }
 - 
 - 
 - 
 - void setup() {
 -   //Der MAX7219 ist beim Starten im Power-Saving Modus,
 -   //er muss aufgeweckt werden.
 -   //The MAX7219 is in power-saving mode on startup,
 -   //we have to do a wakeup call
 -   lc.shutdown(0, false);
 -   //Helligkeit auf einen Mittelwert
 -   //Set the brightness to a medium values 
 -   lc.setIntensity(0, 8);
 -   //und Display lschen
 -   //and clear the display 
 -   lc.clearDisplay(0);
 - 
 -   randomSeed(analogRead(0));
 -   DiceValue=0;
 -   
 -   for (int i = 0; i < 6; i++) {
 -     DiceXpos[i]=DicePic[7][i][0];
 -     DiceYpos[i]=DicePic[7][i][1];
 -     
 -     DiceXdir[i]=random(3)-1;
 -     DiceYdir[i]=random(3)-1;
 -     DiceXspeed[i]=random(126)+120;
 -     DiceYspeed[i]=random(126)+120;
 -     }
 - 
 -   //Pins einstellen
 -   //Setup the pins
 -   pinMode(PinTiltX, INPUT_PULLUP);
 -   pinMode(PinTiltY, INPUT_PULLUP);
 -   attachInterrupt(digitalPinToInterrupt(PinTiltX),SetSpeedX,CHANGE);
 -   attachInterrupt(digitalPinToInterrupt(PinTiltY),SetSpeedY,CHANGE);
 -   
 -   lc.clearDisplay(0);
 - 
 -   timestamp=millis();
 -   Mode=1;
 - 
 -   ShowDicePic(6);
 -   delay(1000);
 -   
 -   lc.clearDisplay(0);
 -   Mode=0;
 -   Serial.begin(9600);
 -   step=0;
 -   shakes=0;
 - }
 - 
 - void loop() {
 -   delay(50);
 -   step=step+1;
 -   if (step>20) {
 -     //1 sek ist vorbei
 -     //1 sec is over
 -     step=0;
 -     ShakesPerSecond=shakes;
 -     shakes=0;
 -   }
 - 
 -   if (Mode==0) {
 -     MoveDots();
 -     if (millis()-timestamp>2000) {
 -       //seit 2 sek kein Schtteln mehr
 -       //there is no shaking since 2 sec
 -       Mode=1;
 -       DiceValue=random(6)+1;
 -       ShowDicePic(DiceValue);
 -     }
 -   }
 - 
 -   if (ShakesPerSecond>5) {
 -     //Es wird wieder geschttelt
 -     //shaking again
 -     Mode=0;
 -   }
 - 
 - }
 
  复制代码
  
 
 |