Eriflex Verteilerbloecke


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Hammerspiel mit Foliendrucksensor


Anzeige


Mit dem „Hammerspiel mit Foliendrucksensor“ basteln wir ein lustiges Spiel für einen, zwei oder mehrere Spieler. An einer bestimmten Stelle wird ein Drucksensor, der ein analoges Signal liefern kann, angebracht. Das analoge Signal wird mithilfe eines Mikrocontrollers, in dem Fall Arduino Mega, ausgewertet. Die Auswertung wird auf einem Bildschirm, hier RGB-Matrix mit 64x64 RGB-Leds, visualisiert.
Die Spielregeln sind alles andere als kompliziert. Ein Spieler schlägt mit einem Hammer möglichst „gefühlvoll“ auf den Sensor und wartet ab, wie sein Schlag bewertet wird. Jeder Spieler hat bei einem Versuch fünf Schläge. Für jeden Schlag gibt es Punkte. Der Spieler, die die meisten Punkte gesammelt hat, ist der Gewinner.
Die Schwierigkeit bei dem Spiel besteht darin, jedem Schlag eine bestimmte Kraft zu verleihen. Fällt der Schlag zu schwach aus, kriegt der Spieler keinen Punkt. Übertreibt er mit seiner Kraft und schlägt auf den Sensor zu stark, gibt es ebenfalls keine Punkte. Man muss die zu einsetzende Schlagkraft gut einschätzen, um seine Punktesammlung vergrößern zu können.
In dieser Spielausführung kann man mit einem Schlag maximal drei oder fünf Punkte bekommen. Fünf Punkte erhält man, indem man sozusagen ins Schwarze trifft. Um das Spiel interessanter zu gestalten, kann die Punkteskala problemlos erweitert werden.

Anzeige

Anzeige

Als „Bildschirm“ fungiert in der Schaltung eine RGB-Matrix, die für Anzeigezwecke immerhin 4096 LEDs zur Verfügung stellt. Jeder Schlag wird mit einem farbigen, senkrecht aufgestellten Balken visualisiert. Die Bereiche, wo man Punkte bekommen kann, sind deutlich markiert. Zusätzlich zu der Balkenanzeige wird nach jedem Hammerschlag die erreichte Punktezahl angezeigt. Bei einem „Schuss ins Schwarze“ wird als Belohnung zusätzlich ein lächelndes Smiley angezeigt.

Mikrocontroller

mikrocontroller

Die Aufgabe einer Schnittstelle zwischen dem Sensor und Anzeigetafel übernimmt in dem Beispiel Arduino Mega. Er stellt uns ausreichende Anzahl an Pins zur Verfügung, sodass die Komponenten problemlos angeschlossen werden können und noch eine beachtliche Pinanzahl für eventuelle Erweiterungen zur Verfügung steht. Viel zu tun hat der Mikrocontroller nicht. Er fragt fortlaufend den analogen Eingang, um festzustellen, ob gerade ein Hammerschlag ausgeführt wurde, ab. Sobald dies festgestellt wird, wird der gemessene Wert entsprechend skaliert und zwecks Ausgabe zur Matrix geschickt. Anschließend wartet er auf den nächsten Hammerschlag.

Drucksensor

Drucksensor

Der Sensor ist wasserdicht und verändert bei Krafteinwirkung seinen Widerstand. Angeschlossen an eine kleine Platine bildet er ein Modul mit drei Anschlusspins. Die Veränderung des Widerstandes wirkt sich auf das analoge Signal, das einen Wert zwischen 0V und VCC annehmen kann. Angeschlossen an einen analogen Arduino-Pin liefert das Signal Werte zwischen 0 und 1023. Der Sensor kann sowohl mit 3,3V als auch mit 5V betrieben werden.

Anschlüsse:
Vcc – Spannungsversorgung
GND – Masse
Sig – Analoges Ausgangssignal

Schaltplan

Schaltplan



Testschaltung

Testschaltung



Programm (Sketch)


// *********************************************************************************************
// Hammerspiel mit Foliendrucksensor
// Eine Schaltung mit Foliendrucksensor, Arduino Mega und RGB-Matrix 64x64
// Arduino IDE 2.3.2
// *********************************************************************************************

#include "RGBmatrixPanel.h"                                // Matrix - Bibliothek                

#define CLK 11                                             // Pins für Matrix-Anschlüsse
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
#define E A4

RGBmatrixPanel matrix(A, B, C, D, E, CLK, LAT, OE, false, 64);

unsigned long Millis_Aktuell, Millis_Alt_1, Millis_Alt_2;
int X, Y;
int Drucksensor_Signal;
int Signal_Wert_Maximal;
int Balken_Anzahl;

// *********************************************************************************************
void setup() {

    matrix.begin();
    delay(100);
    matrix.drawRect(0, 0, 64, 64, matrix.Color333(7, 0, 7));    // Außen Rahmen Violett
    matrix.drawRect(10, 7, 10, 55, matrix.Color333(7, 7, 0));   // Ergebnisfeld

    matrix.drawLine(20, 19, 20, 24, matrix.Color333(7, 0, 7));  // Punkte Markierung
    matrix.drawLine(21, 25, 21, 28, matrix.Color333(7, 0, 0));
    matrix.drawLine(20, 29, 20, 34, matrix.Color333(7, 0, 7));

    matrix.drawLine(51, 1, 51, 15, matrix.Color333(0, 0, 7));   // Bunte Linien Ecke rechts oben
    matrix.drawLine(52, 1, 52, 25, matrix.Color333(0, 7, 7));
    matrix.drawLine(53, 1, 53, 12, matrix.Color333(0, 7, 0));
    matrix.drawLine(54, 1, 54, 15, matrix.Color333(0, 0, 7));
    matrix.drawLine(55, 1, 55, 10, matrix.Color333(0, 7, 7));
    matrix.drawLine(56, 1, 56, 27, matrix.Color333(0, 7, 0));
    matrix.drawLine(57, 1, 57, 13, matrix.Color333(0, 7, 7));
    matrix.drawLine(58, 1, 58, 12, matrix.Color333(0, 7, 0));
    matrix.drawLine(59, 1, 59, 15, matrix.Color333(0, 0, 7));

    Millis_Alt_1 = Millis_Alt_2 = millis();                // Millisekunden aktuell festhalten
}

// *********************************************************************************************
void loop() {

    Drucksensor_Signal = analogRead (A5);                  // Druck permanent abfragen
    Millis_Aktuell = millis();                             // Millisekunden aktuell
                                          
    if (Drucksensor_Signal > 20) {                                   // Sensor meldet Versuch
        matrix.fillRect(12, 9, 6, 48, matrix.Color333(0, 0, 0));     // Ergebnisfeld Löschen
        matrix.fillRect(25, 20, 10, 14, matrix.Color333(0, 0, 0));   // Punkte-Anzeige Löschen
        matrix.fillRect(35, 42, 11, 11, matrix.Color333(0, 0, 0));   // Smiles Löschen
        Millis_Alt_1 = Millis_Alt_2 = Millis_Aktuell;
        Signal_Wert_Maximal = 0;
        Balken_Anzahl = 0;

        while (Millis_Aktuell - Millis_Alt_1 < 1000) {          // Abfrage mindestens 1 Sek. lang
            Millis_Aktuell = millis();
            if (Drucksensor_Signal > Signal_Wert_Maximal) {     // Maximalen Wert ermitteln
                Signal_Wert_Maximal = Drucksensor_Signal;       // Neuer Wert gefunden
            }
                                                                // Ergebnisfeld füllen schon während
                                                                // der 1. Sek. Abfrage
            if (Millis_Aktuell - Millis_Alt_2 >= 30) {          // Ein Balken pro 30 msek.
                int Wert = Signal_Wert_Maximal / 20;            // 1 Balken = 20 (von 1023 / 5V)
                if (Wert > Balken_Anzahl) {
                    Balken_Anzahl++;                            // Balkenanzahl festhalten
                    Y = 60 - Balken_Anzahl;                     // Y-Koordinate
                    matrix.drawLine(12, Y, 17, Y, matrix.Color333(0, 0, 7));   // Balken zeichnen
                }
                Millis_Alt_2 = Millis_Aktuell;
            }
            Drucksensor_Signal = analogRead (A5);
        }
                                                                // 1 Sek. abgelaufen
        int Wert = Signal_Wert_Maximal / 20;                    // Gesamtmessung auswerten
        if (Wert > Balken_Anzahl) {                             // Restliche Balken 
            for (int i = Balken_Anzahl; i <= Wert; i++ ) {      // Balken zeichnen
                Y = 60 - i;
                matrix.drawLine(12, Y, 17, Y, matrix.Color333(0, 0, 7));
                int k;
                k++;
                delay(30+k*10);                                 // Anzeige oben immer langsamer
            }
        }
                                                                // Punkte anzeigen
                                                                // 3 Pkt. Bereich 1 = 520 - 639
                                                                // 5 Pkt. Bereich 2 = 640 - 719 Volltreffer
                                                                // 3 Pkt. Bereich 2 = 720 - 839 
        if (Signal_Wert_Maximal >= 520 && Signal_Wert_Maximal <= 639) {            
            Punktenzahl ('3');
        }
        if (Signal_Wert_Maximal >= 640 && Signal_Wert_Maximal <= 719) {
            Punktenzahl ('5');
            Smiles(40, 47);
        }
        if (Signal_Wert_Maximal >= 720 && Signal_Wert_Maximal <= 839) {            
            Punktenzahl ('3');
        }      
        if (Signal_Wert_Maximal < 520 or Signal_Wert_Maximal > 839) {
            Punktenzahl ('0');
        }                  
    }
}

// *********************************************************************************************
void Punktenzahl (char Ziffer) {
              
    matrix.fillRect(25, 20, 10, 14, matrix.Color333(0, 0, 0));       // Feld Löschen
    matrix.setTextSize(2);                                           // Textgröße
    matrix.setCursor(25, 20);                                        // Cursor Position
    matrix.setTextColor(matrix.Color333(7,7,0));                     // Textfarbe
    matrix.println(Ziffer);                                          // Ziffer anzeigen
}

// *********************************************************************************************
void Smiles(int X, int Y) {
                                                                     // Smiles Elemente zeichnen
    matrix.drawCircle(X, Y, 5, matrix.Color333(0, 7, 7));                      // Kreis
    matrix.fillRect(X - 2, Y - 2, 2, 2, matrix.Color333(0, 7, 7));             // Augen
    matrix.fillRect(X + 1, Y - 2, 2, 2, matrix.Color333(0, 7, 7));
    matrix.drawLine(X - 1, Y + 3, X + 1, Y + 3, matrix.Color333(0, 7, 7));     // Mund
    matrix.drawPixel(X - 2, Y + 2, matrix.Color333(0, 7, 7));
    matrix.drawPixel(X + 2, Y + 2, matrix.Color333(0, 7, 7));
                                                                     
    X=25;                                                            // Roter Laufpunkt
    int Summand = 0;
    for (int i=0; i<480; i++) {
        if (X == 25) { Summand = 1;}
        if (X == 55) { Summand = -1;}
        X = X + Summand;
                 matrix.drawLine(X+1, 55, X+1, 56, matrix.Color333(0, 0, 0));  // Löschen
                 matrix.drawLine(X, 55, X, 56, matrix.Color333(7, 0, 0));      // Zeichnen
                 matrix.drawLine(X-1, 55, X-1, 56, matrix.Color333(0, 0, 0));  // Löschen
                 delay (20);                     
    }
    matrix.drawLine(X, 55, X, 56, matrix.Color333(0, 0, 0));                   // löschen
}
// *********************************************************************************************
        

Damit das Programm einwandfrei funktioniert, muss die Matrix-Bibliothek "RGBmatrixPanel.h" installiert werden.
Die Hauptaufgabe des Programms besteht darin, das analoge Signal von dem Drucksensor auszuwerten. Charakteristisch für den Sensor ist, dass das Signal bei Einwirkung einer Kraft oft ein Signal mit mehreren Spitzen liefert. Darüber hinaus kann festgestellt werden, dass das analoge Signal noch bestimmte Werte aufweist, obwohl die Krafteinwirkung bereits beendet ist.
Das Programm beginnt mit der Signalauswertung dann, wenn das Signal Werte über 20 liefert (Maximaler Wert bei 5V beträgt 1023). Die Abfrage, um zeitliche Verzögerungen abzufangen, dauert eine Sekunde lang. Es wird der maximale Wert, der in der Zeit gemessen wurde, berücksichtig. Alternativ könnte man an dieser Stelle einen Mittelwert bilden.
Der gemessene Wert wird mit einer senkrechten Balken-Säule auf der Matrix visualisiert. Die Säule besteht aus einer Reihe waagerechten Balken, die aus sechs Pixel bestehen.
Die Balkenanzeige beginnt direkt nach dem Hammerschlag, noch während der Abfrage des analogen Eingangs. Nach Ablauf einer Sekunde werden dann die restlichen Balken hinzugefügt.


Kurzvideo

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz