Ich wollte gerade mal schnell ein kleines Nano Projekt durchziehen, aber ich komme nicht weiter, weil es nur funktioniert, wenn ich unnatürlich fest auf den Sensor klopfe.
Es ist dieser flache Piezzo mit einer kleinen Verstärkerplatine.
Ich habe einen Timer laufen, der sofort anhalten soll, wenn ein moderates Geräusch (Klopfen auf den Tisch) registriert wird.
Ich hab den Digtalen Port 3 als Eingang für den Klopfsensor genommen, da ich da einen Interrupt aufsetzen kann.
Muß der Sensor an einen analogen Port?
Hier mal der code:
#include <Adafruit_NeoPixel.h> //Neopixel library
#include <TM1637.h> //Display
// Pin-Konfiguration
const int buttonPin = 2; // Pin, an dem der Taster angeschlossen ist
#define PIN 6 // Pin, an dem der Neopixel-Streifen angeschlossen ist
#define NUMPIXELS 5 // Anzahl der LEDs im Streifen
// Definiere die Pins für das TM1637-Modul
const int CLK = 4; // Takt-Pin des TM1637-Moduls
const int DIO = 5; // Daten-Pin des TM1637-Moduls
// Variablen für den Timer
unsigned long startTime = 0; // Startzeit des Timers
unsigned long elapsedTime = 0; // Gemessene Zeit in Millisekunden
bool timerRunning = false; // Status des Timers
bool lastButtonState = HIGH; // Status des Tasters beim letzten Überprüfen
// Erstelle ein NeoPixel-Objekt
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// Erstelle ein TM1637-Objekt
TM1637 display(CLK, DIO);
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Taster-Pin als Eingang mit internem Pullup-Widerstand
Serial.begin(9600); // Serielle Kommunikation starten
pixels.begin(); // Initialisiere die Neopixel-Bibliothek
pixels.show(); // Alle Pixel ausschalten
display.set(5); // Helligkeit des Displays einstellen (0-7)
attachInterrupt(digitalPinToInterrupt(3), stopTimer, RISING); // Interrupt an Pin 3 auf steigende Flanke setzen
}
void loop() {
bool buttonState = digitalRead(buttonPin); // Tasterzustand lesen
// Überprüfen, ob der Taster gedrückt wurde (fallende Flanke)
if (buttonState == LOW && lastButtonState == HIGH) {
if (!timerRunning) {
// Timer starten nach LED-Sequenz
startampel();
startTimer(); // Timer startet nach der LED-Sequenz
} else {
// Timer stoppen, wenn er bereits läuft
stopTimer();
}
delay(50); // Entprellen, um versehentliche Mehrfachauslösungen zu verhindern
}
// Aktuellen Status des Tasters für die nächste Abfrage speichern
lastButtonState = buttonState;
// Falls Timer läuft, die aktuelle Laufzeit anzeigen
if (timerRunning) {
displayTime(millis() - startTime); // Funktion zur Anzeige der laufenden Zeit aufrufen
}
delay(10); // Kurze Pause für glattere Ausgabe
}
// Funktion zum Setzen der Farbe eines einzelnen Pixels
void setPixelColor(int pixel, uint8_t red, uint8_t green, uint8_t blue) {
if (pixel >= 0 && pixel < NUMPIXELS) {
pixels.setPixelColor(pixel, pixels.Color(red, green, blue));
}
}
// Funktion zum Setzen der Farben mehrerer LEDs
void startampel() {
displayTime(0); //reset display
setPixelColor(0, 255, 0, 0); // first pixel out of the loop to get an immediate start
pixels.show();
for (int i = 1; i <= NUMPIXELS; i++) { // Setzt eine nach der anderen LED auf Rot
setPixelColor(i, 255, 0, 0);
delay(1000);
pixels.show();
}
for (int i = 0; i <= NUMPIXELS; i++) {
setPixelColor(i, 0, 255, 0); // Setzt alle LEDs auf Grün
}
pixels.show();
}
// Funktion zum Ausschalten aller LEDs
void clearAllPixels() {
for (int i = 0; i < NUMPIXELS; i++) {
setPixelColor(i, 0, 0, 0); // Setze jede LED auf schwarz (aus)
}
pixels.show(); // Zeige alle Änderungen an
}
// Funktion zum Starten des Timers
void startTimer() {
startTime = millis(); // Startzeit speichern
timerRunning = true;
Serial.println("Timer gestartet");
}
// Funktion zum Stoppen des Timers
void stopTimer() {
if (timerRunning) {
elapsedTime = millis() - startTime; // Gesamtzeit berechnen
displayTime(elapsedTime);
timerRunning = false;
clearAllPixels();
Serial.print("Timer gestoppt. Laufzeit: ");
Serial.print(elapsedTime / 1000.0, 2); // Umrechnung in Sekunden mit zwei Dezimalstellen
Serial.println(" Sekunden");
}
}
// Display
void displayTime(unsigned long Result) {
// Serial.println(Result); /
// Begrenze den Wert auf 4 Stellen, um das Display nicht zu überladen
if (Result > 60000) Result = 60000;
if (Result < 0) Result = 0;
int sekunden = Result / 1000; // Ganze Sekunden
int zehntelsekunden = (Result % 1000) / 100; // Zehntelsekunden
int hundertstelsekunden = (Result % 100) / 10;
display.display(0, sekunden / 10); // Zeigt die Zehnerstelle der Sekunden
display.display(1, sekunden % 10); // Zeigt die Einerstelle der Sekunden
display.point(1);
display.display(2, zehntelsekunden); // Zeigt die Zehntelsekunden
display.display(3, hundertstelsekunden);
}